libuv 定时器错误使用引发的惨案

今天我们正在开发的游戏在测试过程中,服务器又挂了,用gdb加载core文件后看到最后的堆栈信息如下

Program terminated with signal SIGSEGV, Segmentation fault.
#0  0x00007fa57d86da66 in uv_timer_init (loop=0x7fa57da7bc80 <default_loop_struct>, handle=0x2081e28) at src/unix/timer.c:55
#1  0x000000000043d326 in Room::Room(int, bool) ()
#2  0x00000000004437e7 in RoomManager::creatRoom(std::vector<Player, std::allocator<Player> >&) ()
#3  0x0000000000491506 in AsyncCreateRoomTask::run() ()
#4  0x000000000040accf in timer_cb(uv_timer_s*) ()
#5  0x00007fa57d86df1e in uv__run_timers (loop=loop@entry=0x7fa57da7bc80 <default_loop_struct>) at src/unix/timer.c:165
#6  0x00007fa57d861f72 in uv_run (loop=0x7fa57da7bc80 <default_loop_struct>, mode=UV_RUN_DEFAULT) at src/unix/core.c:350
#7  0x0000000000409ca9 in main ()

查看libuv的源码,是下面代码引起的错误

uv__handle_init(loop, (uv_handle_t*) handle, UV_TIMER);

对应的宏定义是

#define uv__handle_init(loop_, h, type_)                                      \
  do {                                                                        \
    (h)->loop = (loop_);                                                      \
    (h)->type = (type_);                                                      \
    (h)->flags = UV__HANDLE_REF;  /* Ref the loop when active. */             \
    QUEUE_INSERT_TAIL(&(loop_)->handle_queue, &(h)->handle_queue);            \
    uv__handle_platform_init(h);                                              \
  }                                                                           \
  while (0)

检查了loop和uv_timer_t均为有效指针,并且排除有多线程的竞争操作。

查看uv_timer_t的loop和type以及flags都正常赋值,于是基本锁定错误源在QUEUE_INSERT_TAIL 这个插入队列尾部的操作。
在尾部插入操作中,需要将loop的pre指向节点的next设置为uv_timer_t,但是读取loop的pre指向的是一个未分配内存的地址,然后触发了段错误。
 
下午几个小时经过细致的代码检查,终于找到了错误原因:libuv一个timer的结束需要调用uv_close,而原来一直只调用了uv_timer_stop,并且把uv_timer_t给delete掉了。由于没有调用uv_close,uv_timer_t还在loop的handle_queue中,在很小的机会下,系统之后又将原来这个uv_timer_t的空间分配给了其他对象,而这个对象刚好又修改到了原来handle_queue的next指针,让它的变成了一个未分配的内存地址,然后在新定时器加入进行插入队列的操作时候触发了段错误。
 
 

转载于:https://www.cnblogs.com/doublerain/p/8667724.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值