【发布时间】:2013-03-26 03:29:12
【问题描述】:
我在 linux x64 进程中追逐 Heisenbug。 (使用调试器或 strace 附加到进程使问题永远不会发生。)当代码检测到故障并以这种方式附加 gdb 时,我已经能够进入无限循环,但它只是向我显示了一个文件应该工作的描述符 (fd) 不再有效。我真的很想了解 fd 的历史,因此尝试了 strace,但这当然不会让问题回购。
其他因素表明 gdb/strace 的问题在于时间。我尝试使用-etrace=desc 甚至-eraw=open 运行strace 并输出到ramdisk 以查看是否会以正确的方式减少strace 开销以触发问题,但没有成功。我尝试运行 strace+,但它比 strace 慢了一个数量级。
我附加的进程部分是我没有源代码访问权限的商业二进制文件,部分是我预加载到进程空间中的代码,所以printf-everywhere 不是 100% 可能的。
您对如何追踪 fd 历史有什么建议吗?
更新:添加了关于 strace+ 的注释
【问题讨论】:
-
程序是多线程的吗?也许
fd已在其他线程中关闭.... -
确实如此,这也是我非常喜欢操作系统对 fd 发生的事情的看法的另一个原因。
-
解决此类问题的正确方法是完全消除错误的可能性。重构您的代码,以便您有一个“拥有”一个文件的单个线程,该文件将直接打开、读取和关闭文件,并且其他线程只能请求从线程安全队列读取/写入(使用锁/计数信号量是另一种可能性,但队列通常更容易编写且更安全)。
-
@Lie Ryan:如果我拥有所有代码,这是可能的,但在这种情况下,我只控制预加载的代码,这就是为什么我仍在尝试获得有关如何监控外部 fd。