仅当函数的返回值等于“Value”时,gdb 是不是可以在函数上以非交互方式有条件地中断?

Posted

技术标签:

【中文标题】仅当函数的返回值等于“Value”时,gdb 是不是可以在函数上以非交互方式有条件地中断?【英文标题】:Can gdb conditionally break non-interactively on function only if the function's return value is equal to "Value"?仅当函数的返回值等于“Value”时,gdb 是否可以在函数上以非交互方式有条件地中断? 【发布时间】:2018-06-27 18:47:13 【问题描述】:

我正在使用带有 -x 参数的 gdb,以便在无需在每个断点处以交互方式继续进行调试。

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

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

[root@***.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@***.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】:

假设我只想在 foo(...) 的返回不等于“Alice”的情况下中断 SomeSourceFile:123。

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

如果您可以像这样修改源代码,这也是微不足道的

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

现在你可以简单地在第 125 行设置断点,你就完成了。

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

你必须明白,编译器调用了一些bool operator==(),将返回值与truefalse进行比较,当条件为假时,有条件地在if的主体周围跳转。

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

反汇编该范围的指令将允许您找到对operator== 的调用,并显示将EAXJEJNE)与01 进行比较的指令。

然后您可以在条件跳转指令上设置断点,并使用 $EAX(或 $RAX 用于 64 位代码)作为该断点上的条件。

【讨论】:

以上是关于仅当函数的返回值等于“Value”时,gdb 是不是可以在函数上以非交互方式有条件地中断?的主要内容,如果未能解决你的问题,请参考以下文章

如何检查 GDB 中函数的返回值?

oracle怎么写IF语句?

仅当 .includes() 使用 .find() 找到某些内容时才返回值

MySQL函数和操作符

PostgreSQL 中的分组限制:显示每个组的前 N ​​行,但仅当这些行中的第一行等于特定数据时

Javascript/Jquery-如何检查函数是不是返回任何值?