前言 如下所示,通常情况下,我们只能看到触发断点线程的指令代码。
如果希望看到另外一个函数或方法的指令,通常需要打开另外的工具。比如 Hopper。
x 命令 实际上,lldb 已经提供了一个方便的工具查看汇编代码。
x
是 lldb 的 memory read
命令缩写,它支持部分 GDB 简写格式的语法 GDB to LLDB command map
Length
代表重复次数,默认是 1。通过它,可以控制多少个单位的内存进行输出。 Format
输出内容的格式,常见对应关系如下所示,
o - octal
x - hexadecimal
d - decimal
u - unsigned decimal
t - binary
f - floating point
a - address
c - char
s - string
i - instruction
b - bytes
h - Halfwords(two bytes)
w - Words (four bytes)
g - Giant words (eight bytes) [Address expression]
任意合法的地址表达
(lldb) x /3i NSLog
0x1a8dcb72c: 0xd10083ff sub sp , sp , #0x20 ; =0x20
0x1a8dcb730: 0xa9017bfd stp x29, x30, [sp, #0x10]
0x1a8dcb734: 0x910043fd add x29, sp, #0x10 ; =0x10
(lldb) b NSLog
Breakpoint 4: where = Foundation`NSLog, address = 0x00000001a8dcb72c
(lldb) x/3i 0x00000001a8dcb72c
0x1a8dcb72c: 0xd10083ff sub sp, sp, #0x20 ; =0x20
0x1a8dcb730: 0xa9017bfd stp x29, x30, [sp, #0x10]
0x1a8dcb734: 0x910043fd add x29, sp, #0x10 ; =0x10
(lldb) b dic
Breakpoint 5: where = testLock`-[DataManager dic] at DataManager.m:14, address = 0x0000000104ee9d24
(lldb) x /3i 0x0000000104ee9d24
0x104ee9d24: 0xd10043ff sub sp , sp , #0x10 ; =0x10
0x104ee9d28: 0xf90007e0 str x 0, [sp, #0x8]
0x104ee9d2c: 0xf90003e1 str x1, [sp]
(lldb) x /3i $pc
-> 0x104ee9bc4: 0xf85c83a0 ldur x 0, [x29, #-0x38]
0x104ee9bc8: 0x940001e5 bl 0x104eea35c ; symbol stub for : objc_release
0x104ee9bcc: 0xf85e83a8 ldur x8, [x29, #-0x18]
(lldb) x /3i 4377713956
0x104ee9d24: 0xd10043ff sub sp , sp , #0x10 ; =0x10
0x104ee9d28: 0xf90007e0 str x 0, [sp, #0x8]
0x104ee9d2c: 0xf90003e1 str x1, [sp]
合法的地址,如 0x0000000104ee9d24
4377713956
函数名 NSLog
寄存器名 $pc
实战 如下所示,我们可以通过以下步骤打印。
1、获取任意函数或者方案的地址。
2、以汇编格式打印该地址后方的内容。
下面,我们验证一下上面的汇编内容。
首先,我们先查看通过 Xcode 生成的汇编代码,(655-673行)
略以 .
"
Lfunc
Ltmp
开头的辅助信息后,我们可以发现两份数据完全一致。
至此,可以确认,通过 x
命令可以正确打印任意函数的汇编代码
参考文章 GDB to LLDB command map
GDB Memory
lldb