LLDB

LLDB

  • po: 为 print object 的缩写,显示对象的文本描述, expression -O的别称
  • bt: 打印当前堆栈信息
  • register read xx: 读取寄存器
  • memory read/个数+格式+每个地址单元的长度 内存地址 查看内存数据
    • 默认为:memory read/16xb
    • 格式: x-16进制、f-浮点数,d-10进制,u-10进制无符号,o-8进制,t-2进制
      a-16进制格式+实际地址类型,i-指令地址格式,c-按字符格式
    • 字节数: b-1个字节,h-2个字节,w-4个字节,g-8个字节。
    • x = memory read x/16xb
  • memory write 地址 数据 向指定内存写入数据 命令格式
    1
    2
    // 命令 + 子命令 + 命令选项 + 命令参数
    <command> [<subcom> [<subcom>...]] <action> [-options [optionvalue]] [arg [arg...]]

    常用命令

expression

执行表达式并将表达式的执行结果输出打印。开发中常用po来打印对象,po实际上就是expression -O的别名。

breakpoint

代码调试断点

指定文件和行号设置断点:
1
2
breakpoint set --file easeapi.c --line 12
breakpoint set -f ViewController.m -l 12
指定函数名称设置断点:
1
2
3
4
5
6
7
8
9
10
//对于C函数,填写完整的函数名称。
breakpoint set --name easeapi_func
breakpoint set -n easeapi_func

//对于Objective-C函数,填写完整的方法签名Selector字符串。
breakpoint set -n viewDidAppear:
breakpoint set -n tableView:cellForRowAtIndexPath:

//对于Swift方法,填写函数名称,参数省略。
breakpoint set -n easeapi_func
指定对象方法设置断点:
1
2
3
4
breakpoint set -n "-[ViewController viewDidAppear:]"
breakpoint set -n "+[ViewController classFunc]"
//Swift函数
breakpoint set -n "ViewController.easeapi_func"
指定代码地址设置断点:
1
2
breakpoint set --address 0x1021744bb
breakpoint set -a 0x1021744bb
查看已设置的断点
1
breakpoint list

每一次设置的断点都是逻辑断点(对应编号1、2、3等),一个逻辑断点可以解析为多个断点位置(对应编号1.1等)

取消断点
1
breakpoint delete 断点编号

若不加编号则为所有断点

watchpoint

内存调试断点

设置观察变量:
1
2
watchpoint set variable value
watchpoint set variable self->_dataArray //不能使用点语法
设置观察内存地址:
1
watchpoint set expression 0x000000016f47fc70
查看所有内存断点:
1
watchpoint list
删除内存断点:
1
2
watchpoint delete index
watchpoint delete

register

寄存器操作

register read 读取所有寄存器
ARM64架构中共有34个寄存器,包括31个通用寄存器、SP、PC、CPSR。

  • 通用寄存器
    • r0 - r30是31个通用寄存器,每个寄存器可以存取一个64位大小的数。
    • 当使用x0 - x30访问时,它就是一个64位的数。
    • 当使用w0 - w30访问时,是这些寄存器的低32位。
    • r29又称FP寄存器(frame point),主要用来保存栈帧(栈底)指针。
    • r30又称LR寄存器(link register),主要用来保存函数返回地址。
  • SP:stack pointer,栈顶指针;
  • PC:用来记录当前执行的指令地址;
  • CPSR:状态寄存器。

读取指定寄存器的值:

1
register read x1

写入寄存器:

1
register write x0 1

memory

内存操作

从内存读取数据

memory read/个数+格式+每个地址单元的长度 内存地址

  • 默认为:memory read/16xb
  • 格式: x-16进制、f-浮点数,d-10进制,u-10进制无符号,o-8进制,t-2进制;
    a-16进制格式+实际地址类型,i-指令地址格式,c-按字符格式
  • 字节数: b-1个字节,h-2个字节,w-4个字节,g-8个字节。

等价于 x/16xb = memory read/16xb

往内存写入数据

1
2
3
memory write 地址 数据
//以8字节对齐,写入两个数据
memory write 0x000000016f08fc70 -s 8 0x01 0x02

image

image镜像文件操作

查看已经加载的Image

1
image list

查看信息

1
2
3
4
5
6
7
8
9
//查找类信息
image lookup --type UIViewController
image lookup -t UIViewController
//查找符号
image lookup --name viewDidLoad
image lookup -n viewDidLoad
//查找地址
image lookup --address 0x000000018ff60490
image lookup -a 0x000000018ff60490

导出image信息:

1
2
3
4
//导出所有sections信息
image dump sections
//导出所有符号信息
image dump symtab

thread

线程操作

查看线程列表
thread list
其中,使用*标记当前线程;使用#标记线程编号。

获取线程调用栈:

1
2
3
4
5
6
//获取当前线程调用栈
thread backtrace
//函数的堆栈
bt
//获取所有线程调用栈
thread backtrace all

在Xcode中,有四个控制Debug的按钮:

  • Continue:程序继续运行
    thread continue/continue/c
  • Step over:单步指定,遇到子函数时断点不会进入子函数。
    thread step-over/next/n
  • Step into:单步运行,遇到子函数时断点会进入子函数。
    thread step-into/step/s
  • Step out:执行完当前函数剩余的代码,返回上一层函数。
    thread step-out/finish

修改函数返回:

1
thread return 10

frame

栈帧信息
查看当前栈帧变量:

1
frame variable

disassemble

显示汇编代码
使用d/di/dis同等效果。

1
2
3
4
5
disassemble -b
disassemble --frame
disassemble --name func_name
disassemble -a address
disassemble -s address
文章目录
  1. 1. LLDB
    1. 1.1. 常用命令
      1. 1.1.1. expression
      2. 1.1.2. breakpoint
        1. 1.1.2.0.1. 指定文件和行号设置断点:
        2. 1.1.2.0.2. 指定函数名称设置断点:
        3. 1.1.2.0.3. 指定对象方法设置断点:
        4. 1.1.2.0.4. 指定代码地址设置断点:
        5. 1.1.2.0.5. 查看已设置的断点
        6. 1.1.2.0.6. 取消断点
      3. 1.1.2.1. watchpoint
        1. 1.1.2.1.1. 设置观察变量:
        2. 1.1.2.1.2. 设置观察内存地址:
        3. 1.1.2.1.3. 查看所有内存断点:
        4. 1.1.2.1.4. 删除内存断点:
    2. 1.1.3. register
    3. 1.1.4. memory
      1. 1.1.4.1. 从内存读取数据
      2. 1.1.4.2. 往内存写入数据
    4. 1.1.5. image
    5. 1.1.6. thread
    6. 1.1.7. frame
    7. 1.1.8. disassemble