前言
上周[2020.05.23]想要 直接使用 fastdebug 版本的 jdk 来进行调试, 可惜失败了
原来是 缺少 可执行文件关联的, object file, 里面记录了 关联的源码的一些信息
看来还是 免不了, 需要 手动 编译 open jdk, 哎
本文主要是两个东西 : 1. 查看 object file 中的汇编信息, 2. 基于 hopper disassembler 来调试 代码
测试用例
//
// Created by Jerry.X.He on 2019-12-09.
//
#include <iostream>
using namespace std;
int main() {
int x = 2;
int y = 3;
int z = x + y;
cout << " x + y = " << z << endl;
return 0;
}
执行效果如下
查看 object file 中的汇编信息
从可执行文件中查询 object file 的信息
master:cmake-build-debug jerry$ nm -pa HelloWorld | grep OSO
000000005dedb851 - 03 0001 OSO /Users/jerry/ClionProjects/HelloWorld/cmake-build-debug/CMakeFiles/HelloWorld.dir/Test01AddOpe.cpp.o
查看 object file 中的代码的信息 (忽略了部分无关的代码)
master:HelloWorld.dir jerry$ objdump -S -l Test01AddOpe.cpp.o
Test01AddOpe.cpp.o: file format Mach-O 64-bit x86-64
Disassembly of section __TEXT,__text:
_main:
; /Users/jerry/ClionProjects/HelloWorld/Test01AddOpe.cpp:8
; int main() {
0: 55 pushq %rbp
1: 48 89 e5 movq %rsp, %rbp
4: 48 83 ec 20 subq $32, %rsp
8: 48 8b 3d 00 00 00 00 movq (%rip), %rdi
f: c7 45 fc 00 00 00 00 movl $0, -4(%rbp)
; /Users/jerry/ClionProjects/HelloWorld/Test01AddOpe.cpp:10
; int x = 2;
16: c7 45 f8 02 00 00 00 movl $2, -8(%rbp)
; /Users/jerry/ClionProjects/HelloWorld/Test01AddOpe.cpp:11
; int y = 3;
1d: c7 45 f4 03 00 00 00 movl $3, -12(%rbp)
; /Users/jerry/ClionProjects/HelloWorld/Test01AddOpe.cpp:12
; int z = x + y;
24: 8b 45 f8 movl -8(%rbp), %eax
27: 03 45 f4 addl -12(%rbp), %eax
2a: 89 45 f0 movl %eax, -16(%rbp)
; /Users/jerry/ClionProjects/HelloWorld/Test01AddOpe.cpp:14
; cout << " x + y = " << z << endl;
2d: 48 8d 35 2c 0c 00 00 leaq 3116(%rip), %rsi
34: e8 00 00 00 00 callq 0 <_main+0x39>
39: 8b 75 f0 movl -16(%rbp), %esi
3c: 48 89 c7 movq %rax, %rdi
3f: e8 00 00 00 00 callq 0 <_main+0x44>
44: 48 89 c7 movq %rax, %rdi
47: 48 8d 35 00 00 00 00 leaq (%rip), %rsi
4e: e8 00 00 00 00 callq 0 <_main+0x53>
53: 31 c9 xorl %ecx, %ecx
; /Users/jerry/ClionProjects/HelloWorld/Test01AddOpe.cpp:16
; return 0;
55: 48 89 45 e8 movq %rax, -24(%rbp)
59: 89 c8 movl %ecx, %eax
5b: 48 83 c4 20 addq $32, %rsp
5f: 5d popq %rbp
60: c3 retq
61: 66 2e 0f 1f 84 00 00 00 00 00 nopw %cs:(%rax,%rax)
6b: 0f 1f 44 00 00 nopl (%rax,%rax)
上面的注释, 已经解释的相当详尽了, 因此 这里就不赘述了
hopper disassembler 调试 HelloWorld
hopper disassembler 加载可执行文件, 如上图, 汇编代码 和 object file 中的内容一致, 不过没有 加注释的 object file 中的信息那么详尽
因为程序本身也比较简单, 因此 没得太多的 需要描述的
图中 0000000100001174 的位置, 我添加了一个断点, 然后执行到 断点处, 我调试到了 图中 RIP 的指令的位置
此时通用寄存器的信息入上图 , 我们重点关注一下 栈帧中的信息
栈帧信息如上图
bp 寄存器为 0x7FFEEFBFFDB0, sp 寄存器为 0x7FFEEFBFFD90
0x7FFEEFBFFDA0 行 从右到左 依次为 : 这个slot不清楚, x, y, z
0x7FFEEFBFFD90 行 最右边的 8字节 暂存的 rax
这边这个 console 似乎是 基于 lldb, 使用非常方便
参考
LLDB not showing source code