GDB命令

来源:互联网 发布:知乎 贫困生 人肉 编辑:程序博客网 时间:2024/05/17 06:04

说明:部分摘抄自《零点起飞学 Linux C》

安装GDB

Ubuntu等基于Debian的linux: apt-get install gdb
Fedora等基于RPM的linux:yum install gdb

使用GDB

  1. 启动/退出GDB $gdb 退出quit (简写为q)
  2. 载入程序 gdb examplefile example
  3. 列出源码 list (简写为l)(gdb)l 3,5 列出3~5行代码
  4. 执行程序 (gdb)run or r
  5. 使用帮助功能(gdb)help or (gdb)help run(具体命令)

设置断点与管理断点

  1. 设置断点:
    1. (gdb)break 9 or (gdb)b 9 在第9行设置断点
    2. 继续运行程序(gdb)continue or c
    3. break命令后也可以跟函数名,使程序在进入指定的函数之前停下来。设置断点也可以进行条件判断,即只有条件为真、程序到达指定行或函数时停下来。(gdb)b 9 if i>9
  2. 查看断点信息:(gdb)info break
  3. 删除断点:
    1. (gdb)delete 1 or d 1 删除编号为1的断点
    2. (gdb)d 1-6 删除编号为1-6的断点
  4. 删除指定行上的断点:(gdb)clear 9
  5. 禁用指定的断点 (gdb)disable 1(gdb)info break查看断点信息
  6. 设置观察点 (gdb)watch tol 观察变量tol ,必须在断点后设置观察点,run后才能设置。
  7. 当变量或表达式的值发生变化时,暂停程序的运行,如果想在变量或表达式被读时暂停程序的运行,可以使用rwatch命令;如果想在变量或表达式被读或被写时暂停程序的运行,可以使用awatch命令。info watchpoints查看当前所有观察点,可以用delete命令删除指定的观察点。

显示数据与改变量值

显示数据用于查看数据在程序运行过程中的值。改变变量值是在程序调试过程中,可以修改变量的值,以方便发现错误。

  1. 显示变量或表达式的值:(gdb)print (or p)tol
  2. 指定格式:(gdb)p/x tol 以十六进制格式显示
  3. t:二进制 o (八进制)d(十进制)c(字符格式) f(浮点数)
    print 命令可以显示数组内容、函数调用等信息。(gdb) p *a@6 *a为数组的地址,6为数组的长度。查看a数组各元素的值
  4. 自动显示变量或表达式的值
    (gdb) display tol 每次运行到断点处都会自动显示变量tol的值。

    (gdb) info display
    undisplay 或delete display
    disable display
    enable display

  5. 通过whatis或ptype命令来查看变量的数据类型

    (gdb) whatis a
    (gdb) ptype tol

  6. 修改变量的值

    (gdb) set tol=100

执行命令和调试函数

单步调试:
单步执行就是一步一步跟踪程序执行的流程,根据变量的值,找到错误的原因。
step(简写为s)可以跟踪进入函数内部,在执行到函数调用部分时,GDB会给出提示信息,包括被调函数的入口参数、起始行号等。同时也会给出函数中将要执行的语句及所在行的号。
next(简写为n)不进入函数,将函数调用看做是一条语句,不跟踪进入函数内部。
s进入函数后,return 和finish命令退出被调用的函数。
执行到指定行 :(gdb) until 行号
跳转执行:(gdb) jump 行号
强制调用函数:call printf("End\n")

查看堆栈信息

程序运行中调用函数时,函数的首地址、参数、以及函数内的局部变量等都会被压入程序栈内。
backtrace(简写为bt)和frame(简写为f)命令查看栈的信息。
(gdb) f 1 1为栈帧的编号
查看当前栈帧的详细信息,info frame 或(info f)
查看源程序信息:(gdb) info source
查看寄存器:info registers(不包括浮点寄存器)
info all-registers(包括浮点寄存器)
(gdb)p $eip访问单个寄存器,在寄存器前面加$
查看程序的汇编代码:在调试程序过程中,可以通过disassemble命令来显示程序的汇编代码! disassemble printinfo

在linux平台下GDB是一款强大的调试工具。
GDB主要帮你完成以下四个方面的功能
1、 启动你的程序,可以按照你的自定义的要求随心所欲的运行程序。
2、 可让被调试的程序在你所指定的调置的断点处停住。(断点可以是条件表达式)
3、 当程序被停住时,可以检查此时你的程序中所发生的事。
4、 动态的改变你程序的执行环境。

一般来说GDB主要调试的是C/C++的程序。

调试信息(-g)

要调试C/C++的程序,首先在编译时,我们必须要把调试信息加到可执行文件中。使用编译器(cc/gcc/g++)的 -g 参数可以做到这一点。
如:
> cc -g hello.c -o hello
> g++ -g hello.cpp -o hello
如果没有-g,你将看不见程序的函数名、变量名,所代替的全是运行时的内存地址。当你用-g把调试信息加入之后,并成功编译目标代码以后,让我们来看看如何用gdb来调试他。
启动GDB的方法有以下几种:
1、gdb "program" program也就是你的执行文件,一般在当前目录下。
2、gdb "program” core 用gdb同时调试一个运行程序和core文件,core是程序非法执行后core dump后产生的文件。
3、gdb program PID 如果你的程序是一个服务程序,那么你可以指定这个服务程序运行时的进程ID。gdb会自动attach上去,并调试他。program应该在PATH环境变量中搜索得到。
在启动了gdb后,就可以开始使用gdb中命令了。如果希望查看都有哪些命令,可以输入help进行查询。

下面简单演示几个小例子:
示例一:在进入函数func时,设置一个断点。可以敲入break func,或是直接就是b func
(gdb) b func
Breakpoint 1 at 0x8048458: file hello.c, line 10.
示例二:敲入b按两次TAB键,你会看到所有b打头的命令:
(gdb) b
backtrace break bt

示例三:调试C++的程序时,有可能函数名一样。如:
(gdb) b 'bubble( M-?
bubble(double,double) bubble(int,int)
(gdb) b 'bubble(
你可以查看到C++中的所有的重载函数及参数。(注:M-?和“按两次TAB键”是一个意思

需要特别说明的是,在gdb中运行程序时,使用run命令,可能需要做以下的操作。

  1. 程序运行参数。
    set args可指定运行时参数。(如:set args 10 20 30 40 50)
    show args命令可以查看设置好的运行参数。   
  2. 运行环境。
    path “dir” 可设定程序的运行路径。
    show paths 查看程序的运行路径。
    set environment varname [=value] 设置环境变量。如:set env USER=hchen
    show environment [varname] 查看环境变量。
  3. 工作目录。
    cd “dir” 相当于shell的cd命令。
    pwd 显示当前的所在目录。
  4. 程序的输入输出。
    info terminal 显示你程序用到的终端的模式。
    使用重定向控制程序输出。如:run > outfile
    tty命令可以指写输入输出的终端设备。如:tty /dev/ttyb

gdb可以对多个线程设置断点
gdb 可以打印栈信息

下面是我借鉴的几个网址:
GDB十分钟教程 (讲了一些最常用的参数,和一个简单练习。入门很不错,我以前就是按这学习的)
陈皓的GDB调试程序(讲得挺详细的,提到了好多功能,不看不知道,如果能把GDB运用好,那会节省多少工作量)

gcc/g++在执行编译工作的时候,总共需要以下几步:
1.预处理,生成.i的文件[预处理器cpp]
2.将预处理后的文件转换成汇编语言,生成文件.s[编译器egcs]
3.有汇编变为目标代码(机器代码)生成.o的文件[汇编器as]
4.连接目标代码,生成可执行程序[链接器ld]

GCC 常用命令行:
我常用一句:gcc -Wall -g example.c -o example
-Wall 启动所有警告消息
-g 获取有关调试程序的详细信息。
(注意:不能和优化选项一起使用,因为在对代码进行优化的过程中,某些代码可能被改写,或为了取得最佳的性能而进行了重组,这样对程序的跟踪和调试时非常不利的。)

总结:

只是看了一下他们有哪些功能。不怕不熟练,就怕不知道。我们有时候费很大力气搞出来的东西,其实工具自身已经自带这个功能,一个参数搞定~~~对GCC和GDB的有些功能暂时还没有用到,所以体会不是很深。

GDB命令

0 0