【问题标题】:Ways to get strace-like output for Heisenbug为 Heisenbug 获得类似 strace 的输出的方法
【发布时间】: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。

标签: linux polling strace


【解决方案1】:

我通过以下方式解决了跟踪问题:

  1. 围绕相关系统调用预加载包装存根函数open()close()poll()
  2. 在 ramdisk 上创建的文件名中记录相关信息。

(实际问题是一场竞赛,内核的poll() 字符串访问pollfd 内存并返回EFAULT。)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-10-18
    • 2011-08-16
    • 2023-03-18
    • 1970-01-01
    • 1970-01-01
    • 2021-11-23
    相关资源
    最近更新 更多