logo资料库

GDB教程完全版.pdf

第1页 / 共26页
第2页 / 共26页
第3页 / 共26页
第4页 / 共26页
第5页 / 共26页
第6页 / 共26页
第7页 / 共26页
第8页 / 共26页
资料共26页,剩余部分请下载后查看
GDB 教程 GDB 是一个强大的命令行调试工具。大家知道命令行的强大就是在于,其可以形成执行 序列,形成脚本。UNIX 下的软件全是命令行的,这给程序开发提供了极大的便利,命令行 软件的优势在于,他们可以非常容易的集成在一起,使用几个简单的已有工具的命令,就可 以做出一个非常强大的功能。 于是 UNIX 下的软件比 windows 下的软件更能有机的结合,各自发挥各自的长处,组合 成更为强劲。而 windows 下的图形软件基本上各自为营,互相不能条用,很不利于各种软 件的相互集成。在这里并不是要和 windows 做个什么比较,所谓“寸有所长,尺有所短”, 图形化工具还是有不如命令行的地方。 用 GDB 调试程序 GDB 概述 GDB 是 GNU 开源组织发布的一个强大的 UNIX 下调试程序工具。或许各位比较喜欢那种 图形界面方式的,像 VC,BCB 等 IDE 的调试,但如果你是在 UNIX 平台下作软件,你会 发现 GDB 这个调试工具有比 VC,BCB 的图形化调试器更强大的功能。所谓“寸有所长, 尺有所短”就是这个道理。 一般来说,GDB 主要帮助你完成下面四个方面的功能: 1、启动你的程序,可以按照你自定义的要求随心所欲的运行程序。 2、可以让调试程序在你所指定的位置的断点处停止。 3、当程序停止时,可以检查此时你的程序中所发生的事情。 4、动态的改变你程序的执行环境。 从上面看来,GDB 和一般的调试工具没有什么两样,基本上也是完成这些功能,不过在 细节上,你会发现 GDB 这个调试工具的强大,大家可能习惯图形化的调试工具,但有时候, 命令行的调试工具却有着图形化工具所不能完成的功能。 让我们来看一个例子: 源程序:test.c 1 #include 2 3 int func(int n) 4 { 5 int sum=0,i; 6 for(i=0; i
14 main() 15 { 16 int i; 17 long result = 0; 18 for(i=1; i<=100; i++) 19 { 20 result += i; 21 } 22 23 printf("result[1-100] = %d \n", result ); 24 printf("result[1-250] = %d \n", func(250) ); 25 } 编译生成执行文件: gcc –g test.c –o test 使用 GDB 调试: gdb test ——————启动 GDB GNU gdb 5.1.1 Copyright 2002 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 "i386-suse-linux"... (gdb) list ——————从第一行列出源码 1 #include 2 3 int func(int n) 4 { 5 int sum=0,i; 6 for(i=0; i
19 { 20 result += i; (gdb) break 16 ——————设置断点,在源程序第 16 行处。 Breakpoint 1 at 0x8048496: file tst.c, line 16. (gdb) break func ——————设置断点,在函数 func()入口处。 Breakpoint 2 at 0x8048456: file tst.c, line 5. (gdb) info break ——————查看断点信息。 Num Type Disp Enb Address What 1 breakpoint keep y 0x08048496 in main at tst.c:16 2 breakpoint keep y 0x08048456 in func at tst.c:5 (gdb) run ——————运行程序 Starting program: /home/hchen/test/tst Breakpoint 1, main () at tst.c:17 ——————在断点处停住。 17 long result = 0; (gdb) next ——————单条语句执行。 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) continue ——————继续运行程序 Continuing. result[1-100] = 5050 ——————程序输出。 Breakpoint 2, func (n=250) at tst.c:5 5 int sum=0,i; (gdb) n 6 for(i=1; i<=n; i++) (gdb) print i ——————打印变量 i 的值。 $1 = 134513808 (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 ——————p 是 print 的缩写
$4 = 3 (gdb) bt ——————查看函数堆栈 #0 func (n=250) at tst.c:5 #1 0x080484e4 in main () at tst.c:24 #2 0x400409ed in __libc_start_main () from /lib/libc.so.6 (gdb) finish ——————推出函数 Run till exit from #0 func (n=250) at tst.c:5 0x080484e4 in main () at tst.c:24 24 printf("result[1-250] = %d \n", func(250) ); Value returned is $6 = 31375 (gdb) continue Continuing. result[1-250] = 31375 ——————程序输出。 Program exited with code 027.——————程序退出,调试结束。 (gdb) quit ——————退出 gdb 好了,有了以上的感性认识,还是让我们来系统的认识一下 gdb 吧。 使用 GDB 一般来说 GDB 主要调试的是 C/C++程序。要调试 C/C++程序,首先在编译时,我们必须 要把调试信息加到可执行文件中。使用编译器(cc/gcc/g++)的-g 参数可以做到这一点,如: $ cc –g hello.c –o hello $ g++ -g hello.cpp –o hello 如果没有-g,你将看不见程序的函数名,变量名,所代替的全是运行的内存地址。当你用 -g 把调试信息假如之后,并成功编译目标代码以后,让我们来看看如果用 GDB 调试它。 启动 GDB 的方法有以下几种: 1、 gdb program 也就是你的执行文件,一般在当前目录下。 2、 gdb core 用 gdb 同时调试一个运行程序和 core 文件,core 是程序非法执行后 core dump 后产生 的文件。 3、 gdb 如果你的程序是一个服务程序,那么你可以指定这个服务程序运行时的进程 ID。gdb 会自动 attach 上去,并调试它。program 应该在 PATH 环境变量中搜索到。 GDB 启动时,可以加上一些 GDB 的启动开关,详细的开关可以用 gdb –help 来查看。下 面只列举一些比较常用的参数: -symbols -s 从指定文件中读取符号表。 -se file 从指定文件中读取符号表信息,并把他用在可执行文件中。
-core -c 调试 core dump 的 core 文件。 -directory -d 加入一个源文件的搜索路径。默认搜索路径是环境变量中 PATH 所定义的路径。 GDB 的命令概貌 启动 gdb 后,就进入了 gdb 的调试环境,就可以使用 gdb 的命令开始调试程序了,gdb 的 命令可以使用 help 命令来查看,如下所示: (gdb) help List of classes of commands: aliases -- Aliases of other commands breakpoints -- Making program stop at certain points data -- Examining data files -- Specifying and examining files internals -- Maintenance commands obscure -- Obscure features running -- Running the program stack -- Examining the stack status -- Status inquiries support -- Support facilities tracepoints -- Tracing of program execution without stopping the program user-defined -- User-defined commands Type "help" followed by a class name for a list of commands in that class. Type "help" followed by command name for full documentation. Command name abbreviations are allowed if unambiguous. (gdb) gdb 的命令很多,gdb 把之分成很多种类。help 命令只是列出了 gdb 的命令种类,如果要 看种类中的命令,使用 help 命令,如:help breakpoints,查看设置断点的所有命令。 也可以直接 help 来查看命令的帮助。 Gdb 中,输入命令时,可以不用打全命令,只用打命令的前几个字符就可以了,当然,命 令的前几个字符要标志着一个唯一的命令,在 linux 下,可以敲击两次 TAB 键来补齐命令的 全称,如果有重复的,gdb 会把其列出来。 示例一:在进入函数 func 时,设置一个断点。可以敲击 break func,或者直接就是 b func (gdb) b func Breakpoint 1 at 0x8048458: file hello.c, line 10. 示例二:敲入 b 按两次 TAB 键,你会看到所有 b 开头的命令:
(gdb) b backtrace break bt 示例三:只记得函数的前缀,可以这样: (gdb) b make_<按 TAB 键> make_a_section_from_file make_environ make_abs_section make_function_type make_blockvector make_pointer_type make_cleanup make_reference_type make_command make_symbol_completion_list (gdb) b make_ GDB 把所有 make 开头的函数全部列出来给你查看。 示例四:调试 C++程序,可以函数名一样。如: (gdb) b ‘bubble(<按两次 TAB 键> bubble(double,double) bubble(int,int) (gdb) b ‘bubble 你可以查看到 C++中所有的重载函数以及参数 要退出 GDB,只要 quit 或命令简称 q 就行了。 GDB 中运行 UNIX 的 Shell 程序 在 gdb 环境中,你可以执行 UNIX 的 shell 命令,使用 gdb 的 shell 命令来完成: shell 调用 UNIX 的 shell 来执行,环境变量 SHELL 中定义的 UNIX 的 shell 将会被用来执行,如果 SHELL 没有定义,那就使用 UNIX 的标准 shell: /bin/sh 还有一个 gdb 命令是 make: make 可以在 gdb 中执行 make 命令来重新 build 自己的程序。这个命令等价于“make make ” 在 GDB 中运行程序 1、 当以` set args 可指定运行时参数。(如:set args 10 20 30 40 50) show args 命令可以查看设置好的运行参数。 2、 运行环境 path可设定程序的运行路径。 show paths 查看程序的运行路径。 set environment varname[=value]设置环境变量。如:set env USER=hchen show environment[varname]查看环境变量 3、 工作目录 cd 相当于 shell 的 cd 命令。 pwd 显示当前的工作目录。
4、 程序的输入输出 info terminal 显示程序用到的终端的模式 使用重定向空值程序输出。如 run>outfile tty 命令可以指定写输入输出的终端设备。如 tty /dev/ttyb 调试已运行的程序 两种方法: 1、 在 UNIX 下用 ps 查看正在运行的程序的 PID(进程 ID),然后用 gdb PID 格式挂接正在运行的程序。 2、 先用 gdb关联上源代码,并进行 gdb,在 gdb 中用 attach 命令来挂接进程的 PID,并用 detach 来取消挂接的程序。 暂停/恢复程序运行 调试程序中,暂停进程运行时必须的,GDB 可以方便的暂停程序的运行。你可以设置程 序在哪停住,在什么条件下停住,在收到什么信号时停住等等。你便于你查看运行的变量, 以及运行时的流程。 当进程被 gdb 停住时,你可以使用 info program 来查看程序是否在运行、进程号、被暂停 的原因。 在 gdb 中,我们可以有以下几种暂停方式:断点(breakpoint)、观察点(watchpoint)、捕 捉点(catchpoint)、信号(signals)、线程停止(thread stops)。如果要恢复程序运行,可以 使用 c 或者 continue 命令。 一、设置断点(breakpoint) 我们用 break 命令设置断点。下面有几点设置断点的方法: break 在进入指定函数时停住。C++中可以使用 class::function 或 function(type,type)格式来指 定函数名。 break 在指定行号停住。 break +offset break –offset 在当前行号的前面或者后面的 offset 行停住。Offset 为自然数。 break filename:linenum 在源文件 filename 的 linenum 行处停住。 break filename:function 在源文件 filename 的 function 函数的入口处停住。 break *address 在程序运行的内存地址处停住。 break
break 命令没有参数时,表示在下一条指令处停住。 break…if …可以是上述的参数,condition 表示条件,在条件成立时停住。比如在循环体 中,可以设置 break if i=100,表示当 i 为 100 时停住程序。 查看断点时,可使用命令 info 命令,如下所示:(注:n 表示断点号) info breakpoints[n] info break[n] 二、 设置捕捉点(catchpoint) 我们可以设置捕捉点来捕捉程序运行时的一些事件。如:载入共享库(动态链接库)或 是 C++的异常,设置捕捉点的格式为: catch 当 event 发生时,停住程序。Event 可以是下面的内容: 1、throw 一个 C++抛出的异常(throw 为关键字), 2、catch 一个 C++捕捉到的异常(catch 为关键字), 3、exec 调用系统调用 exec 时(exec 为关键字,目前此功能只在 HP-UX 下有用) 4、fork 调用系统调用 fork 时。(fork 为关键字,目前此功能只在 HP-UX 下有用) 5、vfork 调用系统调用 vfork 时。(vfork 为关键字,目前此功能只在 HP-UX 下 有用) 6、load 或 load 载入共享库(动态链接库)时。(load 为关键字, 目前此功能只在 HP-UX 下有用) 7、 unload 或 unload 卸载共享库(动态链接库)时。(unload 为关 键字,目前此功能只在 HP-UX 下有用) tcatch 只设置一次捕捉,当程序停住后,断点被自动删除。 三、 维护停止点 上面说了如何设置程序的停止点,GDB 中的停止点也就是上述的三类。在 GDB 中,如 果你觉得已定义好的停止点没有用了,你可以使用 delete、clear、disable、enable 这几个 命令来进程维护。 clear 清楚所有已定义的停止点。 clear clear 清楚所有设置在函数上的停止点。 clear clear 清楚所有设定在指定行上的停止。 delete [breakpoints][range…] 删除指定的断点,breakpoints 为断点号。如果不指定断点号,则表示删除所有的
分享到:
收藏