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