Mar*_*yer 4 debugging multithreading gdb deadlock
我将 GDB 附加到用 pthreads 编写的死锁应用程序。大约有 10 个线程都被阻塞了,我想知道哪些线程持有哪些锁。这在使用 SOS.dll 的 WinDbg 中是可能的;这在 GDB 中可能吗?
在至少一种 Linux 版本上,C++11 std::mutex 有一个名为 __owner 的成员,它包含当前锁定互斥锁的线程的线程 ID。在 gdb 中使用“信息线程”会显示 gdb 使用的线程编号以及线程 ID(请参阅“LWP”编号),允许您切换到该线程(“线程 N”),然后检查调用堆栈(“backtrace ”)。
您应该询问的不是 GDB,而是您正在使用的特定 pthread 库和操作系统。
pthread 库通过一组系统调用与内核合作实现互斥体。如果其互斥体的实现嵌入了一些东西来将保存互斥体的最后一个线程绑定到互斥体数据结构中,那么您可以使用 GDB 来获取该信息。
您的内核可能会跟踪该信息。例如,在 Mac OS X 下,与内核调试工具包捆绑在一起的 GDB 脚本集合kgmacros包含一个showallmtx可以完全执行您想要的操作的命令。问题是:要使用它,您必须当时调试机器的内核,这意味着您需要使用不同的机器进行调试。
当然,您可能有一个/dev/kmem设备文件,只要您能找到它,它就可以让您在内核内存中浏览并访问必要的数据结构。
但这一切实际上取决于您的系统 - 您的 pthread 库和操作系统内核 - 而不是 GDB。
您还可以尝试创建类型的互斥体PTHREAD_MUTEX_ERRORCHECK;这将导致pthread_mutex_lock()返回EDEADLK而不是死锁。然后,您可以在发生这种情况时中断并重新启动非僵局流程。