在gdb中打破失败的断言的正确方法是什么?

21 c++ debugging gdb assert g++

我试图在我的程序中捕获失败的断言.我正在使用一个直接调用assert()的库,而不是自定义函数或宏,并且它在此库中我正在尝试跟踪几个与移植相关的错误.涉及的所有内容都使用g ++中的调试符号进行编译.

我找到的最好的解决方案是破坏文件:assert的行,以及assert表达式的条件.这允许在失败之前停止断言,但这是一个可怕的解决方案.它需要针对每个可能失败的断言进行特殊设置,不能在我的IDE中运行,并且通常需要付出太多努力.

如何以允许检查assert调用范围内的callstack和变量的方式使用gdb和gcc 中断任何失败的断言?

如果解决方案允许我放弃断言的失败并继续运行,那将会更好.

Pet*_*r M 24

设置断点abort()似乎是最好的答案.

break abort 在gdb的CLI中.

  • 这才是天才! (4认同)

Cir*_*四事件 5

没有break需要在Linux上,只需要输入bt上的提示

abort()导致SIGABRT在Linux中引发信号,并且默认情况下GDB已中断信号。例如:

交流电

#include <assert.h>

void g(int i) {
    assert(0);
}

void f(int i) {
    g(i);
}

int main(void) {
    f(1);
}
Run Code Online (Sandbox Code Playgroud)

然后:

gcc -std=c99 -O0 -ggdb3 -o a a.c
gdb -ex run ./a
Run Code Online (Sandbox Code Playgroud)

然后只需输入btshell:

(gdb) bt
#0  __GI_raise (sig=sig@entry=6) at ../sysdeps/unix/sysv/linux/raise.c:58
#1  0x00007ffff7a483ea in __GI_abort () at abort.c:89
#2  0x00007ffff7a3ebb7 in __assert_fail_base (fmt=<optimized out>, assertion=assertion@entry=0x555555554788 "0", file=file@entry=0x555555554784 "a.c", line=line@entry=4, 
    function=function@entry=0x55555555478a <__PRETTY_FUNCTION__.1772> "g") at assert.c:92
#3  0x00007ffff7a3ec62 in __GI___assert_fail (assertion=0x555555554788 "0", file=0x555555554784 "a.c", line=4, function=0x55555555478a <__PRETTY_FUNCTION__.1772> "g")
    at assert.c:101
#4  0x00005555555546ca in g (i=1) at a.c:4
#5  0x00005555555546df in f (i=1) at a.c:8
#6  0x00005555555546f0 in main () at a.c:12
Run Code Online (Sandbox Code Playgroud)

其中已经显示了功能值(f (i=1))。

您也可以照常执行:

(gdb) f 4
#4  0x00005555555546ca in g (i=1) at a.c:4
4           assert(0);
(gdb) p i
$1 = 1
Run Code Online (Sandbox Code Playgroud)

用于控制GDB默认情况下是否断开信号的设置为:handle all nostop如以下所示:如何处理GDB中的所有信号

已在Ubuntu 16.10,gdb 7.11中测试。

  • 注意:在某些平台上(例如,在某些Windows外壳下的MinGW),gdb看不到SIGABRT信号,因此程序仅在assert上死掉而没有停止gdb,但是在中止上设置断点仍然有效。 (2认同)