繁体   English   中英

如何调试罕见的死锁?

[英]How to debug a rare deadlock?

我正在尝试调试很少有死锁的自定义线程池实现。 所以我不能使用像gdb这样的调试器,因为我在遇到死锁之前点击了100次“启动”调试器。

目前,我在shell脚本的无限循环中运行线程池测试,但这意味着我无法看到变量等等。 我正在尝试std::cout数据,但这会减慢线程并减少死锁的风险,这意味着我可以在获取消息之前等待1小时的无限。 然后我没有得到错误,我需要更多的消息,这意味着再等一个小时......

如何有效地调试程序,以便它一遍又一遍地重启直到它死锁? (或者我应该用所有代码打开另一个问题以获得一些帮助?)

先感谢您 !

奖金问题:如何使用std::condition_variable检查一切正常? 您无法确定哪个线程处于睡眠状态或者在wait条件下是否出现竞争条件。

有两种基本方法:

  1. 在调试器下自动运行程序。 使用gdb program -ex 'run <args>' -ex 'quit'应该在调试器下运行程序,然后退出。 如果程序仍以某种形式存在(段错误,或者您手动破坏),则会要求您确认。
  2. 重现死锁连接调试器。 例如,gdb可以作为gdb <program> <pid>运行以附加到正在运行的程序 - 只需等待死锁然后附加即可。 当附加的调试器导致更改时间并且您无法再重置错误时,这尤其有用。

通过这种方式,您可以在循环中运行它并在喝咖啡时等待结果。 顺便说一句 - 我发现第二种选择更容易。

如果这是某种功课 - 一次又一次地重新启动调试将是一种合理的方法。

如果有人为你等待的每一个小时付钱,他们可能更愿意投资支持基于重放的调试的软件,即一个记录程序所做的一切的软件,每条指令,并允许你一次又一次地重放它,来回调试。 因此,不是添加更多调试,而是记录发生死锁的会话,然后在发生死锁之前开始调试。 你可以随心所欲地来回走动,直到你终于找到了罪魁祸首。

链接中提到的软件实际上支持Linux和多线程。

您可以使用https://stackoverflow.com/a/8657833/341065中显示的命令在GDB中运行测试用例: gdb --eval-command=run --eval-command=quit --args ./a.out

我自己也用过这个:( (while gdb --eval-command=run --eval-command=quit --args ./thread_testU ; do echo . ; done)

一旦它死锁并且没有退出,你可以通过CTRL + C中断它进入调试器。

查找死锁的简单快速调试是将一些全局变量修改为您要调试的位置,然后将其打印在信号处理程序中。 您可以使用SIGINT(使用ctrl+c打断时发送)或SIGTERM(杀死程序时发送):

int dbg;

int multithreaded_function()
{
  signal(SIGINT, dbg_sighandler);
  ...
  dbg = someVar;
  ...  
}

void  dbg_sighandler(int)
{
  std::cout << dbg1 << std::endl;
  std::exit(EXIT_FAILURE);
}

就像你用ctrl+c中断程序时,你只看到所有调试变量的状态。

另外,你可以在shell循环中运行它:

$> while [ $? -eq 0 ]
   do
   ./my_program
   done

这将永远运行你的程序,直到它失败( $?是你的程序的退出状态,你退出信号处理程序中的EXIT_FAILURE)。

它对我来说效果很好,尤其是找出在锁定之前和之后传递了多少线程。

它非常质朴,但您不需要任何额外的工具,并且实施起来很快。

Mozilla rr基于开源重放的调试

https://github.com/mozilla/rr

Hans 提到了基于重放的调试 ,但有一个特定的开源实现值得一提:Mozilla rr

首先进行记录运行,然后您可以根据需要重复完全相同的运行,并在GDB中观察它,并保留所有内容,包括输入/​​输出和线程排序。

官方网站提到:

rr最初的动机是让间歇性故障的调试变得容易

此外, rr使GDB调试反转的命令,如reverse-next去前行,这使得它更容易找到问题的根源。

以下是rr的最小示例: 如何转到GDB中的上一行?

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM