Learn to use GDB (1)

What is gdb?

gdb在linux下是一款非常强大的程序调试工具,有的时候会有比IDE更强大的代码调试功能。

GDB, the GNU Project debugger, allows you to see what is going on ‘inside’ another program while it executes — or what another program was doing at the moment it crashed.
GDB can do four main kinds of things (plus other things in support of these) to help you catch bugs in the act:

  • Start your program, specifying anything that might affect its behavior.
  • Make your program stop on specified conditions.
  • Examine what has happened, when your program has stopped.
  • Change things in your program, so you can experiment with correcting the effects of one bug and go on to learn about another.
    The program being debugged can be written in Ada, C, C++, Objective-C, Pascal (and many other languages). Those programs might be executing on the same machine as GDB (native) or on another machine (remote). GDB can run on most popular UNIX and Microsoft Windows variants.

—–from gnu.org

wiki上你一定可以得到更多的信息。

一个简单的小程序

//test.cpp
#include <iostream>
using namespace std;

int foo(){
    int a = 10;
    cout << "function foo" << endl;
}

int main(){
    foo();
    int a = 100;
    return 0;
}

编译:

g++ test.cpp -g -o test

记得编译的时候要加上-g选项,这样才能让生成的程序具有调试的信息。

命令列表

用于启动gdb的命令

$ gdb

启动gdb

$ gdb -tui

启动gdb,并且分屏显示源代码

$ gdb app

启动gdb,并且加载app程序。要注意的是,这个app程序必须在编译的时候开启了-g选项。

$gdb <program> <pid>

启动程序之后,再用gdb调试。

这里,<program>是程序的可执行文件名,<PID>是要调试程序的PID.如果你的程序是一个服务程序,那么你可以指定这个服务程序运行时的进程ID。gdb会自动attach上去,并调试他。program应该在PATH环境变量中搜索得到。

$gdb <pid>

启动程序之后,再用gdb调试。

这里,程序是一个服务程序,那么你可以指定这个服务程序运行时的进程ID,<PID>是要调试程序的PID.这样gdb就附加到程序上了,但是现在还没法查看源代码,用file命令指明可执行文件就可以显示源代码了。

在gdb中常用的交互命令

所有命令都可以使用[tab]键补全。

(gdb) help

获得gdb的帮助信息

(gdb) file app

载入要调试的可执行文件app。如果刚开始是以$ gdb而不是$ gdb app启动的,那么使用这样的方式来载入文件。当然,要记得文件的编译选项。

(gdb) run

使用run命令来运行程序,你可以在这个命令的后面继续输入该程序输入的参数。当然也可以使用输入输出的重定向符,和shell通配符。

(gdb) set args <arg_list>

修改为调试程序传入的参数。

(gdb) show args

查看缺省的参数列表。

(gdb) list

默认的list会显示当前行和之后的10行代码,当然我们可以通过list的参数来改变。list的说明如下:

With no argument*, lists ten more lines after or around previous listing.
“list -” lists the ten lines before a previous ten-line listing.
One argument specifies a line, and ten lines are listed around that line.
Two arguments with comma between specify starting and ending lines to list.
Lines can be specified in these ways:

LINENUM, to list around that line in current file,
FILE:LINENUM, to list around that line in that file,
FUNCTION, to list around beginning of that function,
FILE:FUNCTION, to distinguish among like-named static functions.
*ADDRESS, to list around the line containing that address.
With two args if one is empty it stands for ten lines away from the other arg.

(gdb) next

no argument 执行下一步(不会跟进函数中)
one argument (形如:(gdb) next N) 执行N次下一步

(gdb) [Enter]

执行上一次的命令。什么都不输入直接回车就可以了。

(gdb) step

no argument 执行下一步(会跟进函数中,并一行一行执行)
one argument (形式同next) 执行N次下一步

(gdb) finish

执行完当前函数,直到函数返回再停止。
Execute until selected stack frame returns. Upon return, the value returned is printed and put in the value history.

(gdb) until

执行完当前循环体,要求当前位置在一个循环的头部。
Execute until the program reaches a source line greater than the current or a specified location (same args as break command) within the current frame.

(gdb) return

忽略当前函数没有执行完的部分,强制返回,可以接一个表达式,来表示这个return的返回值。
Make selected stack frame return to its caller.
Control remains in the debugger, but when you continue execution will resume in the frame above the one now selected.
If an argument is given, it is an expression for the value to return.

(gdb) break N

在当前文件的第N行设置断点。

(gdb) break FUNCTION

在当前文件的函数FUNCTION处设置断点。

(gdb) break FILENAME: N

给某文件的第N行设置断点。

(gdb) info breakpoints

查看当前的所有断点。包括断点号,断点位置等。

(gdb) delete

no argument 删除所有断点。
one argument 删除N号断点。

(gdb) clear [LINENUM|FUNCTION|*ADDRESS]

LINENUM: 删除第N行上的所有断点。
FUNCTION: 删除函数头部的所有断点。
*ADDRESS: 删除在这个地址上的所有断点。

(gdb) continue

运行,直到遇到下一个断点。

(gdb) backtrace

命令产生一张列表,包含着从最近的过程开始的所有有效过程和调用这些过程的参数。当然,这里也会显示出当前运行到了哪里(文件,行)。

(gdb) show language

查看当前调试程序的语言环境。

(gdb) info frame

查看当前函数的程序语言

(gdb) info source

显示当前调试的源文件。

(gdb) set language c++

手动设置当前语言为c++。

(gdb) kill

终止一个正在调试的程序。

(gdb) watch

Set a watchpoint for an expression.
Usage: Watch [-l|-location] EXPRESSION
A watchpoint stops execution of your program whenever the value of an expression changes.
if -l or -location is given, this evaluates EXPRESSION and watches the memory to which it refers.

当输入的表达式变化的时候就停住。

(gdb) print var

以显示被调试的语言中任何有效的表达式。表达式除了包含你程序中的变量外,还可以包含函数调用,复杂数据结构和历史等等。
(我的理解是这个表达式会被执行,并且把返回值输出出来。可以使用类似于x=4的形式在运行中修改变量的值)

(gdb) print /x var

以指定格式显示,支持的格式有:

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

(gdb) whatis EXP

显示表达式EXP的类型。可以使用ptype获取一个更详细的显示,它会同时打印出结构的定义。

</body></html>

    原文作者:TwIStOy
    原文地址: https://segmentfault.com/a/1190000000636464
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞