Freebsd 下 glx 的一点问题
最近特别忙,经常连续工作超过 10 小时。所以情绪也有点不稳定,有的应该在半小时处理完的问题,会拖上几个小时。比如昨天就碰到一个。
由于底层代码由我一个人做了大规模重构(在不改变中间层的基础上做的),大约修改了一万多行代码,上百个 C 文件,其中重写了数千行。这样的变动实在太大,以至于出了罕见的问题后,很让人头痛。新的代码在 Windows 和 Ubuntu 上都一切正常,惟独在 Freebsd 上,程序退出的时候会引起一个 core dump 。
我对 gdb 调试器的高阶运用显然经验不足,加上这几年写代码也不怎么调试。(IMHO ,与其增加调试能力,不如提高设计能力和编写高质量代码的能力;让 bug 不容易出现,或是把 bug 限制在很小的范围,比解决 bug 更重要)在尝试过初步的调试后,我还是使用大脑做静态分析。确定问题出在 so 文件的显式关闭 (主动调用 dlclose)的环节。
根据常规推断,如果在 dlclose 后,程序异常,最可能是其它模块引用了其中的代码段,或静态数据段。实际现象中,进程崩溃在 C 的 main 函数返回之后。而我的系统整个是用 C 构建的,不会有 C++ 里那么多的跟这些有关的相关问题。所以可以推断是进程隐式加载的 so 最后卸载时发生的问题。
这个合乎逻辑的推理最终也基本得到证实,看起来很简单。不知道昨天我怎么就吃错药了,足足浪费了 4 小时来得到结论。
实际调试过程是这样的。我用二分法去掉某些代码,想看看把测试程序缩减到什么程度,问题会消失。这显然是个不肯动脑子的傻方案。鉴于精神不佳,姑且原谅一下。凡是愚蠢的方法,在有效的同时,一定是件体力活。干的时间久点就可以理解了。最终我发现,在 X Window 创建之后,为了隐藏鼠标光标,我调用了一个 X 的 API :XCreateBitmapFromData 。如果不调这个 API ,系统结束后就没有问题。但这个 API 本身调用是成功的。
在没有经过大脑的状态下,我拼命的往这个小洞里钻。又是怀疑 API 传入的参数,又是怀疑 XLib 的工作方式。接着,我又发现了另外几个 X 调用会引起问题。全部的现象都是,调用时成功,程序结束时崩溃。当然具体情况也分两类,一类是毫无朕兆,另一类是,调整一些次序,会提前得到 X Server 发过来的错误。这后一类近一步的加深了我的错觉。
最终,我发现,即使不改变代码,修改最终编译的链接参数也会引起问题。
如果程序只链接 GL 库,就一切正常。但是多链接一个 GLU 或是别的跟 openGL 有关的库,例如 GLEW ,就会在程序退出的时候崩溃。即使,我缩减后的测试代码里没有用到任何 GLU 或 GLEW 里的函数也一样。
当然,测试代码里使用了 glx 的一个 API ,必须链接 GL 库。
暂时还不能确定引起进程崩溃的 bug 直接的罪魁祸首在哪个位置。还是多休息一下,精力充沛时再回头来看比较好。好在 freeBSD 上有全部相关源码,我的桌面也是 buildworld 出来的,等周一再仔细看看吧。
虽然程序世界里,因果关系往往都非常明显,远没有现实世界那么复杂。但偶而也会遇到一些棘手的问题。当然是否棘手取决于你对系统的犄角旮旯的了解程度。或许你难以理解的问题,换个具有相关知识的人就变的一览无遗。就好象 Windows 上的木马病毒泛滥,许多用户在中招后毫无察觉;但 Windows Geek 们不装所谓杀毒软件,一有异向就会立刻察觉到。
链接,其实是个很复杂的过程。有经验的程序员一不小心也会中招。我曾经帮同事查过一个跟 lua 有关的问题,最终就是因为错误的链接导致进程内同时存在了两份 lua core 的代码。导致某些静态变量有了两份。这种问题往往会被隐藏很久,最终会以奇怪的形式暴露出来,而超出一般程序员的调试能力。
btw, 我认为,这次遇到的问题以前就存在,只是这次重构暴露出来而已。因为早先的代码,我自己完成了链接和二进制模块加载的过程。这次我想简化这个环节,更依赖系统提供的相关机制。
3 月 25 日补充:
问题的根本原因见:libstdc++ 卸载问题
Comments
Posted by: microcai | (20) December 6, 2010 04:34 AM
Posted by: Cloud | (19) April 2, 2009 05:00 PM
Posted by: 赵中 | (18) April 2, 2009 04:17 PM
Posted by: 赵中 | (17) April 2, 2009 04:12 PM
Posted by: mikeshi | (16) March 25, 2009 08:37 AM
Posted by: mikeshi | (15) March 24, 2009 04:29 PM
Posted by: Cloud | (14) March 24, 2009 02:00 PM
Posted by: mikeshi | (13) March 24, 2009 10:17 AM
Posted by: dreamfly | (12) March 23, 2009 04:54 PM
Posted by: Rain | (11) March 23, 2009 03:17 PM
Posted by: hacker47 | (10) March 23, 2009 08:21 AM
Posted by: Cloud | (9) March 23, 2009 12:47 AM
Posted by: analyst | (8) March 22, 2009 10:56 PM
Posted by: demon0 | (7) March 22, 2009 10:46 PM
Posted by: analyst | (6) March 22, 2009 10:34 PM
Posted by: sheep | (5) March 22, 2009 09:54 PM
Posted by: tangfl | (4) March 22, 2009 09:52 PM
Posted by: gg | (3) March 22, 2009 07:52 PM
Posted by: Anonymous | (2) March 22, 2009 07:34 PM
Posted by: 云端孤鹜 | (1) March 22, 2009 06:59 PM