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.    //要使用fileexec-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小时内删除。