技术头条 - 一个快速在微博传播文章的方式     搜索本站
您现在的位置首页 --> 算法 --> 一个链接 lua 引起的 bug , 事不过三

一个链接 lua 引起的 bug , 事不过三

浏览:1491次  出处信息

    今天花了将近 3 个小时帮同事看一个崩在 lua VM 中的 bug 结果打乱了进度,没有在年前把预想的东西做完。其实说起来这不是个大问题,以前也碰到过。我检讨自己没有在看到出错时的调用栈时去看一眼 lua 相关的代码。如果是那样,因为以前遇到过同样的问题,所以就可以条件反射出问题原因,而不用荒废宝贵了数小时时间了。

    唉,这下整合的进度没接上,过年不能自己一个人接着做下面的活了。

    下面记录一下这个 bug ,提醒自己第三次遇到时不用再花时间找问题:

    问题的缘由是因为的不同的 lua 扩展库链接的时候多链接了一份 lua 库,导致进程内有超过一份 lua 库。这是在写 Makefile 时不小心造成的。知道原因后自然很容易解决。要么把 lua 编译成 .so ;要么只有嵌入的主框架使用 -E 参数静态链接 lua 的静态库。这里就不展开说了。

    用了 lua 十年,绝对不是第一次帮其他用 lua 的同学指出这个问题。下面要讨论的是错误产生后,程序是怎么崩溃的。

    lua 的代码中几乎没有使用全局变量。就是说,lua 的 api 的相关状态仅存在于参数 L 中,而和库无关。这点 lua 实现的是很漂亮的。对于一个无外部状态的 api ,理论上无论代码段在进程内被链接再多次,都不会有副作用的。但副作用的确又发生了,为何?

    问题出在 ltable.c 中引用了一个静态全局变量 dummynode_ 。这个东西是做什么用的呢?

    在 lua table 实现中,为了不让 hash part 为空的时候不引用 NULL 指针(一种优化),而引用了这个 dummynode ,这样就可以减少操作表时的判断操作。

    由于这个 dummynode 是静态分配出来的特殊节点,所以是不能调用内存管理函数去释放它的。lua 另外用一个宏来判断一个节点是否为 dummynode 。

#define isdummy(n)      ((n) == dummynode)

    当进程中链接了多份 lua 库时,就出现了多份 dummynode 对象,自然 isdummy 的行为就可能不正确了。那么接下来的释放工作则会崩掉,看起来段错误会发生在 lua_Alloc 中。

    问题多出现在运行过程中,向空 table 插入第一个 hash 值时,也就是 luaH_resize 函数的最后一行:

 if (!isdummy(nold))
    luaM_freearray(L, nold, cast(size_t, twoto(oldhsize))); /* free old array */

    或是关闭 lua state 时,释放 table 时,的 luaH_free 函数最前面:

  if (!isdummy(t->node))
    luaM_freearray(L, t->node, cast(size_t, sizenode(t)));

    之所以我把代码和出错位置列出来,是因为我今天不是第一次专门分析这个点了。如果我下午在刚出问题时,能够在看到 stack traceback 信息的函数名)luaH_resize 打开 lua 的源代码看一眼的话,我相信我能立刻回想起上次分析这个问题的情景,从而节省掉后来浪费在查别的地方上的无尽时间。

    希望经过这次,下次有人向我反应类似问题时,我能直接对应到问题。

建议继续学习:

  1. Nginx与Lua    (阅读:4691)
  2. Lua GC 的源码剖析 (2)    (阅读:3906)
  3. Ameba , 一个简单的 lua 多线程实现    (阅读:3594)
  4. Lua GC 的源码剖析 (4)    (阅读:3441)
  5. 使用 luajit 的 ffi 绑定 zeromq    (阅读:3363)
  6. Proto Buffers in Lua    (阅读:3150)
  7. Lua GC 的源码剖析 (1)    (阅读:3078)
  8. 一个 Lua 内存泄露检查工具    (阅读:3041)
  9. Lua GC 的源码剖析 (6) 完结    (阅读:2629)
  10. Lua GC 的源码剖析 (3)    (阅读:2345)
QQ技术交流群:445447336,欢迎加入!
扫一扫订阅我的微信号:IT技术博客大学习
<< 前一篇:Amazon DynamoDB详解
后一篇:累积发送模式 >>
© 2009 - 2024 by blogread.cn 微博:@IT技术博客大学习

京ICP备15002552号-1