GDB进阶之路_new
优点
不依赖于具体执行 环境。
缺点
编译速度慢,可执 行文件占用空间大, 运行时耗内存。 依赖于具体执行环 境是否有程序使用 的第三方库。
动态链接库(*.so)
编译速度快,编译 后的执行文件占用 空间小,省内存。
基础篇:GDB之必备
GDB 常用命令 命令
list (l) run (r) continue (c) next (n) step (s) print (p) quit (q) watch (w) break (b) 执行当前被调试的程序 从断点挂起处继续执行 执行一行源代码但不进入函数内部 执行一行源代码而且进入函数内部 打印变量值 终止 gdb 使你能监视一个变量的值而不管它何时被改变 在代码里设置断点, 这将使程序执行到这里时被挂起。
进阶篇:简单又不简单的命令
1、continue/step/next 分别简称c/s/n,很常用的命令,另外,还有一个 start命令,很方便的命令,其相 当于在程序首行设定一个断点 首行设定一个断点然后运行run。 首行设定一个断点 2、break 简称b,此外,我们一般都先入为地把break N当成break的基本格式,其实break 是可以跟条件表达式 条件表达式,比如 break cm_xxx.C:158 if x > 0xffff0000,这个功能有的 条件表达式 时候比watch好用多了。 3、print 调试程序过程中,可以用print来修改变量值 修改变量值,格式如下: 修改变量值 (gdb) print x=4 4、print 用print打印 打印STL容器 容器的方法: 打印 容器 void dump(std::map<int, int>& x) { for(std::map<int, int>::const_iterator i = x.begin()), j(x.end()); i != j; i++) printf(“x[%d] = %d”, i->first, i->second);}
进阶篇:变量查看的技巧
3、 打印unicode字符串信息,例如: (gdb) start Breakpoint 1 at 0x40055c: file a.C, line 6. Starting program: /home/zyy/a.out main () at a.C:6 6 char * szAnsi = "Innovating Together Across Borders"; (gdb) n 7 wchar_t * szUnicode =L"软通动力 创新无边界"; (gdb) 8 } (gdb) p szAnsi $1 = 0x400670 "Innovating Together Across Borders" (gdb) p szUnicode $2 = (wchar_t *) 0x400698 直接调用print命令无法打印汉字,只会列出首地址,所以我们要想个办法, 类似于前面的call功能,不过是利用gdb本身提供的接口和语法。
进阶篇:变量查看的技巧
A. 修改.gdbinit文件,该文件是gdb启动时读的一个配置项,提供了接口定 义,我们可以定义一个wprint接口,负责打印双字节。 define wprint set $fd = open("/tmp/wprint", 577) set $x = write($fd, $arg0, wcslen($arg0) * sizeof(wchar_t)) set $y = close($fd) shell wprint end B. 提供wprint命令的实现,并生成wprint可执行文件,如下: setlocale(LC_ALL, ""); const char* file_name = "/tmp/wprint"; FILE* f = fopen(file_name, "rb"); if(f == 0) {printf("Open '%s' error! ", file_name); return -1;} fseek(f, 0, SEEK_END); long file_size = ftell(f) + 1; fseek(f, 0, SEEK_SET); wchar_t* buf = (wchar_t*)malloc(file_size + sizeof(wchar_t)); int r = fread(buf, 1, file_size, f); buf[file_size / sizeof(wchar_t)] = 0; printf("%S ", buf); free(buf);
进阶篇:变量查看的技巧
C. 将wprint文件拷到/tmp和/usr/bin中,此时便相当于添加了一个wprint命 令。 (gdb) start Breakpoint 1 at 0x40055c: file a.C, line 6. Starting program: /home/zyy/a.out main () at a.C:6 6 char * szAnsi = "Innovating Together Across Borders"; (gdb) n 7 wchar_t * szUnicode =L"软通动力 创新无边界"; (gdb) 8 } (gdb) p szAnsi $1 = 0x400670 "Innovating Together Across Borders" (gdb) p szUnicode $2 = (wchar_t *) 0x400698 (gdb) wprint szUnicode 软通动力 创新无边界 (gdb)
进阶篇:变量查看的技巧
4、 查看内存 使用examine命令(简写是x)来查看内存地址中的值,语法如下(n、f、u 时可选参数): x/ n:表示显示内存的长度。 f:表示显示的格式。 u:表示从当前地址往后请求的字节数。 n/f/u三个参数可以一起使用。例如: 命令:x/3uh 0x54320 表示,从内存地址0x54320读取内容,h表示以双字节 为一个单位,3表示三个单位,u表示按十六进制显示。 其实用的最多的也最简单的,就是直接后面带上数字,每次显示一个4字节 的信息,从低字节开始数,例如: main () at a.C:6 6 char * tmp = "1234567890"; (gdb) p tmp $1 = 0x400670 "1234567890" (gdb) x /4 0x400670 0x400670: 0x34333231 0x38373635 0x00003039 0x00000000 (gdb)
GDB进阶之路
Consumer公共部件开发部 潘剑
目录
基础篇 进阶篇 高级篇
基础篇:GDB之必备
可执行程序生成过程
基础篇:GDB之必备
UNIX下用到的一些库
类型
静态链接库(*.a)
使用方式
在程序链接时,把 第三方的库文件链 接进可执行文件。 程序链接时,只把 依赖的动态链接库 的库名放入可执行 文件中。
查看整个程序断点信息,如断点的个数及其位置; (gdb)info break 查看整个程序断点信息,如断点的个数及其位置; Num Type Disp Enb Address What 1 breakpoint keep y 0x080483c4 in main at overflow.c:15 breakpoint already hit 1 time (gdb)info all 显示整个程序运行到此时,各个寄存器中的值; 显示整个程序运行到此时,各个寄存器中的值;
进阶篇:变量查看的技巧
1、 在GDB中,你可以随时查看以下三种变量的值: 全局变量(所有文件可见的) 静态全局变量(当前文件可见的) 局部变量(当前Scope可见的) 另外,变量冲突的情况下可以用域操作符“::”,可以文件指定或类、函数指 定,例如: file::variable function::variable 2、 固定长度打印数组信息 (gdb) p *array@3 $1 = {0, 1, 2} (gdb) p *array@10 $2 = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9} (gdb)
基础篇:GDB调试举例
(gdb)b 15 “b+数字”是在某一行设置一个断点,可以同时设置多个断点; 数字” 数字 是在某一行设置一个断点,可以同时设置多个断点; Breakpoint 1 at 0x80483c4: file overflow.c, line 15. (gdb)r 5 hello 运行程序,在设置的断点处停止。注意程序的运行规则,如加参数等; 运行程序,在设置的断点处停止。注意程序的运行规则,如加参数等; Starting program: /root/test/day7/a.out 5 hello Breakpoint 1, main (argc=3, argv=0xbfffdea4) at overflow.c:15 停止在断点处; 停止在断点处; 15 i=atoi(argv[1]); (gdb)p i $1 = -1073747112 (gdb)n 16 s=i; (gdb)p i $2 = 5 查看一下此时变量i的值; 查看一下此时变量 的值; 的值 由于i此时还未有值 出现一个随机的值; 此时还未有值, 由于 此时还未有值,出现一个随机的值; 单步执行程序后半部分; 单步执行程序后半部分; 显示执行的是哪一行; 显示执行的是哪一行; 查看执行上一步语句之后变量i的值; 查看执行上一步语句之后变量 的值; 的值
描述
列出产生执行文件的源代码的一部分
基础篇:GDB调试举例
#gcc -g a.c -o a.out #gdb a.out 编译时-g 打开调试选项; 编译时 打开调试选项; 注意gdb后面跟的是可执行程序; 后面跟的是可执行程序; 注意 后面跟的是可执行程序 GNU gdb 6.6 Copyright (C) 2006 Free Software Foundation, Inc. GDB is free software, covered by the GNU General Public License, and you are welcome to change it and/or distribute copies of it under certain conditions. Type "show copying" to see the conditions. There is absolutely no warranty for GDB. Type "show warranty" for details. This GDB was configured as "x86_64-suse-linux". (gdb)l l是list的缩写,是查看源程序内容的命令; 的缩写, 是 的缩写 是查看源程序内容的命令; 1 #include<stdio.h> 2 #include<string.h> 3 int main(int argc,char* argv[]) 4 { 5 unsigned short s; (gdb)<enter> 直接回车时重复执行上次的命令; 直接回车时重复执行上次的命令;