文档章节

配合LLDB调试器进行iOS代码调试

法斗斗
 法斗斗
发布于 2016/05/20 11:17
字数 3390
阅读 341
收藏 0
点赞 2
评论 0

配合LLDB调试器进行iOS代码调试

 

配合LLDB调试器进行iOS代码调试

        在一款完整iOS移动应用的开发中,代码的调试和编写占着同等重要的地位。Xcode默认使用LLDB作为代码调试器,LLDB功能丰富且强大,恰当的使用它,可以帮助开发者事半功倍的完成代码调试的工作。

1.expression代码执行指令

        关于LLDB调试器,最常用的指令应该是p与po了,开发者常用这两个命令来进行对象的打印操作,p会打印出对象地址和类型,po则会额外打印出对象的值得内容,实际上,这两个命令都是expression相关命令的简写。expression命令也并非简单的打印命令,实际上它是一个执行代码命令,执行后将返回值进行打印,这个命令有一个十分强大的特点,它可以真实改变程序运行中变量的值。例如在如下代码中的int c = a+b 一行添加一个断点,运行工程。

    int a = 0;
    int b = 1;
    int c = a+b;
    NSLog(@"%d",c);

如果开发者不进行任何认为操作,此时打印出的值应该是1,为了测试,可以在调试区输入如下命令:

(lldb) expression a=1

此后跳过断点继续运行程序,可以看到打印的结果如下,c变成2。

(lldb) expression a=1
(int) $0 = 1
2016-04-24 11:39:40.213 BreakPointTest[1010:79065] 2

通过上面的演示,我们发现使用LLDB调试代码十分方便的一个特点,当我们知道程序某个地方可能会出现问题,为了找到解决方法,不使用LLDB时我们可能需要在代码中添加大量的打印函数,并且多次尝试修改源代码才能解决问题,如果使用LLDB的expression命令,我们不仅不需要添加额外的打印代码,也不需要直接修改源代码,在调试区进行多次调试,直到找到正确的修改方法后再对源代码修改一次即可。

2.frame代码堆栈块信息相关指令

      当Xcode进入断点调试或者遇到异常程序崩溃时,在Xcode左侧的导航区都会将程序运行中的相关堆栈块信息列举出来,例如使用如下测试代码,在text方法中的int c = a+b 一行添加一个断点。

#import "ViewController.h"
@interface ViewController ()
{
    int ab;
}
@end
@implementation ViewController
- (void)viewDidLoad {
    [super viewDidLoad];
    ab = 1;
    [self test];  
}
-(void)test{
    int a = 0;
    int b = 1;
    int c = a+b;
    NSLog(@"%d",c);
}
@end

当程序运行到断点处断开时,Xcode左侧的堆栈块如下图所示:

从图中可以看出,程序当前处于激活状态的线程有5个,程序目前断在线程1中的test方法堆栈块中,使用frame info指令可以打印当前堆栈块的信息,示例如下:

(lldb) frame info
frame #0: 0x0000000102497905 BreakPointTest`-[ViewController test](self=0x00007fcd5b413320, _cmd="test") + 37 at ViewController.m:39

在打印的信息中,会有所在的文件名称和函数名称及堆栈块标号和内存地址。

      在实际代码调试过程中,程序运行的回溯是一个重要的方法,例如上面的代码例子,虽然现在断点断在test方法中,开发者可能需要在viewDidLoad方法中进行相关调试,例如上面viewDidLoad方法中有一个变量ab,如果想查看ab变量的值,我们就需要将当前选中调试的堆栈块选择为viewDidLoad方法所在的堆栈块,从Xcode左侧导航区可以看到,viewDidLoad方法堆栈块的标号为1,执行如下LLDB指令即可切换:

(lldb) frame select 1
frame #1: 0x00000001024978cb BreakPointTest`-[ViewController viewDidLoad](self=0x00007fcd5b413320, _cmd="viewDidLoad") + 91 at ViewController.m:31
   28  	    int a = 0;
   29  	    int b = 1;
   30  	    int c = a+b;
-> 31  	    NSLog(@"%d",c);
   32  	}
   33  	@end

从打印信息可以看到,现在选中的调试堆栈块已经切换到viewDidLoad方法,再使用expression指令时就可以操作这个方法中的相关变量了。

      在使用LLDB工具前,遇到这样的情况,我往往会采用打多个断点,一步步追溯代码的运行过程并检查过程中变量的值是否正确,调试起来并不十分方便,如果不小心错过了某个断点,又要重新开始,通过选择调试的frame堆栈块可以十分方便的解决这个问题。

      与frame相关的还有一个指令十分有用,下面的指令可以打印出当前堆栈块中所有对象的内容:

(lldb) frame variable
(ViewController *) self = 0x00007fcd5b413320
(SEL) _cmd = "test"
(int) a = 0
(int) b = 1
(int) c = 0

variable后面也可以添加参数名来打印特定对象的内容:

(lldb) frame variable a
(int) a = 0

3.thread线程操作相关指令

      上面提到过,程序运行中会有多个激活的线程,每个线程中又有许多堆栈块,frame相关指令用于综合调试各个堆栈块,thread指令则是用于综合调试各个线程。首先Xcode左侧导航区为我们列出的线程堆栈块并不是当前线程中的所有堆栈块,使用如下命令可以打印出当前线程的所有堆栈块:

(lldb) thread backtrace
* thread #1: tid = 0x152f8, 0x0000000102497905 BreakPointTest`-[ViewController test](self=0x00007fcd5b413320, _cmd="test") + 37 at ViewController.m:39, queue = 'com.apple.main-thread', stop reason = breakpoint 2.1
  * frame #0: 0x0000000102497905 BreakPointTest`-[ViewController test](self=0x00007fcd5b413320, _cmd="test") + 37 at ViewController.m:39
    frame #1: 0x00000001024978cb BreakPointTest`-[ViewController viewDidLoad](self=0x00007fcd5b413320, _cmd="viewDidLoad") + 91 at ViewController.m:31
    frame #2: 0x0000000103475984 UIKit`-[UIViewController loadViewIfRequired] + 1198
    frame #3: 0x0000000103475cd3 UIKit`-[UIViewController view] + 27
    frame #4: 0x000000010334bfb4 UIKit`-[UIWindow addRootViewControllerViewIfPossible] + 61
    frame #5: 0x000000010334c69d UIKit`-[UIWindow _setHidden:forced:] + 282
    frame #6: 0x000000010335e180 UIKit`-[UIWindow makeKeyAndVisible] + 42
    frame #7: 0x00000001032d2ed9 UIKit`-[UIApplication _callInitializationDelegatesForMainScene:transitionContext:] + 4131
    frame #8: 0x00000001032d9568 UIKit`-[UIApplication _runWithMainScene:transitionContext:completion:] + 1769
    frame #9: 0x00000001032d6714 UIKit`-[UIApplication workspaceDidEndTransaction:] + 188
    frame #10: 0x0000000105d438c8 FrontBoardServices`__FBSSERIALQUEUE_IS_CALLING_OUT_TO_A_BLOCK__ + 24
    frame #11: 0x0000000105d43741 FrontBoardServices`-[FBSSerialQueue _performNext] + 178
    frame #12: 0x0000000105d43aca FrontBoardServices`-[FBSSerialQueue _performNextFromRunLoopSource] + 45
    frame #13: 0x0000000102e4a301 CoreFoundation`__CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE0_PERFORM_FUNCTION__ + 17
    frame #14: 0x0000000102e4022c CoreFoundation`__CFRunLoopDoSources0 + 556
    frame #15: 0x0000000102e3f6e3 CoreFoundation`__CFRunLoopRun + 867
    frame #16: 0x0000000102e3f0f8 CoreFoundation`CFRunLoopRunSpecific + 488
    frame #17: 0x00000001032d5f21 UIKit`-[UIApplication _run] + 402
    frame #18: 0x00000001032daf09 UIKit`UIApplicationMain + 171
    frame #19: 0x0000000102497c3f BreakPointTest`main(argc=1, argv=0x00007fff5d768668) + 111 at main.m:14
    frame #20: 0x00000001056fe92d libdyld.dylib`start + 1
    frame #21: 0x00000001056fe92d libdyld.dylib`start + 1

thread list指令则可以打印出当前所有激活的线程,如下:

(lldb) thread list
Process 1049 stopped
* thread #1: tid = 0x152f8, 0x0000000102497905 BreakPointTest`-[ViewController test](self=0x00007fcd5b413320, _cmd="test") + 37 at ViewController.m:39, queue = 'com.apple.main-thread', stop reason = breakpoint 2.1
  thread #2: tid = 0x1531b, 0x0000000105a43ee2 libsystem_kernel.dylib`kevent64 + 10, queue = 'com.apple.libdispatch-manager'
  thread #3: tid = 0x1531c, 0x0000000105a435e2 libsystem_kernel.dylib`__workq_kernreturn + 10
  thread #4: tid = 0x15324, 0x0000000105a435e2 libsystem_kernel.dylib`__workq_kernreturn + 10
  thread #5: tid = 0x15328, 0x0000000105a435e2 libsystem_kernel.dylib`__workq_kernreturn + 10

thread info可以打印出当前选中调试的线程的信息:

(lldb) thread info
thread #1: tid = 0x152f8, 0x0000000102497905 BreakPointTest`-[ViewController test](self=0x00007fcd5b413320, _cmd="test") + 37 at ViewController.m:39, queue = 'com.apple.main-thread', stop reason = breakpoint 2.1

同样也可以使用thread select指令来切换选中调试的线程:

(lldb) thread select 2

thread continue指令用于继续执行当前的线程:

(lldb) thread continue
2016-04-24 12:29:54.562 BreakPointTest[1049:86776] 1
Resuming thread 0x152f8 in process 1049
Process 1049 resuming

4.disassemble代码反汇编相关指令

      disassemble相关指令用于输出某段程序的汇编代码,执行disassemble指令将会反汇编当前函数:

BreakPointTest`-[ViewController test]:
    0x10aab7940 <+0>:  pushq  %rbp
    0x10aab7941 <+1>:  movq   %rsp, %rbp
    0x10aab7944 <+4>:  subq   $0x20, %rsp
    0x10aab7948 <+8>:  leaq   0x1711(%rip), %rax        ; @"%d"
    0x10aab794f <+15>: movq   %rdi, -0x8(%rbp)
    0x10aab7953 <+19>: movq   %rsi, -0x10(%rbp)
    0x10aab7957 <+23>: movl   $0x0, -0x14(%rbp)
    0x10aab795e <+30>: movl   $0x1, -0x18(%rbp)
->  0x10aab7965 <+37>: movl   -0x14(%rbp), %ecx
    0x10aab7968 <+40>: addl   -0x18(%rbp), %ecx
    0x10aab796b <+43>: movl   %ecx, -0x1c(%rbp)
    0x10aab796e <+46>: movl   -0x1c(%rbp), %esi
    0x10aab7971 <+49>: movq   %rax, %rdi
    0x10aab7974 <+52>: movb   $0x0, %al
    0x10aab7976 <+54>: callq  0x10aab7c80               ; symbol stub for: NSLog
    0x10aab797b <+59>: addq   $0x20, %rsp
    0x10aab797f <+63>: popq   %rbp
    0x10aab7980 <+64>: retq

     使用disassemble -b则会输出带字节信息的汇编代码:

(lldb) disassemble -b
BreakPointTest`-[ViewController test]:
    0x10aab7940 <+0>:  55                    pushq  %rbp
    0x10aab7941 <+1>:  48 89 e5              movq   %rsp, %rbp
    0x10aab7944 <+4>:  48 83 ec 20           subq   $0x20, %rsp
    0x10aab7948 <+8>:  48 8d 05 11 17 00 00  leaq   0x1711(%rip), %rax        ; @"%d"
    0x10aab794f <+15>: 48 89 7d f8           movq   %rdi, -0x8(%rbp)
    0x10aab7953 <+19>: 48 89 75 f0           movq   %rsi, -0x10(%rbp)
    0x10aab7957 <+23>: c7 45 ec 00 00 00 00  movl   $0x0, -0x14(%rbp)
    0x10aab795e <+30>: c7 45 e8 01 00 00 00  movl   $0x1, -0x18(%rbp)
->  0x10aab7965 <+37>: 8b 4d ec              movl   -0x14(%rbp), %ecx
    0x10aab7968 <+40>: 03 4d e8              addl   -0x18(%rbp), %ecx
    0x10aab796b <+43>: 89 4d e4              movl   %ecx, -0x1c(%rbp)
    0x10aab796e <+46>: 8b 75 e4              movl   -0x1c(%rbp), %esi
    0x10aab7971 <+49>: 48 89 c7              movq   %rax, %rdi
    0x10aab7974 <+52>: b0 00                 movb   $0x0, %al
    0x10aab7976 <+54>: e8 05 03 00 00        callq  0x10aab7c80               ; symbol stub for: NSLog
    0x10aab797b <+59>: 48 83 c4 20           addq   $0x20, %rsp
    0x10aab797f <+63>: 5d                    popq   %rbp
    0x10aab7980 <+64>: c3                    retq

      使用disassemble -c 指令可以设置输出汇编代码的行数,如下:

(lldb) disassemble -c 5
BreakPointTest`-[ViewController test]:
    0x10aab7940 <+0>:  pushq  %rbp
    0x10aab7941 <+1>:  movq   %rsp, %rbp
    0x10aab7944 <+4>:  subq   $0x20, %rsp
    0x10aab7948 <+8>:  leaq   0x1711(%rip), %rax        ; @"%d"
    0x10aab794f <+15>: movq   %rdi, -0x8(%rbp)

      使用disassemble -l只输出当前断点处汇编代码:

BreakPointTest`-[ViewController test] + 37 at ViewController.m:30
   29  	    int b = 1;
-> 30  	    int c = a+b;
   31  	    NSLog(@"%d",c);
BreakPointTest`-[ViewController test]:
->  0x10aab7965 <+37>: movl   -0x14(%rbp), %ecx

      使用disassemble -m混合显示汇编代码:

(lldb) disassemble -m
BreakPointTest`-[ViewController test] at ViewController.m:27
   26  	}
   27  	-(void)test{
   28  	    int a = 0;
BreakPointTest`-[ViewController test]:
    0x10aab7940 <+0>:  pushq  %rbp
    0x10aab7941 <+1>:  movq   %rsp, %rbp
    0x10aab7944 <+4>:  subq   $0x20, %rsp
    0x10aab7948 <+8>:  leaq   0x1711(%rip), %rax        ; @"%d"
    0x10aab794f <+15>: movq   %rdi, -0x8(%rbp)
    0x10aab7953 <+19>: movq   %rsi, -0x10(%rbp)
BreakPointTest`-[ViewController test] + 23 at ViewController.m:28
   27  	-(void)test{
   28  	    int a = 0;
   29  	    int b = 1;
    0x10aab7957 <+23>: movl   $0x0, -0x14(%rbp)
BreakPointTest`-[ViewController test] + 30 at ViewController.m:29
   28  	    int a = 0;
   29  	    int b = 1;
   30  	    int c = a+b;
    0x10aab795e <+30>: movl   $0x1, -0x18(%rbp)
BreakPointTest`-[ViewController test] + 37 at ViewController.m:30
   29  	    int b = 1;
-> 30  	    int c = a+b;
   31  	    NSLog(@"%d",c);
->  0x10aab7965 <+37>: movl   -0x14(%rbp), %ecx
BreakPointTest`-[ViewController test] + 40 at ViewController.m:30
   29  	    int b = 1;
   30  	    int c = a+b;
   31  	    NSLog(@"%d",c);
    0x10aab7968 <+40>: addl   -0x18(%rbp), %ecx
BreakPointTest`-[ViewController test] + 43 at ViewController.m:30
   29  	    int b = 1;
   30  	    int c = a+b;
   31  	    NSLog(@"%d",c);
    0x10aab796b <+43>: movl   %ecx, -0x1c(%rbp)
BreakPointTest`-[ViewController test] + 46 at ViewController.m:31
   30  	    int c = a+b;
   31  	    NSLog(@"%d",c);
   32  	}
    0x10aab796e <+46>: movl   -0x1c(%rbp), %esi
BreakPointTest`-[ViewController test] + 49 at ViewController.m:31
   30  	    int c = a+b;
   31  	    NSLog(@"%d",c);
   32  	}
    0x10aab7971 <+49>: movq   %rax, %rdi
    0x10aab7974 <+52>: movb   $0x0, %al
    0x10aab7976 <+54>: callq  0x10aab7c80               ; symbol stub for: NSLog
BreakPointTest`-[ViewController test] + 59 at ViewController.m:32
   31  	    NSLog(@"%d",c);
   32  	}
   33  	@end
    0x10aab797b <+59>: addq   $0x20, %rsp
    0x10aab797f <+63>: popq   %rbp
    0x10aab7980 <+64>: retq

      使用disassemble -p进行当前行的汇编代码输出:

(lldb) disassemble -p
BreakPointTest`-[ViewController test]:
->  0x10aab7965 <+37>: movl   -0x14(%rbp), %ecx
    0x10aab7968 <+40>: addl   -0x18(%rbp), %ecx
    0x10aab796b <+43>: movl   %ecx, -0x1c(%rbp)
    0x10aab796e <+46>: movl   -0x1c(%rbp), %esi

5.其他LLDB常用指令

        bt指令用于打印当前线程所有堆栈块信息:

(lldb) bt
* thread #1: tid = 0x19f11, 0x000000010aab7965 BreakPointTest`-[ViewController test](self=0x00007fee9c11e330, _cmd="test") + 37 at ViewController.m:30, queue = 'com.apple.main-thread', stop reason = breakpoint 2.1
  * frame #0: 0x000000010aab7965 BreakPointTest`-[ViewController test](self=0x00007fee9c11e330, _cmd="test") + 37 at ViewController.m:30
    frame #1: 0x000000010aab792b BreakPointTest`-[ViewController viewDidLoad](self=0x00007fee9c11e330, _cmd="viewDidLoad") + 91 at ViewController.m:22
    frame #2: 0x000000010ba95984 UIKit`-[UIViewController loadViewIfRequired] + 1198
    frame #3: 0x000000010ba95cd3 UIKit`-[UIViewController view] + 27
    frame #4: 0x000000010b96bfb4 UIKit`-[UIWindow addRootViewControllerViewIfPossible] + 61
    frame #5: 0x000000010b96c69d UIKit`-[UIWindow _setHidden:forced:] + 282
    frame #6: 0x000000010b97e180 UIKit`-[UIWindow makeKeyAndVisible] + 42
    frame #7: 0x000000010b8f2ed9 UIKit`-[UIApplication _callInitializationDelegatesForMainScene:transitionContext:] + 4131
    frame #8: 0x000000010b8f9568 UIKit`-[UIApplication _runWithMainScene:transitionContext:completion:] + 1769
    frame #9: 0x000000010b8f6714 UIKit`-[UIApplication workspaceDidEndTransaction:] + 188
    frame #10: 0x000000010e3638c8 FrontBoardServices`__FBSSERIALQUEUE_IS_CALLING_OUT_TO_A_BLOCK__ + 24
    frame #11: 0x000000010e363741 FrontBoardServices`-[FBSSerialQueue _performNext] + 178
    frame #12: 0x000000010e363aca FrontBoardServices`-[FBSSerialQueue _performNextFromRunLoopSource] + 45
    frame #13: 0x000000010b46a301 CoreFoundation`__CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE0_PERFORM_FUNCTION__ + 17
    frame #14: 0x000000010b46022c CoreFoundation`__CFRunLoopDoSources0 + 556
    frame #15: 0x000000010b45f6e3 CoreFoundation`__CFRunLoopRun + 867
    frame #16: 0x000000010b45f0f8 CoreFoundation`CFRunLoopRunSpecific + 488
    frame #17: 0x000000010b8f5f21 UIKit`-[UIApplication _run] + 402
    frame #18: 0x000000010b8faf09 UIKit`UIApplicationMain + 171
    frame #19: 0x000000010aab7c5f BreakPointTest`main(argc=1, argv=0x00007fff55148668) + 111 at main.m:14
    frame #20: 0x000000010dd1e92d libdyld.dylib`start + 1
    frame #21: 0x000000010dd1e92d libdyld.dylib`start + 1

 

  c指令继续运行线程process continue效果一样。

        call指令运行一个表达式, expression 效果一样。

        detach指令结束当前调试的线程。

        di指令反汇编当前函数disassemble相同。

        exit指令退出lldb调试器。

        finish指令完成当前堆栈块的调试,程序会继续运行。

        n指令进行单步调试,next作用一样。

        p指令expression作用一样。

        print指令用于变量的打印。

        r指令重新运行应用程序。

        quit指令结束调试。

        bugreport指令用于创建堆栈信息报告。

        command history指令用于打印LLDB调试命令记录。

        help指令用于查询LLDB相关调试指令的用法。

        apropo指令用于查询某些包含某些关键字的指令。

        version指令用于查询LLDB调试器的版本,如下:

(lldb) version
lldb-350.0.21.3

        image list命令用于打印工程中所有用到的库文件。

       image相关指令还有一个十分有用的命令,image lookup --address可以查询某个内存地址的内容,如下:

(lldb) image lookup --address 0x000000010373e885
      Address: CoreFoundation[0x00000000000f4885] (CoreFoundation.__TEXT.__text + 996309)
      Summary: CoreFoundation`-[__NSArray0 objectAtIndex:] + 101

        image lookup --type用于查询某种类型中包含的属性,如下:

(lldb) image lookup --type UILabel
Best match found in /Users/vip/Library/Developer/Xcode/DerivedData/BreakPointTest-cearqrjqbntqcnfgiqzpxhyadewi/Build/Products/Debug-iphonesimulator/BreakPointTest.app/BreakPointTest:
id = {0x000082c1}, name = "UILabel", byte-size = 8, decl = UILabel.h:18, compiler_type = "@interface UILabel : UIView
@property ( getter = text,setter = setText:,readwrite,copy,nonatomic ) NSString * text;
@property ( getter = font,setter = setFont:,readwrite,nonatomic ) UIFont * font;
@property ( getter = textColor,setter = setTextColor:,readwrite,nonatomic ) UIColor * textColor;
@property ( getter = shadowColor,setter = setShadowColor:,readwrite,nonatomic ) UIColor * shadowColor;
@property ( getter = shadowOffset,setter = setShadowOffset:,assign,readwrite,nonatomic ) CGSize shadowOffset;
@property ( getter = textAlignment,setter = setTextAlignment:,assign,readwrite,nonatomic ) NSTextAlignment textAlignment;
@property ( getter = lineBreakMode,setter = setLineBreakMode:,assign,readwrite,nonatomic ) NSLineBreakMode lineBreakMode;
@property ( getter = attributedText,setter = setAttributedText:,readwrite,copy,nonatomic ) NSAttributedString * attributedText;
@property ( getter = highlightedTextColor,setter = setHighlightedTextColor:,readwrite,nonatomic ) UIColor * highlightedTextColor;
@property ( getter = isHighlighted,setter = setHighlighted:,assign,readwrite,nonatomic ) BOOL highlighted;
@property ( getter = isUserInteractionEnabled,setter = setUserInteractionEnabled:,assign,readwrite,nonatomic ) BOOL userInteractionEnabled;
@property ( getter = isEnabled,setter = setEnabled:,assign,readwrite,nonatomic ) BOOL enabled;
@property ( getter = numberOfLines,setter = setNumberOfLines:,assign,readwrite,nonatomic ) NSInteger numberOfLines;
@property ( getter = adjustsFontSizeToFitWidth,setter = setAdjustsFontSizeToFitWidth:,assign,readwrite,nonatomic ) BOOL adjustsFontSizeToFitWidth;
@property ( getter = baselineAdjustment,setter = setBaselineAdjustment:,assign,readwrite,nonatomic ) UIBaselineAdjustment baselineAdjustment;
@property ( getter = minimumScaleFactor,setter = setMinimumScaleFactor:,assign,readwrite,nonatomic ) CGFloat minimumScaleFactor;
@property ( getter = allowsDefaultTighteningForTruncation,setter = setAllowsDefaultTighteningForTruncation:,assign,readwrite,nonatomic ) BOOL allowsDefaultTighteningForTruncation;
@property ( getter = preferredMaxLayoutWidth,setter = setPreferredMaxLayoutWidth:,assign,readwrite,nonatomic ) CGFloat preferredMaxLayoutWidth;
@property ( getter = minimumFontSize,setter = setMinimumFontSize:,assign,readwrite,nonatomic ) CGFloat minimumFontSize;
@property ( getter = adjustsLetterSpacingToFitWidth,setter = setAdjustsLetterSpacingToFitWidth:,assign,readwrite,nonatomic ) BOOL adjustsLetterSpacingToFitWidth;
@end"

       x指令可以读取某段内存的二进制数据:

(lldb) x 0x000000010373e885
0x10373e885: 66 66 2e 0f 1f 84 00 00 00 00 00 55 48 89 e5 48  ff.........UH..H
0x10373e895: 8d 3d 6d f2 28 00 e8 c0 d9 f0 ff 48 89 05 c1 58  .=m.(......H...X

 

        LLDB的用法和技巧还有很多,它可以大大提高我们调试代码的效率,有疏漏和错误之处,还望与志同道合的朋友共同学习进步。

© 著作权归作者所有

共有 人打赏支持
法斗斗
粉丝 20
博文 336
码字总数 6335
作品 0
杨浦
程序员
如何在Electra越狱的设备上使用LLDB调试应用程序

        在3月18日的时候,我就曾发表过一篇关于在Electra越狱的设备上使用LLDB调试应用程序的文章。本文我将在此基础上,做进一步的更新优化。   我试图在google搜索,有关使用Ele...

FreeBuf ⋅ 05/29 ⋅ 0

如何做好iOS应用安全?这有一把行之有效的“三板斧”

本文由 网易云 发布 iOS应用面临很多破解问题,常见的有IAP内购破解、山寨版本、破解版本等;大众应用上,微信抢红包、微信多开等;而在iOS游戏上,越来越泛滥的外挂问题也不断困扰着游戏厂商...

wangyiyungw ⋅ 05/15 ⋅ 0

移动应用开源调试平台Sonar

Sonar是Facebook开源的移动应用Debug平台, 支持iOS 和 Android的应用程序,并可使用插件 API 进行扩展。 Sonar 由两部分组成:桌面客户端和移动 SDK。 Sonar 使用者与桌面客户端进行交互,而...

marsdream ⋅ 06/15 ⋅ 0

面试官自述:面向高级开发人员的iOS面试问题

当您准备进行技术性iOS面试时,了解您可能会询问哪些主题以及经验丰富的iOS开发人员期望什么是非常重要的。 这是许多硅谷公司用来衡量iOS候选人资历水平的一系列问题。 这些问题涉及iOS开发的...

菇哒微课 ⋅ 04/26 ⋅ 0

ios APP 兼容性调试 版本升级

调试IOS 插件app兼容问题 目前无法兼容IOS 11.2.2-11.3系统 目前会会闪退 调试后需要加密

吴雄辉 ⋅ 04/10 ⋅ 0

Unity与IOS交互,调用IOS系统相机和相册

前面两篇总结了一下unity与android的简单交互和调用安卓系统相机和相册,比较蛋疼的是,后来发现不同的测试机上会有不同的bug。。。下阶段要一个一个的解决一下 今天总结一下与IOS的交互。这...

qq_32587659 ⋅ 05/16 ⋅ 0

iOS高仿QQ侧滑控件、下载框架、动画效果、扫一扫、颜色变化、K线图等源码

iOS精选源码 仿京东"加入购物车"转场动画(http://www.code4app.com/thread-28162-1-1.html) ColorTool(颜色转换)(http://www.code4app.com/thread-29256-1-1.html) Swift 专业版K线(http://w......

sunnyaigd ⋅ 04/17 ⋅ 0

Appuploader的安装介绍

注意:下载AU后需安装java8运行环境才能启动;安装好了最新Java8运行环境,解压AU软件包,无需安装,Windows 64位系统点击appuploader.exe启动;如果是Linux/Windows 32位系统或Mac系统双击appuplo...

webmirror ⋅ 05/11 ⋅ 0

Unity调用IOS的StoreKit实现在游戏内部的对游戏进行星级评价和评论

一 Xcode端的OC代码 在Xcode里面新建一个空的工程(不会搞的百度一下),然后创建一个.h和.m文件,记住要把.m的后缀改成.mm(.mm文件和.m文件的区别就是:.mm文件除了可以包含Objective-C和C...

caohonghong123 ⋅ 04/19 ⋅ 0

iOS小白点效果、打地鼠游戏、轮播效果、画板、富文本编辑器等源码

iOS精选源码 美团外卖商家点菜页面(http://www.code4app.com/thread-29383-1-1.html) 板书录制演示程序(http://www.code4app.com/thread-29384-1-1.html) 分类轮播、直播间礼物列表轮播 -- O...

sunnyaigd ⋅ 04/24 ⋅ 0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

Redis 单线程 为何却需要事务处理并发问题

Redis是单线程处理,也就是命令会顺序执行。那么为什么会存在并发问题呢? 个人理解是,虽然redis是单线程,但是可以同时有多个客户端访问,每个客户端会有 一个线程。客户端访问之间存在竞争...

码代码的小司机 ⋅ 30分钟前 ⋅ 0

到底会改名吗?微软GVFS 改名之争

微软去年透露了 Git Virtual File System(GVFS)项目,GVFS 是 Git 版本控制系统的一个开源插件,允许 Git 处理 TB 规模的代码库,比如 270 GB 的 Windows 代码库。该项目公布之初就引发了争...

linux-tao ⋅ 40分钟前 ⋅ 0

笔试题之Java基础部分【简】【二】

1.静态变量和实例变量的区别 在语法定义上的区别:静态变量前要加static关键字,而实例变量前则不加。在程序运行时的区别:实例变量属于某个对象的属性,必须创建了实例对象,其中的实例变...

anlve ⋅ 57分钟前 ⋅ 0

Lombok简单介绍及使用

官网 通过简单注解来精简代码达到消除冗长代码的目的 优点 提高编程效率 使代码更简洁 消除冗长代码 避免修改字段名字时忘记修改方法名 4.idea中安装lombnok pom.xml引入 <dependency> <grou...

to_ln ⋅ 今天 ⋅ 0

【转】JS浮点数运算Bug的解决办法

37.5*5.5=206.08 (JS算出来是这样的一个结果,我四舍五入取两位小数) 我先怀疑是四舍五入的问题,就直接用JS算了一个结果为:206.08499999999998 怎么会这样,两个只有一位小数的数字相乘,怎...

NickSoki ⋅ 今天 ⋅ 0

table eg

user_id user_name full_name 1 zhangsan 张三 2 lisi 李四 `` ™ [========] 2018-06-18 09:42:06 星期一½ gdsgagagagdsgasgagadsgdasgagsa...

qwfys ⋅ 今天 ⋅ 0

一个有趣的Java问题

先来看看源码: public class TestDemo { public static void main(String[] args) { Integer a = 10; Integer b = 20; swap(a, b); System.out......

linxyz ⋅ 今天 ⋅ 0

十五周二次课

十五周二次课 17.1mysql主从介绍 17.2准备工作 17.3配置主 17.4配置从 17.5测试主从同步 17.1mysql主从介绍 MySQL主从介绍 MySQL主从又叫做Replication、AB复制。简单讲就是A和B两台机器做主...

河图再现 ⋅ 今天 ⋅ 0

docker安装snmp rrdtool环境

以Ubuntu16:04作为基础版本 docker pull ubuntu:16.04 启动一个容器 docker run -d -i -t --name flow_mete ubuntu:16.04 bash 进入容器 docker exec -it flow_mete bash cd ~ 安装基本软件 ......

messud4312 ⋅ 今天 ⋅ 0

OSChina 周一乱弹 —— 快别开心了,你还没有女友呢。

Osc乱弹歌单(2018)请戳(这里) 【今日歌曲】 @莱布妮子 :分享吴彤的单曲《好春光》 《好春光》- 吴彤 手机党少年们想听歌,请使劲儿戳(这里) @clouddyy :小萝莉街上乱跑,误把我认错成...

小小编辑 ⋅ 今天 ⋅ 9

没有更多内容

加载失败,请刷新页面

加载更多

下一页

返回顶部
顶部