环境:gcc (OpenWrt/Linaro GCC 4.8)

以如下的简单代码为例,说明gdb的使用。

 void func1(int a, int b)
{
int c;
c = a + b;
} int main(void)
{ func1(,);
return ;
}

1. gdb 下一步的命令

a.执行下一行语句(语句级别)
  next(或n) 执行下一行语句,如果是函数调用则直接将函数执行完;相当于visual studio调试器中的"Step Over (单步跟踪)"
  step(或s) 执行下一行语句,如果是函数调用则进入函数中。即常说的单步调试,相当于visual studio调试器中的"Step Into (单步跟踪进入)"
  这两个命令必须在有源代码调试信息的情况下才可以使用(GCC编译时使用“-g”参数)
b.执行下一条指令(指令级)
  si 类似于s;
  ni 类似于n;
  这两个命令(si/ni)所针对的是汇编指令

2. disassemble

可以反汇编当前函数或者指定的函数,
单独用disassemble命令是反汇编当前函数,
如果disassemble命令后面跟函数名或地址,则反汇编指定的函数.

(gdb) disassemble
Dump of assembler code for function main:
0x00008440 <+>: push {r11, lr}
0x00008444 <+>: add r11, sp, #
=> 0x00008448 <+>: mov r0, #
0x0000844c <+>: mov r1, #
0x00008450 <+>: bl 0x8410 <func1>
0x00008454 <+>: mov r3, # ; 0x64
0x00008458 <+>: mov r0, r3
0x0000845c <+>: pop {r11, pc}
End of assembler dump. (gdb) disassemble
Dump of assembler code for function func1:
0x00008410 <+>: push {r11} ; (str r11, [sp, #-]!)
0x00008414 <+>: add r11, sp, #
0x00008418 <+>: sub sp, sp, #
0x0000841c <+>: str r0, [r11, #-]
0x00008420 <+>: str r1, [r11, #-]
=> 0x00008424 <+>: ldr r2, [r11, #-]
0x00008428 <+>: ldr r3, [r11, #-]
0x0000842c <+>: add r3, r2, r3
0x00008430 <+>: str r3, [r11, #-]
0x00008434 <+>: sub sp, r11, #
0x00008438 <+>: pop {r11} ; (ldr r11, [sp], #)
0x0000843c <+>: bx lr
End of assembler dump.

3. 显示寄存器的信息

info registers可以显示所有寄存器的当前值(不包括浮点寄存器)

info all-registers(包括浮点寄存器)
简写: i r

 (gdb) info registers
r0 0xb
r1 0x16
r2 0xbefffe2c
r3 0x8440
r4 0xbeffff14
r5 0x8304
r6 0xbefffc80
r7 0x8
r8 0x0
r9 0x0
r10 0xb6ffef7c
r11 0xbefffc64
r12 0xbefffd68
sp 0xbefffc50 0xbefffc50
lr 0x8454
pc 0x8424 0x8424 <func1+>
cpsr 0x60000010
(gdb) i r
r0 0xb
r1 0x16
r2 0xbefffe2c
r3 0x8440
r4 0xbeffff14
r5 0x8304
r6 0xbefffc80
r7 0x8
r8 0x0
r9 0x0
r10 0xb6ffef7c
r11 0xbefffc64
r12 0xbefffd68
sp 0xbefffc50 0xbefffc50
lr 0x8454
pc 0x8424 0x8424 <func1+>
cpsr 0x60000010

4.查看内存的值:

gdb中使用"x"命令来打印内存的值,格式为"x/nfu addr"。含义为以f格式打印从addr开始的n个长度单元为u的内存值。参数具体含义如下:

a)n:输出单元的个数。
b)f:是输出格式。比如x是以16进制形式输出,o是以8进制形式输出,等等。
  x(hex) 按十六进制格式显示变量。
  d(decimal) 按十进制格式显示变量。
  u(unsigned decimal) 按十进制格式显示无符号整型。
  o(octal) 按八进制格式显示变量。
  t(binary) 按二进制格式显示变量。
  a(address) 按十六进制格式显示变量。
  c(char) 按字符格式显示变量。
  f(float) 按浮点数格式显示变量
c)u:标明一个单元的长度。b是一个byte,h是两个byte(halfword),w是四个byte(word),g是八个byte(giant word)

 举例:
以16进制格式打印从add开始的16个byte的值:
(gdb) x/16xb $r11
0xbefffc64: 0x6c 0xfc 0xff 0xbe 0x00 0x00 0x00 0x00
0xbefffc6c: 0xc4 0xcc 0xfc 0xb6 0x00 0x90 0xfd 0xb6

5.打印栈帧信息:

frame 打印当前栈帧的简要信息。

 (gdb) frame
# func1 (a=, b=) at hello.c:
in hello.c

6.info frame 打印当前栈帧的详细信息。

 (gdb) info frame
Stack level , frame at 0xbefffc68:
pc = 0x8434 in func1 (hello.c:); saved pc 0x8454
called by frame at 0xbefffc70
source language c.
Arglist at 0xbefffc64, args: a=, b=
Locals at 0xbefffc64, Previous frame's sp is 0xbefffc68
Saved registers:
r11 at 0xbefffc64

7.info frame args 打印指定栈帧的详细信息

 (gdb) i f
Stack frame at 0xbefffc70:
pc = 0x8454 in main (hello.c:); saved pc 0xb6fcccc4
caller of frame at 0xbefffc68
source language c.
Arglist at 0xbefffc6c, args:
Locals at 0xbefffc6c, Previous frame's sp is 0xbefffc70
Saved registers:
r11 at 0xbefffc68, lr at 0xbefffc6c

8.info args 打印函数参数信息

 (gdb) info args
a =
b =

9.info locals 打印当前可访问的局部变量的信息。

 (gdb) info locals
c =

10.怎样知道一个栈帧的大小?

fp和sp之间的区域就是一个函数的栈帧的大小。
fp一般是指r11寄存器。
sp一般是指r13寄存器。

 (gdb) i r
r0 0xb
r1 0x16
r2 0xb
r3 0x8440
r4 0xbeffff14
r5 0x8304
r6 0xbefffc80
r7 0x8
r8 0x0
r9 0x0
r10 0xb6ffef7c
r11 0xbefffc64
r12 0xbefffd68
sp 0xbefffc50 0xbefffc50
lr 0x8454
pc 0x8428 0x8428 <func1+>
cpsr 0x60000010 (gdb) disassemble
Dump of assembler code for function func1:
0x00008410 <+>: push {r11} ; (str r11, [sp, #-]!)
=> 0x00008414 <+>: add r11, sp, # ;将sp中的内存地址放入r11,即设置fp
0x00008418 <+>: sub sp, sp, # ;将sp中的内存地址减小20,即设置func1的栈顶指针,如上两条指令执行完后,该函数的栈帧的大小就确定了, bytes
0x0000841c <+>: str r0, [r11, #-] ;函数参数赋值,将r0中的值存入[r11, #-]内存地址,即函数实参入栈
0x00008420 <+>: str r1, [r11, #-] ;函数参数赋值,将r1中的值存入[r11, #-]内存地址
0x00008424 <+>: ldr r2, [r11, #-]
0x00008428 <+>: ldr r3, [r11, #-]
0x0000842c <+>: add r3, r2, r3
0x00008430 <+>: str r3, [r11, #-]
0x00008434 <+>: sub sp, r11, #
0x00008438 <+>: pop {r11} ; (ldr r11, [sp], #)
0x0000843c <+>: bx lr
End of assembler dump.

有时在调试过程中,想记录下来操作的过程及相关信息,那么 执行set logging on即可打卡记录,默认存在gdb.txt。

当然也可以自己指定log文件,set logging file logname

set logging overwrite on命令可以让输出覆盖之前的日志文件;而 “set logging redirect on”命令会让gdb的日志不会打印在终端

gdb 详解的更多相关文章

  1. GDB详解

    1 简介 2 生成调试信息 3 启动GDB 的方法 4 程序运行上下文 4.1 程序运行参数 4.2 工作目录 4.3 程序的输入输出 5 设置断点 5.1 简单断点 5.2 多文件设置断点 5.3 ...

  2. 调试工具GDB详解

    1 简介 2 生成调试信息 3 启动GDB 的方法 4 程序运行上下文 4.1 程序运行参数 4.2 工作目录 4.3 程序的输入输出 5 设置断点 5.1 简单断点 5.2 多文件设置断点 5.3 ...

  3. GDB scheduler-locking 命令详解

    GDB scheduler-locking 命令详解 GDB> show scheduler-locking     //显示线程的scheduler-locking状态GDB> set ...

  4. 【转】段错误调试神器 - Core Dump详解

    from:http://www.embeddedlinux.org.cn/html/jishuzixun/201307/08-2594.html 段错误调试神器 - Core Dump详解 来源:互联 ...

  5. Linux /dev目录详解和Linux系统各个目录的作用

    Linux /dev目录详解(转http://blog.csdn.net/maopig/article/details/7195048) 在linux下,/dev目录是很重要的,各种设备都在下面.下面 ...

  6. linux 中/proc 详解

    proc 文件系统 在Linux中有额外的机制可以为内核和内核模块将信息发送给进程-- /proc 文件系统.最初设计的目的是允许更方便的对进程信息进行访问(因此得名),现在它被每一个有有趣的东西报告 ...

  7. Linux 之 编译器 gcc/g++参数详解

    2016年12月9日16:48:53 ----------------------------- 内容目录: [介绍] gcc and g++分别是gnu的c & c++编译器 gcc/g++ ...

  8. Linux中/proc目录下文件详解

    转载于:http://blog.chinaunix.net/uid-10449864-id-2956854.html Linux中/proc目录下文件详解(一)/proc文件系统下的多种文件提供的系统 ...

  9. netstat命令详解

    它主要的用法和详解! (netstat -na 命令),本文主要是说Linux下的netstat工具,然后详细说明一下各种网络连接状态. netstat -nat |awk ‘{print $}’|s ...

随机推荐

  1. python3开发进阶-Django框架的详解

    一.MVC框架和MTV框架 MVC,全名是Model View Controller,是软件工程中的一种软件架构模式,把软件系统分为三个基本部分: 模型(Model).视图(View)和控制器(Con ...

  2. jQuery判断一个元素是否为另一个元素的子元素

    判断:当前元素是否是被筛选元素的子元素 jQuery.fn.isChildOf = function(b){ return (this.parents(b).length > 0); }; 判断 ...

  3. 显示/隐藏Mac系统中所有的隐藏文件

    显示: 在终端输入:defaults write com.apple.finder AppleShowAllFiles YES 隐藏: 在终端输入:defaults write com.apple.f ...

  4. 让你的saga更具有可伸缩性(Scaling NServiceBus Sagas)

    https://lostechies.com/jimmybogard/2013/03/26/scaling-nservicebus-sagas/ 当我们使用NServiceBus sagas (pro ...

  5. Nagle算法&&延时确认

    数据流分类 成块数据 交互数据   Rlogin需要远程系统(服务器)回显我们(客户)键入的字符 数据字节和数据字节的回显都需要对方确认 rlogin 每次只发送一个字节到服务器,而Telnet 可以 ...

  6. 【tomcat】FileNotFoundException: C:\Program Files\Java\apache-tomcat-8.5.11-geneshop3\webapps\ROOT\index.html (拒绝访问。)

    新装系统后,tomcat启动起来 提示如下错误: Caused by: java.io.FileNotFoundException: C:\Program Files\Java\apache-tomc ...

  7. ios滚动UIScrollView的setContentOffset方法

    在UIScrollView,setContentOffset方法的功能是跳转到你指定内容的坐标,[self.scroview setContentOffset:CGPointMake(0, 50) a ...

  8. [Android 新特性] 有史来最大改变 Android 5.0十大新特性

    距离Android系统上一次重大更新不到一年的时间,谷歌再一次从KitKat升级到了Lollipop,而两次都使用糖果来命名,营销的目的显露无 遗.当我们首次看到Android 5.0 Lollipo ...

  9. wine 魔兽争霸

    连接参见http://linux-wiki.cn/wiki/%E7%94%A8Wine%E8%BF%90%E8%A1%8C%E9%AD%94%E5%85%BD%E4%BA%89%E9%9C%B8III ...

  10. Tornado框架的初步使用

    Tornado的搭建很简单,使用pip,或者下载源码均可.   我们先看一个最简单的程序: import tornado.ioloop import tornado.web class MainHan ...