在 Linux 下通过反汇编排查程序错误,通常用于:
下面按实战流程给你一个清晰、可操作的排查思路。
编译时加:
gcc -g -O0 -o test test.c
-g:调试符号-O0:不优化,反汇编好读如果是已发布程序:
.debug 或 debuginfo 包最好| 工具 | 用途 |
|---|---|
objdump |
静态反汇编 |
gdb |
动态调试 + 反汇编 |
nm |
看符号 |
addr2line |
地址转源码行 |
readelf |
看 ELF 结构 |
strace |
系统调用层面 |
objdump -d -M intel test
-d:反汇编代码段-M intel:Intel 语法(比 AT&T 好读)objdump -d -M intel test | grep -A 50 "<main>:"
nm test
gdb ./test
(gdb) run
程序崩了后:
(gdb) bt
看调用栈
(gdb) disassemble
反汇编当前崩溃位置
(gdb) info registers
看寄存器状态(很重要)
(gdb) bt
#0 0x0000000000401145 in func ()
(gdb) disassemble 0x401145
例如:
mov rax, [rdi]
说明:
rdi 是 NULL(gdb) info registers rdi
gcc -O0 -g
(gdb) list
layout(gdb) layout asm
或
(gdb) layout split
同时看源码 + 汇编
ulimit -c unlimited
./test
gdb ./test core
addr2line -e test 0x401145
strings test
| 错误 | 汇编特征 |
|---|---|
| 空指针解引用 | mov [reg], ... reg=0 |
| 栈溢出 | push 很多 / sub rsp, 巨大 |
| 除零 | div / idiv |
| 越界写 | 修改不属于自己的地址 |
| 死循环 | jmp 回自己 |
gdb 运行bt 看哪里崩disassemble 看指令info reg 看数据addr2line 定位源码objdump 静态分析如果你愿意,可以把:
bt 输出贴出来,我可以直接帮你逐条分析是哪条指令出错。