pthreads调试需要帮助

时间:2010-07-14 11:38:34

标签: debugging gdb pthreads

我有一个服务器 - 客户端程序,其中服务器和客户端都有多个线程。存在可变数量的客户端和服务器(例如3个服务器(副本),10个客户端)。我正在调试这个程序中的源文件。我认为存在某种僵局,可能如下:

服务器方法已经保留了互斥锁,来自客户端的请求会调用想要再次获取互斥锁的服务器方法。

该程序由测试脚本启动,该脚本生成服务器和客户端,并使客户端向服务器发送特定请求。我在可疑的代码区域中使用了以下代码来查看是否存在死锁,但它似乎无法正常工作,即代码既不会阻塞也不会阻塞:

if (pthread_mutex_lock(&a_mutex) == EDEADLK) {
    cout<<"couldnt acquire lock."<<endl;
}
else cout<<"acquired lock"<<endl;

我尝试使用gdb调试(通过附加一个正在运行的服务器进程)。我为a_mutex添加了“display”和“watch”(在不同的gdb运行中)。我得到以下表格的结果:

1: a_mutex = {__data = {__lock = 2, __count = 0, __owner = 4193, __kind = 0, __nusers = 2, 
{__spins = 0, __list = {__next = 0x0}}}, 
  __size = "\002\000\000\000\000\000\000\000a\020\000\000\000\000\000\000\002\000\000  \000\000\000\000", __align = 2}

我不知道上面输出中所有内容的含义,但我可以看到一个线程(4193)正在持有互斥锁。我看到了该线程的回溯(剪断):

#0  0xb8082430 in __kernel_vsyscall ()
#1  0xb7e347a6 in nanosleep () from /lib/tls/i686/cmov/libc.so.6
#2  0xb7e345be in sleep () from /lib/tls/i686/cmov/libc.so.6
#3  0x0804cb59 in class1::method1 (this=0xbfa9fe6c, clt=1, id=
    {static npos = 4294967295, _M_dataplus = {<std::allocator<char>> = {<__gnu_cxx::new_allocator<char>> = {<No data fields>}, <No data fields>}, _M_p = 0xb7c9c11c "l/%\b"}})
at file1.cc:33

我不知道错误的方式和位置。

我非常感谢您对以下问题的任何帮助:

  1. 调试此类条件/程序的好方法是什么?
  2. 如何检测死锁情况(即锁定被锁定和未被释放的位置)?
  3. 在这样的多进程程序中,有没有更好的方法来使用gdb? (即检查所有进程中的状态?配置gdb以在进程开始之前监视/显示变量?)
  4. 因为,当我在服务器启动后(通过测试器脚本)将gdb与服务器连接起来时,服务器可能已经在我要检查的代码之前已经超前了。我尝试在可疑区域之前添加一个睡眠(20)以帮助我使用gdb,但我认为这不是一个好方法。我还认为打开多个终端,手动启动服务器和客户端以及检查每个终端的状态也不是一个好主意(如果我错了请纠正我。)
  5. PS:我已经阅读了这个question

    非常感谢。

1 个答案:

答案 0 :(得分:4)

使用GDB并将其附加到挂起的程序。然后用 “线程应用所有bt”(我想但我没有系统方便)。

它会给你一个所有线程的回溯,你应该这样做 能够看到哪个线程正在做什么。

如果这个问题很容易重现,你可以使用strace来给出 你得到一些锁定信息。