gdb调式程序
分类:
版权声明:本文为博主原创文章,未经博主允许不得转载。
最近要调试PHP源代码,使用工具GDB.
1. GDB简介
GDB是Linux/Unix下一个GNU调试程序,是用来调试C与C++程序的强力调试器。能够让用户在程序运行时观察程序的内部结构和内存的使用情况。
作用:
1)按照自定义的方式启动运行需要调试的程序。
2)可以使用指定位置和条件表达式的方式来设置断点。
3)程序暂停时的值的监视。
4)动态改变程序的执行环境。
2. 基本操作命令:
这里只介绍常用命令的简单用法,如需读者想更加深入的了解,还请读者参照gdb手册。也可以使用--help查看。
基本命令列表:
命令
|
解释
|
简写
|
file
|
装入想要调试的可执行文件
|
无
|
list
|
列出产生执行文件源代码的一部分
|
l
|
next
|
执行一行源代码但不进入函数内部
|
n
|
step
|
执行一行源代码而且进入函数内部
|
s
|
run
|
执行当前被调试的程序
|
r
|
continue
|
继续执行程序
|
c
|
quit
|
终止GDB
|
q
|
print
|
输出当前指定变量的值
|
p
|
break
|
在代码里设置断点
|
b
|
info break
|
查看设置断点的信息
|
i b
|
delete
|
删除设置的断点
|
d
|
watch
|
监视一个变量的值,一旦值有变化,程序停住
|
wa
|
help
|
GDB中的帮助命令
|
h
|
3,编程实例
创建c文件:test.c
- #include<stdio.h>
- #include<string.h>
- void prints(int i)
- {
- printf("hello %d\n", i);
- }
- void main ()
- {
- int i =0;
- for(i=1;i<6;i++){
- prints(i);
- }
- }
编译,其目标文件为test
gcc -o test test.c
这个程序执行
- ./test
时显示如下结果:
hello 1
hello 2
hello 3
hello 4
hello 5
4 gdb调试程序
如果需要使用gdb调试
在编译test.c的时候,并把调试选项打开:
- gcc -o -ggdb test test.c
(调试选项资料:
调试选项(DEBUGGING OPTION)
GNU CC拥有许多特别选项,既可以调试用户的程序,也可以对GCC排错:-g
以操作系统的本地格式(stabs, COFF, XCOFF,或DWARF).产生调试信息. GDB能够使用这些调试信息.
在大多数使用stabs格式的系统上, `-g'选项启动只有GDB才使用的额外调试信息;这些信息使GDB 调试效果更好,但是有可能导致其他调试器崩溃,或拒绝读入程序.如果你确定要控制是否生成额外的信息, 使用`-gstabs+', `-gstabs', `-gxcoff+', `-gxcoff', `-gdwarf+',或`-gdwarf' (见下文).
和大多数C编译器不同, GNU CC允许结合使用`-g'和`-O'选项.优化的代码偶尔制造 一些惊异的结果:某些声明过的变量根本不存在;控制流程直接跑到没有预料到的地方;某些语句因为计算结果是常量或已经确定而 没有执行;某些语句在其他地方执行,因为他们被移到循环外面了.
然而它证明了调试优化的输出是可能的.对可能含有错误的程序使用优化器是合理的.
如果GNU CC支持输出多种调试信息,下面的选项则非常有用.
-ggdb
以本地格式(如果支持)输出调试信息,尽可能包括GDB扩展.
)
1)启动
2)载入文件:file命令
file test
结果:
- gcc -o -ggdb test test.c
也可以通过直接启动的方式载入文件:
- root@ubuntu:/opt/c++# gdb test
- GNU gdb (Ubuntu/Linaro 7.2-1ubuntu11) 7.2
- Copyright (C) 2010 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://www.gnu.org/software/gdb/bugs/>...
- Reading symbols from /opt/c++/test...done.
3)list命令
也可以过回车查看源代码
- (gdb) list
- 1 #include<stdio.h>
- 2 #include<string.h>
- 3 void prints(int i)
- 4 {
- 5 printf("hello %d\n", i);
- 6 }
- 7 void main ()
- 8
- 9 {
- 10 int i =0;
- (gdb)
一次只列10行,如果要从11行开始继续列源代码可以输入
(gdb) list
也可以什么都不输直接敲回车,gdb提供了一个很方便的功能,在提示符下直接敲回车表示用适当的参数重复上一条命令。
回车:
- (gdb) list
- 1 #include<stdio.h>
- 2 #include<string.h>
- 3 void prints(int i)
- 4 {
- 5 printf("hello %d\n", i);
- 6 }
- 7 void main ()
- 8
- 9 {
- 10 int i =0;
- (gdb)
- 11 for(i=1;i<6;i++){
- 12 prints(i);
- 13 }
- 14
- 15 }
- 16
- (gdb)
4)单步逐条执行 next
首先用start命令开始执行程序:
- (gdb) start
- Temporary breakpoint 1 at 0x80483e9: file test1.c, line 10.
- Starting program: /opt/c++/test1
- Temporary breakpoint 1, main () at test1.c:10
- 10 int i =0;
- (gdb)
main
函数中变量定义之后的第一条语句处等待我们发命令,gdb列出这条语句表示它还没执行,并且马上要执行我们可以用next命令(简写为n)控制这些语句一条一条地执行:
- (gdb) next
- 11 for(i=1;i<6;i++){
- (gdb) (直接回车)
- 12 prints(i);
- (gdb)
- hello 1
- 11 for(i=1;i<6;i++){
- (gdb)
- 12 prints(i);
- (gdb)
- hello 2
- 11 for(i=1;i<6;i++){
- (gdb)
- 12 prints(i);
- (gdb)
- hello 3
- 11 for(i=1;i<6;i++){
- (gdb)
- 12 prints(i);
- (gdb)
- hello 4
- 11 for(i=1;i<6;i++){
- (gdb)
- 12 prints(i);
- (gdb)
- hello 5
- 11 for(i=1;i<6;i++){
- (gdb)
- 15 }
- (gdb)
5)逐条执行并进入函数:
用start命令重新来过,step命令(简写为s)进入 函数中去执行:
- (gdb) start
- Temporary breakpoint 2 at 0x80483e9: file test1.c, line 10.
- Starting program: /opt/c++/test1
- Temporary breakpoint 2, main () at test1.c:10
- 10 int i =0;
- (gdb) next
- 11 for(i=1;i<6;i++){
- (gdb) next
- 12 prints(i);
- (gdb) step
- prints (i=1) at test1.c:5
- 5 printf("hello %d\n", i);
- (gdb)
在函数中有几种查看状态的办法,backtrace命令(简写为bt)可以查看函数调用的栈帧:
- (gdb) bt
- #0 prints (i=1) at test1.c:5
- #1 0x08048407 in main () at test1.c:12
- (gdb)
6)在可以用info命令(简写为i)查看局部变量
- i locals
如果想查看main函数当前局部变量的值也可以做到,先用frame命令(简写为f)选择1号栈帧然后再查看局部变量:
- (gdb) f 1
- #1 0x08048407 in main () at test1.c:12
- 12 prints(i);
- (gdb)
7)输出当前指定变量的值 print
- (gdb) p i
- $1 = 1
- (gdb)