现在的位置: 首页 > 综合 > 正文

gdb修改寄存器值进行调试

2013年09月22日 ⁄ 综合 ⁄ 共 4031字 ⁄ 字号 评论关闭

    昨天在测试同事的一段代码时,返回值没有保存到变量中,而是直接进行判断的,类似这样:

 

    由于check_state()是来自另一个.a文件的函数,所以无法改变它的返回值,每次它都返回非0值(导致func1()每次都返回-1。),但是我想测试func1()返回0时代码的执行情况。同事在此处并没有用一个变量来存储这个返回值,所以无法通过设置变量的值达到效果。

    每个C语言的函数,都会通过寄存器返回值,所以我们可以通过修改func1()中寄存器的值,达到我们的测试目的。


    写一个简单的测试代码来说明用法(检测输入参数是否大于10):

 

编译:

~# gcc -g -Wall main.c -o main

 

测试过程:

~# gdb main

GNU gdb Fedora (6.8-37.el5)
Copyright (C) 2008 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 "i386-redhat-linux-gnu"...
(gdb) b main
Breakpoint 1 at 0x80483e9: file main.c, line 14.
(gdb) r 7
Starting program: /root/program/testgdb/main 7

Breakpoint 1, main (argc=2, argv=0xbf89e694) at main.c:14
14              int input_val = 0;
(gdb) n
15              if(argc < 2)
(gdb)
20              input_val = atoi(argv[1]);
(gdb)
21              if(func1(input_val))
(gdb) s
func1 (input=7) at main.c:6
6               if(input < 10)
(gdb) n
7                       return -1;
(gdb) disassemble   ---- 反编译一下当前函数
Dump of assembler code for function func1:
0x080483b4 <func1+0>:   push   %ebp
0x080483b5 <func1+1>:   mov    %esp,%ebp
0x080483b7 <func1+3>:   sub    $0x4,%esp
0x080483ba <func1+6>:   cmpl   $0x9,0x8(%ebp)
0x080483be <func1+10>:  jg     0x80483c9 <func1+21>
0x080483c0 <func1+12>:  movl   $0xffffffff,-0x4(%ebp)
0x080483c7 <func1+19>:  jmp    0x80483d0 <func1+28>
0x080483c9 <func1+21>:  movl   $0x0,-0x4(%ebp)
0x080483d0 <func1+28>:  mov    -0x4(%ebp),%eax  ---- 返回值将保存到eax寄存器中
0x080483d3 <func1+31>:  leave  
0x080483d4 <func1+32>:  ret    
End of assembler dump.
(gdb) i r  ---- 查看当前寄存器的值,主要是eax,此时还未执行"return -1"
eax            0x7      7
ecx            0x0      0
edx            0x0      0
ebx            0x9f8ff4 10457076
esp            0xbf89e5c4       0xbf89e5c4
ebp            0xbf89e5c8       0xbf89e5c8
esi            0x8b0ca0 9112736
edi            0x0      0
eip            0x80483c0        0x80483c0 <func1+12>
eflags         0x293    [ CF AF SF IF ]
cs             0x73     115
ss             0x7b     123
ds             0x7b     123
es             0x7b     123
fs             0x0      0
gs             0x33     51
(gdb) n
10      }
(gdb) i r   ----- 查看当前寄存器的信息,此时已执行"return -1",eax的值也变成了-1
eax            0xffffffff       -1
ecx            0x0      0
edx            0x0      0
ebx            0x9f8ff4 10457076
esp            0xbf89e5c4       0xbf89e5c4
ebp            0xbf89e5c8       0xbf89e5c8
esi            0x8b0ca0 9112736
edi            0x0      0
eip            0x80483d3        0x80483d3 <func1+31>
eflags         0x293    [ CF AF SF IF ]
cs             0x73     115
ss             0x7b     123
ds             0x7b     123
es             0x7b     123
fs             0x0      0
gs             0x33     51
(gdb) set $eax = 0    ---- 通过set命令修改eax的值,与变量不同,修改寄存器的值时,需要在寄存器名称前加'$'
(gdb) i r    ---- 再次查看eax的值,eax已变为0.
eax            0x0      0
ecx            0x0      0
edx            0x0      0
ebx            0x9f8ff4 10457076
esp            0xbf89e5c4       0xbf89e5c4
ebp            0xbf89e5c8       0xbf89e5c8
esi            0x8b0ca0 9112736
edi            0x0      0
eip            0x80483d3        0x80483d3 <func1+31>
eflags         0x293    [ CF AF SF IF ]
cs             0x73     115
ss             0x7b     123
ds             0x7b     123
es             0x7b     123
fs             0x0      0
gs             0x33     51
(gdb) n    ----  继续执行代码,可看到程序输出"Input numeric is bigger than 10."。我们通过修改寄存器的值,对程序代码的执行过程进行了控制。
main (argc=2, argv=0xbf89e694) at main.c:24
24                      printf("Input numeric is bigger than 10./n");
(gdb) c
Continuing.
Input numeric is bigger than 10.

Program exited normally.
(gdb)

 

    对于一些小程序,这么测试还是很有效的。

 

 

抱歉!评论已关闭.