美文网首页
使用 GDB 进行调试

使用 GDB 进行调试

作者: wjundong | 来源:发表于2021-07-17 19:07 被阅读0次

实例

  • demo.s
.section .data

output:
    .ascii "The processor Vender ID is 'xxxxxxxxxxxx'\n"

.section .text
.globl _start

_start:
    nop
    // 获取 CPU ID
    movl $0, %eax
    cpuid
    
    // 将 CPU ID 填充到 output 的占位符部分
    movl $output, %edi
    movl %ebx, 28(%edi)
    movl %edx, 32(%edi)
    movl %ecx, 36(%edi)

    // 系统调用, 显示 CPUID
    movl $4, %eax
    movl $1, %ebx
    movl $output, %ecx
    movl $42, %edx
    int $0x80
    movl $1, %eax
    movl $0, %ebx
    int $0x80

    // 系统调用, 返回程序执行结果
    movl $1, %eax
    movl $0, %ebx
    int $0x80
    ret

编译链接

  1. 汇编器编译
    as demo.s -32 -gstabs 
    ld ./a.out demo -m elf_i386 
    
  2. gcc 编译
    gcc demo.s -o demo -m32 -g
    

使用 gdb 调试需要在as编译时加入参数 -gstabs 或者 gcc 加入 -g.

调试

gdb ./demo

在 gdb 中执行 run 命令运行程序:

(gdb) run
Starting program: /home/shino/code/ass/a.out 
The processor Vender ID is 'GenuineIntel'
[Inferior 1 (process 3031) exited normally]
(gdb)

可以看到程序正常执行并返回, gdb 调试常用命令如下

  • 设置断点: break
    格式为 break * label+offset, 比如在程序最开始设置断点:
    (gdb) break * _start
    Breakpoint 1 at 0x8049000: file demo.s, line 18.
    (gdb) break * _start + 5
    Breakpoint 2 at 0x8049005: file demo.s, line 19.
    (gdb) run
    Starting program: /home/shino/code/ass/demo 
    
    Breakpoint 1, _start () at demo.s:18
    18          movl $0, %eax
    (gdb)
    

    上述设置了两个断点, 一个是在起始地址 _start, 另一个是相对 _start 地址偏移了5个字节的地址, 这个地址刚好是 cpuid 代码地址, 然后运行程序, 这时程序停在了断点 1 处.

  • 继续执行: cont
    (gdb) cont
    Continuing.
    
    Breakpoint 2, _start () at demo.s:19
    19          cpuid
    (gdb)
    

    使用 cont 指令让代码继续运行, 代码往下执行遇到第二个断点停了下来.

  • 单步运行: next 或 step
    (gdb) next
    22          movl $output, %edi
    (gdb) 
    

    使用 next 单步运行, 程序执当前行汇编指令, 并停在下一行.

  • 显示所有寄存器的值: info registers
    (gdb) s
    23          movl %ebx, 28(%edi)
    (gdb) info registers 
    eax            0x1b                27
    ecx            0x6c65746e          1818588270
    edx            0x49656e69          1231384169
    ebx            0x756e6547          1970169159
    esp            0xffffcef0          0xffffcef0
    ebp            0x0                 0x0
    esi            0x0                 0
    edi            0x0                 0
    eip            0x8049007           0x8049007 <_start+7>
    eflags         0x202               [ IF ]
    cs             0x23                35
    ss             0x2b                43
    ds             0x2b                43
    es             0x2b                43
    fs             0x0                 0
    gs             0x0                 0
    k0             0x0                 0
    k1             0x0                 0
    k2             0x0                 0
    k3             0x0                 0
    k4             0x0                 0
    k5             0x0                 0
    k6             0x0                 0
    k7             0x0                 0
    (gdb) 
    

    s 命令可用于报告当前位置

  • 显示特定寄存器或者来自程序的变量的值: print
    • print/d 以十进制显示
    • print/t 以二进制显示
    • print/x 以十六进制显示
    (gdb) print/x $ebx
    $1 = 0x756e6547
    (gdb)
    

    显示了 EBX 寄存器的值

  • 显示特定内存位置的内容: x
    x 命令的格式是 x/nyz, 和 print 类型, x 可以使用 / 后面的修饰符改变输出结果, 各个修饰符的含义如下
    • n : 直接用数字表示要显示的字段数.
    • y : 设置输出格式
      • c 输出字符
      • d 输出十进制
      • x 输出十六进制
    • z 设置每个字段的长度
      • b 用于字节
      • h 用于 16 位字
      • w 用于 32 位字
    (gdb) x/42cb &output
    0x804a000:      84 'T'  104 'h' 101 'e' 32 ' '  112 'p' 114 'r' 111 'o' 99 'c'
    0x804a008:      101 'e' 115 's' 115 's' 111 'o' 114 'r' 32 ' '  86 'V'  101 'e'
    0x804a010:      110 'n' 100 'd' 101 'e' 114 'r' 32 ' '  73 'I'  68 'D'  32 ' '
    0x804a018:      105 'i' 115 's' 32 ' '  39 '\'' 120 'x' 120 'x' 120 'x' 120 'x'
    0x804a020:      120 'x' 120 'x' 120 'x' 120 'x' 120 'x' 120 'x' 120 'x' 120 'x'
    0x804a028:      39 '\'' 10 '\n'
    (gdb) 
    

    我们用字符形式显示了 output 标签所在的内存地址前42个字节的内容, & 符号用于表明他是一个内存地址.

相关文章

  • 使用gdb进行调试

    gcc -g main.c -o main.out 使用-g进行编译后 可以使用gdb进行调试gdb ./ma...

  • 使用 GDB 进行调试

    实例 demo.s 编译链接 汇编器编译as demo.s -32 -gstabs ld ./a.out demo...

  • gcc常用命令

    gdb相关 gcc加-g才能使用gdb调试gdb -tui a.out打开调试界面run/stop/continu...

  • gdb

    gdb调试工具使用

  • Xcode debug Hotspot(一)——创建Xcode项

    概述 前面安装gdb调试hotspot里面,我记录了自己安装gdb调试hotspot的过程。后来我发现,使用gdb...

  • GDB使用指南

    gdb是linux下的一款动态调试工具,以下是使用gdb调试程序常用到的命令,我尽量以图文的方式进行讲解,希望对初...

  • android ndk 调试项目

    调试项目 在构建应用后,您可能需要对其进行调试。本节介绍 NDK 的调试工具。 首先介绍如何使用 ndk-gdb ...

  • 使用 GDB 调试 Android 应用

    GNU 工程调试器(GDB)是一个常用的 Unix 调试器。本文详述使用 gdb 调试 Android 应用和进程...

  • GDB 配置

    摘要:调试器 GDB 的配置 GDB 配置 使用 GDB 扩展来配置 GDB 事实上我还是觉得原生的 GDB 就...

  • Mac使用vscode调试c/c++

    mac上在vsCode上进行c/c++程序的调试 目的在mac上使用vscode 和 lldg/gdb调试工具 对...

网友评论

      本文标题:使用 GDB 进行调试

      本文链接:https://www.haomeiwen.com/subject/uggwpltx.html