当前位置:首页>Linux>ARM Linux Core Dump高阶调试:gdb查看ARM寄存器与反汇编指令

ARM Linux Core Dump高阶调试:gdb查看ARM寄存器与反汇编指令

  • 2026-10-11 08:23:39
ARM Linux Core Dump高阶调试:gdb查看ARM寄存器与反汇编指令

大家好,我是一个爱分享的牛马程序员,工作中碰到,加上自己理解,很高兴给大家分享。

在ARM Linux系统中,Core Dump文件包含程序崩溃时的寄存器状态和内存镜像。掌握gdb的ARM特定调试命令,能快速定位因寄存器异常、指令执行错误导致的崩溃。本文聚焦info registers与disassemble命令的ARM优化用法,结合实际案例解析ARM架构下的调试技巧。

一、核心考点拆解ARM架构与x86的寄存器布局、指令集存在显著差异,调试需关注:

•寄存器命名:ARM寄存器包括r0-r15(通用寄存器)、CPSR(程序状态寄存器)等;
•调用约定:前4个参数通过r0-r3传递,返回值在r0;
•指令反汇编:区分ARM指令(32位)与Thumb指令(16位),关注PC(r15)、LR(r14)的异常值。

二、关键调试命令与实例

1.查看ARM寄存器状态使用info registers查看崩溃时的寄存器值,重点关注:

实例:

(gdb) info registers

r0             0x0      0

r1             0x7f3c20000a00  140727668400640

r2             0x400    1024

r3             0x0      0

r4             0x55f8d7a32b00  93958556621312

r5             0x0      0

r6             0x0      0

r7             0x0      0

r8             0x0      0

r9             0x0      0

r10            0x0      0

r11            0x0      0

r12            0x0      0

sp             0x7ffd8a6b3200  140727668400640

lr             0x55f8d7a32b00  93958556621312

pc             0x55f8d7a32b00  0x55f8d7a32b00 <write_buffer+128>

cpsr           0x20000010  536870928

分析:r1为目标地址,r2为写入长度,pc指向崩溃指令,CPSR标志位显示无异常。

◦r0-r3:函数参数或返回值;
◦r13(SP):栈指针;
◦r14(LR):函数返回地址;
◦r15(PC):当前执行指令地址;
◦CPSR:条件标志位,判断分支是否正确跳转。
2.反汇编ARM/Thumb指令使用disassemble命令反汇编崩溃点附近的指令,区分ARM/Thumb模式:

(gdb) disassemble $pc-20, $pc+20

Dump of assembler code from 0x55f8d7a32ae0 to 0x55f8d7a32b20:

0x55f8d7a32ae0 <write_buffer+104>:  ldr     r3, [r0, r2]

0x55f8d7a32ae4 <write_buffer+108>:  str     r3, [r1, r2]

0x55f8d7a32ae8 <write_buffer+112>:  add     r2, r2, #0x4

0x55f8d7a32aec <write_buffer+116>:  cmp     r2, r3

0x55f8d7a32af0 <write_buffer+120>:  bne     0x55f8d7a32ae0 <write_buffer+104>

0x55f8d7a32af4 <write_buffer+124>:  mov     r0, r1

0x55f8d7a32af8 <write_buffer+128>:  bx      lr  # 当前执行的指令(pc指向此处)

分析:崩溃指令为bx lr(跳转回调用函数),若lr值异常(如被覆盖),会导致错误跳转。

三、ARM特有调试技巧

3.验证函数参数传递根据ARM调用约定,前4个参数通过r0-r3传递:

(gdb) p/x $r0  # 第一个参数(地址)

$1 = 0x7f3c20000a00

(gdb) p/x $r1  # 第二个参数(长度)

$2 = 0x400

若参数值异常,可追溯到调用函数的r0-r3赋值逻辑。

4.分析异常向量表ARM异常(如SIGSEGV)触发时,PC会跳转到异常向量表。通过反汇编向量表定位异常类型:

(gdb) disassemble 0x0  # 异常向量表起始地址

Dump of assembler code from 0x0 to 0x1c:

0x0:   b       0x10  # 复位异常

0x4:   b       0x14  # 未定义指令

0x8:   b       0x18  # SWI

0xc:   b       0x1c  # 预取指令中止

0x10:  b       0x20  # 数据中止

0x14:  b       0x24  # 保留

0x18:  b       0x28  # IRQ

0x1c:  b       0x2c  # FIQ

若崩溃时PC指向0x0附近,说明触发了复位或其他异常。

5.处理Thumb指令调试若程序使用Thumb指令(16位),需指定反汇编模式:

(gdb) set arm disassembler-mode thumb

(gdb) disassemble $pc-10, $pc+10

四、实战案例

假设ARM程序因栈溢出崩溃,调用栈显示memcpy越界:

void copy_data(char *dst, char *src, int len) {

   memcpy(dst, src, len);  // 崩溃点

}

6.寄存器分析

(gdb) info registers r0 r1 r2

r0             0x7ffd8a6b3200  140727668400640  // dst

r1             0x55f8d7a32a00  93958556621312  // src

r2             0x2000   8192  // len(实际dst仅分配1024字节)

len=0x2000远大于dst的大小,导致栈溢出。

7.反汇编验证

(gdb) disassemble memcpy

Dump of assembler code for function memcpy:

0x55f8d7a31c00 <memcpy+0>:     push    {r4, r5, r6, lr}

0x55f8d7a31c04 <memcpy+4>:     cmp     r2, #0x0

0x55f8d7a31c08 <memcpy+8>:     beq     0x55f8d7a31c64 <memcpy+100>

0x55f8d7a31c0c <memcpy+12>:    ldr     r4, [r0], #0x4

0x55f8d7a31c10 <memcpy+16>:    str     r4, [r1], #0x4

...

memcpy循环复制len次,因len过大导致栈溢出,覆盖返回地址(lr)。

五、总结ARM架构的调试需结合寄存器特性与指令集分析:

•info registers快速定位寄存器异常(如lr被篡改);
•disassemble验证指令逻辑(如分支是否正确跳转);
•调用约定分析参数传递路径,异常向量表追溯崩溃类型。

实际调试中,可配合x命令查看内存数据,或使用set修改寄存器值模拟异常场景,提升调试效率。

如果文章对你有提升,帮忙点赞,分享,关注。十分感谢

最新文章

随机文章