问题:使用json.Marshal将结构体解析成json时,程序panic了。
panic的提示为reflect: Field index out of range
使用的golang的版本是1.15,服务运行的服务器版本是CentOS Linux release 7.9.2009 (Core)
具体出错信息:
2021/04/22 18:19:21 http: panic serving 127.0.0.1:30418: reflect: Field index out of range
goroutine 15849 [running]:
net/http.(*conn).serve.func1(0xc00052a140)
/usr/local/go/src/net/http/server.go:1801 +0x147
panic(0x872fe0, 0x9a7690)
/usr/local/go/src/runtime/panic.go:975 +0x47a
encoding/json.(*encodeState).marshal.func1(0xc000329880)
/usr/local/go/src/encoding/json/encode.go:326 +0x85
panic(0x872fe0, 0x9a7690)
/usr/local/go/src/runtime/panic.go:969 +0x1b9
reflect.Value.Field(0x90a360, 0xc000112c00, 0x199, 0xffffffff, 0x454cc7, 0x0, 0xc000329538)
**/usr/local/go/src/reflect/value.go:854 +0xd9**
encoding/json.structEncoder.encode(0xc0002d6900, 0xf, 0x10, 0xc000290c60, 0xc0001d0200, 0x90a360, 0xc000112c00, 0x199, 0x100)
/usr/local/go/src/encoding/json/encode.go:745 +0x85
encoding/json.arrayEncoder.encode(0xc000290cc0, 0xc0001d0200, 0x86d800, 0xc0005ec348, 0x97, 0xc000110100)
/usr/local/go/src/encoding/json/encode.go:886 +0xd6
encoding/json.sliceEncoder.encode(0xc000170d80, 0xc0001d0200, 0x86d800, 0xc0005ec348, 0x97, 0x100)
/usr/local/go/src/encoding/json/encode.go:860 +0x8f
encoding/json.structEncoder.encode(0xc0000ebb00, 0x5, 0x8, 0xc000290cf0, 0xc0001d0200, 0x8dee60, 0xc0005ec340, 0x99, 0x8d0100)
/usr/local/go/src/encoding/json/encode.go:759 +0x2ab
encoding/json.(*encodeState).reflectValue(0xc0001d0200, 0x8dee60, 0xc0005ec340, 0x99, 0xc000320100)
/usr/local/go/src/encoding/json/encode.go:358 +0x82
encoding/json.(*encodeState).marshal(0xc0001d0200, 0x8dee60, 0xc0005ec340, 0x100, 0x0, 0x0)
/usr/local/go/src/encoding/json/encode.go:330 +0xf4
encoding/json.Marshal(0x8dee60, 0xc0005ec340, 0x8dee60, 0xc0005ec340, 0x0, 0x1, 0xa)
/usr/local/go/src/encoding/json/encode.go:161 +0x52
schedule.TaskExecResultHandler(0x9b8ec0, 0xc0002940e0, 0xc000374200)
**/home/lrf/gitlab/vrv-job/job-engine/schedule/web.go:258** +0x64e
net/http.HandlerFunc.ServeHTTP(0x945580, 0x9b8ec0, 0xc0002940e0, 0xc000374200)
/usr/local/go/src/net/http/server.go:2042 +0x44
github.com/gorilla/mux.(*Router).ServeHTTP(0xc0001283c0, 0x9b8ec0, 0xc0002940e0, 0xc000374000)
/home/lrf/golang/pkg/mod/github.com/gorilla/mux@v1.8.0/mux.go:210 +0xd3
net/http.serverHandler.ServeHTTP(0xc000294000, 0x9b8ec0, 0xc0002940e0, 0xc000374000)
/usr/local/go/src/net/http/server.go:2843 +0xa3
net/http.(*conn).serve(0xc00052a140, 0x9b9d80, 0xc0005ec000)
/usr/local/go/src/net/http/server.go:1925 +0x8ad
created by net/http.(*Server).Serve
/usr/local/go/src/net/http/server.go:2969 +0x36c
出错处代码:
type QueryTaskExecResult struct {
Code int `json:"code"`
Result []taskdb.TaskExecutor `json:"result"`
TotalPage int64 `json:"totalPage"`
TotalCount int64 `json:"totalCount"`
ErrMsg string `json:"errMsg"`
}
var result QueryTaskExecResult
...
by, err := json.Marshal(result) //出错行
panic处代码
846 // Field returns the i'th field of the struct v.
847 // It panics if v's Kind is not Struct or i is out of range.
848 func (v Value) Field(i int) Value {
849 if v.kind() != Struct {
850 panic(&ValueError{"reflect.Value.Field", v.kind()})
851 }
852 tt := (*structType)(unsafe.Pointer(v.typ))
853 if uint(i) >= uint(len(tt.fields)) {
854 panic("reflect: Field index out of range")
855 }
856 field := &tt.fields[i]
857 typ := field.typ
...
出错误时的操作
服务启了个http服务,然后一直使用postman进行查询操作,有几率触发该panic。
并且,调用json.Unmarshal解析入参时也有几率报reflect: Field index out of range
出现的频率很高,几乎是必现。
请教各位大神,这种挂在官方库中的地方,该如何排查?
我自己尝试复现没成功,是否能提供完整的可复现问题的代码?或者至少把taskdb.TaskExecutor是什么以及是怎么生成的说明下。
如果不能,
1.你可以在structEncoder.encode加日志调试。
2.应该是QueryTaskExecResult.Result导致的,仔细看看这个结构是不是并发不安全什么的