我正在尝试调试一个很少有死锁的自定义线程池实现。因此,我不能使用像gdb这样的调试器,因为在出现死锁之前,我已经单击了like 100次“启动”调试器。
目前,我在shell脚本中的无限循环中运行线程池测试,但这意味着我看不到变量等等。我正在尝试std::cout数据,但是这会减慢线程的速度,降低死锁的风险,这意味着我可以在收到消息之前用无限长时间等待大约1小时。然后我就不知道错误了,我需要更多的信息,这意味着多等一个小时.
如何有效地调试程序,使其一次又一次地重新启动,直到死锁?(或者也许我应该用所有的代码来回答另一个问题,以寻求帮助?)
提前谢谢你!
附加问题:如何检查std::condition_variable是否一切正常?您无法真正判断哪个线程处于休眠状态,或者在wait条件上是否发生了争用条件。
发布于 2015-01-04 22:37:21
有两种基本方法:
gdb program -ex 'run <args>' -ex 'quit'应该在调试器下运行程序,然后退出。如果程序仍然以一种或另一种形式存在(分段错误,或者您手动破坏了它),您将被要求确认。gdb <program> <pid>运行,以附加到正在运行的程序--只需等待死锁,然后附加。当附加调试器导致定时被更改,并且您不能再复制错误时,这尤其有用。这样,您就可以在循环中运行它,并在喝咖啡时等待结果。顺便说一句-我觉得第二个选择更容易。
发布于 2015-01-04 22:27:02
如果这是一种家庭作业--用更多的调试一次又一次地重新启动将是一种合理的方法。
如果有人为你等待的每一个小时付费,他们可能更愿意投资于一个支持基于重放的调试的软件,也就是说,一个软件记录程序所做的一切,每条指令,并允许你一次又一次地重复它,反复调试。因此,您没有添加更多的调试,而是记录发生死锁的会话,然后在死锁发生之前开始调试。你可以随心所欲地来回走动,直到你终于找到了罪魁祸首。
链接中提到的软件实际上支持Linux和多线程。
发布于 2018-04-28 07:23:40
基于Mozilla rr的开源重放调试
汉斯提到的基于重放的调试,但是有一个特别的开源实现是值得一提的: Mozilla rr。
首先执行记录运行,然后可以根据需要重放完全相同的运行次数,并在GDB中观察它,它保留一切,包括输入/输出和线程排序。
官方网站提到:
rr最初的动机是使间歇性故障的调试更容易
此外,rr允许GDB反向调试命令(如reverse-next )转到上一行,这使得查找问题的根本原因更加容易。
下面是rr在运行中的一个最小示例:如何转到GDB中的前一行?
https://stackoverflow.com/questions/27770896
复制相似问题