unexpected fault address 0x0
fatal error: fault
[signal SIGSEGV: segmentation violation code=0x80 addr=0x0 pc=0x46639f]
goroutine 26 [running]:
runtime.throw({0x10bae71?, 0x0?})
/goroot/src/runtime/panic.go:992 +0x71 fp=0xc0002a70d0 sp=0xc0002a70a0 pc=0x436331
runtime.sigpanic()
/goroot/src/runtime/signal_unix.go:825 +0x305 fp=0xc0002a7120 sp=0xc0002a70d0 pc=0x44c585
aeshashbody()
/goroot/src/runtime/asm_amd64.s:1343 +0x39f fp=0xc0002a7128 sp=0xc0002a7120 pc=0x46639f
runtime.mapiternext(0xc00004e900)
/goroot/src/runtime/map.go:934 +0x2cb fp=0xc0002a7198 sp=0xc0002a7128 pc=0x41022b
runtime.mapiterinit(0xc000280400?, 0xc0001f8f70?, 0x0?)
/goroot/src/runtime/map.go:861 +0x228 fp=0xc0002a71b8 sp=0xc0002a7198 pc=0x40ff08
reflect.mapiterinit(0x40f81d?, 0xf094c0?, 0xc0001f8f78?)
/goroot/src/runtime/map.go:1373 +0x19 fp=0xc0002a71e0 sp=0xc0002a71b8 pc=0x462c19
github.com/modern-go/reflect2.(*UnsafeMapType).UnsafeIterate(...)
/gopath/pkg/mod/github.com/modern-go/reflect2@v1.0.1/unsafe_map.go:112
github.com/json-iterator/go.(*sortKeysMapEncoder).Encode(0xc0005d0ae0, 0xc0001383d8, 0xc00028ca80)
/gopath/pkg/mod/github.com/json-iterator/go@v1.1.10/reflect_map.go:291 +0x225 fp=0xc0002a7350 sp=0xc0002a71e0 pc=0x5e9045
github.com/json-iterator/go.(*onePtrEncoder).Encode(0xc00056d3a0, 0xc0005d0840, 0xc00004e900?)
/gopath/pkg/mod/github.com/json-iterator/go@v1.1.10/reflect.go:219 +0x82 fp=0xc0002a7388 sp=0xc0002a7350 pc=0x5e1502
github.com/json-iterator/go.(*Stream).WriteVal(0xc00028ca80, {0xf29420, 0xc0005d0840})
/gopath/pkg/mod/github.com/json-iterator/go@v1.1.10/reflect.go:98 +0x158 fp=0xc0002a73f8 sp=0xc0002a7388 pc=0x5e0818
github.com/json-iterator/go.(*frozenConfig).Marshal(0xc000150280, {0xf29420, 0xc0005d0840})
/gopath/pkg/mod/github.com/json-iterator/go@v1.1.10/config.go:299 +0xc9 fp=0xc0002a7490 sp=0xc0002a73f8 pc=0x5d7ac9
今天用go1.18编译了之前的项目运行的时候core了,代码里面使用了recover捕获,然后用runtime.Stack打印了现场,看了下堆栈的信息发现是我们在使用json-iterator时出的问题,找到json-iterator的github
https://github.com/json-iterator/go/issues/608
解决方案已经有了,执行go get github.com/json-iterator/go@v1.1.12
看了下主要改动是json-iterator引用的reflect2包,增加了一个go_below_118.go文件一个go_above_118.go文件,主要区别是mapiterinit这个函数
//go_above_118.go
//go:noescape
//go:linkname mapiterinit reflect.mapiterinit
func mapiterinit(rtype unsafe.Pointer, m unsafe.Pointer, it *hiter)
func (type2 *UnsafeMapType) UnsafeIterate(obj unsafe.Pointer) MapIterator {
var it hiter
mapiterinit(type2.rtype, *(*unsafe.Pointer)(obj), &it)
return &UnsafeMapIterator{
hiter: &it,
pKeyRType: type2.pKeyRType,
pElemRType: type2.pElemRType,
}
}
//go_below_118.go
//go:noescape
//go:linkname mapiterinit reflect.mapiterinit
func mapiterinit(rtype unsafe.Pointer, m unsafe.Pointer) (val *hiter)
func (type2 *UnsafeMapType) UnsafeIterate(obj unsafe.Pointer) MapIterator {
return &UnsafeMapIterator{
hiter: mapiterinit(type2.rtype, *(*unsafe.Pointer)(obj)),
pKeyRType: type2.pKeyRType,
pElemRType: type2.pElemRType,
}
}
之所以这么改动原因是go1.18修改了mapiterinit接口,本来mapiterinit接口没有导出,奈何reflect2使用了骚操作go:linkname来引用非导出的接口,完美绕过了编译器,所以编译的时候虽然少了一个入参也没有报错,直到运行的时候才coredump
可以看下go1.18相较于go1.17的改动
go1.18
go1.17