仅当函数的返回值等于“ Value”时,gdb才能有条件地非交互地中断函数吗?

时间:2018-06-27 18:47:13

标签: c++ linux debugging unix gdb

我正在使用带有-x参数的gdb来进行调试,而不必在每个断点处交互式地继续。

[root@StackOverflow.com] $ cat gdb_cmds_01
b SomeSourceFile.cpp:123
commands
bt
cont
end

然后我将附加到在执行过程中使用SomeSourceFile.cpp的进程:

[root@StackOverflow.com] $ gdb -p 'pidof SomeRunningProgram' -x gdb_cmds_01
GNU gdb (GDB) Red Hat Enterprise Linux (7.2-92.el6)
...
<GDB outputs a set S of backtraces as instructed by gdb_cmds_01>

现在,让SomeSourceFile.cpp:123包含如下一行:

if (foo(person, &place, *time) == "Alice") { ... <do stuff > ... }

然后假设仅当foo(...)的返回值等于“ Alice”时,我才想在SomeSourceFile:123上断开输入。

基于: How to inspect the return value of a function in GDB?,我知道gdb可以检查函数的返回值。

https://sourceware.org/gdb/onlinedocs/gdb/Break-Commands.html告诉我,我可以非交互式地检查变量的值:

  

<...>

     

例如,这是当x为正数时,可以使用断点命令在foo的入口处打印x值的方法。

break foo if x>0
commands
silent
printf "x is %d\n",x
cont
end
  

<...>

我尝试过类似的事情:

[root@StackOverflow.com] $ cat gdb_cmds_01
b SomeSourceFile.cpp:123 if foo(person, &place, *time) != "Alice"
commands
bt
cont
end

但是GDB吐出来了:

gdb_cmds_01:1: Error in sourced command file:
No symbol "place" in current context.

这可以解决吗?

为了仅在foo(...) != "Alice"时才在SomeSourceFile.cpp:123上断开,我还可以非交互地检查函数的返回值吗?

换句话说,我只想查看回溯集合S的子集R,这样对于R中的所有回溯b,foo(...)的返回值总是不等于“ Alice”。

1 个答案:

答案 0 :(得分:1)

  

假设仅当foo(...)的返回值不等于“ Alice”时,我才想中断SomeSourceFile:123。

如果您转到较低的级别(汇编程序级别),并且代码是在没有优化的情况下构建的,那么这样做很容易。

如果您可以像这样修改源代码,也很简单

if (foo(...) == "Alice") { ...
} else {
  int x = 0; if (x) abort(); // break here
}

现在,您只需在第125行设置断点即可,

那么如何在不修改源代码的情况下做到这一点?

您必须了解,编译器会调用某些bool operator==(),将返回值与truefalse进行比较,并在条件为false时有条件地跳到if的正文中

(gdb) info line 123将为您提供为此源代码行生成的一系列说明。

分解该范围的指令将使您可以找到对operator==的调用,并向您显示将EAXJEJNE)与{{ 1}}或0

然后可以在条件跳转指令上设置断点,并使用1(对于64位代码,请使用$EAX)。