iOS LLDB常用调试技巧记录汇总

1.单步调试

单步调试通常分为两大类,一类为源码级别(source level),一类为指令级别(instrution level)。一行源代码一般需要多行汇编才可以实现,所以当我们越狱开发调试汇编指令单步调试需要用到(instrution level)指令级别。而每一大类又分为step-in和step-over,step-in会进入函数调用,而step-over会跳过函数调用。

单步调试

1.1源码级别(source level)

1.1.1 step-in
(lldb) thread step-in
(lldb) step
(lldb) s

以上三条命令是等同的。假如我们在ViewController的第20行下了断点,每执行一次上述命令断点会跳转到下一行源代码位置,如果下一行是一个函数调用,会进入函数调用内部。比如当执行到23行时,输入s命令,会进入testMethod函数内部,跳转到39行。

1.1.2 step-over
(lldb) thread step-over
(lldb) next
(lldb) n

以上三条命令是等同的。假如我们在ViewController的第20行下了断点,每执行一次上述命令断点会跳转到下一行源代码位置,如果下一行是一个函数调用,则不会进入函数调用内部。比如当执行到23行时,输入n命令,却不会跳转到39行,而是45行(之所以会跳转到45行,因为在45行设置了断点)。

  • s和n都是跳转到断点的下一行源代码位置,区别为,如果下一行源代码有函数调用,s会进入函数内部,n则会跳过函数执行。如果没有函数调用则两组命令没有任何区别。

1.2指令级别(instrution level)

理解了s和n命令的区别。si和ni同理。假如汇编指令有一个bl跳转指令,si会单步进入bl指令的子函数内部,而ni就不会。

1.2.1 step-in
(lldb) thread step-inst
(lldb) si
1.1.2 step-over
(lldb) thread step-inst-over
(lldb) ni

1.3 step-out

(lldb) thread step-out
(lldb) finish
  • setp out 从一个函数跳出。
  • 如果没有执行s或者si,却执行了finish,其实会跳转到汇编指令bl的下一条位置(step out默认是从一个函数跳出,对系统函数调用一定是通过bl执行了函数调用,下一个位置必定为bl的下一个位置)
  • 要从嵌套的step out中退出,执行c命令即可跳转到下一个断点。

对于单步调试总结下:对于逆向开发si和ni命令会使用较多,正向App开发,s和n命令较多

1.4 s(si)、n(ni)和xcode调试工具对应关系

xcode调试工具
1.3.1xcode第二个图标
  • 点击第二个图标,同continue命令,即c是等同的,跳转到下一个断点。
1.3.2xcode第三个图标
  • 点击第三个图标,同thread step-over(next、n)。
  • 按住Control键,同时点击第三个图标,同thread step-inst-over(ni)命令。
  • 同时按住Control键+Shift键,并同时点击第三个图标,同thread step-over(next、n)。
1.3.3xcode第四个图标
  • 点击第四个图标,同thread step-in(step、s)。
  • 按住Control键,同时点击第四个图标,同thread step-inst(si)命令。我们可以通过xcode调试时,按住Control键,会发现需要点击多次断点才会移动到下一行(原因是一行源代码一般需要多行汇编才可以实现)
  • 同时按住Control键+Shift键,并同时点击第四个图标,同同thread step-in(step、s)。
1.3.4xcode第五个图标
  • 点击第五个图标,同finish(即f命令,thread step-out)

2.断点命令

2.1设置断点

  • 通过函数名字设置断点
(lldb) breakpoint set --name "-[NSString stringWithFormat:]"
(lldb) br s -n "-[NSString stringWithFormat:]"
(lldb) b -[NSString stringWithFormat:]
  • 通过地址设置断点
(lldb) breakpoint set --address 0x00000001c44441d0
(lldb) br s -a 0x00000001c44441d0

2.2列举所有断点

(lldb) breakpoint list
(lldb) br l

2.3删除断点

(lldb) breakpoint delete 1
(lldb) br del 1

3. expression命令

3.1打印变量

  • print 简写p 是 expression -- 别名,打印基本数据类型。
  • po 是 expr -o -- 的别名。
(lldb) expr -o -- [SomeClass returnAnObject]
or using the po alias:
(lldb) po [SomeClass returnAnObject]

以特定格式打印变量
下面分别以16进制(x),字符(c),二进制(t)打印变量

(lldb) p/x 2
(int) $0 = 0x00000002
(lldb) p/c (char)97
(char) $2 = 'a'
(lldb) p/t 2
(int) $4 = 0b00000000000000000000000000000010

3.2申明变量

(lldb) e NSString* abc = @"abc"
(lldb) po abc
abc

3.3修改变量

在如下函数设置断点


修改变量

如图所示,ii初始值为0,但是可以通过expression命令修改其初始化值为 10000

lldb) p ii
(int) $0 = 0
(lldb) e ii = 10000
(int) $1 = 10000
(lldb) p ii
(int) $2 = 10000

4.调试信息

  • frame info 可以查看当前调试的行数和源码信息
(lldb) frame info
frame #0: 0x0000000104cc6d1c TestPAD`-[ViewController testParam:b:c:d:](self=0x0000000149d0aaa0, _cmd="testParam:b:c:d:", a=10, b=20, c=30, d=40) at ViewController.m:31
  • thread info 可以查看当前调试线程、行数、和源码信息
(lldb) thread info 
thread #1: tid = 0xfb0ab5, 0x0000000104cc6d1c TestPAD`-[ViewController testParam:b:c:d:](self=0x0000000149d0aaa0, _cmd="testParam:b:c:d:", a=10, b=20, c=30, d=40) at ViewController.m:31, queue = 'com.apple.main-thread', stop reason = breakpoint 9.1
  • thread list 可以查看当前所有线程的调试状态
lldb) thread list
Process 29252 stopped
* thread #1: tid = 0xfb0ab5, 0x0000000104cc6d1c TestPAD`-[ViewController testParam:b:c:d:](self=0x0000000149d0aaa0, _cmd="testParam:b:c:d:", a=10, b=20, c=30, d=40) at ViewController.m:31, queue = 'com.apple.main-thread', stop reason = breakpoint 9.1
  thread #3: tid = 0xfb0ad8, 0x000000018608fdf4 libsystem_dnssd.dylib`ConvertHeaderBytes, queue = 'com.skyeye.analytics.network.queue'
  thread #4: tid = 0xfb0ad9, 0x00000001860f5dbc libsystem_kernel.dylib`__workq_kernreturn + 8
  thread #5: tid = 0xfb0ada, 0x0000000186206c1c libsystem_pthread.dylib`start_wqthread
  thread #6: tid = 0xfb0adb, 0x00000001860d4bc4 libsystem_kernel.dylib`mach_msg_trap + 8, queue = 'com.SkyEye.905541C85D654B539C85DEECF2689651.0x1c0462b00.network'
  thread #7: tid = 0xfb0adc, 0x00000001860d4bc4 libsystem_kernel.dylib`mach_msg_trap + 8, name = 'com.apple.uikit.eventfetch-thread'
  thread #8: tid = 0xfb0ade, 0x00000001860f5c1c libsystem_kernel.dylib`__ulock_wait + 8, queue = 'com.skyeye.analytics.interface.queue'
  thread #9: tid = 0xfb0ae0, 0x00000001860d4bc4 libsystem_kernel.dylib`mach_msg_trap + 8, name = 'com.apple.NSURLConnectionLoader'
  thread #10: tid = 0xfb0ae2, 0x0000000186206c1c libsystem_pthread.dylib`start_wqthread
  • frame variable(简写 fr v)当前调试堆栈的所有参数和临时变量
(lldb) frame variable
(ViewController *) self = 0x0000000149d0aaa0
(SEL) _cmd = "testParam:b:c:d:"
(int) a = 10
(int) b = 20
(int) c = 30
(int) d = 40
(int) ii = 10000
  • register read 返回当前线程通用寄存器的值(对64为对应x0-x31)
 lldb) register read
General Purpose Registers:
        x0 = 0x0000000149d0aaa0
        x1 = 0x0000000104d9dd46  "testParam:b:c:d:"
        x2 = 0x000000000000000a
        x3 = 0x0000000000000014
        x4 = 0x000000000000001e
        x5 = 0x0000000000000028
        x6 = 0x0000000000000000
        x7 = 0x000000016b156808
        x8 = 0x0000000104dd9330  "testParam:b:c:d:"
        x9 = 0x0000000000000000
       x10 = 0x0086860100868680
       x11 = 0x0000000000868601
       x12 = 0x0000000000868500
       x13 = 0x0000000000000001
       x14 = 0x0000000000000000
       x15 = 0x00868601008686c0
       x16 = 0x0000000000000000
       x17 = 0x0000000104cc6cf4  TestPAD`-[ViewController testParam:b:c:d:] at ViewController.m:29
       x18 = 0x0000000000000000
       x19 = 0x00000001b70ab8c0  UIKit`_UIApplicationLinkedOnVersion
       x20 = 0x0000000149d0aaa0
       x21 = 0x0000000000000018
       x22 = 0x0000000190799d6a  "count"
       x23 = 0x0000000000000000
       x24 = 0x0000000000000000
       x25 = 0x000000014a017c00
       x26 = 0x0000000000000408
       x27 = 0x00000001c0099410
       x28 = 0x0000000000000000
        fp = 0x000000016b157f60
        lr = 0x0000000104cc6bbc  TestPAD`-[ViewController viewDidLoad] + 164 at ViewController.m:24
        sp = 0x000000016b157f30
        pc = 0x0000000104cc6d1c  TestPAD`-[ViewController testParam:b:c:d:] + 40 at ViewController.m:31
      cpsr = 0x20000000
  • register read --all(简写 re r -a) 返回当前线程所有寄存器的值(对64位架构,包含x0-x31、s0-s31 d0-d31 v0-v31 w0-w31)
  • thread backtrace(简写 bt)当前线程堆栈回溯信息
(lldb) bt
* thread #1, queue = 'com.apple.main-thread', stop reason = breakpoint 9.1
  * frame #0: 0x0000000104cc6d1c TestPAD`-[ViewController testParam:b:c:d:](self=0x0000000149d0aaa0, _cmd="testParam:b:c:d:", a=10, b=20, c=30, d=40) at ViewController.m:31
    frame #1: 0x0000000104cc6bbc TestPAD`-[ViewController viewDidLoad](self=0x0000000149d0aaa0, _cmd="viewDidLoad") at ViewController.m:24
    frame #2: 0x000000018fa14efc UIKit`-[UIViewController loadViewIfRequired] + 1040
    frame #3: 0x000000018fabc5ec UIKit`-[UINavigationController _updateScrollViewFromViewController:toViewController:] + 76
    frame #4: 0x000000018fabba8c UIKit`-[UINavigationController _startTransition:fromViewController:toViewController:] + 196
    frame #5: 0x000000018fabb490 UIKit`-[UINavigationController _startDeferredTransitionIfNeeded:] + 1168
    frame #6: 0x000000018fabaf0c UIKit`-[UINavigationController __viewWillLayoutSubviews] + 164
    frame #7: 0x000000018fabae0c UIKit`-[UILayoutContainerView layoutSubviews] + 188
    frame #8: 0x000000018fa122f8 UIKit`-[UIView(CALayerDelegate) layoutSublayersOfLayer:] + 1276
    frame #9: 0x000000018a5cbec8 QuartzCore`-[CALayer layoutSublayers] + 184
    frame #10: 0x000000018a5cffa8 QuartzCore`CA::Layer::layout_if_needed(CA::Transaction*) + 332
    frame #11: 0x000000018a53ea98 QuartzCore`CA::Context::commit_transaction(CA::Transaction*) + 336
    frame #12: 0x000000018a564eb4 QuartzCore`CA::Transaction::commit() + 540
    frame #13: 0x000000018fc90174 UIKit`__34-[UIApplication _firstCommitBlock]_block_invoke_2 + 140
    frame #14: 0x00000001865860fc CoreFoundation`__CFRUNLOOP_IS_CALLING_OUT_TO_A_BLOCK__ + 20
    frame #15: 0x00000001865859cc CoreFoundation`__CFRunLoopDoBlocks + 288
    frame #16: 0x00000001865836dc CoreFoundation`__CFRunLoopRun + 1068
    frame #17: 0x00000001864a3fb8 CoreFoundation`CFRunLoopRunSpecific + 436
    frame #18: 0x000000018833bf84 GraphicsServices`GSEventRunModal + 100
    frame #19: 0x000000018fa782e8 UIKit`UIApplicationMain + 208
    frame #20: 0x0000000104cd5d14 TestPAD`main(argc=1, argv=0x000000016b15b9c8) at main.m:14
    frame #21: 0x0000000185fc656c libdyld.dylib`start + 4
  • thread backtrace all(简写bt all)所有线程堆栈回溯信息
  • memory read (简写x)以给定格式读取给定内存地址数据
    (1)比如以字符串读取x1寄存器的值
(lldb) memory read -f s $x1
或者
(lldb) x -f s $x1
或者
(lldb) x/s $x1
输出为:
0x104d9dd46: "testParam:b:c:d:"

(2)读取栈中所有值,即sp和fp连续内存区域值。

(lldb) x -f A $sp $fp

(3) 读取目标内存指令,比如x/10xg sp 。10后面的x代表用16进制来显示结果,g代表giant word(8字节)大小。所以x/10xgsp就是用16进制显示栈区10个64位元素内容。常见的大小格式为"b-byte"(1字节) "h-half word"(2字节) "w-word"(4字节) "g-giant word"(8字节)

  • disassemble --frame(简写di -f)将当前frame的当前函数转为汇编代码
  • disassemble --name "函数名字"(简写di -n )将当前frame的指定的函数转为汇编代码
(lldb)  di -n "-[ViewController testParam:b:c:d:]"

TestPAD`-[ViewController testParam:b:c:d:]:
    0x104cc6cf4 <+0>:   sub    sp, sp, #0x40             ; =0x40 
    0x104cc6cf8 <+4>:   stp    x29, x30, [sp, #0x30]
    0x104cc6cfc <+8>:   add    x29, sp, #0x30            ; =0x30 
    0x104cc6d00 <+12>:  stur   x0, [x29, #-0x8]
    0x104cc6d04 <+16>:  stur   x1, [x29, #-0x10]
    0x104cc6d08 <+20>:  stur   w2, [x29, #-0x14]
    0x104cc6d0c <+24>:  str    w3, [sp, #0x18]
    0x104cc6d10 <+28>:  str    w4, [sp, #0x14]
    0x104cc6d14 <+32>:  str    w5, [sp, #0x10]
    0x104cc6d18 <+36>:  str    wzr, [sp, #0xc]
->  0x104cc6d1c <+40>:  ldur   w2, [x29, #-0x14]
    0x104cc6d20 <+44>:  ldr    w3, [sp, #0xc]
    0x104cc6d24 <+48>:  add    w2, w3, w2
    0x104cc6d28 <+52>:  str    w2, [sp, #0xc]
    0x104cc6d2c <+56>:  ldr    w2, [sp, #0x18]
    0x104cc6d30 <+60>:  ldr    w3, [sp, #0xc]
    0x104cc6d34 <+64>:  add    w2, w3, w2
    0x104cc6d38 <+68>:  str    w2, [sp, #0xc]
    0x104cc6d3c <+72>:  ldr    w2, [sp, #0x14]
    0x104cc6d40 <+76>:  ldr    w3, [sp, #0xc]
    0x104cc6d44 <+80>:  add    w2, w3, w2
    0x104cc6d48 <+84>:  str    w2, [sp, #0xc]
    0x104cc6d4c <+88>:  ldr    w2, [sp, #0x10]
    0x104cc6d50 <+92>:  ldr    w3, [sp, #0xc]
    0x104cc6d54 <+96>:  add    w2, w3, w2
    0x104cc6d58 <+100>: str    w2, [sp, #0xc]
    0x104cc6d5c <+104>: ldr    w2, [sp, #0xc]
    0x104cc6d60 <+108>: mov    x0, x2
    0x104cc6d64 <+112>: mov    x1, sp
    0x104cc6d68 <+116>: str    x0, [x1]
    0x104cc6d6c <+120>: adrp   x0, 249
    0x104cc6d70 <+124>: add    x0, x0, #0xc68            ; =0xc68 
    0x104cc6d74 <+128>: bl     0x104d9a9b4               ; symbol stub for: NSLog
    0x104cc6d78 <+132>: ldp    x29, x30, [sp, #0x30]
    0x104cc6d7c <+136>: add    sp, sp, #0x40             ; =0x40 
    0x104cc6d80 <+140>: ret    

4.Match-O可执行文件及Shared库查询命令

  • image list(简写im li) 列举所有可执行文件和系统库信息
(lldb) image list -o -f "TestPAD"
[  0] 0x0000000004ca4000 /Users/shiguiling063/Library/Developer/Xcode/DerivedData/TestPAD-bpwpvzedhypusjgfujyksktehppj/Build/Products/Debug-iphoneos/TestPAD.app/TestPAD
  • image lookup -r -n <FUNC_REGEX> 从debug符号标中正则匹配函数
(lldb) image  lookup -r -n "testParam"
或者
(lldb) im  loo -r -n "testParam"
2 matches found in /Users/shiguiling063/Library/Developer/Xcode/DerivedData/TestPAD-bpwpvzedhypusjgfujyksktehppj/Build/Products/Debug-iphoneos/TestPAD.app/TestPAD:
        Address: TestPAD[0x0000000100022cf4] (TestPAD.__TEXT.__text + 118184)
        Summary: TestPAD`-[ViewController testParam:b:c:d:] at ViewController.m:29        Address: TestPAD[0x0000000100022cf4] (TestPAD.__TEXT.__text + 118184)
        Summary: TestPAD`-[ViewController testParam:b:c:d:] at ViewController.m:29
  • image lookup --type "定义名称" 查找定义
(lldb)  image lookup --type ViewController
或者
(lldb) im loo -t ViewController
Best match found in /Users/shiguiling063/Library/Developer/Xcode/DerivedData/TestPAD-bpwpvzedhypusjgfujyksktehppj/Build/Products/Debug-iphoneos/TestPAD.app/TestPAD:
id = {0xb00000042}, name = "ViewController", byte-size = 16, decl = ViewController.h:11, compiler_type = "@interface ViewController : UITableViewController{
    NSArray * _dataArr;
}
@property ( getter = dataArr,setter = setDataArr:,readwrite,copy,nonatomic ) NSArray * dataArr;
@end"
  • image dump symtab -m "模块名" Dump出给定模块的所有符号
    比如需要Dump出测试工程TestPAD所有的符号(如果不指定模块名,会Dump出所有符号,包扩系统库的,会比较耗时)
(lldb)  image dump symtab -m TestPAD
Symtab, file = /Users/shiguiling063/Library/Developer/Xcode/DerivedData/TestPAD-bpwpvzedhypusjgfujyksktehppj/Build/Products/Debug-iphoneos/TestPAD.app/TestPAD, num_symbols = 4121:
               Debug symbol
               |Synthetic symbol
               ||Externally Visible
               |||
Index   UserID DSX Type            File Address/Value Load Address       Size               Flags      Name
------- ------ --- --------------- ------------------ ------------------ ------------------ ---------- ----------------------------------
[    0]      0 D   SourceFile      0x0000000000000000                    Sibling -> [   19] 0x00640000 /Users/shiguiling063/Downloads/越狱开发相关/TestPADSource/TestPAD/PAD/PADSource/TalkingData/SkyEyeData/Codeless/SEObjectSerializer.m
[    1]      2 D   ObjectFile      0x000000005b55a875                    0x0000000000000000 0x00660001 /Users/shiguiling063/Library/Developer/Xcode/DerivedData/TestPAD-bpwpvzedhypusjgfujyksktehppj/Build/Intermediates.noindex/TestPAD.build/Debug-iphoneos/TestPAD.build/Objects-normal/arm64/SEObjectSerializer.o
[    2]      4 D   Code            0x0000000100006028                    0x0000000000000140 0x000e0000 -[SEObjectSerializer initWithConfiguration:objectIdentityProvider:]
[    3]      8 D   Code            0x0000000100006168                    0x000000000000035c 0x000e0000 -[SEObjectSerializer serializedObjectsWithRootObject:]
[    4]     12 D   Code            0x00000001000064c4                    0x0000000000000c00 0x000e0000 -[SEObjectSerializer visitObject:withContext:]
[    5]     16 D   Code            0x00000001000070c4                    0x0000000000000120 0x000e0000 -[SEObjectSerializer classHierarchyArrayForObject:]
[    6]     20 D   Code            0x00000001000071e4                    0x000000000000027c 0x000e0000 -[SEObjectSerializer allValuesForType:]
[    7]     24 D   Code            0x0000000100007460                    0x000000000000053c 0x000e0000 -[SEObjectSerializer parameterVariationsForPropertySelector:]
[    8]     28 D   Code            0x000000010000799c                    0x0000000000000968 0x000e0000 -[SEObjectSerializer instanceVariableValueForObject:propertyDescription:]
[    9]     32 D   Code            0x0000000100008304                    0x000000000000040c 0x000e0000 -[SEObjectSerializer invocationForObject:withSelectorDescription:]
[   10]     36 D   Code            0x0000000100008710                    0x0000000000000578 0x000e0000 -[SEObjectSerializer propertyValue:propertyDescription:context:]
[   11]     40 D   Code            0x0000000100008c88                    0x000000000000099c 0x000e0000 -[SEObjectSerializer propertyValueForObject:withPropertyDescription:context:]
[   12]     44 D   Code            0x0000000100009624                    0x000000000000009c 0x000e0000 -[SEObjectSerializer isNestedObjectType:]
[   13]     48 D   Code            0x00000001000096c0                    0x0000000000000264 0x000e0000 -[SEObjectSerializer classDescriptionForObject:]
[   14]     52 D   Code            0x0000000100009924                    0x0000000000000070 0x000e0000 -[SEObjectSerializer .cxx_destruct]
[   15]     55 D X ObjCIVar        0x00000001001372f0                    0x0000000000000004 0x001e0000 

5.Script & Chisel

LLDB 有内建的,完整的 Python支持。在LLDB中输入 script,会打开一个 Python REPL。你也可以输入一行 python 语句作为 script 命令的参数,这可以运行 python 语句而不进入REPL

(lldb) script print 'Hello World'
Hello World

Facebook开源的Chisel就是基于此实现
Facebook通过python脚本扩展和丰富了lldb命令,具体以Chisel文档为准

Chisel 扩展LLDB命令

6. watchpoint命令

  • Set a watchpoint on a variable when it is written to
(lldb) watchpoint set variable global_var
或者
(lldb) wa s v global_var
  • 根据内存地址设置watchpoint
(lldb) watchpoint set expression -- my_ptr
或者
(lldb) wa s e -- my_ptr
  • 满足条件触发watchpoint
(lldb) watch set var global
(lldb) watchpoint modify -c '(global==5)'
(lldb) c
  • 列举所有watchpoint
(lldb) watchpoint list
或者
(lldb) watch l
  • 删除watchpoint
(lldb) watchpoint delete 1
或者
(lldb) watch del 1

7.其他命令补充

  • register write 将值写回寄存器
    将当前pc寄存器后移8字节
(lldb) register write pc `$pc+8`
  • target stop-hook 仅在触发watchpoint和断点的情况下才会触发stop-hook
    以下命令添加一个stop-hook命令,触发了watchpoint或者断点后,通过frame variable命令输出当前frame所有变量和临时变量
(lldb)  target stop-hook add --one-liner "frame variable"

8.更多

更多LLDB命令请参照LLDB官网公布资料:http://lldb.llvm.org/lldb-gdb.html

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,772评论 6 477
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,458评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,610评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,640评论 1 276
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,657评论 5 365
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,590评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,962评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,631评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,870评论 1 297
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,611评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,704评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,386评论 4 319
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,969评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,944评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,179评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 44,742评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,440评论 2 342

推荐阅读更多精彩内容

  • 一、概述 LLDB全称 [ Low Level Debugger ], 默认内置于Xcode中的动态调试工具。标准...
    Superman168阅读 15,168评论 2 19
  • 你是否曾经苦恼于理解你的代码,而去尝试打印一个变量的值? NSLog(@"%@", whatIsInsideThi...
    F麦子阅读 1,249评论 1 2
  • 转载 与调试器共舞 - LLDB 的华尔兹: https://objccn.io/issue-19-2/ 推荐:i...
    F麦子阅读 3,325评论 0 10
  • 前言 今天花了一天的时间终于把iOS的几种常见的调试方法给学习了一下,在这里给大家分享一下LLDB的使用,同时也是...
    Peak_One阅读 10,991评论 5 33
  • 你是否曾经苦恼于理解你的代码,而去尝试打印一个变量的值? NSLog(@"%@", whatIsInsideThi...
    paraneaeee阅读 1,176评论 0 7