linux gdb调试

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;






猜你喜欢

转载自blog.csdn.net/e1256325535/article/details/51172565