http://blog.csdn.net/nancygreen/article/details/8693312
Linux 包含了一个叫gdb 的GNU 调试程序。gdb 是一个用来调试C和C++程序的强力调试器。它使你能在程序运行时观察程序的内部结构和内存的使用情况。以下是 gdb 所提供的一些功能:它使你能监视你程序中变量的值、它使你能设置断点以使程序在指定的代码行上停止执行、它使你能一行行的执行你的代码。在命令行上键入gdb并按回车键就可以运行gdb 了。(Windows需要安装MinGW或者CygWin并且需要配置环境变量才可以使用)
GDB 命令行参数
启动 GDB:
l gdb executable
l gdb -e executable -c core-file
l gdb executable -pid process-id
(使用命令 'ps -auxw' 可以查看进程的 pid)
选项 | 含义 |
–help | 列出命令行参数。 |
–exec=file | 指定可执行文件。 |
–core=core-file | 指明 core 文件。 |
–command=file | 从指定文件中读取 gdb 命令。 |
–directory=directory | 把指定目录加入到源文件搜索路径中。 |
–cd=directory | 以指定目录作为当前路径来运行 gdb 。 |
–nx | 不要执行 .gdbinit 文件中的命令。默认情况下,这个文件中的命令会在所有命令行参数处理完后被执行。 |
–batch | 在非交互模式下运行 gdb 。从文件中读取命令,所以需要 -x 选项。 |
–symbols=file | 从指定文件中读取符号表。 |
-write | 允许对可执行文件和 core 文件进行写操作。 |
–quiet | 不要打印介绍和版权信息。 |
–tty=device | 指定 device 为运行程序的标准输入输出。 |
–pid=process-id | 指定要附属的进程 ID 。 |
GDB命令
GDB 中使用的命令:
命令 | 描述 |
help | 列出 gdb 帮助信息。 |
help topic | 列出相关话题中的 gdb 命令。 |
help command | 列出命令描述信息。 |
apropos search-word | 搜索相关的话题。 |
info args | 列出运行程序的命令行参数。 |
info breakpoints | 列出断点。 |
info break | 列出断点号。 |
info break breakpoint-number | 列出指定断点的信息。 |
info watchpoints | 列出观察点。 |
info registers | 列出使用的寄存器。 |
info threads | 列出当前的线程。 |
info set | 列出可以设置的选项。 |
Break and Watch | |
break funtion | 在指定的函数,或者行号处设置断点。 |
break +offset | 在当前停留的地方前面或后面的几行处设置断点。 |
break file:func | 在指定的file文件中的func处设置断点。 |
break file:nth | 在指定的file文件中的第nth行设置断点。 |
break *address | 在指定的地址处设置断点。一般在没有源代码时使用。 |
break line-number ifcondition | 如果条件满足,在指定位置设置断点。 |
break line threadthread-number | 在指定的线程中中断。使用info threads可以显示线程号。 |
tbreak | 设置临时的断点。中断一次后断点会被删除。 |
watch condition | 当条件满足时设置观察点。 |
clear | 清除函数func处的断点。 |
delete | 删除所有的断点或观察点。 |
delete breakpoint-number | 删除指定的断点,观察点。 |
disable breakpoint-number-or-range | 不删除断点,仅仅把它设置为无效,或有效。 |
enable oncebreakpoint-number | 设置指定断点有效,当到达断点时置为无效。 |
enable del breakpoint-number | 设置指定断点有效,当到达断点时删除它。 |
finish | 继续执行到函数结束。 |
Line Execution | |
step | 进入下一行代码的执行,会进入函数内部。 |
next | 执行下一行代码。但不会进入函数内部。 |
until until line-number ifcondition | 继续运行直到到达指定行号,或者函数,地址等。 |
return | 弹出选中的栈帧(stack frame)。如果后面指定参数,则返回表达式的值。 |
stepi | 执行下一条汇编/CPU指令。 |
info signals | 当收到信号时执行下列动作:nostop(不要停止程序),stop(停止程序执行),print(显示信号),noprint(不显示),pass/noignore(允许程序处理信号),nopass/ignore(不让程序接受信号) |
where | 显示当前的行号和所处的函数。 |
Program Stack | |
backtrace | 显示当前堆栈的追踪,当前所在的函数。 |
backtrace full | 打印所有局部变量的值。 |
frame number | 选择指定的栈帧。 |
up number | 向上或向下移动指定个数的栈帧。 |
info frame addr | 描述选中的栈帧。 |
info args | 显示选中栈帧的参数,局部变量,异常处理函数。all-reg也会列出浮点寄存器。 |
Source Code | |
list | 列出相应的源代码。 |
set listsize count | 设置list命令打印源代码时的行数。 |
directory directory-name | 在源代码路径前添加指定的目录。 |
directory | 当后面没有参数时,清除源代码目录。 |
Examine Variables | |
print variable | 打印指定变量的值。 |
p *array-var@length | 打印arrary-var中的前length项。 |
p/x var | 以十六进制打印整数变量var。 |
p/d var | 把变量var当作有符号整数打印。 |
p/u var | 把变量var作为无符号整数打印。 |
p/o var | 把变量var作为八进制数打印。 |
p/t var | 以整数二进制的形式打印var变量的值。 |
p/c variable | 当字符打印。 |
p/f variable | 以浮点数格式打印变量var。 |
p/a variable | 打印十六进制形式的地址。 |
x/w address | 打印指定的地址,以四字节一组的方式。 |
call expression | 类似于print,但不打印 void 。 |
disassem addr | 对指定地址中的指令进行反汇编。 |
Controlling GDB | |
set gdb-option value | 设置 GDB 的选项。 |
set print array on | 以可读形式打印数组。默认是 off 。 |
set print array-indexes on | 打印数组元素的下标。默认是 off 。 |
set print pretty on | 格式化打印 C 结构体的输出。 |
set print union on | 打印 C 中的联合体。默认是 on 。 |
set print demangle on | 控制 C++ 中名字的打印。默认是 on 。 |
Working Files | |
info files | 列出当前的文件,共享库。 |
file file | 把file当作调试的程序。如果没指定参数,丢弃。 |
core file | 把file当作 core 文件。如果没指定参数,则丢弃。 |
exec file | 把file当作执行程序。如果没指定参数,则丢弃。 |
symbol file | 从file中读取符号表。如果没指定参数,则丢弃。 |
load file | 动态链入file文件,并读取它的符号表。 |
path directory | 把目录directory加入到搜索可执行文件和符号文件的路径中。 |
Start and Stop | |
run | 从头开始执行程序,也允许进行重定向。 |
continue | 继续执行直到下一个断点或观察点。 |
continue number | 继续执行,但会忽略当前的断点number次。当断点在循环中时非常有用。 |
kill | 停止程序执行。 |
quit | 退出 GDB 调试器。 |
GDB 操作提示
l 在编译可执行文件时需要给 gcc 加上 "-g" 选项,这样它才会为生成的可执行文件加入额外的调试信息。
l 不要使用编译器的优化选项,比如: "-O","-O2"。因为编译器会为了优化而改变程序流程,那样不利于调试。
l 在 GDB 中执行 shell 命令可以使用:shell command
l GDB 命令可以使用 TAB 键来补全。按两次 TAB 键可以看到所有可能的匹配。
l GDB 命令缩写:例如 info bre 中的 bre 相当于 breakpoints。
GDB 在 Emacs 中的操作:
emacs 按键 | 动作 |
M-x gdb | 切换到 gdb 模式。 |
C-h m | 显示 gdb 模式介绍信息。 |
M-s | 等同于gdb 中的 step 命令。 |
M-n | 等同于gdb 中的 next 命令。 |
M-i | 等同于gdb 中的 stepi 命令。 |
C-c C-f | 等同于gdb 中的 finish 命令。 |
M-c | 等同于gdb 中的 continue 命令。 |
M-u | 等同于gdb 中的 up 命令。 |
M-d | 等同于gdb 中的 down 命令。 |
Linux 包含了一个叫gdb 的GNU 调试程序。gdb 是一个用来调试C和C++程序的强力调试器。它使你能在程序运行时观察程序的内部结构和内存的使用情况。以下是 gdb 所提供的一些功能:它使你能监视你程序中变量的值、它使你能设置断点以使程序在指定的代码行上停止执行、它使你能一行行的执行你的代码。在命令行上键入gdb并按回车键就可以运行gdb 了。(Windows需要安装MinGW或者CygWin并且需要配置环境变量才可以使用)
GDB 命令行参数
启动 GDB:
l gdb executable
l gdb -e executable -c core-file
l gdb executable -pid process-id
(使用命令 'ps -auxw' 可以查看进程的 pid)
选项 | 含义 |
–help | 列出命令行参数。 |
–exec=file | 指定可执行文件。 |
–core=core-file | 指明 core 文件。 |
–command=file | 从指定文件中读取 gdb 命令。 |
–directory=directory | 把指定目录加入到源文件搜索路径中。 |
–cd=directory | 以指定目录作为当前路径来运行 gdb 。 |
–nx | 不要执行 .gdbinit 文件中的命令。默认情况下,这个文件中的命令会在所有命令行参数处理完后被执行。 |
–batch | 在非交互模式下运行 gdb 。从文件中读取命令,所以需要 -x 选项。 |
–symbols=file | 从指定文件中读取符号表。 |
-write | 允许对可执行文件和 core 文件进行写操作。 |
–quiet | 不要打印介绍和版权信息。 |
–tty=device | 指定 device 为运行程序的标准输入输出。 |
–pid=process-id | 指定要附属的进程 ID 。 |
GDB命令
GDB 中使用的命令:
命令 | 描述 |
help | 列出 gdb 帮助信息。 |
help topic | 列出相关话题中的 gdb 命令。 |
help command | 列出命令描述信息。 |
apropos search-word | 搜索相关的话题。 |
info args | 列出运行程序的命令行参数。 |
info breakpoints | 列出断点。 |
info break | 列出断点号。 |
info break breakpoint-number | 列出指定断点的信息。 |
info watchpoints | 列出观察点。 |
info registers | 列出使用的寄存器。 |
info threads | 列出当前的线程。 |
info set | 列出可以设置的选项。 |
Break and Watch | |
break funtion | 在指定的函数,或者行号处设置断点。 |
break +offset | 在当前停留的地方前面或后面的几行处设置断点。 |
break file:func | 在指定的file文件中的func处设置断点。 |
break file:nth | 在指定的file文件中的第nth行设置断点。 |
break *address | 在指定的地址处设置断点。一般在没有源代码时使用。 |
break line-number ifcondition | 如果条件满足,在指定位置设置断点。 |
break line threadthread-number | 在指定的线程中中断。使用info threads可以显示线程号。 |
tbreak | 设置临时的断点。中断一次后断点会被删除。 |
watch condition | 当条件满足时设置观察点。 |
clear | 清除函数func处的断点。 |
delete | 删除所有的断点或观察点。 |
delete breakpoint-number | 删除指定的断点,观察点。 |
disable breakpoint-number-or-range | 不删除断点,仅仅把它设置为无效,或有效。 |
enable oncebreakpoint-number | 设置指定断点有效,当到达断点时置为无效。 |
enable del breakpoint-number | 设置指定断点有效,当到达断点时删除它。 |
finish | 继续执行到函数结束。 |
Line Execution | |
step | 进入下一行代码的执行,会进入函数内部。 |
next | 执行下一行代码。但不会进入函数内部。 |
until until line-number ifcondition | 继续运行直到到达指定行号,或者函数,地址等。 |
return | 弹出选中的栈帧(stack frame)。如果后面指定参数,则返回表达式的值。 |
stepi | 执行下一条汇编/CPU指令。 |
info signals | 当收到信号时执行下列动作:nostop(不要停止程序),stop(停止程序执行),print(显示信号),noprint(不显示),pass/noignore(允许程序处理信号),nopass/ignore(不让程序接受信号) |
where | 显示当前的行号和所处的函数。 |
Program Stack | |
backtrace | 显示当前堆栈的追踪,当前所在的函数。 |
backtrace full | 打印所有局部变量的值。 |
frame number | 选择指定的栈帧。 |
up number | 向上或向下移动指定个数的栈帧。 |
info frame addr | 描述选中的栈帧。 |
info args | 显示选中栈帧的参数,局部变量,异常处理函数。all-reg也会列出浮点寄存器。 |
Source Code | |
list | 列出相应的源代码。 |
set listsize count | 设置list命令打印源代码时的行数。 |
directory directory-name | 在源代码路径前添加指定的目录。 |
directory | 当后面没有参数时,清除源代码目录。 |
Examine Variables | |
print variable | 打印指定变量的值。 |
p *array-var@length | 打印arrary-var中的前length项。 |
p/x var | 以十六进制打印整数变量var。 |
p/d var | 把变量var当作有符号整数打印。 |
p/u var | 把变量var作为无符号整数打印。 |
p/o var | 把变量var作为八进制数打印。 |
p/t var | 以整数二进制的形式打印var变量的值。 |
p/c variable | 当字符打印。 |
p/f variable | 以浮点数格式打印变量var。 |
p/a variable | 打印十六进制形式的地址。 |
x/w address | 打印指定的地址,以四字节一组的方式。 |
call expression | 类似于print,但不打印 void 。 |
disassem addr | 对指定地址中的指令进行反汇编。 |
Controlling GDB | |
set gdb-option value | 设置 GDB 的选项。 |
set print array on | 以可读形式打印数组。默认是 off 。 |
set print array-indexes on | 打印数组元素的下标。默认是 off 。 |
set print pretty on | 格式化打印 C 结构体的输出。 |
set print union on | 打印 C 中的联合体。默认是 on 。 |
set print demangle on | 控制 C++ 中名字的打印。默认是 on 。 |
Working Files | |
info files | 列出当前的文件,共享库。 |
file file | 把file当作调试的程序。如果没指定参数,丢弃。 |
core file | 把file当作 core 文件。如果没指定参数,则丢弃。 |
exec file | 把file当作执行程序。如果没指定参数,则丢弃。 |
symbol file | 从file中读取符号表。如果没指定参数,则丢弃。 |
load file | 动态链入file文件,并读取它的符号表。 |
path directory | 把目录directory加入到搜索可执行文件和符号文件的路径中。 |
Start and Stop | |
run | 从头开始执行程序,也允许进行重定向。 |
continue | 继续执行直到下一个断点或观察点。 |
continue number | 继续执行,但会忽略当前的断点number次。当断点在循环中时非常有用。 |
kill | 停止程序执行。 |
quit | 退出 GDB 调试器。 |
GDB 操作提示
l 在编译可执行文件时需要给 gcc 加上 "-g" 选项,这样它才会为生成的可执行文件加入额外的调试信息。
l 不要使用编译器的优化选项,比如: "-O","-O2"。因为编译器会为了优化而改变程序流程,那样不利于调试。
l 在 GDB 中执行 shell 命令可以使用:shell command
l GDB 命令可以使用 TAB 键来补全。按两次 TAB 键可以看到所有可能的匹配。
l GDB 命令缩写:例如 info bre 中的 bre 相当于 breakpoints。
GDB 在 Emacs 中的操作:
emacs 按键 | 动作 |
M-x gdb | 切换到 gdb 模式。 |
C-h m | 显示 gdb 模式介绍信息。 |
M-s | 等同于gdb 中的 step 命令。 |
M-n | 等同于gdb 中的 next 命令。 |
M-i | 等同于gdb 中的 stepi 命令。 |
C-c C-f | 等同于gdb 中的 finish 命令。 |
M-c | 等同于gdb 中的 continue 命令。 |
M-u | 等同于gdb 中的 up 命令。 |
M-d | 等同于gdb 中的 down 命令。 |
GDB十分钟教程
作者: liigo
原文链接: http://blog.csdn.net/liigo/archive/2006/01/17/582231.aspx
日期: 2006年1月16日
本文写给主要工作在Windows操作系统下而又需要开发一些跨平台软件的程序员朋友,以及程序爱好者。
GDB是一个由GNU开源组织发布的、UNIX/LINUX操作系统下的、基于命令行的、功能强大的程序调试工具。
GDB中的命令固然很多,但我们只需掌握其中十个左右的命令,就大致可以完成日常的基本的程序调试工作。
命令 | 解释 | 示例 |
file <文件名> | 加载被调试的可执行程序文件。 因为一般都在被调试程序所在目录下执行GDB,因而文本名不需要带路径。 | (gdb) file gdb-sample |
r | Run的简写,运行被调试的程序。 如果此前没有下过断点,则执行完整个程序;如果有断点,则程序暂停在第一个可用断点处。 | (gdb) r |
c | Continue的简写,继续执行被调试程序,直至下一个断点或程序结束。 | (gdb) c |
b <行号> b <函数名称> b *<函数名称> b *<代码地址> d [编号] | b: Breakpoint的简写,设置断点。两可以使用“行号”“函数名称”“执行地址”等方式指定断点位置。 其中在函数名称前面加“*”符号表示将断点设置在“由编译器生成的prolog代码处”。如果不了解汇编,可以不予理会此用法。 d: Delete breakpoint的简写,删除指定编号的某个断点,或删除所有断点。断点编号从1开始递增。 | (gdb) b 8 (gdb) b main (gdb) b *main (gdb) b *0x804835c (gdb) d |
s, n | s: 执行一行源程序代码,如果此行代码中有函数调用,则进入该函数; n: 执行一行源程序代码,此行代码中的函数调用也一并执行。 s 相当于其它调试器中的“Step Into (单步跟踪进入)”; 这两个命令必须在有源代码调试信息的情况下才可以使用(GCC编译时使用“-g”参数)。 | (gdb) s (gdb) n |
si, ni | si命令类似于s命令,ni命令类似于n命令。所不同的是,这两个命令(si/ni)所针对的是汇编指令,而s/n针对的是源代码。 | (gdb) si (gdb) ni |
p <变量名称> | Print的简写,显示指定变量(临时变量或全局变量)的值。 | (gdb) p i (gdb) p nGlobalVar |
display ... undisplay <编号> | display,设置程序中断后欲显示的数据及其格式。 例如,如果希望每次程序中断后可以看到即将被执行的下一条汇编指令,可以使用命令 “display /i $pc” 其中 $pc 代表当前汇编指令,/i 表示以十六进行显示。当需要关心汇编代码时,此命令相当有用。 undispaly,取消先前的display设置,编号从1开始递增。 | (gdb) display /i $pc (gdb) undisplay 1 |
i | Info的简写,用于显示各类信息,详情请查阅“help i”。 | (gdb) i r |
q | Quit的简写,退出GDB调试环境。 | (gdb) q |
help [命令名称] | GDB帮助命令,提供对GDB名种命令的解释说明。 如果指定了“命令名称”参数,则显示该命令的详细说明;如果没有指定参数,则分类显示所有GDB命令,供用户进一步浏览和查询。 | (gdb) help display |
废话不多说,下面开始实践。
先给出一个示例用的小程序,C语言代码,简单的不能再简单了:
1 | //此程序仅作为“GDB十分钟教程”的示例代码, by liigo |
请将此代码复制出来并保存到文件 gdb-sample.c 中,然后切换到此文件所在目录,用GCC编译之:
gcc gdb-sample.c -o gdb-sample -g |
在上面的命令行中,使用 -o 参数指定了编译生成的可执行文件名为 gdb-sample,使用参数 -g 表示将源代码信息编译到可执行文件中。如果不使用参数 -g,会给后面的GDB调试造成不便。当然,如果我们没有程序的源代码,自然也无从使用 -g 参数,调试/跟踪时也只能是汇编代码级别的调试/跟踪。
下面“gdb”命令启动GDB,将首先显示GDB说明,不管它:
GNU gdb Red Hat Linux (5.3post-0.20021129.18rh) Copyright 2003 Free Software Foundation, Inc. GDB is free software, covered by the GNU General Public License, and you are welcome to change it and/or distribute copies of it under certain conditions. Type "show copying" to see the conditions. There is absolutely no warranty for GDB. Type "show warranty" for details. This GDB was configured as "i386-redhat-linux-gnu". (gdb) |
上面最后一行“(gdb) ”为GDB内部命令引导符,等待用户输入GDB命令。
下面使用“file”命令载入被调试程序 gdb-sample(这里的 gdb-sample 即前面 GCC 编译输出的可执行文件):
(gdb) file gdb-sample Reading symbols from gdb-sample...done. |
上面最后一行提示已经加载成功。
下面使用“r”命令执行(Run)被调试文件,因为尚未设置任何断点,将直接执行到程序结束:
(gdb) r Starting program: /home/liigo/temp/test_jmp/test_jmp/gdb-sample n = 1, nGlobalVar = 88 tempFunction is called, a = 1, b = 2 n = 3 Program exited normally. |
下面使用“b”命令在 main 函数开头设置一个断点(Breakpoint):
(gdb) b main Breakpoint 1 at 0x804835c: file gdb-sample.c, line 19. |
上面最后一行提示已经成功设置断点,并给出了该断点信息:在源文件 gdb-sample.c 第19行处设置断点;这是本程序的第一个断点(序号为1);断点处的代码地址为 0x804835c(此值可能仅在本次调试过程中有效)。回过头去看源代码,第19行中的代码为“n = 1”,恰好是 main 函数中的第一个可执行语句(前面的“int n;”为变量定义语句,并非可执行语句)。
再次使用“r”命令执行(Run)被调试程序:
(gdb) r Starting program: /home/liigo/temp/gdb-sample Breakpoint 1, main () at gdb-sample.c:19 19 n = 1; |
程序中断在gdb-sample.c第19行处,即main函数是第一个可执行语句处。
上面最后一行信息为:下一条将要执行的源代码为“n = 1;”,它是源代码文件gdb-sample.c中的第19行。
下面使用“s”命令(Step)执行下一行代码(即第19行“n = 1;”):
(gdb) s 20 n++; |
上面的信息表示已经执行完“n = 1;”,并显示下一条要执行的代码为第20行的“n++;”。
既然已经执行了“n = 1;”,即给变量 n 赋值为 1,那我们用“p”命令(Print)看一下变量 n 的值是不是 1 :
(gdb) p n $1 = 1 |
果然是 1。($1大致是表示这是第一次使用“p”命令——再次执行“p n”将显示“$2 = 1”——此信息应该没有什么用处。)
下面我们分别在第26行、tempFunction 函数开头各设置一个断点(分别使用命令“b 26”“b tempFunction”):
(gdb) b 26 Breakpoint 2 at 0x804837b: file gdb-sample.c, line 26. (gdb) b tempFunction Breakpoint 3 at 0x804832e: file gdb-sample.c, line 12. |
使用“c”命令继续(Continue)执行被调试程序,程序将中断在第二个断点(26行),此时全局变量 nGlobalVar 的值应该是 88;再一次执行“c”命令,程序将中断于第三个断点(12行,tempFunction 函数开头处),此时tempFunction 函数的两个参数 a、b 的值应分别是 1 和 2:
(gdb) c Continuing. Breakpoint 2, main () at gdb-sample.c:26 26 printf("n = %d, nGlobalVar = %d /n", n, nGlobalVar); (gdb) p nGlobalVar $2 = 88 (gdb) c Continuing. n = 1, nGlobalVar = 88 Breakpoint 3, tempFunction (a=1, b=2) at gdb-sample.c:12 12 printf("tempFunction is called, a = %d, b = %d /n", a, b); (gdb) p a $3 = 1 (gdb) p b $4 = 2 |
上面反馈的信息一切都在我们预料之中,哈哈~~~
再一次执行“c”命令(Continue),因为后面再也没有其它断点,程序将一直执行到结束:
(gdb) c Continuing. tempFunction is called, a = 1, b = 2 n = 3 Program exited normally. |
有时候需要看到编译器生成的汇编代码,以进行汇编级的调试或跟踪,又该如何操作呢?
这就要用到display命令“display /i $pc”了(此命令前面已有详细解释):
(gdb) display /i $pc (gdb) |
此后程序再中断时,就可以显示出汇编代码了:
(gdb) r Starting program: /home/liigo/temp/test_jmp/test_jmp/gdb-sample Breakpoint 1, main () at gdb-sample.c:19 19 n = 1; 1: x/i $pc 0x804835c <main+16>: movl $0x1,0xfffffffc(%ebp) |
看到了汇编代码,“n = 1;”对应的汇编代码是“movl $0x1,0xfffffffc(%ebp)”。
并且以后程序每次中断都将显示下一条汇编指定(“si”命令用于执行一条汇编代码——区别于“s”执行一行C代码):
(gdb) si 20 n++; 1: x/i $pc 0x8048363 <main+23>: lea 0xfffffffc(%ebp),%eax (gdb) si 0x08048366 20 n++; 1: x/i $pc 0x8048366 <main+26>: incl (%eax) (gdb) si 21 n--; 1: x/i $pc 0x8048368 <main+28>: lea 0xfffffffc(%ebp),%eax (gdb) si 0x0804836b 21 n--; 1: x/i $pc 0x804836b <main+31>: decl (%eax) (gdb) si 23 nGlobalVar += 100; 1: x/i $pc 0x804836d <main+33>: addl $0x64,0x80494fc |
接下来我们试一下命令“b *<函数名称>”。
为了更简明,有必要先删除目前所有断点(使用“d”命令——Delete breakpoint):
(gdb) d Delete all breakpoints? (y or n) y (gdb) |
当被询问是否删除所有断点时,输入“y”并按回车键即可。
下面使用命令“b *main”在 main 函数的 prolog 代码处设置断点(prolog、epilog,分别表示编译器在每个函数的开头和结尾自行插入的代码):
(gdb) b *main Breakpoint 4 at 0x804834c: file gdb-sample.c, line 17. (gdb) r The program being debugged has been started already. Start it from the beginning? (y or n) y Starting program: /home/liigo/temp/test_jmp/test_jmp/gdb-sample Breakpoint 4, main () at gdb-sample.c:17 17 { 1: x/i $pc 0x804834c <main>: push %ebp (gdb) si 0x0804834d 17 { 1: x/i $pc 0x804834d <main+1>: mov %esp,%ebp (gdb) si 0x0804834f in main () at gdb-sample.c:17 17 { 1: x/i $pc 0x804834f <main+3>: sub $0x8,%esp (gdb) si 0x08048352 17 { 1: x/i $pc 0x8048352 <main+6>: and $0xfffffff0,%esp (gdb) si 0x08048355 17 { 1: x/i $pc 0x8048355 <main+9>: mov $0x0,%eax (gdb) si 0x0804835a 17 { 1: x/i $pc 0x804835a <main+14>: sub %eax,%esp (gdb) si 19 n = 1; 1: x/i $pc 0x804835c <main+16>: movl $0x1,0xfffffffc(%ebp) |
此时可以使用“i r”命令显示寄存器中的当前值———“i r”即“Infomation Register”:
(gdb) i r eax 0xbffff6a4 -1073744220 ecx 0x42015554 1107383636 edx 0x40016bc8 1073834952 ebx 0x42130a14 1108544020 esp 0xbffff6a0 0xbffff6a0 ebp 0xbffff6a8 0xbffff6a8 esi 0x40015360 1073828704 edi 0x80483f0 134513648 eip 0x8048366 0x8048366 eflags 0x386 902 cs 0x23 35 ss 0x2b 43 ds 0x2b 43 es 0x2b 43 fs 0x0 0 gs 0x33 51 |
当然也可以显示任意一个指定的寄存器值:
(gdb) i r eax eax 0xbffff6a4 -1073744220 |
最后一个要介绍的命令是“q”,退出(Quit)GDB调试环境:
(gdb) q The program is running. Exit anyway? (y or n) y |
版权所有:liigo.com
转载请事先征得作者liigo同意。
liigo@sina.com
www.liigo.com
http://blog.csdn.net/liigo/
QQ: 175199125