我有一个申请。我有源代码(在C中)。无论如何我都可以编译它。添加我想要的任何工具。等等。但是,我不想用一堆printf来源代码。我希望能够生成某种类型的日志,该日志显示何时写入特定值(例如全局结构的某个成员)(其值更改)。我希望能够显示源文件和行号,以及新旧值。
我还希望能够按名称而不是地址指定值。但地址还可以。如果我可以指定一个函数本地的值,则可以获得奖励。
我仍在试图找出gdb的跟踪命令。任何帮助是极大的赞赏。感谢。
答案 0 :(得分:6)
首先,您需要确保使用调试符号编译程序,并且可能没有进行优化以使gdb最有用。对于gcc,那就是-g -O0
。
其次,您正在寻找的功能不是追踪,它的观察点。
(gdb) help watch
Set a watchpoint for an expression.
A watchpoint stops execution of your program whenever the value of
an expression changes.
所以,给出一些示例代码:
int main() {
int a;
a = 1;
a = 2;
return 0;
}
然后您可以在其上运行gdb,并且:
(gdb) b main
Breakpoint 1 at 0x80483a5: file test.c, line 4.
(gdb) run
Starting program: /tmp/test
Breakpoint 1, main () at test.c:4
4 a = 1;
(gdb) watch a
Hardware watchpoint 2: a
(gdb) c
Continuing.
Hardware watchpoint 2: a
Old value = -1207552288
New value = 2
main () at test.c:8
8 return 0;
由于存在堆栈而不是内存,它的工作有点滑稽。如果进行了优化,它的工作量会更少:a会被优化出来。
答案 1 :(得分:3)
如上所述,您需要在变量上设置观察点。
您使用“命令”命令
(gdb) help commands
Set commands to be executed when a breakpoint is hit.
Give breakpoint number as argument after "commands".
With no argument, the targeted breakpoint is the last one set.
The commands themselves follow starting on the next line.
Type a line containing "end" to indicate the end of them.
Give "silent" as the first line to make the breakpoint silent;
then no output is printed when it is hit, except what the commands print.
所以,从watch命令中找到观察点编号,并执行此操作(假设您的手表是第二次休息)
(gdp) commands 2
> print a
> cont
> end
假设a是你想要的变量。如果您对gdb提供的输出感到满意,则可以省略打印行。
您还可以使用原始断点中的命令设置观察点并继续。
答案 2 :(得分:1)
感谢@derobert和@peter!我终于回到了这个,这个:
break main
commands
watch somevar
commands
cont
end
cont
end
run
诀窍。当“somevar”是全局的,或者“main”的本地时,这种方法有效。如果“somevar”是anther函数的本地,只需将“main”替换为上面的函数名称。
将这些命令放在一个文件中(例如“gdbscript”)并运行gdb,如:
gdb -x gdbscript a.out