我正在使用带有-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”。
答案 0 :(得分:1)
假设仅当foo(...)的返回值不等于“ Alice”时,我才想中断SomeSourceFile:123。
如果您转到较低的级别(汇编程序级别),并且代码是在没有优化的情况下构建的,那么这样做很容易。
如果您可以像这样修改源代码,也很简单:
if (foo(...) == "Alice") { ...
} else {
int x = 0; if (x) abort(); // break here
}
现在,您只需在第125行设置断点即可,
那么如何在不修改源代码的情况下做到这一点?
您必须了解,编译器会调用某些bool operator==()
,将返回值与true
或false
进行比较,并在条件为false时有条件地跳到if
的正文中
(gdb) info line 123
将为您提供为此源代码行生成的一系列说明。
分解该范围的指令将使您可以找到对operator==
的调用,并向您显示将EAX
(JE
或JNE
)与{{ 1}}或0
。
然后可以在条件跳转指令上设置断点,并使用1
(对于64位代码,请使用$EAX
)。