我正在寻找一种方法,当一个特定的断点在gdb中命中时做一些动作.
基本上我的程序中有一些memleak.当malloc和free函数命中时,我需要进入函数(步骤)并收集一些基本信息,如addr和size(基本上打印那些值).完成后恢复我的程序.
我们有什么好办法吗?
Fre*_*ihl 59
例如,以下是当x为正数时,如何使用断点命令在入口foo处打印x的值.
break foo if x>0
commands
silent
printf "x is %d\n",x
cont
end
Run Code Online (Sandbox Code Playgroud)
如果在命令列表中指定的第一个命令是silent,则不会打印关于在断点处停止的常规消息.对于要打印特定消息然后继续的断点,这可能是合乎需要的.如果其余命令都没有打印任何内容,则表示没有迹象表明已到达断点.silent仅在断点命令列表的开头有意义.
断点命令的一个应用是补偿一个错误,以便您可以测试另一个错误.在错误的代码行之后放置一个断点,给它一个条件来检测已经完成错误的情况,并给它命令为任何需要它们的变量赋值.以continue命令结束,以便程序不会停止,并以silent命令启动,以便不生成输出.这是一个例子:
break 403
commands
silent
set x = y + 4
cont
end
Run Code Online (Sandbox Code Playgroud)
Ben*_*Ben 50
澄清Fredrik的答案,commands(或者只是command,似乎)自动知道你只是设置一个断点.也就是说,Fredrik所展示的不是多行break命令,它是两个独立的命令:break和commands.它看起来像这样:
(gdb) break 989
Breakpoint 23 at 0x7fffe2761dac: file foo.cpp, line 989.
(gdb) command
Type commands for breakpoint(s) 23, one per line.
End with a line saying just "end".
>silent
>print result
>end
(gdb) c
Continuing.
$79 = {elems = {0, 0}}
(gdb)
Run Code Online (Sandbox Code Playgroud)
dprintf(动态printf)
https://sourceware.org/gdb/onlinedocs/gdb/Dynamic-Printf.html
对于打印物品的特定情况,这是最方便的解决方案:
dprintf <line>, "%u\n", variable
Run Code Online (Sandbox Code Playgroud)
它也可能比commands编译和注入代码更快,而不是将控制权交还给GDB来解释任意命令字符串.TODO我不知道这是否真的完成了.dprintfvs commands:dprintf vs break +命令+ continue之间有什么区别?
详细示例:
main.c中
#include <inttypes.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
int main(void) {
uint32_t i;
uint32_t r = 0;
for (i = 0; i < 10; ++i) {
r += i*i + 13*r*i + 17; /* LINE 10. */
}
printf("%" PRIu32 "\n", r);
return EXIT_SUCCESS;
}
Run Code Online (Sandbox Code Playgroud)
然后:
gcc -ggdb3 -O0 -std=c99 -o main main.c
gdb -batch -nh -q -ex 'dprintf 10, "%u %u\n", i, r' -ex 'run' ./main
Run Code Online (Sandbox Code Playgroud)
输出:
Dprintf 1 at 0x400545: file main.c, line 10.
0 0
1 17
2 256
3 6933
4 277346
5 14699371
6 970158528
7 3628079733
8 3070853710
9 317092431
3057168588
[Inferior 1 (process 14305) exited normally]
Run Code Online (Sandbox Code Playgroud)
在Ubuntu 16.04,GDB 8.2中测试.