Linux技术——gdb调试基础

来源:互联网 发布:淘宝怎么登陆不了 编辑:程序博客网 时间:2024/05/17 03:31

gdb即GNU debugger。
gcc编译选项-g,这样生成的目标代码中就添加了调试信息。
gcc -g –o hello hello.c
gdb完成的大部分工作都可以用很少的命令集合完成。

启动gdb
gdb 程序名 [corefile]
corefile是可选的,但能增强gdb的调试能力。
Linux默认是不生成corefile的,所以需要在用户profile文件中添加
ulimit -c unlimited
修改完成之后让profile文件及时生效

一个有错的程序

#include <stdio.h>void test(void){    int *i = NULL;    *i = 2;}int main(void){    printf(“hello world\n”);    test();    return 0;}

编译这个程序
gcc –g –o hello hello.c
运行hello
Segmentation fault (core dumped)
程序崩溃
ls
core.3563 hello hello.c
我们看到除了hello文件和hello.c文件之外多了core文件

启动gdb
gdb hello core
如果你不喜欢一大堆的软件信息,可以通过-q参数关闭软件信息
gdb -q hello core
0 0x08048394 in test () at hello.c:5
5 *i = 2;
可以看到gdb通过core告诉你,程序哪条语句出现问题

我们做的第一件事就是在gdb环境中运行这个程序
gdb hello
run命令。
Starting program: /home/test/1/hello
hello world

Program received signal SIGSEGV, Segmentation fault.
0x08048394 in test () at hello.c:5
5 *i = 2;
gdb不但能显示出错行号,还能说明出错出现时的内存地址,这个也是潜在的有用信息。

test函数到底出了什么问题?
where命令,显示导致段错误的执行函数树
0 0x08048394 in test () at hello.c:5
1 0x080483be in main () at hello.c:11
问题出在hello.c文件的第5行。

知道函数出错行的上下文对调试程序是很有帮助的。
list [m,n],m,n是要显示包含错误首次出现位置的起始行和结尾行。不带参数的list将显示附近的10行代码

gdb最有用的功能之一就是它可以显示被调试程序中任何表达式、变量的值。
print 变量,表达式。
print ‘file’::变量,表达式,‘’是必须的,以便让gdb知道指的是一个文件名。
print funcname::变量,表达式
(gdb) print i
$1 = (int *) 0x0
显示指针变量i的值为0。
whatis 命令可以告诉你变量的类型, ptype 告诉你结构的定义。
(gdb) whatis i
type = int *

break命令设置断点
break linenum
break funcname
break filename:linenum
break filename:funcname

退出gdb,重新进入调试模式
gdb -q hello
(gdb) break 4
Breakpoint 1 at 0x804838a: file hello.c, line 4.
(gdb) run
Starting program: /home/test/1/hello
hello world

Breakpoint 1, test () at hello.c:4
4 int *i = NULL;
gdb在第4行停止。

continue命令从断点以后继续执行。
delete删除一个断点。
如果设置了很多断点,忘记了哪些断点已经触发,可以使用info break。
(gdb) info break
Num Type Disp Enb Address What
1 breakpoint keep y 0x0804838a in test at hello.c:4
breakpoint already hit 1 time

改变一个变量的值。
set variable varname = value
varname是变量名称,value是变量的新值。

单步调试
step命令
当遇到一个函数的时候,step将进入函数,每次执行一条语句,相当于step into
next命令
当遇到一个函数的时候,next将执行整个函数,相当于step over
return [value]命令
停止执行当前函数,将value返回给调用者,相当于step return
如果需要重复执行一条命令,不需要每次都键入命令,gdb记住了最后一个被执行的命令,只要简单的按enter键就可以重复执行最后的命令

更多详情参考:
Linux GDB 程序调试工具使用详解

0 0
原创粉丝点击