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

gdb学习笔记

2018年04月02日 ⁄ 综合 ⁄ 共 6036字 ⁄ 字号 评论关闭

From:

http://hi.baidu.com/jinglecode/item/cb71fd8a1a3e87d55f0ec159

你可以用 dev-cpp/bin/gdb

学习,也可以用linux来学习;

感谢http://blog.chinaunix.net/u/7918/showart_32864.html

先看一看 gdb 的命令分类:

(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.

查哪一方面的命令就用:

help + cmd

:help stack

标* 为重要命令;

下面举例说明:

//gdbtry.cpp

#include <iostream>
const int SIZE=10;
int dat[SIZE];
int out;
int fuc(int x)
{
    if (x>0)
    printf("%d\n",x);
    else
    printf("%d\n",-x);
};
int main()
{
    int i,j,k;
    for (i=0;i<SIZE;i++)
        dat[i]=10+i;
    out=5;
    k=-10;
    fuc(k);
    for (out=0;out<SIZE;out++)
        printf("int main:%d\n",dat[out]);
    return 0;
}

//end gdbtry.cpp

g++ -g -o yjy.exe gdbtry.cpp

先编译一下,-g 用于加入调试信息

/*

g++ -S gdbtry.cpp

生成gdbtry.s 的汇编文件。以后用这个学汇编

*/

1》装载程序

gdb yjy

或进入gdb后 ,用

file yjy //装载

2》显示源文件

list 1,24

[begin,end], 行号

3》设断点

break main //加函数名

break 18//行号

del 取消所有断点

(gdb) del
Delete all breakpoints? (y or n) y

4》运行

run

5》

程序停在了
Breakpoint 1, main () at gdbtry.cpp:13
13      {

6》询问目前运行到哪

where

(gdb) where
#0 main () at gdbtry.cpp:13

7>显示变量

print i;

(gdb) print dat
$14 = {10, 11, 0, 0, 0, 0, 0, 0, 0, 0}

gdb把变量的值保存在自己设定的变量里,$NUM

print $2

也可打印变量

print 0xFF

$20 = 255

十六进制转换

8》 直接到下一断点

continue

(gdb) continue
Continuing.

Breakpoint 2, main () at gdbtry.cpp:18

9》next

按行执行,遇到函数调用不进入

10》查看断点信息

info break

(gdb) info break
Num Type           Disp Enb Address    What
1   breakpoint     keep y   0x004013ed in main at gdbtry.cpp:13
        breakpoint already hit 1 time
2   breakpoint     keep y   0x00401420 in main at gdbtry.cpp:18
        breakpoint already hit 1 time
3   breakpoint     keep y   0x00401420 in main at gdbtry.cpp:18

11>函数调用

call fuc(100)

12》堆栈信息

先给printf 设个断点

break printf

在调用fuc

(gdb) call fuc(-1)

Breakpoint 4, 0x00410700 in printf ()
The program being debugged stopped while in a function called from GDB.
When the function (fuc(int)) is done executing, GDB will silently
stop (instead of continuing to evaluate the expression containing
the function call).
(gdb) bt
#0 0x00410700 in printf ()
#1 0x004013c6 in fuc(int) (x=-1) at gdbtry.cpp:10
#2 <function called from gdb>
#3 main () at gdbtry.cpp:21

查看堆栈,bt

有四层,程序以栈的方式管理函数调用

13》

敲入b按两次TAB键,你会看到所有b打头的命令:
(gdb) b
backtrace break bt
(gdb)

14》但前目录

pwd

15>程序信息

(gdb) info program
        Using the running image of child thread 3892.0xf54.
Program stopped at 0x401445.
It stopped at a breakpoint that has since been deleted.

16》如果要调试线程的话

用thread

17》搜索源代码

gdb有好多很长的命令,打开头后,用TAB,实现命令补全

(gdb) forward-search main
12      int main()
(gdb)

18》查看地址

info line

(gdb) info line 2
Line 2 of "gdbtry.cpp" is at address 0x401390 <_Z3fuci> but contains no code.
(gdb) info line main
Line 13 of "gdbtry.cpp" starts at address 0x4013c8 <main>
   and ends at 0x4013ed <main+37>.
(gdb) info line fuc
Line 6 of "gdbtry.cpp" starts at address 0x401390 <_Z3fuci>
   and ends at 0x401396 <_Z3fuci+6>.
(gdb)

19>反汇编

(gdb) disassemble fuc
Dump of assembler code for function _Z3fuci:
0x401390 <_Z3fuci>:     push   %ebp
0x401391 <_Z3fuci+1>:   mov    %esp,%ebp
0x401393 <_Z3fuci+3>:   sub    $0x8,%esp
0x401396 <_Z3fuci+6>:   cmpl   $0x0,0x8(%ebp)   // 用0 和x比较               if (x>0)
0x40139a <_Z3fuci+10>: jle    0x4013b1 <_Z3fuci+33> //   比较之后用跳转语句实现分支结构
0x40139c <_Z3fuci+12>: mov    0x8(%ebp),%eax
0x40139f <_Z3fuci+15>: mov    %eax,0x4(%esp,1)
0x4013a3 <_Z3fuci+19>: movl   $0x440000,(%esp,1)
0x4013aa <_Z3fuci+26>: call   0x410700 <printf>  
0x4013af <_Z3fuci+31>: jmp    0x4013c6 <_Z3fuci+54> // 第一个分支结束跳到 函数尾部
0x4013b1 <_Z3fuci+33>: mov    0x8(%ebp),%eax
0x4013b4 <_Z3fuci+36>: neg    %eax
0x4013b6 <_Z3fuci+38>: mov    %eax,0x4(%esp,1)
0x4013ba <_Z3fuci+42>: movl   $0x440000,(%esp,1)
0x4013c1 <_Z3fuci+49>: call   0x410700 <printf>
0x4013c6 <_Z3fuci+54>: leave
0x4013c7 <_Z3fuci+55>: ret
End of assembler dump.
(gdb)

20>查看数组

(gdb) p
$26 = {0, 0, 0, 0, 0}

print 可以用缩写 p

@后是长度

静态数组可直接加名字

动态一般这样:

print

21》显示格式

x 按十六进制格式显示变量。
d 按十进制格式显示变量。
u 按十六进制格式显示无符号整型。
o 按八进制格式显示变量。
t 按二进制格式显示变量。
a 按十六进制格式显示变量。
c 按字符格式显示变量。
f 按浮点数格式显示变量。

(gdb) p /x 123
$29 = 0x7b
(gdb) p /x &dat
$30 = 0x443010
(gdb) p &dat
$31 = (int (*)[10]) 0x443010
(gdb)

22》每次next/step 都显示

display

display /i $pc

$pc是GDB的环境变量,表示着指令的地址,/i则表示输出格式为机器指令码,也就是汇编。于是当程序停下后,就会出现源代码和机器指令码相对应的情形,这是一个很有意思的功能。

(gdb) display /i $pc
1: x/i $eip 0x4013ff <main+55>:        mov    0xfffffffc(%ebp),%edx
(gdb) n
15          for (i=0;i<SIZE;i++)
1: x/i $eip 0x40140f <main+71>:        lea    0xfffffffc(%ebp),%eax
(gdb) n
16              dat[i]=10+i;
1: x/i $eip 0x4013ff <main+55>:        mov    0xfffffffc(%ebp),%edx
(gdb)

23> 显示寄存器

对学汇编很有帮助

(gdb) info registers
eax            0x22ff74 2293620
ecx            0x40ccb0 4246704
edx            0x0      0
ebx            0x4000   16384
esp            0x22ff50 0x22ff50
ebp            0x22ff78 0x22ff78
esi            0x35     53
edi            0xa      10
eip            0x4013ff 0x4013ff
eflags         0x293    659
cs             0x1b     27
ss             0x23     35
ds             0x23     35
es             0x23     35
fs             0x3b     59
gs             0x0      0
fctrl          0xffff037f       -64641
fstat          0xffff0000       -65536
ftag           0xffffffff       -1
fiseg          0x0      0
fioff          0x0      0
foseg          0xffff0000       -65536
fooff          0x0      0
---Type <return> to continue, or q <return> to quit---
fop            0x0      0
(gdb)

24》显示类型

whatis

(gdb) whatis i
type = int
(gdb) whatis dat
type = int [10]
(gdb)

25>显示语言

show language

(gdb) show language
The current source language is "auto; currently c++".
(gdb) help show language
Show the current source language.
(gdb)

设置语言

看看你认识几个啊

(gdb) set language
The currently understood settings are:

local or auto    Automatic setting based on source file
c                Use the C language
c++              Use the C++ language
asm              Use the Asm language
chill            Use the Chill language
fortran          Use the Fortran language
java             Use the Java language
modula-2         Use the Modula-2 language
pascal           Use the Pascal language
scheme           Use the Scheme language
(gdb)

26》大牛的后记,我也有同感

后记
——

GDB是一个强大的命令行调试工具。大家知道命令行的强大就是在于,其可以形成执行序列,形成脚本。UNIX下的软件全是命令行的,这给程序开发提代供了极大的便利,命令行软件的优势在于,它们可以非常容易的集成在一起,使用几个简单的已有工具的命令,就可以做出一个非常强大的功能。

抱歉!评论已关闭.