Jacky's blog
首页
  • 学习笔记

    • web
    • android
    • iOS
    • vue
  • 分类
  • 标签
  • 归档
收藏
  • tool
  • algo
  • python
  • java
  • server
  • growth
  • frida
  • blog
  • SP
  • more
GitHub (opens new window)

Jack Yang

编程; 随笔
首页
  • 学习笔记

    • web
    • android
    • iOS
    • vue
  • 分类
  • 标签
  • 归档
收藏
  • tool
  • algo
  • python
  • java
  • server
  • growth
  • frida
  • blog
  • SP
  • more
GitHub (opens new window)
  • shell

  • tool

    • mac 百问记录
    • mac tool
    • tmux
    • c tool
    • platform
    • dev tool
    • java tool
    • IDEA
    • vscode
    • Docker 使用指南
    • unbuntuOnWindows
    • oh-my-zsh
    • github
    • lldb
      • 基本概念
      • 执行控制
      • 打印变量
        • 常用打印命令
        • po 和 p 的区别
        • 打印可选值
        • 打印复杂对象的属性
      • 表达式执行(运行时修改)
      • 断点管理
        • 设置断点
        • 管理断点
        • 条件断点
        • 断点执行命令(断住后自动执行)
      • 调用栈与线程
        • 调用栈
        • 线程管理
      • 内存查看
        • 内存格式说明
      • 寄存器查看
      • 镜像(模块)查询
      • 常见调试场景
        • 1. 查看崩溃位置
        • 2. 修改变量值绕过逻辑
        • 3. 条件断点排查循环问题
        • 4. 查看对象的属性
        • 5. 调用方法
      • 常见问题
        • Q: 输入变量名报 error: 'xxx' is not a valid command
        • Q: po 打印对象没有输出或输出不完整
        • Q: 断点不生效
        • Q: 打印 Swift 对象时报错
        • Q: 怎么在 LLDB 中执行多行命令
      • 命令速查表
      • 链接
    • ripgrep 高性能文本搜索工具使用指南
    • appium
    • mvn
    • ffmpeg
    • gradle
    • git 使用指南
    • jenv
    • php-fpm
    • raycast
    • VisiData 终极生存指南(vd)
    • yq
    • direnv
    • Vim 编辑器入门指南
    • jadx
    • excalidraw 入门指南
    • whimsical 入门指南
    • mermaid 入门指南
  • client

  • 网络

  • compute_base

  • blog

  • growth

  • java

  • C&C++

  • ai

  • secure

  • cms

  • english

  • 生活

  • 金融学

  • more

  • other
  • tool
Jacky
2023-10-07
目录

lldb

LLDB Debugger (LLDB) 是一个开源、底层调试器(low level debugger), 具有 REPL (Read-Eval-Print Loop, 交互式解释器)、C++ 和 Python 插件, 位于 Xcode 窗口底部控制台中, 也有其他 IDE 加入了 LLDB 调试器, 如 CLion, 当然其也可以在 terminal 中使用。搜罗了一圈, 发现大多数教程还是可视化的使用, 本文就命令行使用 LLDB 调试程序做一个总结

# 基本概念

LLDB(Low Level Debugger)是 Xcode 内置的调试器,在调试程序时通过底部控制台输入命令与调试器交互。

重要:LLDB 控制台中直接输入变量名不是合法命令,会报 error: 'xxx' is not a valid command。打印变量必须使用 po、p、expr 等命令。

# 执行控制

命令 缩写 作用
continue c 继续执行到下一个断点
next n 单步跳过(不进入函数内部)
step s 单步进入(进入函数内部)
finish — 执行到当前函数返回,然后暂停
stepi si 单步执行一条机器指令
nexti ni 单步跳过一条机器指令

# 打印变量

# 常用打印命令

命令 作用 示例
po <expr> 打印对象(print object),调用 description 方法 po self、po data、po user.name
p <expr> 打印基本类型/结构体(print) p count、p data.count、p view.frame
expr <expr> 执行表达式并打印结果 expr data、expr count + 1
frame variable fr v 打印当前栈帧所有局部变量
frame variable <name> fr v <name> 打印指定局部变量

# po 和 p 的区别

po p
全称 print object print
适用 引用类型对象(类、String、Data、NSArray 等) 基本类型(Int、Bool、CGPoint、结构体)
输出 调用对象的 description / debugDescription 打印原始值或内存结构
示例输出 32 bytes (Foundation.Data) data = 32 bytes { ... }

# 打印可选值

po optionalVar          // 打印可选值,nil 时输出 nil,有值时输出 Optional(...)
p optionalVar           // 打印可选值的详细结构
po optionalVar!         // 强制解包后打印(如果为 nil 会崩溃)
1
2
3

# 打印复杂对象的属性

po self.view.frame
po user.name
po array[0]
po dictionary["key"]
1
2
3
4

# 表达式执行(运行时修改)

expr(缩写 e)可以在调试时执行任意表达式,包括修改变量值:

expr count = 10              // 修改局部变量的值
expr self.title = "新标题"    // 修改属性
expr array.append("new")     // 调用方法
expr import UIKit            // 导入框架(有时需要)
1
2
3
4

注意:修改后变量值只在内存中生效,不会写回源码,程序继续执行时使用修改后的值。

# 断点管理

# 设置断点

命令 作用
breakpoint set -n <函数名> b <函数名>,按函数名设断点
breakpoint set -f <文件> -l <行号> b <文件>:<行号>,按文件和行号设断点
breakpoint set -n "-[Class method:]" 给 OC 方法设断点
breakpoint set -n "Class.method()" 给 Swift 方法设断点
breakpoint set -r <正则> 按正则匹配符号设断点

# 管理断点

命令 缩写 作用
breakpoint list br l 列出所有断点
breakpoint delete <编号> br d <编号> 删除指定断点
breakpoint delete br d 删除所有断点(会确认)
breakpoint disable <编号> br dis <编号> 禁用指定断点
breakpoint enable <编号> br en <编号> 启用指定断点
breakpoint command add <编号> br com add <编号> 给断点添加自动执行的命令

# 条件断点

breakpoint set -n "functionName" --condition "count > 5"
# 只有 count > 5 时才会断住
1
2

# 断点执行命令(断住后自动执行)

breakpoint command add 1
> po self
> continue
> DONE
# 断点 1 断住后自动打印 self 然后继续执行
1
2
3
4
5

# 调用栈与线程

# 调用栈

命令 缩写 作用
thread backtrace bt 打印当前线程调用栈
thread backtrace all bt all 打印所有线程调用栈
up — 上移一帧(看调用者)
down — 下移一帧(看被调用者)
frame select <编号> fr s <编号> 跳转到指定栈帧
frame info fr i 查看当前栈帧信息

# 线程管理

命令 作用
thread list 列出所有线程
thread select <编号> 切换到指定线程
thread info 查看当前线程信息
thread continue <编号> 只继续指定线程(其他线程暂停)

# 内存查看

命令 作用 示例
memory read <地址> x <地址>,读取内存 x 0x12345678
memory read -c <数量> -f <格式> <地址> 按指定格式读取内存 x -c 16 -f x 0x1234
memory write <地址> <值> 修改内存 memory write 0x1234 0xff
image lookup -a <地址> 查找地址对应的符号/代码 image lookup -a 0x1234
image list 列出所有加载的模块(二进制/动态库)

# 内存格式说明

x 命令的格式参数 -f:

  • x:十六进制
  • d:十进制
  • u:无符号十进制
  • o:八进制
  • c:字符
  • s:字符串
  • i:指令(反汇编)
x -c 32 -f x 0x12345678    # 读取 32 字节,十六进制显示
x -c 100 -f s 0x12345678   # 读取 100 字节,字符串显示
x -i 0x12345678             # 反汇编指定地址
1
2
3

# 寄存器查看

命令 作用
register read re r,读取所有寄存器
register read <寄存器名> 读取指定寄存器,如 re r x0
register write <寄存器> <值> 修改寄存器值

常见寄存器(ARM64):

  • x0-x7:函数参数和返回值
  • sp:栈指针
  • pc:程序计数器(当前执行地址)
  • lr:链接寄存器(返回地址)

# 镜像(模块)查询

命令 作用
image list 列出所有加载的模块
image lookup -n <符号名> 按符号名查找
image lookup -a <地址> 按地址查找对应的代码位置
image lookup -r -n <正则> 按正则查找符号
image dump sections <模块> 查看模块的段信息
image lookup -a 0x0000000102a3b1c0   # 查崩溃地址对应哪行代码
image lookup -n "ViewController.viewDidLoad"  # 查方法地址
1
2

# 常见调试场景

# 1. 查看崩溃位置

程序崩溃后:

bt                    # 查看调用栈,找到崩溃位置
frame select 1        # 跳转到崩溃的栈帧
po self               # 查看当前对象
po error              # 查看错误信息
1
2
3
4

# 2. 修改变量值绕过逻辑

expr isLoggedIn = true    # 临时修改登录状态
c                          # 继续执行
1
2

# 3. 条件断点排查循环问题

b ViewController.cellForRowAtIndexPath
breakpoint modify 1 --condition "indexPath.row == 5"
# 只有第 5 行才断住
1
2
3

# 4. 查看对象的属性

po self.view.subviews
po user.dictionary
po array.count
1
2
3

# 5. 调用方法

po self.view.description
expr [self doSomething]      # OC 方法调用
expr self.doSomething()      # Swift 方法调用
1
2
3

# 常见问题

# Q: 输入变量名报 error: 'xxx' is not a valid command

A: LLDB 把第一个词当成命令名,直接输入变量名不是命令。打印变量必须用 po 或 p:

po data        # 正确
p data         # 正确
data           # 错误,不是有效命令
1
2
3

# Q: po 打印对象没有输出或输出不完整

A: 尝试用 p 代替,或者用 expr -O -- object(强制对象描述)。Swift 对象有时需要 po 才能正确打印。

# Q: 断点不生效

A:

  1. 确认代码编译的是 Debug 配置(不是 Release)
  2. 确认断点位置的代码确实会执行到
  3. 用 breakpoint list 确认断点已启用
  4. 清理构建文件夹后重新编译:Product → Clean Build Folder

# Q: 打印 Swift 对象时报错

A: 有时需要先导入模块:

expr import UIKit
expr import MyAppName
po self
1
2
3

# Q: 怎么在 LLDB 中执行多行命令

A: 用 expr 后跟大括号:

expr {
    let a = 1
    let b = 2
    print(a + b)
}()
1
2
3
4
5

# 命令速查表

操作 命令
继续 c
单步跳过 n
单步进入 s
跳出函数 finish
打印对象 po <expr>
打印值 p <expr>
执行表达式 expr <expr>
所有局部变量 fr v
调用栈 bt
所有线程调用栈 bt all
设断点 b <函数名/文件:行号>
断点列表 br l
删除断点 br d <编号>
读内存 x <地址>
查地址对应代码 image lookup -a <地址>
线程列表 thread list
切换线程 thread select <编号>

# 链接

  • LLDB 调试命令使用指南 (opens new window)
  • Apple LLDB 官方文档 (opens new window)
  • LLDB Tutorial (opens new window)
#tool
上次更新: 2026/09/10, 20:52:09
github
ripgrep 高性能文本搜索工具使用指南

← github ripgrep 高性能文本搜索工具使用指南→

最近更新
01
direnv
09-09
02
nvim
09-09
03
wget
09-09
更多文章>
Theme by Vdoing | Copyright © 2019-2026 Jacky | MIT License
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式