reflect: call of reflect.Value.Int on ptr

PrinnyQ · 2017-08-20 15:30:20 · 1509 次点击 · 大约8小时之前 开始浏览    置顶
这是一个创建于 2017-08-20 15:30:20 的主题,其中的信息可能已经有所发展或是发生改变。

服务器运行几个月了,最近突然panic在rpc的gob encode函数中,应用层逻辑很简单,所以暂时不太清楚是哪里的问题,正在学习go的rpc源码和gob编码的源码。panic信息如下:

panic: reflect: call of reflect.Value.Int on ptr Value [recovered]
    panic: reflect: call of reflect.Value.Int on ptr Value
goroutine 52598456 [running]:
encoding/gob.catchError(0xc4209e10d0)
    /root/go/src/encoding/gob/error.go:38 +0x95
panic(0xc40860, 0xc42606ad00)
    /root/go/src/runtime/panic.go:489 +0x2cf
reflect.Value.Int(0xbcdec0, 0xc4251fe520, 0x196, 0x196)
    /root/go/src/reflect/value.go:902 +0xb5
encoding/gob.encInt(0xc423ab4ae0, 0xc422da1e40, 0xbcdec0, 0xc4251fe520, 0x196)
    /root/go/src/encoding/gob/encode.go:188 +0x43
encoding/gob.(*Encoder).encodeStruct(0xc4209e1040, 0xc4209e1078, 0xc421a28a20, 0xcc1be0, 0xc4251fe510, 0x199)
    /root/go/src/encoding/gob/encode.go:334 +0x256
encoding/gob.(*Encoder).encode(0xc4209e1040, 0xc4209e1078, 0xcc1be0, 0xc4251fe510, 0x199, 0xc4209c3480)
    /root/go/src/encoding/gob/encode.go:707 +0x1d3
encoding/gob.(*Encoder).EncodeValue(0xc4209e1040, 0xc95bc0, 0xc4251fe510, 0x16, 0x0, 0x0)
    /root/go/src/encoding/gob/encoder.go:250 +0x3ab
encoding/gob.(*Encoder).Encode(0xc4209e1040, 0xc95bc0, 0xc4251fe510, 0x0, 0x0)
    /root/go/src/encoding/gob/encoder.go:175 +0x61
net/rpc.(*gobServerCodec).WriteResponse(0xc422b51ec0, 0xc422d737d0, 0xc95bc0, 0xc4251fe510, 0xc422b43a40, 0xc422b4a350)
    /root/go/src/net/rpc/server.go:424 +0x1dd
net/rpc.(*Server).sendResponse(0xc420055680, 0xc422b45aa0, 0xc421c4ff00, 0xc95bc0, 0xc4251fe510, 0x1334ac0, 0xc422b51ec0, 0x0, 0x0)
    /root/go/src/net/rpc/server.go:366 +0x130
net/rpc.(*service).call(0xc422afe900, 0xc420055680, 0xc422b45aa0, 0xc422b4ec00, 0xc421c4ff00, 0xbc3800, 0xc427ab07e0, 0x16, 0xc95bc0, 0xc4251fe510, ...)
    /root/go/src/net/rpc/server.go:394 +0x22e
created by net/rpc.(*Server).ServeCodec
    /root/go/src/net/rpc/server.go:481 +0x404

源码大致如下:

type RpcArgs struct{
    A string
    B int32
    C string
    D int32
    E String
    F int32 
    G int32
    H int32 
    I bool
    J string
    K int32
    L String
    M int32 
    N int32
    O int32 
    P bool
}
func RPC1(args *RpcArgs, reply *int){
    //some simple logic
    ....
    //do another async rpc call,and then painc in gob encode
    rpc.Client.Go(serviceMethod, args, reply, make(chan *rpc.Call, 1))
}

在encodeStruct里,紧接着调用的是encInt函数,但是最终panic时发现要解析的数据类型是Ptr.不知道有人遇到过这样的问题没,谢谢!


有疑问加站长微信联系(非本文作者)

入群交流(和以上内容无关):加入Go大咖交流群,或添加微信:liuxiaoyan-s 备注:入群;或加QQ群:692541889

1509 次点击  
加入收藏 微博
6 回复  |  直到 2017-08-21 02:19:44
polaris
polaris · #1 · 8年之前

根据错误信息,貌似需要使用 reflect.Value.Elem().Int()

注:这个年代,markdown 语法一点都不了解吗?再说了发布页面右侧有 markdown 语法的简单说明啊!

PrinnyQ
PrinnyQ · #2 · 8年之前
polarispolaris #1 回复

根据错误信息,貌似需要使用 `reflect.Value.Elem().Int()`。 注:这个年代,markdown 语法一点都不了解吗?再说了发布页面右侧有 markdown 语法的简单说明啊!

哦,谢谢提醒。第一次提交时点快了,没调整好格式,我随后就修改了,我这现在看没问题了。 堆栈信息从第一行到最后一行都是go的源码里的函数调用,而且我想不是reflect的使用问题导致,否则要错的话早就出错了

polaris
polaris · #3 · 8年之前

样式没问题是因为我修改了。

是不是通常传递的是 int 值,报错了传的是 int 指针?

PrinnyQ
PrinnyQ · #4 · 8年之前
polarispolaris #3 回复

样式没问题是因为我修改了。 是不是通常传递的是 int 值,报错了传的是 int 指针?

-_-!,多谢~看堆栈信息是在RPC返回的时候,net/rpc.(Server).sendResponse,也就是我那个func RPC1(args RpcArgs, reply int)函数在返回reply int的时候触犯异常的,在真实的函数里边,这个RPC1函数其实就是转发,都没有逻辑,reply在函数中也没有调用和任何赋值,等rpc流程走完直接就返回去了,但是却在encode的时候报错了。

PrinnyQ
PrinnyQ · #5 · 8年之前

-_-!,多谢~看堆栈信息是在RPC返回的时候,net/rpc.(Server).sendResponse,也就是我那个func RPC1(args RpcArgs, reply *int)函数在返回reply *int的时候触犯异常的,在真实的函数里边,这个RPC1函数其实就是转发,都没有逻辑,reply在函数中也没有调用和任何赋值,等rpc流程走完直接就返回去了,但是却在encode的时候报错了。

PrinnyQ
PrinnyQ · #6 · 8年之前

函数是这样,刚才的回复里少*,func RPC1(args RpcArgs, reply *int)

添加一条新回复 (您需要 登录 后才能回复 没有账号 ?)
  • 请尽量让自己的回复能够对别人有帮助
  • 支持 Markdown 格式, **粗体**、~~删除线~~、`单行代码`
  • 支持 @ 本站用户;支持表情(输入 : 提示),见 Emoji cheat sheet
  • 图片支持拖拽、截图粘贴等方式上传