您的位置:首页 > 其它

lldb 常用命令整理

2015-10-26 15:42 351 查看


lldb 常用命令整理 -- 飘云

piaoyun • 2014-11-07 • 发表评论

这里整理一下常用的,我会慢慢添加并总结一些经验,iOS调试中。各位还是逐步放弃GDB吧,这已经成为定局了(虽然我含泪写下这段)~~~

lldb命令支持缩写,自己慢慢研究吧

 

优雅人生飘云原创整理,转载请注明出处!
http://www.dllhook.com http://bbs.chinapyg.com
 

2014-12-02增加:

调试本地文件方法(Mac OS X):(lldb)
target create "/Users/piaoyun/Desktop/xx.app/Contents/MacOS/xxxx"

远程调试方法:

设备端运行:

附加进程:

./debugserver *:1234 -a "YourAPPName"

直接启动进程:

debugserver -x backboard *:1234 /path/to/app/executable

例:

debugserver
-x backboard *:1234 /Applications/MobileNotes.app/MobileNotes

此命令会启动记事本,并断在dyld的第一条指令上

在Mac终端运行lldb命令后,输入以下2条命令:

platform select remote-ios

process connect connect://你的设备IP地址:1234

用USB连接方法:

////////////////////////////////////////////////////////////////////////////////////////

wget http://cgit.sukimashita.com/usbmuxd.git/snapshot/usbmuxd-1.0.8.tar.bz2

tar xjfv usbmuxd-1.0.8.tar.bz2

cd usbmuxd-1.0.8/python-client/

python tcprelay.py -t 1234:1234

在Mac终端运行lldb命令后,输入以下2条命令:

platform select remote-ios

process connect connect://localhost:1234

////////////////////////////////////////////////////////////////////////////////////////

 

-(void)loginWithUserName:(NSString *)username password:(NSString *)password

{

    NSLog(@"login.... username:%@   password:%@", username, password);  // 假设我们在此下断点

}

 

1.expression(或者缩写expr)  表达式 

例子:

expression
$r6 = 1   // 设置r6寄存器的值

expression
$r6       // 查看r6寄存器的值

expression
username(源代码中变量) = @"11111"

 

2.po
表达式

例子:

po
$r6

po
username

 

3.print
(type)表达式

例子:

print
(int)$r6

print
username

 

4.bt
[all]   --- 打印调用堆栈

例子:

bt

返回如下:

* thread #1: tid = 0x1ee09, 0x00035e80 debug`-[ViewController loginWithUserName:password:](self=0x15d7be60, _cmd=0x00036441, username=0x15db0120,
password=0x0003768c) + 168 at ViewController.m:34, queue = 'com.apple.main-thread', stop reason = breakpoint 2.1

  * frame #0: 0x00035e80 debug`-[ViewController loginWithUserName:password:](self=0x15d7be60, _cmd=0x00036441, username=0x15db0120,
password=0x0003768c) + 168 at ViewController.m:34

.

.

.

5.breakpoint
list     //打印断点列表

例子:

br l

返回如下:

Current breakpoints:

1: file = '/Users/piao/Desktop/debug/debug/main.m', line = 16, locations = 1, resolved = 1, hit count = 1

  1.1: where = debug`main + 54 at main.m:16, address = 0x00036232, resolved, hit count = 1 

2: file = '/Users/piao/Desktop/debug/debug/ViewController.m', line = 34, locations = 1, resolved = 1, hit count = 1

  2.1: where = debug`-[ViewController loginWithUserName:password:] + 168 at ViewController.m:34, address = 0x00035e80, resolved,
hit count = 1 

下断:

breakpoint
set -a 函数地址   --常规断点

breakpoint
set --func-regex 函数关键字   --飘云提示:这个非常有用!我也是最近才研究发现的-虽然官方文档一直有,但是没重视

这样下断的优势:

比如再某动态库中有 testA函数,那么常规做法是先 image list -o -f 查看模块基址 然后 image lookup -r -n 函数关键字找到偏移   然后再 br s -a 基址+偏移!

用上面这个命令下端就简洁方便了!!!lldb会自动帮你下断所有匹配特征字的断点,可以模糊匹配哦

再来一个对动态库函数下断的:

breakpoint
set --shlib foo.dylib --name foo

这个也非常有用,可以进行断点过程中的一些自动化处理:

breakpoint
command add 断点序号

6.c

继续执行

7.s 

源码级别单步执行,遇到子函数则进入

8.si

单步执行,遇到子函数则进入

9.n 

源码级别单步执行,遇到子函数不进入,直接步过

10.ni

单步执行,遇到子函数不进入,直接步过

11.finish/f

退出子函数

12.thread
list

 

打印线程列表

 

13.image
lookup -a 表达式、image list

例子:

image
lookup -a $pc

返回如下:

      Address: debug[0x0000b236] (debug.__TEXT.__text + 1254)

      Summary: debug`main + 58 at main.m:16

 

 

打印加载模块列表

image
list [-f -o 通常带这两个参数使用]

返回如下:

[  0] 40E417A4-F966-3DB4-B028-B0272DC016A7 0x000a0000 /Users/piao/Library/Developer/Xcode/DerivedData/debug-bdkhskdqykkoqmhjedilckzvpuls/Build/Products/Debug-iphoneos/debug.app/debug 

      /Users/piao/Library/Developer/Xcode/DerivedData/debug-bdkhskdqykkoqmhjedilckzvpuls/Build/Products/Debug-iphoneos/debug.app.dSYM/Contents/Resources/DWARF/debug

[  1] 011601C0-F561-3306-846B-94A7C8C841DA 0x2d9e6000 /Users/piao/Library/Developer/Xcode/iOS DeviceSupport/7.1.2 (11D257)/Symbols/System/Library/Frameworks/CoreGraphics.framework/CoreGraphics

查找某个函数:

对于有调试符号的这样使用

image
lookup -r -n <FUNC_REGEX>

对于无调试符号的这样使用:

image
lookup -r -s <FUNC_REGEX>

 

14.disassemble
-a 地址

例子:

dis
-a $pc

debug`main at main.m:14:

   0xa71fc:  push   {r7, lr}

   0xa71fe:  mov    r7, sp

   0xa7200:  sub    sp, #0x24

   0xa7202:  movs   r2, #0x0

   0xa7204:  movt   r2, #0x0

   0xa7208:  str    r2, [sp, #0x20]

   0xa720a:  str    r0, [sp, #0x1c]

   0xa720c:  str    r1, [sp, #0x18]

   0xa720e:  blx    0xa7fe0                   ; symbol stub for: 

.

.

.

2015-04-29 添加

disassemble
-A thumb    

可选:

thumbv4t

thumbv5

thumbv5e

thumbv6

thumbv6m

thumbv7

thumbv7f

thumbv7s

thumbv7k

thumbv7m

thumbv7em

///////////////////////////////////////////////

 

15.memory
read [起始地址 结束地址]/寄存器 -outfile 输出路径

例子:

memory
read $pc

0x00035ebe: 0e 98 07 99 09 68 08 9a 90 47 0c 99 03 90 08 46  .....h...G.....F

0x00035ece: 03 99 01 f0 80 e8 02 22 c0 f2 00 02 41 f2 52 10  ......."....A.R.

memory
read 0x35f1c 0x35f46 -outfile /tmp/test.txt  //
将内存区域保存到文件

2015-04-29添加:

默认情况下,memory read 只能读取 1024字节数据

例如:

memory
read 0x1000 0x3000 -outfile /tmp/test.txt 就会报错

error: Normally, 'memory read' will not read over 1024 bytes of data.

解决方法:加-force参数

memory read 0x1000 0x3000 -outfile /tmp/test.txt -force

或者:

memory read 0x1000 -outfile /tmp/test.txt -count 0x2000 -force

memory read $x0(寄存器) -outfile /tmp/test.txt -count 0x2000 -force

--binary
// 二进制输出

例:

memory
read 0x1000 0x3000 -outfile /tmp/test.bin --binary -force

写内存:

memory
write $rip 0xc3

memory write $rip+1
0x90

16.register
read/格式、register write
寄存器名称 数值

例子:

register
read/x

返回如下:

General Purpose Registers:

        r0 = 0x1599e028

        r1 = 0x38131621  libobjc.A.dylib`objc_msgSend + 1

        r2 = 0x000a85cc  "class"

        r3 = 0x000a85d4  (void *)0x000a8618: AppDelegate

        r4 = 0x00000000

        r5 = 0x000a71fd  debug`main + 1 at main.m:14

        r6 = 0x00000000

        r7 = 0x27d63c80

        r8 = 0x27d63c98

        r9 = 0x00000002

       r10 = 0x00000000

       r11 = 0x00000000

       r12 = 0x3a3ff1c8  (void *)0x3875cc19: _Unwind_SjLj_Unregister + 1

        sp = 0x27d63c5c

        lr = 0x38136eaf  libobjc.A.dylib`objc_autoreleasePoolPush + 311

        pc = 0x000a7236  debug`main + 58 at main.m:16

      cpsr = 0x20000030

//
改写r9寄存器例子:

register
write r9 2

 

17.display 表达式     undisplay 序号
例子:

display
$R0

undisplay 1

 

18.内存断点 watchpoint
set expression 地址    /  watchpoint set variable 变量名称 -- (源码调试用到,略过)

例子:

watchpoint
set expression 0x1457fa70

命中后得到结果:

Watchpoint 3 hit:

old value: 3

new value: 4

18.1.条件断点 watchpoint
modify -c 表达式

例子:

watchpoint
modify -c '*(int *)0x1457fa70 == 20'

命中后得到结果:

Watchpoint 3 hit:

old value: 15

new value: 20

除非特别注明,本站所有文字均为原创文章,作者:piaoyun
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: