protobuf中set_allocated_xxx排雷


上周帮同事排了一个protobuf中set_allocated_xxx的雷。

L同事写的gtest单元测试总是报段错误,而且是在最后一个EXPECT_TRUE之后。由于测试的这段代码逻辑比较简单,就是把若干变量设置到protobuf格式的message中,然后再从message中取出来验证一遍。所以一开始,我们怀疑是gtest的使用姿势不对。

尴尬的是,和以往代码库里的test文件进行“姿势”对比之后,并没有发现什么问题。


于是,开始翻看前面的逻辑代码。突然,发现了一个set_allocated_xxx的陌生函数:为啥陌生呢?因为对于嵌套的message对象,我一般会使用mutable_xxx这种方式来设置属性。

allocated”,这个名字引起了我的注意。本能的,我觉得这里可能会引起指针问题。果然,L同事把一个栈上对象的指针填进了set_allocated_xxx的参数列表,而这个函数的说明是这样写的:

  • void set_allocated_foo(string value): Sets the string object to the field and frees the previous field value if it exists. If the string pointer is not NULL, the message takes ownership of the allocated string object and has_foo() will return true. Otherwise, if the value is NULL, the behavior is the same as calling clear_foo(). string
  • release_foo(): Releases the ownership of the field and returns the pointer of the string object. After calling this, caller takes the ownership of the allocated string object, has_foo() will return false, and foo() will return the default value.

也就是说,这里这个栈对象的指针被protobuf接管,在test结束时被销毁了两次:protobuf销毁一次,栈对象自己销毁一次。难怪每次都是在最后一个EXPECT_TRUE之后报错。


使用新函数,文档要看仔细啊。

另外,起函数名也要深思熟虑。设想,如果G记程序员犯懒,直接起一个set_xxx_message的函数名,那我们这个bug就不知道要查多久了==||


推荐阅读:

读写锁的性能一定更好吗
面向数据编程
scala中的传名调用

转载请注明出处: http://blog.guoyb.com/2018/03/10/pb-set-allocated/

欢迎使用微信扫描下方二维码,关注我的微信公众号TechTalking,技术·生活·思考:
后端技术小黑屋

Comments