主要是根据《Linux software debugging with GDB》、《用GDB调试程序》所做的笔记
一、初步
例子一: test.c
#include <stdio.h>
int func(int n)
{
int sum=0, i;
for(i=1; i<=n; i++)
{
sum+=i;
}
return sum;
}
main()
{
int i;
long result = 0;
for(i=1; i<=100; i++)
{
result += i;
}
printf("result[1-100] = %d \n", result );
printf("result[1-250] = %d \n", func(250) );
}
编译过程需要 -g 选项,使生成的可执行文件中包含调试信息
使用GDB调试:
tree@virtual:~/shell$ gdb test GNU gdb (Ubuntu/Linaro 7.4-2012.04-0ubuntu2.1) 7.4-2012.04 Copyright (C) 2012 Free Software Foundation, Inc. License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html> This is free software: you are free to change and redistribute it. There is NO WARRANTY, to the extent permitted by law. Type "show copying" and "show warranty" for details. This GDB was configured as "i686-linux-gnu". For bug reporting instructions, please see: <http://bugs.launchpad.net/gdb-linaro/>... Reading symbols from /home/tree/shell/test...done. (gdb) l 1 //list,显示源码 1 #include <stdio.h> 2 3 int func(int n) 4 { 5 int sum=0, i; 6 for(i=1; i<=n; i++) 7 { 8 sum+=i; 9 } 10 return sum; (gdb) //回车,重复上一次命令 11 } 12 13 14 main() 15 { 16 int i; 17 long result = 0; 18 for(i=1; i<=100; i++) 19 { 20 result += i; (gdb) b 16 //break,在16行处设置断点 Breakpoint 1 at 0x804841a: file test.c, line 16. (gdb) b func //在函数入口处设置断点 Breakpoint 2 at 0x80483ea: file test.c, line 5. (gdb) info b //查看断点信息 Num Type Disp Enb Address What 1 breakpoint keep y 0x0804841a in main at test.c:16 2 breakpoint keep y 0x080483ea in func at test.c:5 (gdb) r //run,运行程序 Starting program: /home/tree/shell/test
Breakpoint 1, main () at test.c:17 17 long result = 0; (gdb) n //next, 单步执行(next是单步步过, step是单步步入) 18 for(i=1; i<=100; i++) (gdb) n 20 result += i; (gdb) n 18 for(i=1; i<=100; i++) (gdb) n 20 result += i; (gdb) c //continue, 继续运行程序 Continuing. result[1-100] = 5050
Breakpoint 2, func (n=250) at test.c:5 5 int sum=0, i; (gdb) n 6 for(i=1; i<=n; i++) (gdb) p i //print, 打印变量i的值 $1 = -1207961320 (gdb) n 8 sum+=i; (gdb) n 6 for(i=1; i<=n; i++) (gdb) p sum $2 = 1 (gdb) n 8 sum+=i; (gdb) p i $3 = 2 (gdb) n 6 for(i=1; i<=n; i++) (gdb) p sum $4 = 3 (gdb) bt //backtrace, 查看函数堆栈 #0 func (n=250) at test.c:6 #1 0x08048461 in main () at test.c:24 (gdb) finish //退出函数 Run till exit from #0 func (n=250) at test.c:6 0x08048461 in main () at test.c:24 24 printf("result[1-250] = %d \n", func(250) ); Value returned is $5 = 31375 (gdb) c Continuing. result[1-250] = 31375 [Inferior 1 (process 3422) exited with code 027] (gdb) q //quit,退出GDB tree@virtual:~/shell$
|
二、断点和观察点进阶
例子二:test2.c
#include <stdio.h>
int wib(int no1, int no2)
{
int result, diff;
diff = no1 - no2;
result = no1 / diff;
return result;
}
int main(int argc, char *argv[])
{
int value, div, result, i, total;
value = 10;
div = 6;
total = 0;
for(i = 0; i < 10; i++)
{
result = wib(value, div);
total += result;
div++;
value--;
}
printf("%d wibed by %d equals %d\n", value, div, total);
return 0;
}
条件断点
root@virtual:/home/tree/shell# gdb test2 GNU gdb (Ubuntu/Linaro 7.4-2012.04-0ubuntu2.1) 7.4-2012.04 Copyright (C) 2012 Free Software Foundation, Inc. License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html> This is free software: you are free to change and redistribute it. There is NO WARRANTY, to the extent permitted by law. Type "show copying" and "show warranty" for details. This GDB was configured as "i686-linux-gnu". For bug reporting instructions, please see: <http://bugs.launchpad.net/gdb-linaro/>... Reading symbols from /home/tree/shell/test2...done. (gdb) b 21 if value != div //设置条件断点 Breakpoint 1 at 0x8048437: file test2.c, line 21. (gdb) info b Num Type Disp Enb Address What 1 breakpoint keep y 0x08048437 in main at test2.c:21 stop only if value != div (gdb) condition 1 value == div //使用condition更改在指定断点号上设置的条件 (gdb) info b Num Type Disp Enb Address What 1 breakpoint keep y 0x08048437 in main at test2.c:21 stop only if value == div (gdb) r Starting program: /home/tree/shell/test2
Breakpoint 1, main (argc=1, argv=0xbffff7c4) at test2.c:21 21 result = wib(value, div); (gdb) info locals //查看局部变量 value = 8 div = 8 result = 4 i = 2 total = 6 (gdb) info b Num Type Disp Enb Address What 1 breakpoint keep y 0x08048437 in main at test2.c:21 stop only if value == div breakpoint already hit 1 time
|
info b查看断点信息,Enb列指定了是否启用该断点。可使用disable <b number>、enable <b number>、delete <b number>来禁用、启用和彻底删除断点
观察点
当指定表达式的值改变时,监视点将中断程序执行,但必须在表达式中所使用的变量在作用域中时设置监视点。
root@virtual:/home/tree/shell# gdb test2
GNU gdb (Ubuntu/Linaro 7.4-2012.04-0ubuntu2.1) 7.4-2012.04 Copyright (C) 2012 Free Software Foundation, Inc. License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html> This is free software: you are free to change and redistribute it. There is NO WARRANTY, to the extent permitted by law. Type "show copying" and "show warranty" for details. This GDB was configured as "i686-linux-gnu". For bug reporting instructions, please see: <http://bugs.launchpad.net/gdb-linaro/>... Reading symbols from /home/tree/shell/test2...done. (gdb) b main Breakpoint 1 at 0x8048415: file eg1.c, line 15. (gdb) r Starting program: /home/tree/shell/test2
Breakpoint 1, main (argc=1, argv=0xbffff7b4) at eg1.c:15 15 value = 10; (gdb) watch div == value Hardware watchpoint 2: div == value (gdb) c Continuing. Hardware watchpoint 2: div == value
Old value = 0 New value = 1 main (argc=1, argv=0xbffff7b4) at eg1.c:19 19 for(i = 0; i < 10; i++)
(gdb) i locals value = 8 div = 8 result = 4 i = 1 total = 6 (gdb) i watch Num Type Disp Enb Address What 2 hw watchpoint keep y div == value breakpoint already hit 1 time
|