7

我想记录同步操作,例如多线程应用程序的锁、信号量、屏障,以便我以后可以重放记录的应用程序,以用于调试。

方法是提供您自己的锁、信号量、条件变量等。这些函数也可以进行日志记录,但我认为这是一种矫枉过正的做法,因为它们必须使用一些常见的同步操作。

所以我的问题是我应该记录哪些同步操作,以便我需要对我的程序进行最少的修改。换句话说,glibc 和系统调用中的哪些函数或宏是构建所有这些同步操作的基础?所以我只修改那些用于记录和重播。

4

3 回答 3

1

在您的情况下,在 Linux 上“记录”系统调用的一种有效方法可能是使用LD_PRELOAD技巧,并用您自己的调用版本覆盖实际的系统调用,这些调用将记录调用的使用,然后转发到实际的系统调用。

Linux Journal中给出了更广泛的示例。

正如您在这些链接中看到的那样,“技巧”的基本要点是您可以让系统在任何其他系统库(例如 pthread 等)之前加载您自己的动态库,然后屏蔽对这些库函数的调用通过将您自己的这些功能版本作为先例。然后,您可以在覆盖函数中记录原始函数的使用,并将参数传递给您尝试记录的实际调用。

这个方法的好处是它几乎可以捕捉到你可以进行的任何调用,包括一个完全保留在用户空间中的函数,以及一个将进行内核调用的函数。

于 2012-05-01T20:49:40.917 回答
1

我能想到的最好的方法是在“记录”模式下使用 gdb 进行调试:

根据此页面:GDB Process Record线程支持正在进行中,但可能尚未完成。


不太严格地回答你的问题,我可以建议吗

在其他平台上,存在其他几个线程检查器,但我对它们没有太多经验。

于 2012-05-01T20:53:32.637 回答
1

所以GDB记录模式不支持多线程,但是RR记录/回放系统绝对支持:https ://rr-project.org/ 。

对于技术限制较少的商业解决方案,还有 UDB:https ://undo.io/solutions/ 。

我已经在调试器上工作了几年,从我所看到的情况来看,GDB 记录+重放的东西实际上还没有为黄金时段做好准备,因为这个和其他原因(例如,速度慢和巨大的内存需求)。

如果您可以让它在您的开发环境中工作,那么记录+重播/可逆调试可能会极大地改变您的工作流程;我希望你能找到一种利用它的方法。

于 2020-12-05T16:45:29.643 回答