一.gdb常用命令:


命令描述

backtrace(或bt)查看各级函数调用及参数

finish连续运行到当前函数返回为止,然后停下来等待命令

frame(或f) 帧编号选择栈帧

info(或i) locals查看当前栈帧局部变量的值

list(或l)列出源代码,接着上次的位置往下列,每次列10行

list 行号列出从第几行开始的源代码

list 函数名列出某个函数的源代码

next(或n)执行下一行语句

print(或p)打印表达式的值,通过表达式可以修改变量的值或者调用函数

quit(或q)退出gdb调试环境

set var修改变量的值

start开始执行程序,停在main函数第一行语句前面等待命令

step(或s)执行下一行语句,如果有函数调用则进入到函数中



*启动gdb 

$gdb 

这样可以和gdb进行交互了。 


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

$gdb -tui 

这样,使用了'-tui'选项,启动可以直接将屏幕分成两个部分,上面显示源代码,比用list方便多了。这时候使用上下方向键可以查看源代码,想要命令行使用上下键就用[Ctrl]n和[Ctrl]p. 


*启动gdb调试指定程序app: 

$gdb app 

这样就在启动gdb之后直接载入了app可执行程序,需要注意的是,载入的app程序必须在编译的时候有gdb调试选项,例如'gcc -g app app.c',注意,如果修改了程序的源代码,但是没有编译,那么在gdb中显示的会是改动后的源代码,但是运行的是改动前的程序,这样会导致跟踪错乱的。 


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

$gdb  

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


*启动程序之后,再启动gdb调试: 

$gdb  

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



**启动gdb之后的交互命令: 

交互命令支持[Tab]补全。 


*显示帮助信息: 

(gdb) help 


*载入指定的程序: 

(gdb) file app 

这样在gdb中载入想要调试的可执行程序app。如果刚开始运行gdb而不是用gdb app启动的话可以这样载入app程序,当然编译app的时候要加入-g调试选项。 


*重新运行调试的程序: 

(gdb) run 

要想运行准备调试的程序,可使用run命令,在它后面可以跟随发给该程序的任何参数,包括标准输入和标准输出说明符(<和> )和shell通配符(*、?、[、])在内。 


*修改发送给程序的参数: 

(gdb) set args no 

这里,假设我使用"r yes"设置程序启动参数为yes,那么这里的set args会设置参数argv[1]为no。 


*显示缺省的参数列表: 

(gdb) show args 


*列出指定区域(n1到n2之间)的代码: 

(gdb) list n1 n2 

这样,list可以简写为l,将会显示n1行和n2行之间的代码,如果使用-tui启动gdb,将会在相应的位置显示。如果没有n1和n2参数,那么就会默认显示当前行和之后的10行,再执行又下滚10行。另外,list还可以接函数名。 

一般来说在list后面可以跟以下这们的参数: 

  行号。 

<+offset>   当前行号的正偏移量。 

<-offset>   当前行号的负偏移量。 

 哪个文件的哪一行。 

 函数名。 

哪个文件中的哪个函数。 

<*address>  程序运行时的语句在内存中的地址。 


*执行下一步: 

(gdb) next 

这样,执行一行代码,如果是函数也会跳过函数。这个命令可以简化为n. 


*执行N次下一步: 

(gdb) next N 


*执行上次执行的命令: 

(gdb) [Enter] 

这里,直接输入回车就会执行上次的命令了。 


*单步进入: 

(gdb) step 

这样,也会执行一行代码,不过如果遇到函数的话就会进入函数的内部,再一行一行的执行。 


*执行完当前函数返回到调用它的函数: 

(gdb) finish 

这里,运行程序,直到当前函数运行完毕返回再停止。例如进入的单步执行如果已经进入了某函数,而想退出该函数返回到它的调用函数中,可使用命令finish. 


*指定程序直到退出当前循环体: 

(gdb) until 

或(gdb) u 

这里,发现需要把光标停止在循环的头部,然后输入u这样就自动执行全部的循环了。 


*跳转执行程序到第5行: 

(gdb) jump 5 

这里,可以简写为"j 5"需要注意的是,跳转到第5行执行完毕之后,如果后面没有断点则继续执行,而并不是停在那里了。 

另外,跳转不会改变当前的堆栈内容,所以跳到别的函数中就会有奇怪的现象,因此最好跳转在一个函数内部进行,跳转的参数也可以是程序代码行的地址,函数名等等类似list。 


*强制返回当前函数: 

(gdb) return 

这样,将会忽略当前函数还没有执行完毕的语句,强制返回。return后面可以接一个表达式,表达式的返回值就是函数的返回值。 


*强制调用函数: 

(gdb) call  

这里,可以是一个函数,这样就会返回函数的返回值,如果函数的返回类型是void那么就不会打印函数的返回值,但是实践发现,函数运行过程中的打印语句还是没有被打印出来。 


*强制调用函数2: 

(gdb) print  

这里,print和call的功能类似,不同的是,如果函数的返回值是void那么call不会打印返回值,但是print还是会打印出函数的返回值并且存放到历史记录中。 


*在当前的文件中某一行(假设为6)设定断点: 

(gdb) break 6 


*设置条件断点: 

(gdb) break 46 if testsize==100 

这里,如果testsize==100就在46行处断点。 


*检测表达式变化则停住: 

(gdb) watch i != 10 

这里,i != 10这个表达式一旦变化,则停住。watch 为表达式(变量)expr设置一个观察点。一量表达式值有变化时,马上停住程序(也是一种断点)。 


*在当前的文件中为某一函数(假设为func)处设定断点: 

(gdb) break func 


*给指定文件(fileName)的某个行(N)处设置断点: 

(gdb) break fileName:N 

这里,给某文件中的函数设置断点是同理的。 


*显示当前gdb断点信息: 

(gdb) info breakpoints 

这里,可以简写为info break.会显示当前所有的断点,断点号,断点位置等等。 


*删除N号断点: 

(gdb) delete N 


*删除所有断点: 

(gdb) delete 


*清除行N上面的所有断点: 

(gdb) clear N 



*继续运行程序直接运行到下一个断点: 

(gdb) continue 

这里,如果没有断点就一直运行。 


*显示当前调用函数堆栈中的函数: 

(gdb) backtrace 

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


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

(gdb) show language 

这里,如果gdb不能识别你所调试的程序,那么默认是c语言。 


*查看当前函数的程序语言: 

(gdb) info frame 


*显示当前的调试源文件: 

(gdb) info source 

这样会显示当前所在的源代码文件信息,例如文件名称,程序语言等。 


*手动设置当前的程序语言为c++: 

(gdb) set language c++ 

这里,如果gdb没有检测出你的程序语言,你可以这样设置。 


*查看可以设置的程序语言: 

(gdb) set language 

这里,使用没有参数的set language可以查看gdb中可以设置的程序语言。 


*终止一个正在调试的程序: 

(gdb) kill 

这里,输入kill就会终止正在调试的程序了。 


*print显示变量(var)值: 

(gdb) print var 

这里,print可以简写为p,print 是gdb的一个功能很强的命令,利用它可以显示被调试的语言中任何有效的表达式。表达式除了包含你程序中的变量外,还可以包含函数调用,复杂数据结构和历史等等。 


*用16进制显示(var)值: 

(gdb) print /x var 

这里可以知道,print可以指定显示的格式,这里用'/x'表示16进制的格式。 

可以支持的变量显示格式有: 

x  按十六进制格式显示变量。 

d  按十进制格式显示变量。 

u  按十六进制格式显示无符号整型。 

o  按八进制格式显示变量。 

t  按二进制格式显示变量。 

a  按十六进制格式显示变量。 

c  按字符格式显示变量。 

f  按浮点数格式显示变量。 



*如果a是一个数组,10个元素,如果要显示则: 

(gdb) print *a@10 

这样,会显示10个元素,无论a是double或者是int的都会正确地显示10个元素。 


*修改运行时候的变量值: 

(gdb) print x=4 

这里,x=4是C/C++的语法,意为把变量x值改为4,如果你当前调试的语言是Pascal,那么你可以使用Pascal的语法:x:=4。 


*显示一个变量var的类型: 

(gdb) whatis var 


*以更详细的方式显示变量var的类型: 

(gdb) ptype var 

这里,会打印出var的结构定义。 

**


[其他] 

============= 

*在Qt4.x环境中打印QString msg;的msg变量: 

步骤如下: 

1)定义一个宏printqstring 

define printqstring 

    printf "(QString)0x%x (length=%i): \"",&$arg0,$arg0.d->size 

    set $i=0 

    while $i < $arg0.d->size 

        set $c=$arg0.d->data[$i++] 

        if $c < 32 || $c > 127 

                printf "\\u0x%04x", $c 

        else 

                printf "%c", (char)$c 

        end 

    end 

    printf "\"\n" 

end 

2)(gdb) printqstring msg 

这里,这个宏可以在gdb中直接定义,据说也可以写到$HOME/.gdbinit,这样每次启动自动加载。 


*调试同时指明生成core文件: 

$gdb core 

用gdb同时调试一个运行程序和core文件,core是程序非法执行后core dump后产生的文件。当程序非法崩溃的时候会产生一个core文件,然后使用这个命令,会直接定位到发生程序崩溃的位置。注意:有时需要设置系统命令“ulimit -c unlimited”才能产生core文件。 



=============gdb查看内存===========

可以使用examine命令(简写是x)来查看内存地址中的值。x命令的语 法如下所示:

x/<n/f/u> <addr>

n、f、u是可选的参数。


n是一个正整数,表示需要显示的内存单元的个数,也就是说从当前地址向后显示几个 内存单元的内容,一个内存单元的大小由后面的u定义。


f 表示显示的格式,参见下面。如果地址所指的是字符串,那么格式可以是s,如果地十是指令地址,那么格式可以是i。


u 表示从当前地址往后请求的字节数,如果不指定的话,GDB默认是4个bytes。u参数可以用下面的字符来代替,b表示单字节,h表示双字节,w表示四字 节,g表示八字节。当我们指定了字节长度后,GDB会从指内存定的内存地址开始,读写指定字节,并把其当作一个值取出来。


<addr>表示一个内存地址。


注意:严格区分n 和u的关系,n表示单元个数,u表示每个单元的大小。 

n/f/u三个参数可以一起使用。例如:
命令:x/3uh 0x54320 表示,从内存地址0x54320读取内容,h表示以双字节为一个单位,3表示输出三个单位,u表示按十六进制显示。

输出格式
一般来说,GDB会根据变量的类型输出变量的值。但你也可以自定义GDB的输出的格式。例如,你想输出一个整数的十六进制,或是二进制来查看这个整型变量 的中的位的情况。要做到这样,你可以使用GDB的数据显示格式:

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

(gdb) help x
Examine memory: x/FMT ADDRESS.
ADDRESS is an expression for the memory address to examine.
FMT is a repeat count followed by a format letter and a size letter.
Format letters are o(octal), x(hex), d(decimal), u(unsigned decimal),
t(binary), f(float), a(address), i(instruction), c(char) and s(string).
Size letters are b(byte), h(halfword), w(word), g(giant, 8 bytes).
The specified number of objects of the specified size are printed
according to the format.

Defaults for format and size letters are those previously used.
Default count is 1. Default address is following last thing printed
with this command or "print".
(gdb) p f1
$4 = 8.25
(gdb) p f2
$5 = 125.5
(gdb) x/x &f1
0xbffff380:    0x41040000
(gdb) x/xw &f1
0xbffff380:    0x41040000
(gdb) x/xw &f2
0xbffff384:    0x42fb0000
(gdb) x/2xw &f1
0xbffff380:    0x41040000    0x42fb0000
(gdb) x/4xw &f1
0xbffff380:    0x41040000    0x42fb0000    0xbffff408    0x00bcba66
(gdb) x/tw &f1
0xbffff380:    01000001000001000000000000000000
(gdb) x/2tw &f1
0xbffff380:    01000001000001000000000000000000    01000010111110110000000000000000
(gdb) p record
$10 = {12, 76, 48, 62, 94, 17, 32, 37, 52, 69}
(gdb) p &record
$11 = (int (*)[10]) 0x8049740
(gdb) x/4uw 0x8049740
0x8049740 <record>:    12    76    48    62
(gdb) x/6ow 0x8049740
0x8049740 <record>:    014    0114    060    076
0x8049750 <record+16>:    0136    021