gdb断点在多线程C程序中断言on

时间:2016-09-08 19:58:09

标签: c++ multithreading gdb

我使用assert中的<cassert>来检查多线程C ++ 11程序中的不变量。当断言失败时,我希望能够在失败的断言时检查失败函数的状态,以及仍然完整的回溯,变量状态等。问题似乎是SIGABRT和我的线程之间的一些交互,因为我的std::threadpthread_kill,可能是由某个默认信号处理程序。如何在断言失败时暂停gdb?

以下是我尝试过的一些事情:

  1. SIGABRT上设置一个抓点。这种情况确实发生了,但为时已晚(__pthread_kill)。

  2. 定义__assert_fail,即extern中声明的<assert.h>,并在其上设置gdb断点。这从来没有被捕获,所以假设pthread在被调用之前被杀死了(?)。

  3. 这里推荐的方法是什么?

2 个答案:

答案 0 :(得分:4)

我做了以下事情:

示例程序:

#include <cassert>
void f2()
{   
    assert(0);
}   

void f1()
{   
   f2();
}   

int main()
{   
    f1();
}  

现在我设置了一个断点到f2,希望我可以在stepi之后逐步使用断言:

gdb > break f2
gdb > run
Breakpoint 11, f2 () at main.cpp:5
gdb > stepi // several times!!!!
0x080484b0 in __assert_fail@plt ()

唉唉!我们可以看到stepi转到符号,告诉我们有一个具有该名称的函数。因此,只设置__assert_fail@plt

的断点
gdb > break __assert_fail@plt
gdb > run
Breakpoint 11, f2 () at main.cpp:5

(gdb) bt
#0  0x080484b0 in __assert_fail@plt () 
#1  0x080485f7 in f2 () at main.cpp:5
#2  0x08048602 in f1 () at main.cpp:10
#3  0x0804861b in main () at main.cpp:15

适合我!

答案 1 :(得分:0)

如果由于某种原因你需要断言断言,Klaus对__assert_fail中断的回答是绝对正确的。

然而,事实证明,设置断点以在多线程程序中查看gdb中的堆栈跟踪根本就没有必要,因为gdb已经在SIGABRT中断并切换了中止线程。在我的情况下,我有一个错误配置的库,导致这个红鲱鱼。如果您尝试使用多线程程序在gdb中查看来自中止代码(SIGABRT)的堆栈跟踪,则无需在gdb中执行任何操作(假设已使用默认信号处理程序)。

仅供参考,您可以通过运行info signals来查看默认信号处理程序,并通过运行SIGABRT来查看info signals SIGABRT相同的信号处理程序。在我的机器上,我看到了这一点,显示该程序将被停止,等等。如果由于某种原因,SIGABRT信号处理程序未设置为在SIGABRT停止,则需要更改该设置。有关详情,请访问https://sourceware.org/gdb/onlinedocs/gdb/Signals.html

(gdb) info signals SIGABRT
Signal        Stop  Print   Pass to program Description
SIGABRT       Yes   Yes Yes     Aborted