使用中有哪些问题
方法一:
func Encode(v *float32) []byte {
return unsafe.Slice((*byte)(unsafe.Pointer(v)), 4)
}
结束
方法2
func Encode(v float32) []byte {
return unsafe.Slice((*byte)(unsafe.Pointer(&v)), 4)
}
两者都在 Little Endian 系统上运行。唯一的区别是 Approach 1 接受指针作为参数,而 Approach 2 接受值作为参数。
我正在调试与
相关的问题fatal error: found bad pointer in Go heap (incorrect use of unsafe or cgo?)
found pointer to free object | bad use of unsafe.Pointer?
我终于发现根本原因可能是由于方法1的使用。有人可以告诉我方法 1 可能存在什么问题吗?一般推荐使用方法2吗?
请注意,
float32
是功能之一。还有其他编码函数也接受 byte arrays
、int8
等。
type Uuid [16]byte
func EncodeUuid(v *Uuid) []byte {
return unsafe.Slice((*byte)(unsafe.Pointer(v)), UuidSize)
}
这里的SO答案提到原始变量可以在调用
Encode()
函数之前被GC'ed。尝试访问已释放指针指向的内存可能会导致“找到指向自由对象的指针”错误。
以下是执行过程中发现的错误日志。
错误日志1
runtime: marked free object in span 0x7fef20c4c8a8, elemsize=24 freeindex=0 (bad use of unsafe.Pointer? try -d=checkptr)
0xc14a028000 free unmarked
0xc14a028018 free unmarked
0xc14a028030 free unmarked
0xc14a028048 free unmarked
0xc14a028060 free unmarked
0xc14a028078 free marked zombie
0x000000c14a028078: 0x000000c0003f2800 0x0000000000000800
0x000000c14a028088: 0x0000000000000800
0xc14a028090 free unmarked
0xc14a029fc8 free unmarked
0xc14a029fe0 free unmarked
fatal error: found pointer to free object
goroutine 1482447 [running]:
runtime.throw({0x29b9a01?, 0xc14a028090?})
/usr/lib/golang/src/runtime/panic.go:1047 +0x5d fp=0xc2555a2ae0 sp=0xc2555a2ab0 pc=0x44775d
runtime.(*mspan).reportZombies(0x7fef20c4c8a8)
/usr/lib/golang/src/runtime/mgcsweep.go:788 +0x2e5 fp=0xc2555a2b60 sp=0xc2555a2ae0 pc=0x435dc5
错误日志2
runtime: pointer 0xc079e0001d to unallocated span span.base()=0xc079dfe000 span.limit=0xc079e2e010 span.state=0
runtime: found in object at *(0xc032b5c180+0x28)
object=0xc032b5c180 s.base()=0xc032b5c000 s.limit=0xc032b5e000 s.spanclass=20 s.elemsize=128 s.state=mSpanInUse
*(object+0) = 0x0
*(object+8) = 0x400000016
*(object+16) = 0xffffffff00000020
*(object+24) = 0x3a665e0
*(object+32) = 0xc0dde3d110
*(object+40) = 0xc079e0001d <==
*(object+48) = 0x8000
*(object+56) = 0x8008
*(object+64) = 0x0
*(object+72) = 0x0
*(object+80) = 0x0
*(object+88) = 0x2
*(object+96) = 0x2000
*(object+104) = 0x6174620
*(object+112) = 0x101
*(object+120) = 0x0
fatal error: found bad pointer in Go heap (incorrect use of unsafe or cgo?)
错误日志3
fatal error: unexpected signal during runtime execution
[signal SIGSEGV: segmentation violation code=0x2 addr=0x450608 pc=0x468c46]
goroutine 1202 [running]:
runtime.throw({0x3f96b81?, 0x0?})
/usr/local/go/src/runtime/panic.go:1047 +0x5d fp=0xc006433cd0 sp=0xc006433ca0 pc=0x454c7d
runtime.sigpanic()
/usr/local/go/src/runtime/signal_unix.go:819 +0x369 fp=0xc006433d20 sp=0xc006433cd0 pc=0x46ce09
runtime.(*waitq).enqueue(...)
/usr/local/go/src/runtime/chan.go:766
runtime.selectgo(0xc006433fb0, 0xc006433ed8, 0x2710?, 0x0, 0x0?, 0x1)
/usr/local/go/src/runtime/select.go:317 +0x7c6 fp=0xc006433e80 sp=0xc006433d20 pc=0x468c46
任何建议都会非常有帮助!
PS: 当GC启动时,这个问题很少发生。因此,为了有积极的GC来测试场景,我目前正在使用
GODEBUG=invalidptr=1,cgocheck=1,madvdontneed=1 GOGC=2 GOMEMLIMIT=10MiB ./my-executable
我如何解决这个问题是通过执行以下步骤
GODEBUG=invalidptr=1,cgocheck=1,madvdontneed=1 GOGC=2 GOMEMLIMIT=10MiB
GODEBUG=invalidptr=1,cgocheck=1,madvdontneed=1 GOGC=2 GOMEMLIMIT=10MiB ./my-service
#!/bin/bash
for i in {1..30}
do
echo "$i"
rm -rf ./results/xxxx
python3 ./run.py -H127.0.0.1 -P6001 -p111 -udump -c ./cases/xxx/q1.sql
....
....
done
git bisect start
# May 5
git bisect bad xxxxx
# May 3
git bisect good xxxx
... build and run the code and tag it as good or bad.
curl -o heap.pprof "http://localhost:9876/debug/pprof/heap?seconds=30"