仅当函数的返回值等于“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==()
,将返回值与true
或false
进行比较,当条件为假时,有条件地在if
的主体周围跳转。
(gdb) info line 123
将为您提供为此源代码行生成的一系列指令。
反汇编该范围的指令将允许您找到对operator==
的调用,并显示将EAX
(JE
或JNE
)与0
或1
进行比较的指令。
然后您可以在条件跳转指令上设置断点,并使用 $EAX
(或 $RAX
用于 64 位代码)作为该断点上的条件。
【讨论】:
以上是关于仅当函数的返回值等于“Value”时,gdb 是不是可以在函数上以非交互方式有条件地中断?的主要内容,如果未能解决你的问题,请参考以下文章
仅当 .includes() 使用 .find() 找到某些内容时才返回值