gdb调试常用的命令:
1.显示程序中的当前位置和表示如何到达当前位置的栈跟踪:bt, where, info stack;这三个的功能都是一样的,在程序崩溃之后使用该命令查看堆栈的历史记录,很管用。
用法:
bt n: 显示程序栈顶的n帧信息;
bt -n: 显示程序栈底的n帧信息;
frame n: 查看第n帧的简要信息;
2.info: 获取和被调试程序的相关信息;
info frame或info frame n: 查看帧或第n帧的详细信息;
info locals: 查看当前帧中的局部变量信息;
3.list: 查看执行位置的代码;
list n: 查看当前文件中第n行周围的源代码;
list func: 查看函数func周围的源代码;
4.print:打印表达式或者变量的信息。
用法:p [/format] exptr;
p temp: 打印变量temp的值;
p /x temp: 按十六进制的形式打印变量temp的值;
------------------------------------------------------------------
format的取值范围有如下几种:
- x 按十六进制格式显示变量。
- d 按十进制格式显示变量。
- u 按十六进制格式显示无符号整型。
- o 按八进制格式显示变量。
- t 按二进制格式显示变量。
- a 按十六进制格式显示变量。
- c 按字符格式显示变量。
- f 按浮点数格式显示变量。
------------------------------------------------------------------
5.查看函数的返回值信息:
a.执行finish至函数结束,此时会自动打印出函数的返回值;
(gdb)finish
Run till exit from #0 foo () at main.c:9
main () at main.c:15
15 }
Value returned is $2 = 100
b.函数返回值会存储在寄存器eax中,可以直接查看该寄存器的值:
(gdb)p $eax
$3 = 100
(gdb) info registers
eax 0x64 100
6.查看内存:
examine命令(简写x): x /(n/f/u) <addr>;
-
n 表示显示内存的长度,也就是说从当前地址向后显示几个地址的内容。-----------显示的变量的个数
-
f 表示显示的格式,如果是字符串,则用s,如果是数字,则可以用i。
-
u 表示从当前地址往后请求的字节数,默认是4个bytes。(b单字节,h双字节,w四字节,g八字节)--------指定每个变量所占用的字节数
-
<addr> 表示一个内存地址。
例如:以两字节为单位显示数组arr的地址后32字节内存信息如下.
(gdb)x /16uh arr
0xbffff4cc: 2 0 4 0 6 0 8 0
0xbffff4dc: 10 0 34032 2052 0 0 0 0
特殊的查看方式:连续内存的查看;
可以使用GDB的"@"操作符查看连续内存,"@"的左边是第一个内存的地址的值,"@"的右边则你你想查看内存的长度。
例如,对于如下代码:int arr[] = {2, 4, 6, 8, 10};,可以通过如下命令查看arr前三个单元的数据。
(gdb)p *arr@3
$2 = {2, 4, 6}
7.设置断点:
a.非条件断点:break test.cpp:10(在test.cpp文件的第10行设置一个断点);
b.条件断点:break test.cpp:38 if count==3(在test.cpp的第38行设置一个断点,如果程序执行到这里的时候count为3,则程序将暂停执行);
c.“break main”:在main函数入口设置断点,可以从程序一开始运行就跟踪调试代码;
8.查看变量的类型:whatis;
whatis p: 查看p的类型;
9.在不同的调用上下文中切换栈帧:frame;
frame num:切换到栈帧号为num的栈中;
在分析核心文件时,通过将遍历栈的命令和检查变量值的“print”命令结合起来,就能够复原程序运行时的全部景象。
10.调试正在运行的进程:有些进程可能无法直接在调试器上运行,可以通过下面的方式来调试这些进程。
第一种是在GDB命令行上指定进程的PID:先执行程序dataserverhq,然后通过ps -aux | grep dataserverhq获取程序的pid,最后在另外一个打开的shell中执行gdb dataserverhq pid;
第二种是先用file命令加载调试时所需的符号表,然后再通过“attaché”命令进行连接:
(gdb) file /home/xiaowp/debugme Reading symbols from /home/xiaowp/debugme...done.
(gdb) attach 555 ……
调试结束结束时,用detach断开连接,让被调试的进程可以继续正常执行下去。
11.载入需要调试的程序:
第一种方法:gdb dataserverhq;
第二种方法:gdb; file dataserverhq;
第三种方法: gdb attach process_pid;
12.恢复程序运行,直到程序结束(从断点处继续运行):continue, c, fg;
13.显示调用和执行一个函数:call function(arg1, arg2,...);
14.结束当前循环:until, u;
15.使用info threads 可以查看运行的线程.
thread num: 切换到线程号为num的线程;
16.查看当前栈层的信息:frame, f;
17.info f(或者info frame):打印出更为详细的当前栈层的信息;
18.强制函数返回:
如果你的调试断点在某个函数中,并还有语句没有执行完。你可以使用 return 命令强制函数忽略还没有执行的语句并返回。
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
还有就是里面某个线程停住,也没死,这种情况一般就是死锁或者涉及消息接受的超时问题(听人说的,没有遇到过)。遇到这种情况,可以使用:
gcore pid (调试进程的pid号)
手动生成core文件,在使用pstack(linux下好像不好使)查看堆栈的情况。
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
gdb的tui(terminal user interface)方法调试代码:
前提:代码跟运行的程序需要在同一台主机上,不然找不到源代码。
打开/关闭方式:ctrl+x+a;
启动方式:gdb -tui ./dataserverhq;