Catalog

1. GDB Introduction
2. GDB基本命令

1. GDB Introduction

GDB是GNU开源组织发布的一个强大的UNIX下的程序调试工具,GDB主要可帮助工程师完成下面4个方面的功能

1. 启动程序,可以按照工程师自定义的要求随心所欲的运行程序
2. 让被调试的程序在工程师指定的断点处停住,断点可以是条件表达式
3. 当程序被停住时,可以检查此时程序中所发生的事,并追索上文
4. 动态地改变程序的执行环境 

在命令行上键入gdb并按回车键就可以运行gdb了, 如果一切正常的话, gdb 将被启动并且你将在屏幕上看到类似的内容

GNU gdb (GDB) Red Hat Enterprise Linux (7.2-75.el6)
Copyright (C) 2010 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.  Type "show copying"
and "show warranty" for details.
This GDB was configured as "x86_64-redhat-linux-gnu".
For bug reporting instructions, please see:
<http://www.gnu.org/software/gdb/bugs/>.
(gdb)
//当启动gdb后,我们能在命令行上指定很多的选项: gdb -h
aliases -- Aliases of other commands
breakpoints -- Making program stop at certain points
data -- Examining data
files -- Specifying and examining files
internals -- Maintenance commands
obscure -- Obscure features
running -- Running the program
stack -- Examining the stack
status -- Status inquiries
support -- Support facilities
tracepoints -- Tracing of program execution without stopping the program
user-defined -- User-defined commands

0x1: GDB启动

//当用这种方式运行gdb,我们能直接指定想要调试的程序. 这将告诉gdb装入名为fname的可执行文件
1. gdb <program>//我们也可以用gdb去检查一个因程序异常终止而产生的core dump文件
2. gdb <corename>//与一个正在运行的程序相连,gdb会自动attach上去,并调试它,program应该在PATH环境变量中搜索得到
3. gdb programname pid

0x2: GDB启动参数

gdb [-help] [-nx] [-q] [-batch] [-cd=dir] [-f] [-b bps] [-tty=dev] [-s symfile] [-e prog] [-se prog] [-c core] [-x cmds] [-d dir] [prog[core|procID]]1. -help (-h):                列出所有选项,并附简要说明
2. -symbols=file (-s file):        读出文件(file)中的符号表
3. -write:                开通(enable)往可执行文件和核心文件写的权限
4. -exec=file (-e file):        在适当时候把File作为可执行的文件执行,来检测与core dump结合的数据
5. -se File:                从File读取符号表并把它作为可执行文件
6. -core File (-c File):        把File作为core dump来执行
7. -directory=Directory (-d Directory):    把Dicrctory加入源文件搜索的路径中
8. -cd=Directory:            运行GDB,使用Directory作为它的工作目录,取代当前工作目录

0x3: 为调试编译代码

为了使gdb正常工作,你必须使你的程序在编译时包含调试信息(DEBUG信息)。调试信息包含你程序里的每个变量的类型和在可执行文件里的地址映射以及源代码的行号。gdb利用这些信息使源代码和机器码相关联

//在编译时用"-g"选项打开调试选项
gcc –g gdb_example.c –o gdb_example
g++ –g gdb_example.c –o gdb_example

2. GDB基本命令

0x1: 测试环境准备

#include <stdio.h>
#include <string.h>
#include <malloc.h>void my_print (char *string)
{ printf ("The string is %s\n", string);
}void my_print2 (char *string)
{char *string2; int size, i; size = strlen (string); string2 = (char *) malloc (size + 1);for (i = 0; i < size; i++){string2[size - i] = string[i];} string2[size+1] = '\0';printf ("The string printed backward is %s\n", string2);
}main ()
{ char my_string[] = "hello there"; my_print (my_string); my_print2 (my_string);
}
//gcc -g test.c -o test 

结果不符合预期,我们通过GDB调试这个程序来学习GDB的调试命令

0x2: list命令

在gdb中运行"list/l"命令可以列出代码

1. 显示程序第linenum行周围的源程序
list <linenum>
l <linenum>2. 显示函数名为function的函数的源程序
list <function>
l <function> 3. 显示当前行后面的源程序
list4. 显示当前行前面的源程序
list - 

0x3: run命令

在gdb中,运行程序使用run命令,run指令会重头运行一次程序。在程序运行前,我们可以设置如下4方面的工作环境

1. 程序运行参数  1) 指定运行时参数: set args 10 20 30 40 502) 查看设置好的运行参数: show args
2. 运行环境1) 设定程序的运行路径: path <dir>2) 查看程序的运行路径: show paths3) 设置环境变量: set environment varname [=value],如set env USER=baohua;4) 查看环境变量: show environment [varname]
3. 工作目录1) cd <dir>: 相当于shell的cd命令2) pwd: 显示当前所在的目录。
4. 程序的输入输出1) info terminal: 用于显示程序用到的终端的模式2) gdb中也可以使用重定向控制程序输出,如: run > outfile 3) tty命令可以指定输入输出的终端设备,如:tty /dev/ttyS1 

在gdb提示符下按回车健将重复上一个命令

0x4: break命令

在gdb中用break命令来设置断点,设置断点的方法包括

1. 在进入指定函数时停住,C++中可以使用class::function或function(type, type)格式来指定函数名
break <function>2. 在指定行号停住
break <linenum>3. 在当前行号的前面或后面的offset行停住,offiset为自然数
break +offset
break -offset4. 在源文件filename的linenum行处停住
break filename:linenum5. 在源文件filename的function函数的入口处停住
break filename:function6. 在程序运行的内存地址处停住
break *address7. break命令没有参数时,表示在下一条指令处停住
break8. 条件IF断点
break ... if <condition>1) "..."可以是上述的break <linenum>、break +offset / break –offset中的参数2) condition表示条件
在条件成立时停住。比如在循环体中,可以设置break if i=100,表示当i为100时停住程序 9. xbreak在当前函数的退出的点上设置一个断点10. txbreak
在当前函数的退出的点上设置一个临时的断点(只可使用一次)11. 查看断点时
info
info breakpoints [n]、info break [n](n表示断点号)

0x5: 单步命令

在调试过程中

1. next/n命令: 用于单步执行,类似VC++中的step over,next单步不会进入函数的内部
2. step/s命令: 在单步执行一个函数时,会进入其内部,类似VC++中的step into

单步执行的更复杂用法包括

1. 单步跟踪
step <count>
如果有函数调用,则"进入"该函数(进入函数的前提是,此函数被编译有debug信息)。step后面不加count表示一条条地执行,加表示执行后面的count条指令,然后再停住 2. 单步跟踪next <count>
如果有函数调用,它"不会"进入该函数。同样地,next后面不加count表示一条条地执行,加表示执行后面的count条指令,然后再停住 3. set step-mode1) set step-mode on: 打开step-mode模式,这样,在进行单步跟踪时,程序不会因为没有debug信息而不停住,这个参数的设置可便于查看机器码2) set step-mod off: 关闭step-mode模式。4. finish
运行程序,直到当前函数完成返回,并打印函数返回时的堆栈地址和返回值及参数值等信息 5. until/u
一直在循环体内执行单步,退不出来是一件令人烦恼的事情,until命令可以运行程序直到退出循环体 6. stepi/si、nexti/ni
stepi和nexti用于单步跟踪一条机器指令,一条程序代码有可能由数条机器指令完成,stepi和nexti可以单步执行机器指令7. display/i $pc
单步跟踪会在打出程序代码的同时打出机器指令,即汇编代码

0x6: continue命令

当程序被停住后,可以使用continue/c命令,(fg命令同continue命令)恢复程序的运行直到程序结束,或到达下一个断点,命令格式为

continue [ignore-count]
c [ignore-count]
fg [ignore-count]
//ignore-count表示忽略其后多少次断点

0x7: print命令

在调试程序时,当程序被停住时,可以使用print/p命令,或是同义命令inspect来查看当前程序的运行数据。print命令的格式是

print <expr>
//<expr>是表达式,是被调试的程序中的表达式 

print /<f> <expr>
/*
<f>是输出的格式
1. x: 按十六进制格式显示变量
2. d: 按十进制格式显示变量
3. u: 按十六进制格式显示无符号整型
4. o: 按八进制格式显示变量
5. t: 按二进制格式显示变量
6. a: 按十六进制格式显示变量
7. c: 按字符格式显示变量
8. f: 按浮点数格式显示变量
*/expr: 表达式
在表达式中,有几种GDB所支持的操作符,它们可以用在任何一种语言中
1. "@"是一个和数组有关的操作符
2. "::"指定一个在文件或是函数中的变量
3. "{<type>} <addr>"表示一个指向内存地址<addr>的类型为type的一个对象

0x8: watch命令

watch一般来观察某个表达式(变量也是一种表达式)的值是否有变化了,如果有变化,马上停住程序。我们有下面的几种方法来设置观察点
1. watch <expr>
为表达式(变量)expr设置一个观察点。一量表达式值有变化时,马上停住程序2. rwatch <expr>
当表达式(变量)expr被读时,停住程序3. awatch <expr>
当表达式(变量)的值被读或被写时,停住程序4. info watchpoints
列出当前所设置了的所有观察点 

0x9: examine命令

我们可以使用examine/x命令,来查看内存地址中的值。examine命令的语法如下所示

x/<n/f/u> <addr>
1. <addr>: 表示一个内存地址
2. <n/f/u>: 可选的参数1) n: 一个正整数,表示显示内存的长度,也就是说从当前地址向后显示几个地址的内容2) f: 显示的格式,如果地址所指的是字符串,那么格式可以是s,如果地址是指令地址,那么格式可以是i3) u: 表示从当前地址往后请求的字节数,如果不指定的话,GDB默认是4字节。u参数可以被一些字符代替4) b: 表示单字节5) h: 表示双字节6) w: 表示四字节7) g: 表示八字节
当我们指定了字节长度后,GDB会从指定的内存地址开始,读写指定字节,并把其当作一个值取出来。n、f、u这3个参数可以一起使用,例如命令
x/3uh 0x54320: 表示从内存地址0x54320开始以双字节为1个单位(h)、16进制方式(u)显示3个单位(3)的内存 

0x10: set命令

修改寄存器
1. set $v0 = 0x004000000
2. set $epc = 0xbfc00000   修改内存
1. set {unsigned int}0x8048a51=0x0 

0x11: jump命令

一般来说,被调试程序会按照程序代码的运行顺序依次执行,但是GDB也提供了乱序执行的功能,也就是说,GDB可以修改程序的执行顺序,从而让程序随意跳跃

1. jump <linespec>: 指定下一条语句的运行点1) <linespec>可以是文件的行号2) 可以是file:line格式3) 也可以是+num这种偏移量格式,表示下一条运行语句从哪里开始2. jump <address>
这里的<address>是代码行的内存地址
//注意,jump命令不会改变当前的程序栈中的内容(它是纯粹的EIP修改跳转),所以,如果使用jump从一个函数跳转到另一个函数,当跳转到的函数运行完返回,进行出栈操作时必然会发生错误,这可能导致意想不到的结果,所以最好只用jump在同一个函数中进行跳转 

0x12: signal命令

使用singal命令,可以产生一个信号量给被调试的程序,如中断信号"Ctrl+C"。这非常方便于程序的调试,可以在程序运行的任意位置设置断点,并在该断点用GDB产生一个信号量,这种精确地在某处产生信号的方法非常有利于程序的调试

signal命令的语法是:signal <signal>
//UNIX的系统信号量通常从1到15,所以<signal>取值也在这个范围 

0x13: return命令

如果在函数中设置了调试断点,在断点后还有语句没有执行完,这时候我们可以使用return命令强制函数忽略还没有执行的语句并返回

return
return <expression>
//return命令用于取消当前函数的执行,并立即返回,如果指定了<expression>,那么该表达式的值会被作为函数的返回值

0x14: call命令

call命令用于强制调用某函数

call <expr>
表达式中可以一是函数,以此达到强制调用函数的目的,它会显示函数的返回值(如果函数返回值不是void) 

0x15: info命令

info命令可以在调试时用来查看相关信息

1. 寄存器1) info registers: 查看除了浮点寄存器以外的寄存器2) info all-registers: 查看所有寄存器,包括浮点寄存器3) info registers <regname ...>: 查看所指定的寄存器2. 断点1) info break: 查看断点信息3. 观察点1) info watchpoints: 列出当前所设置的所有观察点4. 信号1) info signals: 查看有哪些信号正在被GDB检测2) info handle: 查看有哪些信号正在被GDB检测5. info line <xx>: 查看源代码在内存中的地址
info line后面可以跟行号、函数名、文件名:行号、文件名:函数名等多种形式,例如下面的命令会打印出所指定的源码在运行时的内存地址:
//info line tst.c:func  6. info threads: 查看多线程

0x16: set scheduler-locking off|on|step

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

与多线程调试相关的命令还包括

1. thread ID
切换当前调试的线程为指定ID的线程  2. break thread_test.c:123 thread all
在所有线程中相应的行上设置断点3. thread apply ID1 ID2 command
让一个或者多个线程执行GDB命令command 4. thread apply all command
让所有被调试线程执行GDB命令command

0x17:disassemble

disassemble命令用于反汇编,它可被用来查看当前执行时的源代码的机器码,其实际上只是把目前内存中的指令dump出来

1. 反汇编一个函数
disass func_name2. 反汇编一段内存地址, 第1个参数是起始地址,第2个是终止地址
disassemble 0x0 0x10
//可以使用 info line 命令来映射一个源码行到程序地址,然后使用命令disassemble显示一个地址范围的机器指令3. disassemble 不带参数
默认的反汇编范围是 所选择帧的pc附近的函数

0x18: kill [filename]

终止正在调试的程序

0x19: clear

删除一个断点,这个命令需要指定代码行或者函数名作为参数

0x20: bt/Backtrace

显示程序堆栈信息,即显示函数调用栈的信息

0x21: enable、enable

1. disable: 禁止断点功能,这个命令需要禁止的断点在断点列表索引值作为参数
2. enable: 允许断点功能,这个命令需要允许的断点在断点列表索引值作为参数

0x22: ignore

忽略某个断点制定的次数

ignore 4 23: 忽略断点4的23次运行,在第24次的时候中断

0x23: load

动态载入一个可执行文件到调试器

0x24: whatis

显示变量的值和类型

0x25: ptype

显示变量的类型

0x26: make

使你能不退出GDB就可以重新产生可执行文件

0x27: shell

使你能不离开GDB就执行 UNIX shell 命令

Relevant Link:

http://www.chinalinuxpub.com/doc/pro/gdb.html
http://www.vimer.cn/2009/11/%E4%BD%BF%E7%94%A8gdb%E8%B0%83%E8%AF%95%E7%A8%8B%E5%BA%8F%E8%AF%A6%E8%A7%A3.html
https://www.ibm.com/developerworks/cn/linux/sdk/gdb/
http://blog.csdn.net/21cnbao/article/details/7385161
http://www.vimer.cn/2009/11/%E4%BD%BF%E7%94%A8gdb%E8%B0%83%E8%AF%95%E7%A8%8B%E5%BA%8F%E8%AF%A6%E8%A7%A3.html

Copyright (c) 2015 LittleHann All rights reserved

Linux GDB Debugging相关推荐

  1. Linux GDB常用命令一栏

    Linux GDB 常用命令如下: 1.启动和退出gdb (1)启动:gdb ***:显示一段版权说明: (*** 表示可执行程序名) (2)退出:quit.有的时候输入quit后会出现相关提示:类似 ...

  2. linux子系统gdp调试,Linux GDB调试 详述

    今天来分享下gdb的简单调试,我这里写了个例子 三个.c文件 func1.c func2.c main.c 首先生成可调试的执行文件 gcc -g func1.c func2.c main.c -o ...

  3. linux gdb 脚本,如何写gdb命令脚本

    作为UNIX/Linux下使用广泛的调试器,gdb不仅提供了丰富的命令,还引入了对脚本的支持:一种是对已存在的脚本语言支持,比如python,用户可以直接书写python脚本,由gdb调用python ...

  4. 【Linux】一步一步学Linux——gdb命令(258)

    00. 目录 文章目录 00. 目录 01. 命令概述 02. 命令格式 03. 常用选项 04. 参考示例 05. 附录 01. 命令概述 gdb命令包含在GNU的gcc开发套件中,是功能强大的程序 ...

  5. linux gdb使用

    为什么80%的码农都做不了架构师?>>>    转自http://blog.csdn.net/qzwujiaying/article/details/5880268 Linux 下 ...

  6. linux gdb模式下无反应,Linux,GDB 嵌入式Linux的GDB远程调试的问题--断点没反应

    院士 2006-12-22 22:43:00    评分 2楼 问 我用的是BF531 uClinux Linux version 2.6.16.11-ADI-2006R1-hhbf (root@se ...

  7. linux gdb#039;查找寄存器地址,【Linux跟踪和调试】gdb

    8种机械键盘轴体对比 本人程序员,要买一个写代码的键盘,请问红轴和茶轴怎么选? gdb是一个由GNU开源组织发布的.UNIX/LINUX操作系统下的.基于命令行的.功能强大的程序调试工具.对于一名Li ...

  8. Linux GDB调试

    Linux 段错误调试 core 文件调试 编译时 加上 -g 使编译出的文件带 调试信息 gcc -g main.c -o main 使编译出的可执行文件带调试信息gdb main //对 main ...

  9. Linux gdb多进程、多线程调试

    目录 常用命令 堆栈相关命令 更为详细的断点调试 gdb多进程调试 gdb多线程调试 前言 gdb 是 linux 平台下进行程序调试的最常用的工具.简单的程序调试就是加断点,然后一步一步让程序运行, ...

最新文章

  1. python 南京大学_南京大学python课程系列笔记之python基础之第一周:走进python
  2. Openstack_单元测试工具 tox
  3. Uncaught ReferenceError: webpackJsonp is not defined at app.js vendor.js
  4. Zabbix的架构配置选项
  5. Python第四章__装饰器、迭代器
  6. 【Python CheckiO 题解】Index Power
  7. linux进程管理子系统分析,linux进程管理子系统简要分析
  8. 解决zookeeper启动失败Could not find or load main class org.apache.zookeeper.server.quorum.QuorumPeerMain报错
  9. 超分辨率分析(四)--Deep Image Prior
  10. 130242014029-黄超强-实验一
  11. python字符串注意点
  12. 凯撒/摩斯/栅栏/维吉尼亚/元音密码加解密的Python实现
  13. 三维数字沙盘电子沙盘MR AR VR虚拟现实无人机倾斜摄影三维全景建模卫星图片矢量
  14. 默然日记20150207
  15. 【图解CAN总线】-7-Classic CAN 2.0总线网络“负载率”计算(方法二)
  16. java多线程:线程间的通信-生产者和消费者(三)
  17. TI达芬奇系列TMS320DM8148浮点DSP C674x + ARM Cortex-A8高性能视频处理器;
  18. vue调倍速后声音变了_pr加速人声后声音变调失真怎么办?
  19. 德国交通标志检测识别数据集
  20. 实现多态的三个必要条件

热门文章

  1. Android Studio出现R.raw文件标红找不到错误(有多个模块的Project)
  2. Window.location.href命令在JS中跳转无效或自动忽略
  3. java如何对foo bar调用方法_关于java:如何测试工厂方法传递给构造函数的参数?...
  4. I²C那点事儿(一)
  5. 20201008:力扣209周周赛题解(下)
  6. 借助计算机软件进行文学写作,网络文学创作对编辑提出的新要求及建议
  7. disruptor小结--生产者代码
  8. Google人工智能面试·真·题(附参考答案+攻略)
  9. 北京成立前沿国际人工智能研究院,李开复出任首任院长
  10. 区别德语的公母阴阳性别的秘诀