我将GDB附加到用pthreads编写的死锁应用程序。有大约10个线程都被阻止,我想知道哪些线程由哪些线程保持。这在使用SOS.dll的WinDbg中是可能的;这可能在GDB吗?
答案 0 :(得分:4)
在至少一种Linux版本中,C ++ 11 std :: mutex有一个名为__owner的成员,它包含当前锁定互斥锁的线程的线程ID。在gdb中使用“info threads”显示gdb使用的线程号以及线程ID(请参阅“LWP”号),允许您切换到该线程(“线程N”),然后检查调用堆栈(“回溯” “)。
答案 1 :(得分:3)
您应该询问的不是GDB,而是您正在使用的特定pthread库和操作系统。
pthread库通过一些系统调用与内核协作实现互斥。如果它的互斥锁实现嵌入了将互斥锁保存到互斥锁数据结构中的最后一个线程,则可以使用GDB来获取该信息。
您的内核可能会跟踪该信息。例如,在Mac OS X中,与内核调试工具包kgmacros
捆绑在一起的GDB脚本集合包含一个命令showallmtx
,它将完全按照您的意愿执行。问题:要使用它,你必须在当时调试机器的内核,这意味着你需要使用不同的机器进行调试。
当然,您可能有一个/dev/kmem
设备文件,只要您可以找到它,就可以在内核的内存中访问并访问必要的数据结构。
但这一切都取决于你的系统 - 你的pthread库和操作系统内核 - 而不是GDB。
您还可以尝试创建PTHREAD_MUTEX_ERRORCHECK
类型的互斥锁;这将导致pthread_mutex_lock()
返回EDEADLK
而不是死锁。然后,您可以在发生这种情况时中断并在非死锁进程中生根。
答案 2 :(得分:2)
GDB 可以能够显示此信息,但它们没有实现此功能:它需要调试器和线程库之间的合作,尽管libthread_db库。
Solaris下的DBX - 至少 - (来自Sun,它有帮助!)正确实现了这个feature(寻找锁部分)