GDB常用指令

官方资料

陈皓大神笔记:1234567扩展

本笔记基于陈皓大神的笔记

启动GDB

调试程序

gdb <program>

调试core

gdb <program> core

调试运行中的进程

gdb <program> <PID>

gdb attach <PID>

启动时常用参数

  • -s/-symbols <file> :指定符号表
  • -se file:指定文件中读取符号表信息
  • -directory\-d <directory>:加入一个源文件的搜索路径,默认搜索路径是环境变量中PATH所定义的路径。
  • -core/-c <file>:调试core dump的core文件

启动时常用指令

程序运行参数
set args #可指定运行时参数。(如:set args 10 20 30 40 50)
show args #命令可以查看设置好的运行参数。
设置运行环境
path <dir> #可设定程序的运行路径。
show paths #查看程序的运行路径。
set environment varname [=value] #设置环境变量。如:set env USER=hchen
show environment [varname] #查看环境变量。
设置工作目录
cd <dir> #相当于shell的cd命令。
pwd #显示当前的所在目录。
程序的输入输出
info terminal #显示你程序用到的终端的模式。
run > outfile #使用重定向控制程序输出

运行shell命令

shell <command string>

可以在gdb中直接make,rebuild 程序

make <make-args> = shell make <make-args>

暂停/恢复

设置断点

  • 函数

    break <function>/<filename:function>

    c++中可以使用class::function或function(type,type)格式来指定函数名。

  • 行号

    break <linenum>/<filename:linenum>

  • 内存:

    break *address

    在程序运行的内存地址处停住

  • 条件

    break ... if <condition>

    …可以是上述的参数,condition表示条件

  • 打印断点

    info breakpoints/break [n]

设置观察点

观察某个表达式(变量也是一种表达式)的值是否有变化了

  • expr值有变化时,马上停住程序

    watch <expr>

  • expr被读时,停住程序

    rwatch <expr>

  • expr被读或被写时,停住程序

    awatch <expr>

  • 打印观察点

    info watchpoints

设置捕获事件

捕捉程序运行时的一些事件

  • 格式

    • catch <event>
    • tcatch <event>:设置捕捉点,当停住后自动删除。
  • 事件

    • throw :C++抛出的异常
    • catch:C++捕捉到的异常
    • exec/fork/vfork:exec/fork/vfork被调用
    • load/unload:载入/卸载动态库

维护停止点与停止条件

  • clear:清除所有的停止点
  • clear <function>/<filename:function>: 清除该函数上所有的停止点
  • clear <linenum>/<filename:linenum>:清除该行上所有的停止点
  • delete/disable/enable [breakpoints] [range...]:删除/禁用/使能指定断点
  • condition <bnum> <expression>:修改断点停止条件,bnum–断点号
  • condition <bnum>:删除断点停止条件
  • ignore <bnum> <count>:忽略断点的停止条件count次

恢复运行与单步调试

  • 继续:continue/fg [ignore-count]

    ignore-count:跳过断点次数

  • 逐语句:step <count>

  • 逐过程:next <count>

  • step-mode模式:set step-mode on/off

    单步跟踪时,程序不会因为没有debug信息而不停住

  • 离开当前函数:finish

  • 离开当前循环体:until/u

  • 单步一条机器指令:stepi/si/nexti/ni

  • 运行:run/r

信号

  • 指令

    handle <signal> <keywords...>

  • keywords

    • nostop:不停止运行,但会打印信息
    • stop:停止运行。
    • print:打印信息
    • noprint:不打印信息
    • pass/noignore:信号下发给程序
    • nopass/ignore:信号不下发给程序
  • 查看有哪些信号在被GDB检测

    info signals/handle

多线程调试

当你的程序被GDB停住时,所有的运行线程都会被停住

  • 查看线程

    info threads

  • 切换线程

    thread <ID>

  • 特定线程打断点

    break <linespec> thread <threadno> [if ...]

  • 控制其他线程

    set scheduler-locking off|on|step

    • off:不锁定任何线程,也就是所有线程都执行,这是默认值。
    • on:只有当前被调试程序会执行。
    • step:在单步的时候,除了next过一个函数的情况以外,只有当前线程会执行。

查看信息

查看栈信息

  • 栈的所有信息
    • bt:调用栈的所有信息
    • bt <n> :打印栈顶上n层的栈信息
    • bt <-n>:打印栈底下n层的栈信息
  • 切换当前栈
    • 默认当前层:栈顶层
    • f <n>:切换至第n层
    • up/down <n>:向上/下面移动n层,可以不打n,表示向上/下移动一层
  • 信息打印
    • info f:当前栈层的详情
    • info args:入参及其值
    • info locals:所有局部变量及其值。

查看源程序

显示源代码
  • list <linenum>/<function>/<first>, <last>/ , <last>/<+|-offset>:显示周围代码/函数代码/行区域代码/向前|后便宜
  • set listsize <count>:设置一次显示源代码的行数
搜索源代码
  • 向前搜索:forward-search/search <regexp>,regexp为正则表达式
  • 全部搜索:reverse-search <regexp>
源文件路径
  • 设置路径

    directory <dirname ... >

    dir <dirname ... >

  • 清除路径

    directory

  • 显示路径

    show directories

源代码的内存
  • 查看源码在内存中的地址

    info line <function>/<filename:function>/<linenum>/<filename:linenum>

  • 查看函数的汇编代码

    disassemble <function>/<filename:function>

查看变量

指令格式
  • 命令

    print <expr>

    print /<f> <expr>:f 输出格式

  • 操作符

    • @:是一个和数组有关的操作符
    • :::指定一个在文件或是一个函数中的变量。
    • {<type>} <addr>:表示一个指向内存地址<addr>的类型为type的一个对象。
数组

p *array@len

输出格式
  • x:按十六进制格式显示变量
  • d:按十进制格式显示变量
  • u:按十六进制格式显示无符号整型
  • o:按八进制格式显示变量
  • t:按二进制格式显示变量
  • a:按十六进制格式显示变量
  • c:按字符格式显示变量
  • f:按浮点数格式显示变量
查看内存
  • 指令

    examine 简写 x

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

    例子:x/3uh 0x54320

  • 参数

    • n:表示显示内存的长度,也就是说从当前地址向后显示几个地址的内容
    • f:表示显示的格式,参上
    • u:表示数据宽度,默认是4B。u参数可以用下面的字符来代替
      • b表示单字节
      • h表示双字节
      • w表示四字节
      • g表示八字节
自动显示

设置自动显示的变量,当程序停住时,或单步时,这些变量会自动显示

  • display <expr>/display/<fmt> <expr>/ display/<fmt> <addr>
  • undisplay/delete <dnums...>:删除自动显示
  • disable/enable display <dnums...>:禁用/使能自动显示
  • info display:展示自动显示表
打印的历史记录

每一个print都会被GDB记录下来。GDB会以$1, $2, $3 …这样的方式为你每一个print命令编上号。于是,你可以使用这个编号访问以前的表达式,如$1

定义环境变量

和shell一样使用$

  • 定义:set $i = 0
  • 显示:show convenience
  • 使用:$i
显示选项

​ 略,个人觉得默认的挺好用的

查看寄存器

​ 略,目前从事服务器开发,不大可能接触。

改变程序的执行

修改变量值

print x=4

跳转执行

  • jump <linespec>

    <linespce>:文件的行号,可以是file:line格式,可以是+num这种偏移量格式

  • jump <address>

    <address>:代码行的内存地址

  • 注意事项:jump不会改变当前的程序栈中的内容,所以,当你从一个函数跳到另一个函数时,当函数运行完返回时进行弹栈时必然会发生错误,所以最好是同一个函数中进行跳转。

产生信号量

  • signal <singal>

  • <singal>:UNIX的系统信号量通常从1到15。所以<singal>取值也在这个范围

  • single命令和shell的kill命令不同,系统的kill命令发信号给被调试程序时,是由GDB截获的,而single命令所发出一信号则是直接发给被调试程序的

强制函数返回

return

return <expression>

强制调用函数

call <expr>

设置生成dump

Windows

  • SetUnhandledExceptionFilter() :崩溃时触发的回调函数
  • 使用dbghelp.lib的MiniDumpWriteDump(),生成dump文件
  • 使用在VS工程中,打开dmp文件(仅限于本机生成的)
#include "stdafx.h"  
#include <windows.h>  
#include <DbgHelp.h>  
#pragma comment(lib, "dbghelp.lib")  

static char* g_szFilePath;
//我们的回调函数  
LONG __stdcall ExceptCallBack( EXCEPTION_POINTERS *pExcPointer)  
{  
	MessageBox(NULL,"程序崩溃!",NULL,MB_OK);  
  
	//创建dump文件  
	HANDLE hFile = CreateFile(g_szFilePath, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS,FILE_ATTRIBUTE_NORMAL ,NULL);  
	  
	//向文件写下当前程序崩溃相关信息  
	MINIDUMP_EXCEPTION_INFORMATION loExceptionInfo;  
	loExceptionInfo.ExceptionPointers = pExcPointer;  
	loExceptionInfo.ThreadId = GetCurrentThreadId();  
	loExceptionInfo.ClientPointers = TRUE;  
	MiniDumpWriteDump(GetCurrentProcess(), GetCurrentProcessId(),hFile, MiniDumpNormal, &loExceptionInfo, NULL, NULL);  
	CloseHandle(hFile);  
  
	return EXCEPTION_EXECUTE_HANDLER;  
}  

void Dump_Init(char* szFilePath){
    g_szFilePath = szFilePath;
	SetUnhandledExceptionFilter(ExceptCallBack); 
} 
/* 
int _tmain(int argc, _TCHAR* argv[])  
{  
	//设置崩溃回调函数  
	Dump_Init("C:/Users/liliangwei/Desktop/dump.dmp");
    int * p = NULL;  
	*p = 1;  
	return 0;  
} */

Linux

如果无目录名,则core生成在运行目录

查看

cat /proc/sys/kernel/core_pattern

暂时
  • 打开core:ulimit -c unlimited

  • 设置目录与文件名:echo '%e.core.%p' > /proc/sys/kernel/core_pattern

永久
  • /etc/profile中最后添加ulimit -c unlimited
  • /sbin/sysctl -w kernel.core_pattern=%e.core.%p

GDB 指令缩写

缩写原义意义
bbreak打断点
ccontinue继续
ddelete删除断点
fframe栈层跳转
iinfo查看信息
jjump程序跳转
llist展示源码
nnext单步-过程
pprint打印与设置变量
rrun运行
sstep单步-语句
uuntil离开循环体
ninexti机器级单步
sistepi机器级单步
btbacktrace所有栈信息
wawatch设置观察点
igignore忽略断点
finfinish离开函数
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值