GDB技巧整理
https://blog.atime.me/note/gdb-tricks.html
整理常用的gdb技巧。
常用命令
常用的gdb命令...
启动gdb
直接运行
gdb --args prog arg1 arg2
运行gdb后使用run命令
gdb prog
run arg1 arg2attach到已运行的程序
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 abc type = struct XXX {
int val;
}
ptype可以输出表达式的返回类型,具体介绍可参考Examining the Symbol Table。
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
有时候,如果字符串太长,gdb可能只打印一部分,这时候如下设置来打印全部内容:
(gdb) set print elements 0
examine
examine(x)可以按照一定的格式打印内存地址处的数据,详细文档可参考这里。
(gdb) x/{COUNT}{FMT}{SIZE} {ADDRESS}
{COUNT}
: 打印的数目,默认为1。{FMT}
: 打印的格式1,默认为上次使用的{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 0x401419
0x401419 <main()+113>: 0x55c3c900000000b8 (gdb) x/i 0x40138d
=> 0x40138d <crash(int, double)+41>: mov -0x10(%rbp),%eax (gdb) x/1fg 140737488346064
0x7fffffffdbd0: 10.125
设置源码目录
参考Specifying Source Directories,使用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是被移除后单独存储的调试信息。参考stackoverflow上的一个问题,可以如下分离调试信息:
# 编译程序,带调试信息(-g)
gcc -g -o test main.c # 拷贝调试信息到test.debug
objcopy --only-keep-debug test test.debug # 移除test中的调试信息
strip --strip-debug --strip-unneeded test # 然后启动gdb
gdb -s test.debug -e test # 或这样启动gdb
gdb
(gdb) exec-file test
(gdb) symbol-file test.debug
分离出的调试信息test.debug还可以链接回可执行文件test中
objcopy --add-gnu-debuglink test.debug test
然后就可以正常用addr2line等需要读取调试信息的程序了
addr2line -e test 0x401c23
更多内容可阅读GDB: Debugging Information in Separate Files。
在内存和文件系统之间拷贝数据
将内存数据拷贝到文件里
dump binary value file_name variable_name
dump binary memory file_name begin_addr end_addr改变内存数据
使用set命令
执行gdb脚本
常用的gdb操作,比如打断点等可以放在一个gdb脚本里,然后使用时导入即可。例如:
b main.cpp:15
b test.cpp:18
gdb运行时,使用source命令即可导入
(gdb) source /path/to/breakpoints.txt
或gdb运行时导入
gdb -x /path/to/breakpoints.txt prog
对于每次gdb运行都要调用的脚本,比如设置字符集等,可以放在~/.gdbinit初始文件里,这样每次gdb启动时都会自动调用。
输出到文件
可以通过set logging on
将命令的输出保存到默认的gdb.txt文件中。当然也可以通过set logging file my_log.txt
来设置输出文件的路径。
执行命令并退出
有时候需要gdb执行若干条命令后就立即退出,而不是进入交互界面,这时可以使用-batch
选项。
gdb -ex "set pagination 0" -ex "thread apply all bt" -batch -p $pid
上面的命令打印$pid进程所有线程的堆栈并退出。
自定义命令
参考gdb/Define,可以在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
捕获exception
gdb遇到未处理的exception时,并不会捕获处理。但是参考Set Catchpoints,可以使用catch catch
命令来捕获exception。
阅读资料
GDB技巧整理的更多相关文章
- IT第十天 - String和StringBuffer的比较、编程设计技巧整理、本周总结 ★★★
IT第十天 上午 String 1.String在进行多次的+扩展时,会严重的降低处理效率,因为String长度是不可变的,在进行+运算改变字符串时,会自动创建很多临时字符串,并不是在原字符串上追加, ...
- Tensorflow小技巧整理:修改张量特定元素的值
TensorFlow小技巧整理:修改张量特定元素的值 最近在做一个摘要生成的项目,过程中遇到了很多小问题,从网上查阅了许多别人解决不同问题的方法,自己也在旁边开了个jupyter notebook搞些 ...
- sqlmap常用技巧整理
言 通过在乌云网上出现的很多SQL注入漏洞,因此来总结一下,大致使用SQLMAP所遇到的参数. 基本结构 基本SQLMAP的使用方式就如下所示,使用参数式的方式,按需求添加. 12 sqlmap.py ...
- aptana studio 使用技巧整理
aptana studio 使用技巧整理 https://192.168.1.16/web/punica/adaptana studio 使用技巧整理http://uedfans.cn/ 推荐一个网站 ...
- sql事务的使用及其技巧整理
sql事务的使用及其技巧整理 概述: 在实际项目开发中,为了确保数据操作结果的一致性等要求,事务是一个必不可少的解决利器. 根据SQLSERVER实现原理,其实,SQLSERVER的每一条执行语句都是 ...
- apache环境.htaccess设置301跳转及常用.htaccess技巧整理
apache环境.htaccess设置301跳转及常用.htaccess技巧整理 无论是Nginx,还是Apache都各自有优势,对于我们普通用户而言基本上也没有多大的区别.在虚拟主机环境中,基本上都 ...
- linux下gdb调试方法与技巧整理
参考博客: https://blog.csdn.net/niyaozuozuihao/article/details/91802994 1.运行命令run:简记为 r ,其作用是运行程序,当遇到断点 ...
- CSS对浏览器的兼容性(IE和Firefox)技巧整理
CSS对浏览器的兼容性有时让人很头疼,或许当你了解当中的技巧跟原理,就会觉得也不是难事,从网上收集了IE7,6与Fireofx的兼容性处理技巧并整理了一下.对于web2.0的过度,请尽量用xhtml格 ...
- Linux/Mac OS 个人常用Terminal技巧整理
刚开始接触linux有些不适应,走了不少弯路,一直没有系统的学过linux应用,基本都是零零散散Google出来的知识,在这里做个整理: Vi/Vim 基本操作: 刚开始接触linux时,不懂vi吃了 ...
随机推荐
- 帝国cms 列表页分页样式修改美化【2】
上一篇(帝国cms 列表页分页样式修改美化[1])中我们已经对分页说了一个大概,下面我们就自己动手弄一个分页把: 第一步:进入帝国cms后台,点击系统设置->系统参数设置->信息设置:里面 ...
- STM32随记
定时器(Timer): 分为高级,通用,基本三种. M3:8个 高级:TIM1,TM8 通用:TIM2~TIM5 基本:TIM6,TIM7 M0:8个 高级:TIM1 通用:TIM2,TIM3,TIM ...
- SQL的四种语言和数据库范式
1. SQL的四种语言 DDL(Data Definition Language)数据库定义语言 CREATE ALTER DROP TRUNCATE COMMENT RENAME DML(Data ...
- Uva_11916 Emoogle Grid
题目链接 题意: 有个N X M的棋盘, 有K种颜色, 有B个不可涂色的位置, 共有R种涂色方案. 1)每个可涂色的位置必须涂上一种颜色 2)不可涂色位置不能涂色 3)每个位置必须从K种颜色中选出一种 ...
- C#Lambda表达式学习日记
Lambda表达式只是用更简单的方式来写匿名方法,彻底简化了对.NET委托类型的使用. 现在,如果我们要使用泛型 List<> 的 FindAll() 方法,当你从一个集合去提取子集时,可 ...
- 随着visual studio 2013 发布.带来的一些变化
1.asp.net a.在2013中, asp.net走向了统一.使用不同的asp.net 框架搭(web forms ,api, mvc )建混合应用 b.身份验证 无身份验证 个人用户账户 (窗体 ...
- hdu 2955 Robberies 背包DP
Robberies Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total S ...
- Tomcat7+Redis存储Session(转)
PS:截止到2015-05-12前是不支持Tomcat8的,详情见官网:https://github.com/jcoleman/tomcat-redis-session-manager 前提:你已经部 ...
- mysql表分区、查看分区
原文地址:http://blog.csdn.net/feihong247/article/details/7885199 一. mysql分区简介 数据库分区 数据库分区是一种物理数据库设 ...
- 利用Trie树对字符串集合进行排序并计算特征值
该算法用于将一组乱序的字符串反序列化到一个Trie树中,这个过程即可视为对字符串进行了一次排序. 还可以通过调用 GetFeatureString 将该 Trie 树重新序列化. #include & ...