资讯专栏INFORMATION COLUMN

XCode调试技巧

graf / 2893人阅读

摘要:下可以使用实现,但下语法含义变化了,用替代指令配合与断点,可以在运行时动态的控制程序的运行状态可以执行一段代码,打印调用栈三断点的使用技巧一个断点可以做些什么事情可以加入一个条件,当满足此条件时触发断点。

本文从以前做的幻灯中整理而来的,主要讲一下XCode结合LLDB调试命令以及OBJC运行时的调试技巧。

一、常用宏定义

1、OPTIMIZE,Debug和Release判定

Release编译时定义

当我们想要某些代码只在Debug环境下才运行可以使用此宏定义判别

2、i386x86_64,模拟器环境判定

模拟器编译时定义

有时工程依赖的Lib库只编译了真机的代码,模拟器编译出错。为了可以模拟器调试,使用此宏略过不能编译的代码

3、__IPHONE_8_0等,编译SDK的判定

SDK中会声明当前SDK版本定义,并且保留过往SDK版本定义

有时我们编写的代码可能不会在最新的SDK编译,旧版本SDK编译会有潜在问题。使用此判定针对新老SDK版本分别编写代码

__IPHONE_OS_VERSION_MAX_ALLOWED,此宏定义声明了当前编译的SDK版本,可进行比较

4、使用-D编译器选项为编译Target追加宏定义

在工程Target的Other C Flags项目中定义

同一份代码可能由于证书、渠道、UI的不同,会建立多个Target分别进行打包。通过编译时追加宏定义,可在运行时判定Target。

下例中定义了一个宏XDTarget,其值为800100。

每一个Target可为XDTarget定义不同的值,这样运行时就可以判别Target,也免去了手工修改的麻烦。

5、NOP,空语句

C语言中有nop()函数,表示一条空语句。OC中没有提供。

可以设计一个宏进行代替,用于挂载条件断点调试使用。

二、常用调试命令

1、PO,输出对象信息

po调用NSObject的description方法打印对象

po 变量名

po 内存地址

po 可返回对象的表达式

如果对象没有被释放,PO会输出内容,否则只输出一个代表野指针的数字。根据此特性可在循环引用检查中判定对象是否被正常释放。

配合表达式进行复杂查询

2、P,输出变量的值

p (类型)表达式

除了值类型,也可以直接打印结构体数据

3、Call,执行一段代码

call (返回类型)表达式

调试状态下,对于点语法支持不佳。如果发现符号未找到的情况,尝试使用发送消息的方式。如果还不行,根据提示,声明类型。对于PO、P等指令同样也需要注意

可以修改值。

gdb下可以使用set实现,但lldb下set语法含义变化了,用call替代set指令

配合NOP与断点,可以在运行时动态的控制程序的运行状态

可以执行一段代码

4、bt,打印调用栈

三、断点的使用技巧

1、一个断点可以做些什么事情?

可以加入一个条件,当满足此条件时触发断点。

或者当执行某些次后才会触发

可以执行若干种类的action

当经过此断点时,执行action但是不会中断程序

2、异常断点

某些crash是由程序抛出的异常导致的,比如数组越界。可以通过添加异常断点监控异常抛出的位置。

3、符号断点

当符号对应的方法被调用时,中断

-/+[类 方法]

举个例子:当UIViewController被载入时触发,并将当前的调用栈输出

4、内存断点

当该块内存被调用时中断

可通过XCode调试界面简化指令添加

添加时,需要预先打断,找到要监视的内存地址(注意,地址每次启动都会失效)

可以输出值的变化。可以找出内存是何时被修改的,值是如何变化的。

四、灵活的使用调试手段

以上这些调试手段虽然看起来比较简单,但只要灵活运用,就可以为调试带来很多便利和可能性。
比如下面一个例子


图中有三个变量a,b,c。只要在NOP语句加入一个执行call命令的条件断点,通过调节断点的开闭,就可以在程序运行时动态的控制a,b,c的数值。这使得不用编写调试代码,就可以模拟各个状态,动态的调试程序分支。

此外,当程序发生异常时,一般是通过控制台报错信息,被动的定位问题所在。如果使用调试命令结合OBJC的运行时,可以主动的获知发生异常的状态。在MRC开发的时代,对于多次释放对象的问题,甚至可以一定程度的将僵尸对象还原回原始的对象,从而定位问题所在。

所以只要灵活的运用上面这些调试手段,相信您也会很快成为一个调试高手。

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/15731.html

相关文章

  • iOS 进阶必读 - 收藏集 - 掘金

    摘要:深入研究捕获外部变量和实现原理掘金前言是语言的扩充功能,而在和中引入了这个新功能。是由和两位大神在对的开发过程中中所有变换操作底层实现分析上掘金前言在上篇文章中,详细分析了是创建和订阅的详细过程。 深入研究Block捕获外部变量和__block实现原理 - 掘金 前言 Blocks是C语言的扩充功能,而Apple 在OS X Snow Leopard 和 iOS 4中引入了这个新功能B...

    sf_wangchong 评论0 收藏0
  • iOS 进阶必读 - 收藏集 - 掘金

    摘要:深入研究捕获外部变量和实现原理掘金前言是语言的扩充功能,而在和中引入了这个新功能。是由和两位大神在对的开发过程中中所有变换操作底层实现分析上掘金前言在上篇文章中,详细分析了是创建和订阅的详细过程。 深入研究Block捕获外部变量和__block实现原理 - 掘金前言 Blocks是C语言的扩充功能,而Apple 在OS X Snow Leopard 和 iOS 4中引入了这个新功能Bl...

    szysky 评论0 收藏0
  • iOS 进阶必读

    摘要:广州线下活动八面玲珑的淘宝出品月日,由淘宝主办的地下铁沙龙在广州广电平云广场举办。此次邀请的嘉宾在方面有所实践探索,分别来自腾讯淘宝公司。从这次入院考试开始,就成功入院了。一常见类信号类。然而实际使用过程中,还是会遇到一些问题,比如的问题。 初探 CALayer 属性 一直觉得一个 view 就一个 layer,到今天才发现不是这样子的。 Xcode8调试黑科技:Memory Grap...

    waruqi 评论0 收藏0
  • iOS 进阶必读

    摘要:广州线下活动八面玲珑的淘宝出品月日,由淘宝主办的地下铁沙龙在广州广电平云广场举办。此次邀请的嘉宾在方面有所实践探索,分别来自腾讯淘宝公司。从这次入院考试开始,就成功入院了。一常见类信号类。然而实际使用过程中,还是会遇到一些问题,比如的问题。 初探 CALayer 属性 一直觉得一个 view 就一个 layer,到今天才发现不是这样子的。 Xcode8调试黑科技:Memory Grap...

    lansheng228 评论0 收藏0
  • [译] LLDB 基础

    摘要:让我们使用的聪明才智来为我们推荐设置断点的命令还不赖嘛,还不赖。要改变这个问题我们给表达式设置一个参数这样我们就得到了真正导致的崩溃原因。 原文链接:https://swifting.io/blog/2016/02/19/6-basic-lldb-tips/原作者:Michał Wojtysiak 长话短说 在开发了几年的iOS应用后,我对LLDB调试器的使用已经趋于最小: (lldb...

    Cristalven 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<