环境: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. [BZOJ4337][BJOI2015]树的同构(树的最小表示法)

    4337: BJOI2015 树的同构 Time Limit: 10 Sec  Memory Limit: 256 MBSubmit: 1023  Solved: 436[Submit][Status ...

  2. [CF407E]k-d-sequence

    题意:给定$a_{1\cdots n}$,让你求出一个最长的子串$a_{l\cdots r}$,使得这个子串加上最多$k$个数字并排序后是一个公差为$d$的等差数列 首先$d=0$就是最长连续相等段, ...

  3. identifier is too long 异常处理

    修改了oracle中的表. 报 identifier is too long 错误 我执行的脚本是: ---备份create table MDT_AGREEMENTMANAGEMENT_2018080 ...

  4. 关于BOM UTF8

    这三篇可以看下: http://www.zhihu.com/question/20167122 http://www.cnblogs.com/DDark/archive/2011/11/28/2266 ...

  5. golangWEB框架gin学习之获取post参数

    原文地址:http://www.niu12.com/article/41 package main import ( "fmt" "github.com/gin-goni ...

  6. telnet命令

    详细资料 telnet命令使用方法详解-telnet命令怎么用-win7没有telent怎么办 2017年07月26日 15:37:36 阅读数:1010 什么是Telnet? 对于Telnet的认识 ...

  7. linux基础-第十八单元_nginx部署

    一.基本环境配置 1.1.安装常用软件 yum install wget -y 1.2.Install yum repo mv /etc/yum.repos.d/CentOS-Base.repo /e ...

  8. 在 Word 中的受支持的区域设置标识符的列表

    这篇文章包含当前可用的区域设置 ID (LCID) 语言代码的列表.   概要 这篇文章包含当前可用的区域设置 ID (LCID) 语言代码的列表. 区域设置 ID (LCID): 由 Microso ...

  9. J2EE之EJB

     EJB是sun的JavaEEserver端组件模型,最大的用处是部署分布式应用程序.EJB把使用java开发的server组件的部署和开发进行标准化. 凭借java跨平台的优势.用EJB技术部署的分 ...

  10. vue - 总结build.js

    1. 导入外部包,用关键字 const :ES2015->不可变量 内部使用变量,let -> 块级声明 2.无分号结尾(我猜大概是用了es6变量,避免了es5应缺少分号出现的一些问题) ...