2.4 实例—使用gdb调试器
1.编写实例程序gcctest.c,见2.2小节的开头部分
2.编译
[root@localhost gdbtest txt]# gcc gcctest.c -o gcctest [root@localhost gdbtest txt]# gcc -g gcctest.c -o gcctestg [root@localhost gdbtest txt]# ll -rwxr-xr-x 1 root root 5187 04-30 18:42 gcctest -rwxr-xr-x 1 root root 6891 04-30 18:42 gcctestg //注意文件的大小 |
3.启动GDB,执行程序
启动gdb,进入gdb调试环境,可以使用gdb的命令对程序进行调试。
[root@localhost gdbtest txt]# gdb //启动gdb GNU gdb Fedora (6.8-27.el5) Copyright (C) 2008 Free Software Foundation, Inc. License GPLv3+: GNU GPL version 3 or later </licenses/gpl.html> exitedThis 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 "i386-redhat-linux-gnu". (gdb) run gcctest //在gdb中,运行程序使用r或是run命令,注意,gcctest没有调试信息 Starting program: gcctest No executable file specified. Use the "file" or "exec-file" command. //要使用file或exec-file命令指出要运行的程序 (gdb) file gcctest //使用file命令指出要运行的程序gcctest,注意,对gdb命令也可以使用Tab gcctest gcctest.c gcctestg (gdb) file gcctest //使用file命令指出要运行的程序gcctest Reading symbols from /root/Desktop/gdbtest (no debugging symbols found)...done. (gdb) r //在gdb中,运行程序使用r或是run命令 Starting program: /root/Desktop/gdbtest txt/gcctest gcctest (no debugging symbols found) (no debugging symbols found) (no debugging symbols found) hello in main hello 1 hello 2 sum=54125560035401396161080590579269632.000000 Program exited with code 057. (gdb) file gcctestg //使用file命令指出要运行的程序gcctestg Reading symbols from /root/Desktop/gdbtest done. (gdb) r //在gdb中,运行程序使用r或是run命令 Starting program: /root/Desktop/gdbtest txt/gcctestg gcctest hello in main hello 1 hello 2 sum=54125560035401396161080590579269632.000000 Program exited with code 057. (gdb) q //使用q或是quit命令退出gdb [root@localhost gdbtest txt]# |
4.GDB命令简介
(gdb) help // gdb的命令可以使用help命令来查看,gdb的命令很多,gdb将之分成许多种类。 //help命令只列出gdb的命令种类,如果要看其中的命令,可以使用help <class>命令 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 all" for the list of all commands. Type "help" followed by command name for full documentation. Type "apropos word" to search for commands related to "word". Command name abbreviations are allowed if unambiguous. (gdb) help files //使用help <class>命令查看files类中的命令 Specifying and examining files. List of commands: add-shared-symbol-files -- Load the symbols from shared objects in the dynamic linker's link map add-symbol-file -- Load symbols from FILE add-symbol-file-from-memory -- Load the symbols out of memory from a dynamically loaded object file cd -- Set working directory to DIR for debugger and program being debugged core-file -- Use FILE as core dump for examining memory and registers directory -- Add directory DIR to beginning of search path for source files edit -- Edit specified file or function exec-file -- Use FILE as program for getting contents of pure memory file -- Use FILE as program to be debugged forward-search -- Search for regular expression (see regex(3)) from last line listed generate-core-file -- Save a core file with the current state of the debugged process list -- List specified function or line load -- Dynamically load FILE into the running program nosharedlibrary -- Unload all shared object library symbols path -- Add directory DIR(s) to beginning of search path for object files pwd -- Print working directory remote -- Manipulate files on the remote system remote delete -- Delete a remote file remote get -- Copy a remote file to the local system remote put -- Copy a local file to the remote system ---Type <return> to continue, or q <return> to quit--- //一屏显示不完,敲回车键显示后面的内容 reverse-search -- Search backward for regular expression (see regex(3)) from last line listed search -- Search for regular expression (see regex(3)) from last line listed section -- Change the base address of section SECTION of the exec file to ADDR sharedlibrary -- Load shared object library symbols for files matching REGEXP symbol-file -- Load symbol table from executable file FILE Type "help" followed by command name for full documentation. Type "apropos word" to search for commands related to "word". Command name abbreviations are allowed if unambiguous. (gdb) |
5.显示源代码
(gdb) file gcctestg //使用file命令指出要运行的程序gcctestg Load new symbol table from "/root/Desktop/gdbtest txt/gcctestg"? (y or n) y Reading symbols from /root/Desktop/gdbtest done. (gdb) list //显示当前行后面的源程序 1 #include <stdio.h> 2 3 void print_hello1(char *p_str); 4 void print_hello2(char *p_str); 5 6 int main(int argc,char **argv) 7 { 8 double i,sum=0; 9 char *pstr="hello in main"; 10 int arr[]={1,2,3,4,5}; (gdb) list //显示当前行后面的源程序 11 printf("%s\n",pstr); 12 print_hello1("hello 1"); 13 print_hello2("hello 2"); 14 15 for(i=1; i<=1020000020.01*1020000020.01*10100020.01*10100020.00202; i=i*1.0000016) 16 sum=sum/1.0201809902203*1.000102101203*1.00006605+i*10.01016/1.0005; 17 printf("sum=%f\n",sum); 18 } 19 20 void print_hello1(char *p_str) (gdb) //敲回车键,继续执行list命令,显示当前行后面的源程序 21 { 22 printf("%s\n",p_str); 23 } 24 25 void print_hello2(char *p_str) 26 { 27 printf("%s\n",p_str); 28 } (gdb) list 8 //显示程序第8行的周围的源程序 3 void print_hello1(char *p_str); 4 void print_hello2(char *p_str); 5 6 int main(int argc,char **argv) 7 { 8 double i,sum=0; 9 char *pstr="hello in main"; 10 int arr[]={1,2,3,4,5}; 11 printf("%s\n",pstr); 12 print_hello1("hello 1"); (gdb) list 6,10 //显示程序第6-10行的源程序 6 int main(int argc,char **argv) 7 { 8 double i,sum=0; 9 char *pstr="hello in main"; 10 int arr[]={1,2,3,4,5}; (gdb) |
gdb可以显示调试程序(编译程序时一定要加上-g参数,把源程序信息编译到执行文件中)的源代码。可以用list命令显示程序的源代码。list命令的使用方法见表2.16。
表2.16 list命令的使用方法
命令 | 说明 |
list | 显示当前行后面的源代码 |
list <linenum> | 显示程序第linenum行周围的源代码,一般是显示当前行的上5行和下5行,默认共显示10行。当然,也可以使用set listsize命令指定显示的范围 |
set listsize <count> | 设置一次显示源代码的行数 |
show listsize | 查看当前listsize的设置 |
list <function> | 显示函数名为function的函数的源代码 |
list <-offset> | 显示当前行前面的源代码 |
list <+offset> | 显示当前行后面的源代码 |
list <first>,<last> | 显示从first行到last行之间的源代码 |
list ,<last> | 显示从当前行到last行之间的源代码 |
list <filename:linenum> | 显示文件中的一行 |
list <filename: function > | 显示文件中的函数 |
6.源代码的内存地址
(gdb) info address common frame proc source types all-registers copying functions program sources variables args dcache handle registers stack vector auxv display line scope symbol warranty breakpoints extensions linkmap selectors target watchpoints catch files locals set terminal win checkpoints float macro sharedlibrary threads classes forks mem signals tracepoints (gdb) info frame No stack. //注意:此时还没有运行gcctestg程序 (gdb) info line //查看源代码在内存中的地址 Line 10 of "gcctest.c" starts at address 0x80483d1 <main+29> and ends at 0x80483f4 <main+64>. (gdb) info line 1 Line 1 of "gcctest.c" is at address 0x80483b4 <main> but contains no code. (gdb) info line 2 Line 2 of "gcctest.c" is at address 0x80483b4 <main> but contains no code. (gdb) info line 3 Line 3 of "gcctest.c" is at address 0x80483b4 <main> but contains no code. (gdb) info line 4 Line 4 of "gcctest.c" is at address 0x80483b4 <main> but contains no code. (gdb) info line 5 Line 5 of "gcctest.c" is at address 0x80483b4 <main> but contains no code. (gdb) info line 6 Line 6 of "gcctest.c" is at address 0x80483b4 <main> but contains no code. (gdb) info line 7 Line 7 of "gcctest.c" starts at address 0x80483b4 <main> and ends at 0x80483c5 <main+17>. (gdb) info line 8 Line 8 of "gcctest.c" starts at address 0x80483c5 <main+17> and ends at 0x80483ca <main+22>. (gdb) info line 9 Line 9 of "gcctest.c" starts at address 0x80483ca <main+22> and ends at 0x80483d1 <main+29>. (gdb) info line 10 Line 10 of "gcctest.c" starts at address 0x80483d1 <main+29> and ends at 0x80483f4 <main+64>. (gdb) info line 11 Line 11 of "gcctest.c" starts at address 0x80483f4 <main+64> and ends at 0x80483ff <main+75>. (gdb) info line 12 Line 12 of "gcctest.c" starts at address 0x80483ff <main+75> and ends at 0x804840b <main+87>. (gdb) info line 13 Line 13 of "gcctest.c" starts at address 0x804840b <main+87> and ends at 0x8048417 <main+99>. (gdb) info line 14 Line 14 of "gcctest.c" is at address 0x8048417 <main+99> but contains no code. (gdb) info line 15 Line 15 of "gcctest.c" starts at address 0x8048417 <main+99> and ends at 0x804841e <main+106>. (gdb) info line 16 Line 16 of "gcctest.c" starts at address 0x804841e <main+106> and ends at 0x8048451 <main+157>. (gdb) info line 17 Line 17 of "gcctest.c" starts at address 0x804846f <main+187> and ends at 0x8048482 <main+206>. (gdb) info line 18 Line 18 of "gcctest.c" starts at address 0x8048482 <main+206> and ends at 0x804848b <print_hello1>. (gdb) info line 19 Line 19 of "gcctest.c" is at address 0x804848b <print_hello1> but contains no code. (gdb) info line 20 Line 20 of "gcctest.c" is at address 0x804848b <print_hello1> but contains no code. (gdb) info line 21 Line 21 of "gcctest.c" starts at address 0x804848b <print_hello1> and ends at 0x8048491 <print_hello1+6>. (gdb) info line 22 Line 22 of "gcctest.c" starts at address 0x8048491 <print_hello1+6> and ends at 0x804849c <print_hello1+17>. (gdb) info line 23 Line 23 of "gcctest.c" starts at address 0x804849c <print_hello1+17> and ends at 0x804849e <print_hello2>. (gdb) info line 24 Line 24 of "gcctest.c" is at address 0x804849e <print_hello2> but contains no code. (gdb) info line 25 Line 25 of "gcctest.c" is at address 0x804849e <print_hello2> but contains no code. (gdb) info line 26 Line 26 of "gcctest.c" starts at address 0x804849e <print_hello2> and ends at 0x80484a4 <print_hello2+6>. (gdb) info line 27 Line 27 of "gcctest.c" starts at address 0x80484a4 <print_hello2+6> and ends at 0x80484af <print_hello2+17>. (gdb) info line 28 Line 28 of "gcctest.c" starts at address 0x80484af <print_hello2+17> and ends at 0x80484b1. (gdb) |
注意:info line后面可以跟:行号、函数名、文件名:行号、文件名:函数名。
(gdb) disassemble No frame selected. //注意:此时还没有运行gcctestg程序 (gdb) disassemble main //反汇编main函数 Dump of assembler code for function main: 0x080483b4 <main+0>: lea 0x4(%esp),%ecx 0x080483b8 <main+4>: and $0xfffffff0,%esp 0x080483bb <main+7>: pushl -0x4(%ecx) 0x080483be <main+10>: push %ebp 0x080483bf <main+11>: mov %esp,%ebp 0x080483c1 <main+13>: push %ecx 0x080483c2 <main+14>: sub $0x44,%esp 0x080483c5 <main+17>: fldz 0x080483c7 <main+19>: fstpl -0x18(%ebp) 0x080483ca <main+22>: movl $0x8048598,-0xc(%ebp) 0x080483d1 <main+29>: movl $0x1,-0x34(%ebp) 0x080483d8 <main+36>: movl $0x2,-0x30(%ebp) 0x080483df <main+43>: movl $0x3,-0x2c(%ebp) 0x080483e6 <main+50>: movl $0x4,-0x28(%ebp) 0x080483ed <main+57>: movl $0x5,-0x24(%ebp) 0x080483f4 <main+64>: mov -0xc(%ebp),%eax 0x080483f7 <main+67>: mov %eax,(%esp) 0x080483fa <main+70>: call 0x80482c8 <puts@plt> 0x080483ff <main+75>: movl $0x80485a6,(%esp) 0x08048406 <main+82>: call 0x804848b <print_hello1> 0x0804840b <main+87>: movl $0x80485ae,(%esp) 0x08048412 <main+94>: call 0x804849e <print_hello2> 0x08048417 <main+99>: fld1 0x08048419 <main+101>: fstpl -0x20(%ebp) 0x0804841c <main+104>: jmp 0x804845f <main+171> ---Type <return> to continue, or q <return> to quit--- //一屏显示不完,敲回车键显示后面的内容 0x0804841e <main+106>: fldl -0x18(%ebp) 0x08048421 <main+109>: fldl 0x80485c0 0x08048427 <main+115>: fdivrp %st,%st(1) 0x08048429 <main+117>: fldl 0x80485c8 0x0804842f <main+123>: fmulp %st,%st(1) 0x08048431 <main+125>: fldl 0x80485d0 0x08048437 <main+131>: fmulp %st,%st(1) 0x08048439 <main+133>: fldl -0x20(%ebp) 0x0804843c <main+136>: fldl 0x80485d8 0x08048442 <main+142>: fmulp %st,%st(1) 0x08048444 <main+144>: fldl 0x80485e0 0x0804844a <main+150>: fdivrp %st,%st(1) 0x0804844c <main+152>: faddp %st,%st(1) 0x0804844e <main+154>: fstpl -0x18(%ebp) 0x08048451 <main+157>: fldl -0x20(%ebp) 0x08048454 <main+160>: fldl 0x80485e8 0x0804845a <main+166>: fmulp %st,%st(1) 0x0804845c <main+168>: fstpl -0x20(%ebp) 0x0804845f <main+171>: fldl -0x20(%ebp) 0x08048462 <main+174>: fldl 0x80485f0 0x08048468 <main+180>: fucompp 0x0804846a <main+182>: fnstsw %ax 0x0804846c <main+184>: sahf 0x0804846d <main+185>: jae 0x804841e <main+106> 0x0804846f <main+187>: fldl -0x18(%ebp) 0x08048472 <main+190>: fstpl 0x4(%esp) ---Type <return> to continue, or q <return> to quit--- //一屏显示不完,敲回车键显示后面的内容 0x08048476 <main+194>: movl $0x80485b6,(%esp) 0x0804847d <main+201>: call 0x80482b8 <printf@plt> 0x08048482 <main+206>: add $0x44,%esp 0x08048485 <main+209>: pop %ecx 0x08048486 <main+210>: pop %ebp 0x08048487 <main+211>: lea -0x4(%ecx),%esp 0x0804848a <main+214>: ret End of assembler dump. (gdb) disassemble print_hello1 //反汇编print_hello1函数 Dump of assembler code for function print_hello1: 0x0804848b <print_hello1+0>: push %ebp 0x0804848c <print_hello1+1>: mov %esp,%ebp 0x0804848e <print_hello1+3>: sub $0x8,%esp 0x08048491 <print_hello1+6>: mov 0x8(%ebp),%eax 0x08048494 <print_hello1+9>: mov %eax,(%esp) 0x08048497 <print_hello1+12>: call 0x80482c8 <puts@plt> 0x0804849c <print_hello1+17>: leave 0x0804849d <print_hello1+18>: ret End of assembler dump. (gdb) disassemble print_hello2 //反汇编print_hello2函数 Dump of assembler code for function print_hello2: 0x0804849e <print_hello2+0>: push %ebp 0x0804849f <print_hello2+1>: mov %esp,%ebp 0x080484a1 <print_hello2+3>: sub $0x8,%esp 0x080484a4 <print_hello2+6>: mov 0x8(%ebp),%eax 0x080484a7 <print_hello2+9>: mov %eax,(%esp) 0x080484aa <print_hello2+12>: call 0x80482c8 <puts@plt> 0x080484af <print_hello2+17>: leave 0x080484b0 <print_hello2+18>: ret End of assembler dump. (gdb) |
7.暂停/恢复程序运行
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论