Xcode调试LLDB
一、简介
关于Xcode调试,相信大家很多会用断点调试,今天无意间在苹果开发的群里看到了po,瞬间心中有个疑问:po是什么?下面我就百度搜索了一下,介绍一点皮毛。
首先是LLDB,它的全名是lower level debug,意思就是底层调试器。原来苹果用的是GDB,后来发现GDB有一些问题无法解决,所以就用了LLDB,它是高性能的调试器,包括了完整的LLVM编译器,其中LLVM包括了Clang表达式解析器和反汇编程序,它可以理解OC语法。进而进行调试。
其次就是po,网上搜了一下还有p命令。po全称:print object。顾名思义就是打印出一个NSObject,意思是在控制台,你可以使用po命令打印出来一个继承与NSObject的类。例如
(lldb) po self.accountTextField
<UITextField: 0x7a08be30; frame = ( ; ); text = ''; clipsToBounds = YES; opaque = NO; autoresize = RM+BM; tag = ; gestureRecognizers = <NSArray: 0x78ec3a30>; layer = <CALayer: 0x7a08c090>>
这个是我在控制台输入打印出来我这个控制器中的accountTextField显示出来的东西,可以看到里面都是你自己定义的这个对象的基本信息。
还有一个是p命令,p全称是:print。它的用途就是打印出来一些值,例如int float等这样的数值。例如:
(lldb) p n
(NSInteger) $ =
(lldb)
我在一个Controller中定义了一个NSInteger n;然后在控制台输入p n,就会把现在这个状态时n的值给打印出来。
还有一个是expr。expr的全称应该是express吧。不太确定,但是它的功能是可以在调试时动态的制定制定的表达式,并将结果打印出来,你可以在控制台进行表达式操作。很有用的命令。例如
(lldb) expr n==34
(bool) $ = true
还是刚才定义的n,你可以在控制台输入 expr n==34,然后就可以判断出来n和34的大小,当然这只是简单地调试,你还可以写其他的比较复杂的表达式。
还有一个bt命令。bt全称就是thread backtrace.它的作用是打印调用的堆栈。在后面加上参数all即可打印出所有的thread的堆栈。例如:
(lldb) bt
* thread #: tid = 0x1d37f5, 0x0003f508 NotePad`__35-[LoginViewController loginRequest]_block_invoke(.block_descriptor=0x7c8b8b90, gets=0x7be65a80, error=0x00000000, code=) + at LoginViewController.m:, queue = 'com.apple.main-thread', stop reason = breakpoint 2.1 * frame #: 0x0003f508 NotePad`__35-[LoginViewController loginRequest]_block_invoke(.block_descriptor=0x7c8b8b90, gets=0x7be65a80, error=0x00000000, code=) + at LoginViewController.m: frame #: 0x00048d41 NotePad`__35+[RequestService login:userID:pwd:]_block_invoke(.block_descriptor=0x7c8b8b70, operation=0x7c8934a0, responseObject=0x7be65a80) + at RequestService.m: frame #: 0x0008f1bb NotePad`__64-[AFHTTPRequestOperation setCompletionBlockWithSuccess:failure:]_block_invoke54(.block_descriptor=<unavailable>) + at AFHTTPRequestOperation.m: frame #: 0x025755ea libdispatch.dylib`_dispatch_call_block_and_release + frame #: 0x02597bef libdispatch.dylib`_dispatch_client_callout + frame #: 0x0257d6bb libdispatch.dylib`_dispatch_main_queue_callback_4CF + frame #: 0x00ae513e CoreFoundation`__CFRUNLOOP_IS_SERVICING_THE_MAIN_DISPATCH_QUEUE__ + frame #: 0x00aa3f10 CoreFoundation`__CFRunLoopRun + frame #: 0x00aa337b CoreFoundation`CFRunLoopRunSpecific + frame #: 0x00aa31ab CoreFoundation`CFRunLoopRunInMode + frame #: 0x04ada2c1 GraphicsServices`GSEventRunModal + frame #: 0x04ada0fe GraphicsServices`GSEventRun + frame #: 0x011b79b6 UIKit`UIApplicationMain + frame #: 0x0006f33d NotePad`main(argc=, argv=0xbffd2784) + at main.m: frame #: 0x025c3ac9 libdyld.dylib`start +
(lldb) bt all
* thread #: tid = 0x1d37f5, 0x0003f508 NotePad`__35-[LoginViewController loginRequest]_block_invoke(.block_descriptor=0x7c8b8b90, gets=0x7be65a80, error=0x00000000, code=) + at LoginViewController.m:, queue = 'com.apple.main-thread', stop reason = breakpoint 2.1 * frame #: 0x0003f508 NotePad`__35-[LoginViewController loginRequest]_block_invoke(.block_descriptor=0x7c8b8b90, gets=0x7be65a80, error=0x00000000, code=) + at LoginViewController.m: frame #: 0x00048d41 NotePad`__35+[RequestService login:userID:pwd:]_block_invoke(.block_descriptor=0x7c8b8b70, operation=0x7c8934a0, responseObject=0x7be65a80) + at RequestService.m: frame #: 0x0008f1bb NotePad`__64-[AFHTTPRequestOperation setCompletionBlockWithSuccess:failure:]_block_invoke54(.block_descriptor=<unavailable>) + at AFHTTPRequestOperation.m: frame #: 0x025755ea libdispatch.dylib`_dispatch_call_block_and_release + frame #: 0x02597bef libdispatch.dylib`_dispatch_client_callout + frame #: 0x0257d6bb libdispatch.dylib`_dispatch_main_queue_callback_4CF + frame #: 0x00ae513e CoreFoundation`__CFRUNLOOP_IS_SERVICING_THE_MAIN_DISPATCH_QUEUE__ + frame #: 0x00aa3f10 CoreFoundation`__CFRunLoopRun + frame #: 0x00aa337b CoreFoundation`CFRunLoopRunSpecific + frame #: 0x00aa31ab CoreFoundation`CFRunLoopRunInMode + frame #: 0x04ada2c1 GraphicsServices`GSEventRunModal + frame #: 0x04ada0fe GraphicsServices`GSEventRun + frame #: 0x011b79b6 UIKit`UIApplicationMain + frame #: 0x0006f33d NotePad`main(argc=, argv=0xbffd2784) + at main.m: frame #: 0x025c3ac9 libdyld.dylib`start + thread #: tid = 0x1d386e, 0x028c78ce libsystem_kernel.dylib`kevent64 + , queue = 'com.apple.libdispatch-manager' frame #: 0x028c78ce libsystem_kernel.dylib`kevent64 + frame #: 0x025850f0 libdispatch.dylib`_dispatch_mgr_invoke + frame #: 0x02584e48 libdispatch.dylib`_dispatch_mgr_thread + thread #: tid = 0x1d3870, 0x028c6e6a libsystem_kernel.dylib`__workq_kernreturn + frame #: 0x028c6e6a libsystem_kernel.dylib`__workq_kernreturn + frame #: 0x028f32b1 libsystem_pthread.dylib`_pthread_wqthread + frame #: 0x028f0e2e libsystem_pthread.dylib`start_wqthread + thread #: tid = 0x1d3871, 0x028c6e6a libsystem_kernel.dylib`__workq_kernreturn + frame #: 0x028c6e6a libsystem_kernel.dylib`__workq_kernreturn + frame #: 0x028f32b1 libsystem_pthread.dylib`_pthread_wqthread + frame #: 0x028f0e2e libsystem_pthread.dylib`start_wqthread + thread #: tid = 0x1d3872, 0x028c6e6a libsystem_kernel.dylib`__workq_kernreturn + frame #: 0x028c6e6a libsystem_kernel.dylib`__workq_kernreturn + frame #: 0x028f32b1 libsystem_pthread.dylib`_pthread_wqthread + frame #: 0x028f0e2e libsystem_pthread.dylib`start_wqthread + thread #: tid = 0x1d387e, 0x028c09ce libsystem_kernel.dylib`mach_msg_trap + , name = 'AFNetworking' frame #: 0x028c09ce libsystem_kernel.dylib`mach_msg_trap + frame #: 0x028bfa70 libsystem_kernel.dylib`mach_msg + frame #: 0x00aa47d6 CoreFoundation`__CFRunLoopServiceMachPort + frame #: 0x00aa3bb8 CoreFoundation`__CFRunLoopRun + frame #: 0x00aa337b CoreFoundation`CFRunLoopRunSpecific + frame #: 0x00aa31ab CoreFoundation`CFRunLoopRunInMode + frame #: 0x00417498 Foundation`-[NSRunLoop(NSRunLoop) runMode:beforeDate:] + frame #: 0x004b6dcb Foundation`-[NSRunLoop(NSRunLoop) run] + frame #: 0x0004bbbb NotePad`+[AFURLConnectionOperation networkRequestThreadEntryPoint:](self=0x000c6374, _cmd=0x000a2e2b, object=0x00000000) + at AFURLConnectionOperation.m: frame #: 0x00415607 Foundation`-[NSThread main] + frame #: 0x00415560 Foundation`__NSThread__main__ + frame #: 0x028f2e13 libsystem_pthread.dylib`_pthread_body + frame #: 0x028f2d89 libsystem_pthread.dylib`_pthread_start + frame #: 0x028f0e52 libsystem_pthread.dylib`thread_start + thread #: tid = 0x1d3881, 0x028c09ce libsystem_kernel.dylib`mach_msg_trap + , name = 'com.apple.NSURLConnectionLoader' frame #: 0x028c09ce libsystem_kernel.dylib`mach_msg_trap + frame #: 0x028bfa70 libsystem_kernel.dylib`mach_msg + frame #: 0x00aa47d6 CoreFoundation`__CFRunLoopServiceMachPort + frame #: 0x00aa3bb8 CoreFoundation`__CFRunLoopRun + frame #: 0x00aa337b CoreFoundation`CFRunLoopRunSpecific + frame #: 0x00aa31ab CoreFoundation`CFRunLoopRunInMode + frame #: 0x03a45386 CFNetwork`+[NSURLConnection(Loader) _resourceLoadLoop:] + frame #: 0x00415607 Foundation`-[NSThread main] + frame #: 0x00415560 Foundation`__NSThread__main__ + frame #: 0x028f2e13 libsystem_pthread.dylib`_pthread_body + frame #: 0x028f2d89 libsystem_pthread.dylib`_pthread_start + frame #: 0x028f0e52 libsystem_pthread.dylib`thread_start + thread #: tid = 0x1d3884, 0x028c6e6a libsystem_kernel.dylib`__workq_kernreturn + frame #: 0x028c6e6a libsystem_kernel.dylib`__workq_kernreturn + frame #: 0x028f32b1 libsystem_pthread.dylib`_pthread_wqthread + frame #: 0x028f0e2e libsystem_pthread.dylib`start_wqthread + thread #: tid = 0x1d3885, 0x028c6e6a libsystem_kernel.dylib`__workq_kernreturn + frame #: 0x028c6e6a libsystem_kernel.dylib`__workq_kernreturn + frame #: 0x028f32b1 libsystem_pthread.dylib`_pthread_wqthread + frame #: 0x028f0e2e libsystem_pthread.dylib`start_wqthread + thread #: tid = 0x1d3888, 0x028c684e libsystem_kernel.dylib`__select + , name = 'com.apple.CFSocket.private' frame #: 0x028c684e libsystem_kernel.dylib`__select + frame #: 0x00aecb87 CoreFoundation`__CFSocketManager + frame #: 0x028f2e13 libsystem_pthread.dylib`_pthread_body + frame #: 0x028f2d89 libsystem_pthread.dylib`_pthread_start + frame #: 0x028f0e52 libsystem_pthread.dylib`thread_start +
还有br命令。br全称是breakpoint list简写。你可以加入l 即br l.这样可以打印出现在项目中已经打得断点。输入显示的效果如下:
(lldb) br
The following subcommands are supported: clear -- Clears a breakpoint or set of breakpoints in the executable. command -- A set of commands for adding, removing and examining bits of code to be executed when the breakpoint is hit (breakpoint 'commands'). delete -- Delete the specified breakpoint(s). If no breakpoints are specified, delete them all. disable -- Disable the specified breakpoint(s) without removing it/them. If no breakpoints are specified, disable them all. enable -- Enable the specified disabled breakpoint(s). If no breakpoints are specified, enable all of them. list -- List some or all breakpoints at configurable levels of detail. modify -- Modify the options on a breakpoint or set of breakpoints in the executable. If no breakpoint is specified, acts on the last created breakpoint. With the exception of -e, -d and -i, passing an empty argument clears the modification. set -- Sets a breakpoint or set of breakpoints in the executable. For more help on any particular subcommand, type 'help <command> <subcommand>’.
这里可以看出关于br的命令参数。例如输入br l,输出效果如下
(lldb) br l
Current breakpoints: : file = '/zhanggui/NotePad/NotePad/ViewController/LocalPasswordViewController/LocalPasswordViewController.m', line = , locations = (pending) : file = '/zhanggui/NotePad/NotePad/ViewController/LoginViewController/LoginViewController.m', line = , locations = , resolved = , hit count = 2.1: where = NotePad`__35-[LoginViewController loginRequest]_block_invoke + at LoginViewController.m:, address = 0x0003f508, resolved, hit count =
这里就可以打印出来项目中所有的断点信息,例如在哪个控制器中在哪一行等。
此外还有:process continue l,thread step-in l,thread step-inst l,thread step-over l,thread step-over-inst l,thread step-out l,thread list等。大家可以自行测试一下看看什么功能。
这里再补充一下po命令。
1、po $eax。其中$eax是cup的一个寄存器。在一个异常的情况下,这个寄存器将会包含一个异常对象的指针。注意:$eax只会在模拟器里工作,如果在设备上测试,需要使用$r0寄存器。
当你输入po $eax时,如果你的程序没有异常抛出。控制台输出的是:
(lldb) po $eax
<nil>
这很正常,因为$eax包含的是异常对象的指针,你的程序没有异常,所以为空。但是当我抛出异常时,例如showSegue的identifier不存在时,这样就会产生异常,但是我在再次使用po $eax时,打印出来的信息却是:
(lldb) po $eax
error: Couldn't materialize: couldn't read the value of register eax Errored out in Execute, couldn't PrepareToExecuteJITExpression
调试我查看了好多资料,也没有找到原因,所以就暂时先放着了。(谁知道的可以告诉我,万分感谢)。
常规来说,用po [$eax name]可以显示出正在处理的异常的名字。
用po [$eax reason]可以显示出来错误信息。
但是由于我po $eax还没有看出结果,所以上面刚说的那两个也没有测试。
Xcode调试LLDB的更多相关文章
- Xcode中lldb的REPL调试方法
Xcode中lldb调试器有一个repl语句,可以用来模拟swift解释器的REPL行为,即Read Eval Print Loop. 在Xcode里随意打开程序,中断入调试器.在调试控制台中输入re ...
- xcode 调试器 LLDB
本文完全转载,转载地址:点击这里 你是否曾经苦恼于理解你的代码,而去尝试打印一个变量的值? NSLog(@"%@", whatIsInsideThisThing); 或者跳过一个函 ...
- Xcode 调试技巧
一 NSLog调试 官方文档:Logs an error message to the Apple System Log facility. 即NSLog不是作为普通的debug log的,而是err ...
- xcode调试打印QString
xcode调试打印QString xcode内置GDB,在调试工程过程中可以通过print命令打印基本的数据类型,但像QString这样复杂类型就不行了.虽然我们可以在程序代码通过添加Qt的调试打印语 ...
- Xcode 调试技巧 --常用命令和断点
Xcode 中的调试技巧与我们的日常开发息息相关,而这些调试技巧在我们解决Bug时,常常有事半功倍的作用,经常会用到的有各种断点 和 命令.而这些调试技巧也经常会在面试中问到,所以不知道的就来看看吧. ...
- iOS Xcode 调试技巧
一 NSLog调试 官方文档:Logs an error message to the Apple System Log facility. 即NSLog不是作为普通的debug log的,而是err ...
- IOS调试技巧:当程序崩溃的时候怎么办 xcode调试
转自:http://www.ityran.com/archives/1143 ------------------------------------------------ 欢迎回到当程序崩溃的时候 ...
- xcode 调试程序 lldb 使用
xcode 调试程序 lldb 使用 一:lldb是什么 https://developer.apple.com/library/mac/documentation/IDEs/Conceptual/g ...
- Mac OS X 10.9 Mavericks安装后,Xcode调试时模拟器黑屏的处理方法
请耐心的等下去吧,少年! 装了Mac OS X 10.9 Mavericks的同学,如果碰到Xcode调试App时,模拟器黑屏(重置也无效),请耐心的等下去吧,大约10来分钟左右黑屏就会消失,App启 ...
随机推荐
- php,vue,vue-ssr 做出来的页面有什么区别?
欢迎大家前往腾讯云+社区,获取更多腾讯海量技术实践干货哦~ 本文由shirishiyue发表于云+社区专栏 目前我这边的web页面,都是采用php+smarty模板生成的,是一种比较早期的开发模式.好 ...
- 学习实践之DEMO《nodejs模拟POST登陆》
一个简单的PHP接收参数页面 <?php header("content-type:text/html;charset=utf-8"); if($_POST[username ...
- JVM参数以及用法
工作以后,发觉真的几乎没有像大学那样空闲的时间,坐下来看看书写写博客了.最近的一篇博客距离现在已经近一个多月了,最近也在复习Java的东西,准备校招,看了看JVM的东西,就当作记笔记. (一)JVM参 ...
- [Luogu 3787] 冰精冻西瓜
Description 琪露诺是拥有操纵冷气程度的能力的妖精,一天她发现了一片西瓜地.这里有n个西瓜,由n-1条西瓜蔓连接,形成一个有根树,琪露诺想要把它们冷冻起来慢慢吃. 这些西瓜蔓具有神奇的性质, ...
- C#中的readonly跟const用法小结
总结一下常量和只读字段的区别: 由来: 笔者也是在看欧立奇版的<.Net 程序员面试宝典>的时候,才发现自己长久以来竟然在弄不清出两者的情况下,混用了这么长的时间.的确,const与rea ...
- vue生命周期、钩子函数
https://segmentfault.com/a/1190000011381906 详解生命周期和钩子函数 每个vue实例再被创建之前都要经过一系列的初始化过程,这个过程就是vue的生命周期 ...
- MVC之Ajax异步操作
在页面的局部通过Html.Action加载一块分布页,我们可以通过Ajax异步去更换或更新这块分布页 通过一个下拉框值发生变化的时候,我们会去从后台重新访问这个action获取一个新的View,然后替 ...
- oracle与mysql
『创业团队最佳选择是Oracle+MongoDB,而不是MySQL』,当深蓝在QQ群里抛出这样的观点的时候,就像是在马蜂窝里丢了一串鞭炮一样热闹起来. 创业者甲: 开什么玩笑,Oracle要收钱的,太 ...
- vi命令详解2
介绍 vi编辑器是所有Unix及Linux系统下标准的编辑器,它的强大不逊色于任何最新的文本编辑器,这里只是简单地介绍一下它的用法和一小部分指令. 1.vi的基本概念 vi可以分为三种状态,分别如下: ...
- CDN使用心得:加速双刃剑
文章图片存储在GitHub,网速不佳的朋友,请看<CDN 使用心得:加速双刃剑> 或者 来我的技术小站 godbmw.com 本文以腾讯云平台的 CDN 服务为例,记录下在个人网站开发和公 ...