100个GDB小技巧(一)
来源:互联网 发布:js删除对象元素 编辑:程序博客网 时间:2024/05/20 15:10
本文是100个GDB小技巧阅读总结,100个GDB小技巧.
列出函数的名字
在这个例子中源代码如下:
#include <stdio.h>#include <pthread.h>void *thread_func(void *p_arg){ while (1) { sleep(10); }}int main(void){ pthread_t t1, t2; pthread_create(&t1, NULL, thread_func, "Thread 1"); pthread_create(&t2, NULL, thread_func, "Thread 2"); sleep(1000); return;}
然后保存文件为fucntion.c
gcc -g function.c -o function提示如下错误:
/tmp/ccCIJDjs.o: In function main':
pthread_create’
/root/function.c:14: undefined reference to
/root/function.c:15: undefined reference to `pthread_create’
collect2: error: ld returned 1 exit status
错误产生的原因是:
pthread库不是标准linux库,修改为如下方式即可:
gcc -pthread -g function.c -o function
然后gdb function即可.
退出正在调试的函数
例子
#include <stdio.h>int func(void){ int i = 0; i += 2; i *= 10; return i;}int main(void){ int a = 0; a = func(); printf("%d\n", a); return 0;}
技巧
当单步调试一个函数时,如果不想继续跟踪下去了,可以有两种方式退出。
第一种用“finish”命令,这样函数会继续执行完,并且打印返回值,然后等待输入接下来的命令。以上面代码为例:
(gdb) n17 a = func();(gdb) sfunc () at a.c:55 int i = 0;(gdb) n7 i += 2;(gdb) finfind finish(gdb) finishRun till exit from #0 func () at a.c:70x08050978 in main () at a.c:1717 a = func();Value returned is $1 = 20
可以看到当不想再继续跟踪func函数时,执行完“finish”命令,gdb会打印结果:“20”,然后停在那里。
第二种用“return”命令,这样函数不会继续执行下面的语句,而是直接返回。也可以用“return expression”命令指定函数的返回值。仍以上面代码为例:
(gdb) n17 a = func();(gdb) sfunc () at a.c:55 int i = 0;(gdb) n7 i += 2;(gdb) n8 i *= 10;(gdb) rerecord remove-inferiors return reverse-next reverse-steprefresh remove-symbol-file reverse-continue reverse-nexti reverse-stepiremote restore reverse-finish reverse-search(gdb) return 40Make func return now? (y or n) y#0 0x08050978 in main () at a.c:1717 a = func();(gdb) n18 printf("%d\n", a);(gdb) 4019 return 0;
可以看到“return”命令退出了函数并且修改了函数的返回值。
打印函数堆栈帧信息
例子
#include <stdio.h>int func(int a, int b){ int c = a * b; printf("c is %d\n", c);}int main(void) { func(1, 2); return 0;}
技巧
使用gdb调试程序时,可以使用“i frame”命令(i是info命令缩写)显示函数堆栈帧信息。以上面程序为例:
(gdb) b func
Breakpoint 1 at 0x4004d2: file main.c, line 4.
(gdb) r
Starting program: /root/play/main
Breakpoint 1, func (a=1, b=2) at a.c:5
5 printf(“c is %d\n”, c);
(gdb) i frame
Stack level 0, frame at 0x7fffffffe590:
rip = 0x40054e in func (a.c:5); saved rip = 0x400577
called by frame at 0x7fffffffe5a0
source language c.
Arglist at 0x7fffffffe580, args: a=1, b=2
Locals at 0x7fffffffe580, Previous frame’s sp is 0x7fffffffe590
Saved registers:
rbp at 0x7fffffffe580, rip at 0x7fffffffe588
(gdb) i registers
rax 0x2 2
rbx 0x0 0
rcx 0x0 0
rdx 0x7fffffffe688 140737488348808
rsi 0x2 2
rdi 0x1 1
rbp 0x7fffffffe580 0x7fffffffe580
rsp 0x7fffffffe560 0x7fffffffe560
r8 0x7ffff7dd4e80 140737351863936
r9 0x7ffff7dea560 140737351951712
r10 0x7fffffffe420 140737488348192
r11 0x7ffff7a35dd0 140737348066768
r12 0x400440 4195392
r13 0x7fffffffe670 140737488348784
r14 0x0 0
r15 0x0 0
rip 0x40054e 0x40054e
设置临时断点
#include <stdio.h>#include <pthread.h>typedef struct{ int a; int b; int c; int d; pthread_mutex_t mutex;}ex_st;int main(void) { ex_st st = {1, 2, 3, 4, PTHREAD_MUTEX_INITIALIZER}; printf("%d,%d,%d,%d\n", st.a, st.b, st.c, st.d); return 0;}
技巧
在使用gdb时,如果想让断点只生效一次,可以使用“tbreak”命令(缩写为:tb)。以上面程序为例:
(gdb) tb a.c:15
Temporary breakpoint 1 at 0x400500: file a.c, line 15.
(gdb) i b
Num Type Disp Enb Address What
1 breakpoint del y 0x0000000000400500 in main at a.c:15
(gdb) r
Starting program: /data2/home/nanxiao/a
Temporary breakpoint 1, main () at a.c:15
15 printf(“%d,%d,%d,%d\n”, st.a, st.b, st.c, st.d);
(gdb) i b
No breakpoints or watchpoints.
首先在文件的第15行设置临时断点,当程序断住后,用“i b”(”info breakpoints”缩写)命令查看断点,发现断点没有了。也就是断点命中一次后,就被删掉了。
条件断点
#include <stdio.h>int main(void){ int i = 0; int sum = 0; for (i = 1; i <= 200; i++) { sum += i; } printf("%d\n", sum); return 0;}
技巧
gdb可以设置条件断点,也就是只有在条件满足时,断点才会被触发,命令是“break … if cond”。以上面程序为例:
(gdb) start
Temporary breakpoint 1 at 0x4004cc: file a.c, line 5.
Starting program: /data2/home/nanxiao/a
Temporary breakpoint 1, main () at a.c:5
5 int i = 0;
(gdb) b 10 if i==101
Breakpoint 2 at 0x4004e3: file a.c, line 10.
(gdb) c
Continuing.
Breakpoint 2, main () at func.c:10
10 sum += i;
(gdb) p sum
$1 = 5050
可以看到设定断点只在i的值为101时触发,此时打印sum的值为5050。
忽略断点
#include <stdio.h>int main(void){ int i = 0; int sum = 0; for (i = 1; i <= 200; i++) { sum += i; } printf("%d\n", sum); return 0;}
在设置断点以后,可以忽略断点,命令是“ignore bnum count”:意思是接下来count次编号为bnum的断点触发都不会让程序中断,只有第count + 1次断点触发才会让程序中断。以上面程序为例:
(gdb) b 9
Breakpoint 1 at 0x4004e3: file hello.c, line 9.
(gdb) ignore 1 5
Will ignore next 5 crossings of breakpoint 1.
(gdb) r
Starting program: /root/play/hello
Breakpoint 1, main () at hello.c:9
9 sum += i;
Missing separate debuginfos, use: debuginfo-install glibc-2.12-1.149.el6.x86_64
(gdb) p i
$1 = 6
可以看到设定忽略断点前5次触发后,第一次断点断住时,打印i的值是6。如果想让断点从i=1处开始生效,可以将count置为0:“ignore 1 0”.
- 100个GDB小技巧(一)
- 100个gdb小技巧项目
- GDB 100个使用技巧
- gdb 一些小技巧
- [小技巧] gdb -tui
- GDB调试技巧(一)
- 100个Google+小技巧
- GDB的一些小技巧
- [每天一个Linux小技巧] gdb 下一次执行多个命令
- linux之gdb调试常用100个技巧
- 为JavaScript开发人员准备的 21 个小技巧(一)
- VC++编程100个小技巧
- 100个gcc小技巧项目
- VC15个小技巧
- GridView个小技巧
- VC20个小技巧
- Masonry2个小技巧
- docker15个小技巧
- 手把手教你实现线性回归模型
- 虚函数解释说明
- 红黑树下
- HDU 4786 Fibonacci Tree(最小生成树变式)
- vc2010创建lib和使用
- 100个GDB小技巧(一)
- vue依赖webpack的环境配置(一)
- 简单对比几个技术博客类网站
- SpringBoot入门(五)数据库操作入门
- C程序的存储区及堆与栈区别
- 计算机网络(2):其他补充
- Java重要的基础语法(一)
- 使用阿里云智能翻译接口案例——CSDN博客
- 在 golang 中使用 Json