Go json Marshaller 恐慌 "call of reflect.Value.Int on zero Value"

Go json Marshaller panics with "call of reflect.Value.Int on zero Value"

我正在尝试解组具有多层嵌套的复杂结构中的一些数据(因此,不在此处复制结构)。然而,当代码上线时,我们开始在极少数情况下出现以下恐慌(难以量化,但可能是千分之一)。

下面是问题的堆栈跟踪:

panic: reflect: call of reflect.Value.Int on zero Value [recovered]
        panic: reflect: call of reflect.Value.Int on zero Value

    goroutine 568428 [running]:
    encoding/json.(*encodeState).marshal.func1(0xc0081d5c70)
            /usr/local/go/src/encoding/json/encode.go:305 +0x9a
    panic(0x13968c0, 0xc005c2f540)
            /usr/local/go/src/runtime/panic.go:679 +0x1b2
    reflect.Value.Int(...)
            /usr/local/go/src/reflect/value.go:986
    encoding/json.intEncoder(0xc0074b5dc0, 0x0, 0x0, 0x0, 0xc0038b0100)
            /usr/local/go/src/encoding/json/encode.go:522 +0x1d4
    encoding/json.mapEncoder.encode(0x1608760, 0xc0074b5dc0, 0x1385c20, 0xc00119f5e0, 0x195, 0x100)
            /usr/local/go/src/encoding/json/encode.go:706 +0x351
    encoding/json.structEncoder.encode(0xc0002ce600, 0x19, 0x21, 0xc00027ede0, 0xc0074b5dc0, 0x156c820, 0xc00119f510, 0x199, 0x520100)
            /usr/local/go/src/encoding/json/encode.go:664 +0x306
    encoding/json.ptrEncoder.encode(0xc00027ee10, 0xc0074b5dc0, 0x1397e80, 0xc00119f510, 0x16, 0x1390100)
            /usr/local/go/src/encoding/json/encode.go:810 +0xb1
    encoding/json.(*encodeState).reflectValue(0xc0074b5dc0, 0x1397e80, 0xc00119f510, 0x16, 0x100)
            /usr/local/go/src/encoding/json/encode.go:337 +0x82
    encoding/json.(*encodeState).marshal(0xc0074b5dc0, 0x1397e80, 0xc00119f510, 0xc003da0100, 0x0, 0x0)
            /usr/local/go/src/encoding/json/encode.go:309 +0x10b
    encoding/json.Marshal(0x1397e80, 0xc00119f510, 0x40be53, 0x13c4160, 0x1397e80, 0x1, 0x7fa9d5d348b0)
            /usr/local/go/src/encoding/json/encode.go:161 +0x52
    reingames.com/rm/user.(*userCore).MarshalBinary(0xc00119f510, 0x1397e80, 0xc00119f510, 0x7fa9d5d348b0, 0xc00119f510, 0x1)
            /home/shivam/goprojects/rmgs/go/user/profile.go:180 +0x37

我不知道从哪里开始调试它。有没有人经历过类似的事情?快速提问 - 竞争条件(在更新指针时编组指针)会导致这种恐慌吗?

谢谢

是的,一场比赛几乎可以导致任何事情,包括这个。如果您有任何测试要说,运行 go test -race。如果没有,或者没有任何结果,您可以考虑使用金丝雀构建 go build -race,但请参阅 the race detector documentation 了解有关这种情况下的性能和内存使用情况的注意事项。您可能只想自己检查代码以了解比赛。

开始调试的一种方法是:使用 recover() 指令捕获恐慌,并记录有关错误上下文的信息。

这不会“在行为中”捕获竞争条件,但它肯定会帮助您了解有关错误的更多信息(它是否总是出现在相同的元素上?元素是否仍处于有效状态?等等...)

最近也遇到这个问题,大家可以看看代码中是不是协程,有没有正确的slice操作。slice是依赖数组实现的。当底层数组有足够的容量时,追加操作不是只读操作,元素直接添加到数组的空闲位置。因此,多协程在对全局切片进行追加操作时,会操作相同的底层数据,造成读写冲突。导致Go异常json Marshaller.