lldb调试器知多少

lldb调试器简介

lldb 是一个有着 REPL 的特性和 C++ 、Python 插件的开源调试器。lldb调试器的由来是伴随着Xcode的版本升级而来。

Xcode4.3之前使用的默认调试器是gdb, 到Xcode4.3之后便改成了lldb。gdb是UNIX及UNIX-like下的调试工具,是来自于GNU组织。

后被苹果进行优化,功能添加后,改名为lldb。可以说lldb是gdb的高版本。

lldb调试器是一个可执行Mach-O文件,因为通常是和xcode集成在一起,会让人误以为是xcode的一个功能,或者是xcode的一个插件。

然后并非如此,它是一个可执行的应用,可以任意组合,比如:

Mac系统就有自带调试器lldb:

/Library/Developer/CommandLineTools/usr/bin/lldb

Xcode中也自带来了调试器lldb:

/Applications/Xcode.app/Contents/Developer/usr/bin/lldb

lldb调试器使用

在Xcode集成环境中,lldb使用方法简单;

运行Xcode工程后暂停项目,在lldb调试器窗口就可以使用lldb命令进行调试了。

如果没有Xcode集成环境怎么使用lldb呢?

这就有许多步骤需要我们手动完成了。

1.先通过ps查询当前运行的程序:

192:~ zhoufei$ ps aux | grep /Applications

zhoufei           1496   0.8  4.2  6501004 348924   ??  S    10:14下午   0:35.31 /Applications/YoudaoNote.app/Contents/MacOS/YoudaoNote
zhoufei           1255   0.0  2.0  8894360 168828   ??  S    10:01下午   0:43.20 /Applications/Firefox.app/Contents/MacOS/firefox

2.开启调试一个静止的app程序

//通过lldb调试器打开静态程序
192:bin zhoufei$ lldb firefox

//或者

//通过lldb调试器打开 带参数的 静态程序
192:bin zhoufei$ lldb firefox 11 22

3.将lldb调试器附加到一个正在运行的app程序

//1.先打开lldb调试器
192:bin zhoufei$ lldb

//2.将调试器附加到要调试的目标可执行文件上
(lldb) process attach --name firefox
Process 1255 stopped
* thread #1, queue = ‘com.apple.main-thread‘, stop reason = signal SIGSTOP
    frame #0: 0x00007fff7570920a libsystem_kernel.dylib`mach_msg_trap + 10
libsystem_kernel.dylib`mach_msg_trap:
->  0x7fff7570920a <+10>: retq
    0x7fff7570920b <+11>: nop    

libsystem_kernel.dylib`mach_msg_overwrite_trap:
    0x7fff7570920c <+0>:  movq   %rcx, %r10
    0x7fff7570920f <+3>:  movl   $0x1000020, %eax          ; imm = 0x1000020
Target 0: (firefox) stopped.

Executable module set to "/Applications/Firefox.app/Contents/MacOS/firefox".
Architecture set to: x86_64h-apple-macosx.
(lldb) thread list

4.根据调试命令进行调试

lldb调试器常用命令

lldb的命令结构如下:

Command  subCommand action -opt argument

命令  子命令  动作  选项  参数。

<command> [<subcommand> [<subcommand>...]] <action> [-options [option-value]] [argument [argument...]]

1.打印命令

//同expression
p
//打印对象
po

2.项目中mach-o文件查询

//在app使用到的所有mach-o文件中查询

image lookup

//查询 类型UITableViewCell 在mach-o中的定义信息,并打印出最佳匹配
image lookup -t UITableViewCell 

//查询 崩溃内存地址0x000000010e041b62 在mach-o中的定义信息,并打印出最佳匹配
//4   WYDoctorConsultModule_Example       0x000000010e041b62 -[WYFastConsultViewController //emptyViewModelDidRefreshOrderList:] + 162
image lookup -a 0x000000010e041b62

//查询 方法名或者符号名为emptyViewModelDidRefreshOrderList: 在mach-o中的定义信息,并打印出最佳匹配
image lookup -n emptyModelDidRefreshOrderList:

//查询 app中所有使用的mach-o信息,并打印出最佳匹配
image list

3.项目中对某个内存数据进行监控,如:全局变量,静态变量

watchpoint set variable

//对变量self->_pageNo进行监控
watchpoint set variable self->_pageNo

//对内存地址&(self->_pageNo)进行监控
watchpoint set expression &(self->_pageNo)

//查询所有的内存监控
watchpoint list

//删除序号为:1 的内存监控
watchpoint delete 1

//额外命令追加
//当序号:2 断点触发时,执行追加的命令
 watchpoint command add 2
//删除序号:2的命令追加
watchpoint command delete 2
//查询所有追加命令的列表
watchpoint command list

4.为项目源码外的第三方静态库,动态库添加断点

breakpoint set

breakpoint set -a 函数地址
breakpoint set -n 函数名称
//为符合正则表达式函数全部添加断点
breakpoint set -r 任意包含此字符串的函数名称

//breakpoint set -s 动态库名称 -n 动态库方法名
breakpoint set -s dyld -n load

5.函数调用堆栈控制

比Xcode视图展示的线程堆栈更加详细

//打印当前栈帧frame的堆栈信息
thread backtrace
bt命令同上

//函数提前返回
thread return [返回值]

//当前栈帧的所有局部变量
frame variable

//源码级 代码单步执行,下一步
thread step-over, next, n
//指令级 汇编单步执行,下一步
thread step-inst-over, nexti, ni

6.原始命令

原始命令命令后面默认都是参数,

如果要跟选项的话,需要添加 — 声明结束,后面跟着参数。

expression (就是 p/print/call)
expression -o(就是 po)

//打印对象内存地址
expression -o -- 0x1111

7.辅助命令 apropos

可以通过模糊搜索,查询带有关键字的命令

如: apropos list    //查询出所有包含list命令的lldb命令。

lldb调试器扩展

chisel是facebook开源的插件

安装方式简单:

brew install chisel

安装成功后,修改~/.lldbinit文件,在文件的末尾增加一行:

command script import /usr/local/opt/chisel/libexec/fblldb.py

后保存, 重启Xcode或者重新打开终端,让修改生效。

最后

平时的iOS开发中,使用的OC或者Swift是编译性语言,每次修改都有重新编译后才能看到结果,如果合理使用lldb调试器,将会大大提高开发效率。

原文地址:https://www.cnblogs.com/zhou--fei/p/12199342.html

时间: 2024-10-06 10:42:37

lldb调试器知多少的相关文章

【转】浅谈LLDB调试器

随着Xcode 5的发布,LLDB调试器已经取代了GDB,成为了Xcode工程中默认的调试器.它与LLVM编译器一起,带给我们更丰富的流程控制和数据检测的调试功能.LLDB为Xcode提供了底层调试环境,其中包括内嵌在Xcode IDE中的位于调试区域的控制面板,在这里我们可以直接调用LLDB命令.如图1所示: 图1:位于Xcode调试区域的控制台 在本文中,我们主要整理一下LLDB调试器提供给我们的调试命令,更详细的内容可以查看The LLDB Debugger. LLDB命令结构 在使用LL

学习笔记之--认识Xcode中的重要成员:lldb调试器

之前对lldb调试器了解比较少,平时主要用来打印日志和暂定时用鼠标查看属性数据以及使用p po一些简单的命令语句. 今天看了一些关于lldb的文章,顿时觉得之前对它了解太少了,原来它还有那么多的功能. 好记性不如烂笔头,我把方便易用的命令记录下来,方便以后查看. 一.ldb的语法结构 lldb的语法结构如下:<command> [<subcommand> [<subcommand>...]] <action> [-options [option-value]

使用Python脚本强化LLDB调试器

LLDB是Xcode自带的调试器,作为一个iOS应用开发程序员,平时我在开发应用时会使用LLDB来调试代码.在逆向应用时,也会用到LLDB来跟踪应用的执行过程. LLDB还内置了一个Python解析器,使用Python脚本可以方便LLDB的调试,比如自动化执行一些命令,或者自动化处理数据之类的,具体说明可以参考官方的文档:LLDB Python Reference. 以下就以一个具体的例子来演示一个Python脚本的编写过程: 一.获取方法的偏移地址 运行系统自带的计算器Calculator.a

LLDB调试器

#LLDB调试器###简介 你是否曾经苦恼于理解你的代码,而去尝试打印一个变量的值? ```NSLog(@"%@", password);``` 或者跳过一个函数调用来简化程序的行为?实际应该调用这个函数:Foo()```NSNumber *n = @7; //complexCalculate() ;``` 或者伪造一个函数实现? ```int complexCalculate { return 9; /* 万行代码. ...}``` 并且每次必须重新编译,从头开始? 构建软件是复杂的

为什么Xcode调试模式下, lldb调试器打印任何对象都为空, 鼠标指向对变量时显示为nil?

如果之前有对工程打包发布过,那么一定改过这个位置: 如果是Release状态,那么lldb调试器无法打印变量信息,但NSLog却可以.此时将此选项改为"Debug"即可.

iOS LLDB调试器

随着Xcode 5的发布,LLDB调试器已经取代了GDB,成为了Xcode工程中默认的调试器.它与LLVM编译器一起,带给我们更丰富的流程控制和数据检测的调试功能.LLDB为Xcode提供了底层调试环境,其中包括内嵌在Xcode IDE中的位于调试区域的控制面板,在这里我们可以直接调用LLDB命令.如图1所示: 图1:位于Xcode调试区域的控制台 在本文中,我们主要整理一下LLDB调试器提供给我们的调试命令,更详细的内容可以查看The LLDB Debugger. LLDB命令结构 在使用LL

转:iOS LLDB调试器和断点调试

本文转自:http://www.cnblogs.com/wfwenchao/p/3991060.html?utm_source=tuicool&utm_medium=referral 技巧一:运行时修改变量的值 你以前怎么验证是不是某个变量的值导致整段程序不能正常工作?修改代码中的变量的值,然后cmd+r重新启动app?现在你不需要这么做了,只需要设置一个断点,当程序在这进入调试模式后,使用expr命令即可在运行时修改变量的值. 假如有一个loginWithUsername:方法,需要两个参数:

iOS LLDB调试器和断点调试

技巧一:运行时修改变量的值 你以前怎么验证是不是某个变量的值导致整段程序不能正常工作?修改代码中的变量的值,然后cmd+r重新启动app?现在你不需要这么做了,只需要设置一个断点,当程序在这进入调试模式后,使用expr命令即可在运行时修改变量的值. 假如有一个loginWithUsername:方法,需要两个参数:username,password. 首先设置好断点,如下图所示: 运行app,进入断点模式后,在(lldb)后输入 ? 1 2 expr username = @"username&

在lldb调试中调用c++函数

在lldb调试时,调用oc对象的方法不足为奇,因为msgSend是有原型导出的,oc对象的方法都运行期绑定的,绑定信息都在objc_class中.只要在调试中[receiver sel]之类,lldb就自动完成的整个由SEL通过msgSend路由到receiver的IMP方法并执行的整个过程.但是要调用c++函数则没有这么方便,虽然c++函数(包括成员函数和非成员函数)的链接符号有着函数原型的详细信息,但却不包括类的定义和名字空间的定义,即使lldb翻译出这样一个符号(symbol)Quartz