I want to record synchronization operations, such as locks, sempahores, barriers of a multithreaded application, so that I can replay the recorded application later on, for the purpose of debugging.
我想记录同步操作,例如锁,sempahores,多线程应用程序的障碍,以便我可以稍后重放录制的应用程序,以便进行调试。
On way is to supply your own lock, sempaphore, condition variables etc.. functions that also do logging, but I think that is an overkill, because down under they must be using some common synchronization operations.
在路上是提供你自己的锁,sempaphore,条件变量等..也做日志记录的功能,但我认为这是一个矫枉过正,因为他们必须使用一些常见的同步操作。
So my question is which synchronization operations I should log so that I require minimum modifications to my program. In other words, which are the functions or macros in glibc and system calls over which all these synchronization operations are built? So that I only modify those for logging and replaying.
所以我的问题是我应该记录哪些同步操作,以便我对程序进行最少的修改。换句话说,构建所有这些同步操作的glibc和系统调用中的函数或宏是什么?所以我只修改那些用于记录和重放。
2 个解决方案
#1
1
The best I can think of is debugging with gdb in 'record' mode:
我能想到的最好的是在“记录”模式下使用gdb进行调试:
- Gdb process record/replay execution log
Gdb进程记录/重放执行日志
According to this page: GDB Process Record threading support is underway, but it might not be complete yet.
根据这个页面:GDB Process Record线程支持正在进行中,但它可能尚未完成。
Less strictly answering your question, may I suggest
我可以建议,不那么严格地回答你的问题
On other platforms, several other threading checkers exist, but I haven't got much experience with them.
在其他平台上,存在其他几个线程检查程序,但我对它们没有多少经验。
#2
1
In your case, an effective method of "logging" systems calls on Linux may be to use the LD_PRELOAD trick, and over-ride the actual system calls with your own versions of the calls that will log the use of the call and then forward to the actual system call.
在您的情况下,在Linux上“记录”系统调用的有效方法可能是使用LD_PRELOAD技巧,并使用您自己的调用版本覆盖实际系统调用,这些调用将记录调用的使用,然后转发到实际的系统调用。
A more extensive example is given here in Linux Journal.
Linux Journal中给出了一个更广泛的例子。
As you can see at these links, the basic gist of the "trick" is that you can make the system load your own dynamic library before any other system libraries, such as pthreads, etc., and then mask the calls to those library functions by placing your own versions of those functions as the precendent. You can then, inside your over-riding function, log the use of the original function, as well as pass on the arguments to the actual call you're attempting to log.
正如您在这些链接中看到的,“技巧”的基本要点是,您可以使系统在任何其他系统库(如pthread等)之前加载您自己的动态库,然后屏蔽对这些库函数的调用将这些函数的自己版本作为优先级。然后,您可以在您的覆盖函数内部记录原始函数的使用,并将参数传递给您尝试记录的实际调用。
The nice thing about this method is it will catch pretty much any call you can make, both a function that remains entirely in user-land, as well as a function that will make a kernel call.
关于这个方法的好处是它几乎可以捕获你可以进行的任何调用,既可以完全保留在用户区中,也可以用来调用内核函数。
#1
1
The best I can think of is debugging with gdb in 'record' mode:
我能想到的最好的是在“记录”模式下使用gdb进行调试:
- Gdb process record/replay execution log
Gdb进程记录/重放执行日志
According to this page: GDB Process Record threading support is underway, but it might not be complete yet.
根据这个页面:GDB Process Record线程支持正在进行中,但它可能尚未完成。
Less strictly answering your question, may I suggest
我可以建议,不那么严格地回答你的问题
On other platforms, several other threading checkers exist, but I haven't got much experience with them.
在其他平台上,存在其他几个线程检查程序,但我对它们没有多少经验。
#2
1
In your case, an effective method of "logging" systems calls on Linux may be to use the LD_PRELOAD trick, and over-ride the actual system calls with your own versions of the calls that will log the use of the call and then forward to the actual system call.
在您的情况下,在Linux上“记录”系统调用的有效方法可能是使用LD_PRELOAD技巧,并使用您自己的调用版本覆盖实际系统调用,这些调用将记录调用的使用,然后转发到实际的系统调用。
A more extensive example is given here in Linux Journal.
Linux Journal中给出了一个更广泛的例子。
As you can see at these links, the basic gist of the "trick" is that you can make the system load your own dynamic library before any other system libraries, such as pthreads, etc., and then mask the calls to those library functions by placing your own versions of those functions as the precendent. You can then, inside your over-riding function, log the use of the original function, as well as pass on the arguments to the actual call you're attempting to log.
正如您在这些链接中看到的,“技巧”的基本要点是,您可以使系统在任何其他系统库(如pthread等)之前加载您自己的动态库,然后屏蔽对这些库函数的调用将这些函数的自己版本作为优先级。然后,您可以在您的覆盖函数内部记录原始函数的使用,并将参数传递给您尝试记录的实际调用。
The nice thing about this method is it will catch pretty much any call you can make, both a function that remains entirely in user-land, as well as a function that will make a kernel call.
关于这个方法的好处是它几乎可以捕获你可以进行的任何调用,既可以完全保留在用户区中,也可以用来调用内核函数。