博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
gdb使用
阅读量:4489 次
发布时间:2019-06-08

本文共 4355 字,大约阅读时间需要 14 分钟。

编译时需添加-gdwarf-2和-g3两个参数。

加了-g3的参数后,gcc编译的时候,会将扩展的debug 信息编译进二进制文件里面,包括宏定义信息。

 

gdb主动生成core文件:  gcore

break if (condition)

例子: break if (testval > 3) (testval可以是局部变量)

 

显示字符串全部长度

 set print elements 0 

 

整理常用的gdb技巧。

常用命令

常用的gdb命令...

启动gdb

  1. 直接运行

    gdb --args prog arg1 arg2
  2. 运行gdb后使用run命令

    gdb progrun arg1 arg2
  3. attach到已运行的程序

    gdb --pid ${PID_OF_PROG}

ptype

ptype用于显示Symbol的类型,示例源码为:

struct ABC {    int val;}int main() {    ABC abc;    return 0;}

运行gdb:

(gdb) b 7(gdb) r(gdb) ptype abctype = struct XXX {    int val;}

ptype可以输出表达式的返回类型,具体介绍可参考。

print {type} variable

print(p)可以按照某种类型输出变量的值,示例源码如下:

struct ABC {    double val;    int val2;}int main() {    ABC abc;    abc.val = 1.5;    abc.val2 = 10;    void *pAbc = &abc;    return 0;}

运行gdb:

(gdb) b 13(gdb) r(gdb) p pAbc$1 = (void *) 0x7fffffffe710(gdb) p {ABC} 0x7fffffffe710$2 = {val = 1.5, val2 = 10}(gdb) p {ABC} pAbc$3 = {val = 1.5, val2 = 10}(gdb) p * (ABC*) pAbc$4 = {val = 1.5, val2 = 10}(gdb) p {double} pAbc$5 = 1.5(gdb) p * (double*) pAbc$6 = 1.5(gdb) p {int} (pAbc + sizeof (double))$7 = 10(gdb) p * (int*) (pAbc + sizeof (double))$8 = 10

examine

examine(x)可以按照一定的格式打印内存地址处的数据,详细文档可参考。

(gdb) x/{COUNT}{FMT}{SIZE} {ADDRESS}
  • {COUNT}: 打印的数目,默认为1。
  • {FMT}: 打印的格式,默认为上次使用的{FMT}:
    • o(octal): 8进制整数
    • x(hex): 16进制整数
    • d(decimal): 10进制整数
    • u(unsigned decimal): 10进制非负整数
    • t(binary): 2进制整数
    • f(float): 浮点数
    • a(address): 输出相对于前面最近的符号的偏移
    • i(instruction): 输出地址处的汇编指令
    • c(char): 字符
    • s(string): c字符串(null-terminated string)
    • z(hex, zero padded on the left): 见说明
  • {SIZE}: 打印的字节数目,默认为上次使用的{SIZE}:
    • b(byte): 1个字节
    • h(halfword): 2个字节
    • w(word): 4个字节
    • g(giant, 8 bytes): 8个字节
  • {ADDRESS}: 目标地址

几个例子:

(gdb) x/a 0x4014190x401419 
: 0x55c3c900000000b8(gdb) x/i 0x40138d=> 0x40138d
: mov -0x10(%rbp),%eax(gdb) x/1fg 1407374883460640x7fffffffdbd0: 10.125

设置源码目录

参考,使用dir /path/to/your/sources可在调试时添加一个源码目录。

设置字符编码

gdb默认使用utf-8编码,可以使用如下命令修改编码。

set charset GBK

也可直接在~/.gdbinit里设置。

线程相关的命令

下面是一些调试多线程程序时常用的命令:

  • info threads: 查看线程列表
  • thread 2: 切换到2号线程,线程编号可由info threads得知
  • thread apply all bt: 打印所有线程的堆栈

高级技巧

一些不太广为人知的技巧...

加载独立的调试信息

gdb调试的时候可以从单独的符号文件中加载调试信息。

(gdb) exec-file test(gdb) symbol-file test.debug

test是移除了调试信息的可执行文件, test.debug是被移除后单独存储的调试信息。参考,可以如下分离调试信息:

# 编译程序,带调试信息(-g)gcc -g -o test main.c# 拷贝调试信息到test.debugobjcopy --only-keep-debug test test.debug# 移除test中的调试信息strip --strip-debug --strip-unneeded test# 然后启动gdbgdb -s test.debug -e test# 或这样启动gdbgdb(gdb) exec-file test(gdb) symbol-file test.debug

分离出的调试信息test.debug还可以链接回可执行文件test中

objcopy --add-gnu-debuglink test.debug test

然后就可以正常用addr2line等需要读取调试信息的程序了

addr2line -e test 0x401c23

更多内容可阅读。

在内存和文件系统之间拷贝数据

  1. 将内存数据拷贝到文件里

    dump binary value file_name variable_namedump binary memory file_name begin_addr end_addr
  2. 改变内存数据

    使用set命令

执行gdb脚本

常用的gdb操作,比如打断点等可以放在一个gdb脚本里,然后使用时导入即可。例如:

b main.cpp:15b test.cpp:18

gdb运行时,使用source命令即可导入

(gdb) source /path/to/breakpoints.txt

或gdb运行时导入

gdb -x /path/to/breakpoints.txt prog

对于每次gdb运行都要调用的脚本,比如设置字符集等,可以放在~/.gdbinit初始文件里,这样每次gdb启动时都会自动调用。

执行命令并退出

有时候需要gdb执行若干条命令后就立即退出,而不是进入交互界面,这时可以使用-batch选项。

gdb -ex "set pagination 0" -ex "thread apply all bt" -batch -p $pid

上面的命令打印$pid进程所有线程的堆栈并退出。

自定义命令

参考,可以在gdb中自定义命令,比如:

(gdb) define hello(gdb) print "welcome"(gdb) print "hello $arg0"(gdb) end

然后如此调用

(gdb) hello world

即可输出

(gdb) $1 = "welcome"(gdb) $2 = "hello world"

条件断点

在条件断点里可以调用标准库的函数,比如下面这个:

# 如果strA == strB,则在断点处暂停(gdb) b main.cpp:255 if strcmp(strA.c_str(), strB.c_str()) == 0# 还是上面的场景,直接用string类的compare函数(gdb) b main.cpp:255 if strA.compare(strB) != 0 gdb的stl调试方法:
source ./stl-views-1.0.3.gdb    STL的GDB的调试配置STL的gdb调试命令:Data type   GDB command   std::vector
pvector stl_variable std::list
plist stl_variable T std::map
pmap stl_variable std::multimap
pmap stl_variable std::set
pset stl_variable T std::multiset
pset stl_variable std::deque
pdequeue stl_variable std::stack
pstack stl_variable std::queue
pqueue stl_variable std::priority_queue
ppqueue stl_variable std::bitset
td> pbitset stl_variable std::string pstring stl_variable std::widestring pwstring stl_variable pmap var left_var_type right_var_typepmap (*(CRoleItemAbility*)pRole.m_pItemAbi).m_uNormalPack.m_vItemMap TITEMPOS CUnitItem*

  

转载于:https://www.cnblogs.com/bornfish/p/4499783.html

你可能感兴趣的文章
.net 模糊匹配路径
查看>>
用包来组织模型
查看>>
ORA-29857: 表空间中存在域索引和/或次级对象
查看>>
LeetCode58 Length of Last Word
查看>>
Python基础语法 系统学习
查看>>
推荐15款好用的JS开发工具
查看>>
ios开发之数据的持久化存储机制
查看>>
poj 3264
查看>>
图标跟着摄像机(Camera)orthographicSize的值改变大小
查看>>
LeetCode 386——字典序排数
查看>>
Learn day1 变量/数据类型
查看>>
go安装和开发工具安装
查看>>
【Scala】Scala技术栈
查看>>
PAT-A1033 or codeup 2031 To Fill or Not to Fill (贪心)题解
查看>>
实体字符转换,同样变量密码加盐MD5后生成的加密字符串不同解决办法 (原)
查看>>
《Windows核心编程》第十一章——线程池
查看>>
内存优化
查看>>
Go socket
查看>>
无法连接asp.net development server
查看>>
BETTER SUPPORT FOR FUNCTIONAL PROGRAMMING IN ANGULAR 2
查看>>