调试器(GDB)的基本使用方法(之一)

使用gcc的-g选项生成调试信息:
$ gcc -Wall -O2 -g sourcefile        

注意:-O2的'O'是大写字母,不是零。
编译:
$ gcc -Wall -O2 -g -o TestStrcpy TestStrcpy.c              

其中源文件为:
/* filename:    TestStrcpy.c
 * description: Used to test the function "Strcpy"
 * author:      Howard
 * date:        2013-11-22
 * version:     v1.0
 */

#ifndef DE
#define DE
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#endif

int main(void)
{
        char * p;
        char arr[6] = "hello";

        p = arr;
        strcpy(p,arr);

        printf("%s\n",arr);
        printf("%s\n",p);


        return 0;
}

启动GDB
gdb 可执行文件
$ gdb TestStrcpy                                                                                                                                      
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/<username>/CLan/TestStrcpy...done.                                                             
(gdb)                                                                                                                                                      

设置断点:
断点设置格式:
break 函数名
break 行号
break 文件名:行号
break 文件名:函数名
break +偏移量
break -偏移量
break *地址
其中break可以用b代替:
(gdb) b main
Breakpoint 1 at 0x80483d0: file TestStrcpy.c, line 16.
(gdb) b TestStrcpy.c:19
Breakpoint 2 at 0x8048405: file TestStrcpy.c, line 19.
(gdb) b +22
No line 29 in the current file.
Make breakpoint pending on future shared library load? (y or [n]) n
(gdb) b +16
Breakpoint 3 at 0x804840d: file TestStrcpy.c, line 23.
(gdb) b *0x804840f
Breakpoint 4 at 0x804840f: file TestStrcpy.c, line 23.
(gdb) b
No default breakpoint address now.

使用info break查看中断设置信息:
(gdb) info break
Num     Type           Disp Enb Address    What
1       breakpoint     keep y   0x080483d0 in main at TestStrcpy.c:16
2       breakpoint     keep y   0x08048405 in main at TestStrcpy.c:19
3       breakpoint     keep y   0x0804840d in main at TestStrcpy.c:23
4       breakpoint     keep y   0x0804840f in main at TestStrcpy.c:23
(gdb) 

运行
使用run命令运行,也可以简写成r,运行到第一个断点处停止,使用start能达到相同的效果:
(gdb) r
Starting program: /home/shuaihua/CLan/TestStrcpy 

Breakpoint 1, main () at TestStrcpy.c:16
16     {
(gdb) 

使用next执行到下一个断点处(简称n),使用step单步执行。
(gdb) n
21          strcpy(p,arr);
(gdb) 
显示栈帧
backtrace命令可以在遇到断点而暂停执行时显示栈帧,可简写为bt,它的别名有where和info stack——简称info s
格式:
显示所有栈帧:
     backtrace
     bt
只显示开头N个栈帧:
     backtrace N
     bt N
只显示洗后N个栈帧:
     backtrace -N
     bt -N
不仅显示栈帧,还显示局部变量:
     backtrace full
     bt full
     backtrace full N
     bt full N    
     backtrace full -N
     bt full -N
例如:
(gdb) bt
#0  main () at TestStrcpy.c:21
(gdb) bt 3
#0  main () at TestStrcpy.c:21
(gdb) bt full
#0  main () at TestStrcpy.c:21
        p = <optimized out>
        arr = "\000\000\371\204\004\b"
(gdb) 

显示变量
print命令可以显示变量,可简写为p
(gdb) p p                                                                 
$1 = <optimized out>                                              
(gdb) p arr                                                              
$2 = "\000\000\371\204\004\b"                                
(gdb) p *arr                                                             
$3 = 0 '\000'                                                           
(gdb) p arr[0]                                                          
$4 = 0 '\000'                                                           
(gdb) p arr[1]                                                          
$5 = 0 '\000'                                                           
(gdb) p arr[2]                                                          
$6 = -7 '\371'                                                          
(gdb) p arr[3]                                                          
$7 = -124 '\204'                                                       
(gdb) p arr[4]                                                          
$8 = 4 '\004'                                                           
(gdb) p arr[5]                                                          
$9 = 8 '\b'                                                               
(gdb)                                                                      

显示寄存器
使用info reg命令显示寄存器的值:
(gdb) info reg
eax            0x1     1
ecx            0xbffff314     -1073745132
edx            0xbffff2a4     -1073745244
ebx            0x2d7ff4     2981876
esp            0xbffff250     0xbffff250
ebp            0xbffff278     0xbffff278
esi            0x0     0
edi            0x0     0
eip            0x80483da     0x80483da <main+10>
eflags         0x286     [ PF SF IF ]
cs             0x73     115
ss             0x7b     123
ds             0x7b     123
es             0x7b     123
fs             0x0     0
gs             0x33     51

寄存器前面加上$可以显示寄存器的内容:
(gdb) p $eax
$10 = 1
p/格式 变量
格式说明
x显示为十六进制
d显示为十进制
u显示为无符号十进制
o显示为八进制
t显示为二进制,two
a地址
c显示为字符
f浮点数
s字符串
i机器语言


(gdb) p/c $eax
$11 = 1 '\001'
(gdb) p $pc
$12 = (void (*)()) 0x80483da <main+10>
(gdb) p $eip
$13 = (void (*)()) 0x80483da <main+10>
用x命令可以显示内存内容:
(gdb) x $pc
0x80483da <main+10>:     -115 '\215'
(gdb) x/i $pc
=> 0x80483da <main+10>:     lea    0x16(%esp),%ebx

x/i意为显示汇编指令。 
反汇编指令disassemble,简写为disas
格式:
     (1)disassemble
     (2)disassemble 程序计数器
     (3)disassemble 开始地址 结束地址
(1)反汇编当前整个函数,(2)反汇编程序计数器所在的整个函数,(3)反汇编两个地址之间的部分。
(gdb) disassemble $pc
Dump of assembler code for function main:
   0x080483d0 <+0>:     push   %ebp
   0x080483d1 <+1>:     mov    %esp,%ebp
   0x080483d3 <+3>:     push   %ebx
   0x080483d4 <+4>:     and    $0xfffffff0,%esp
   0x080483d7 <+7>:     sub    $0x20,%esp
=> 0x080483da <+10>:     lea    0x16(%esp),%ebx
   0x080483de <+14>:     mov    %gs:0x14,%eax
   0x080483e4 <+20>:     mov    %eax,0x1c(%esp)
   0x080483e8 <+24>:     xor    %eax,%eax
   0x080483ea <+26>:     movl   $0x6c6c6568,0x16(%esp)
   0x080483f2 <+34>:     movw   $0x6f,0x1a(%esp)
   0x080483f9 <+41>:     movl   $0x6,0x8(%esp)
   0x08048401 <+49>:     mov    %ebx,0x4(%esp)
   0x08048405 <+53>:     mov    %ebx,(%esp)
   0x08048408 <+56>:     call   0x80483c0 <__strcpy_chk@plt>
   0x0804840d <+61>:     mov    %ebx,(%esp)
   0x08048410 <+64>:     call   0x8048390 <puts@plt>
   0x08048415 <+69>:     mov    %ebx,(%esp)
   0x08048418 <+72>:     call   0x8048390 <puts@plt>
   0x0804841d <+77>:     xor    %eax,%eax
   0x0804841f <+79>:     mov    0x1c(%esp),%edx
   0x08048423 <+83>:     xor    %gs:0x14,%edx
   0x0804842a <+90>:     jne    0x8048431 <main+97>
   0x0804842c <+92>:     mov    -0x4(%ebp),%ebx
   0x0804842f <+95>:     leave  
   0x08048430 <+96>:     ret    
   0x08048431 <+97>:     call   0x8048380 <__stack_chk_fail@plt>
继续运行
continue
continue 次数
次数为可以忽略断点的次数。
监视点
watch <表达式>
<表达书>发生变化是暂停运行,此处<表达式>的意识是常量或变量等。
awatch <表达式>
<表达式>被访问、改变是暂停运行。
rwatch <表达式>
<表达式>被访问时暂停运行。
(gdb) rwatch strcpy
Hardware read watchpoint 5: strcpy
删除断点和监视点
(gdb) delete 2
(gdb) info b
Num     Type            Disp Enb Address    What
1       breakpoint      keep y   0x080483d0 in main at TestStrcpy.c:16
     breakpoint already hit 1 time
3       breakpoint      keep y   0x080483d0 in main at TestStrcpy.c:16
     breakpoint already hit 1 time
4       breakpoint      keep y   0x0804840f in main at TestStrcpy.c:23
5       read watchpoint keep y              strcpy
(gdb) delete 5
(gdb) info b
Num     Type           Disp Enb Address    What
1       breakpoint     keep y   0x080483d0 in main at TestStrcpy.c:16
     breakpoint already hit 1 time
3       breakpoint     keep y   0x080483d0 in main at TestStrcpy.c:16
     breakpoint already hit 1 time
4       breakpoint     keep y   0x0804840f in main at TestStrcpy.c:23
(gdb) 
改变变量的值
set variable <变量>=<值>
(gdb) p arr
$14 = "\000\000\371\204\004\b"
(gdb) p *arr
$15 = 0 '\000'
(gdb) p arr[0]
$16 = 0 '\000'
(gdb) set variable arr[1] = 23 
(gdb) p arr[1]
$17 = 23 '\027'
(gdb) set variable arr[0] = 100
(gdb) p arr[0]
$18 = 100 'd'
(gdb) set variable arr[0] = 0
(gdb) p arr[0]
$19 = 0 '\000'
生成内核转储文件
(gdb) generate-core-file
Saved corefile core.4063


  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值