XCode的一些调试技巧搜集

XCode 内置GDB,我们可以在命令行中使用 GDB 命令来调试我们的程序。下面将介绍一些常用的命令以及调试技巧。

po 命令:为 print object 的缩写,显示对象的文本描述(显示从对象的 description 消息获得的字符串信息)。

比如:

上图中,我使用 po 命令显示一个 NSDictionary 的内容。注意在左侧我们可以看到 dict 的一些信息:3 key/value pairs,显示该 dict 包含的数据量,而展开的信息显示 isa 层次体系(即class 和 metaclass结构关系)。我们可以右击左侧的 dict,选中“Print Description of "dict"”,则可以在控制台输出 dict 的详细信息:

[cpp] view plaincopyprint?

Printing description of dict:

<CFBasicHash 0x1001149e0 [0x7fff7e27ff40]>{type = immutable dict, count = 3,

entries =>

0 : <CFString 0x100002458 [0x7fff7e27ff40]>{contents = "first"} = <CFString 0x100002438 [0x7fff7e27ff40]>{contents = "one"}

1 : <CFString 0x100002498 [0x7fff7e27ff40]>{contents = "second"} = <CFString 0x100002478 [0x7fff7e27ff40]>{contents = "two"}

2 : <CFString 0x1000024d8 [0x7fff7e27ff40]>{contents = "third"} = <CFString 0x1000024b8 [0x7fff7e27ff40]>{contents = "three"}

}

(gdb)

print 命令:有点类似于格式化输出,可以输出对象的不同信息:

如:

[cpp] view plaincopyprint?

(gdb) print (char *)[[dict description] cStringUsingEncoding:4]

$1 = 0x1001159c0 "{\n    first = one;\n    second = two;\n    third = three;\n}"

(gdb) print (int)[dict retainCount]

$2 = 1

(gdb)

注:4是 NSUTF8StringEncoding 的值。

info 命令:我们可以查看内存地址所在信息

比如 "info symbol 内存地址" 可以获取内存地址所在的 symbol 相关信息:

[cpp] view plaincopyprint?

(gdb) info symbol 0x00000001000017f7

main + 343 in section LC_SEGMENT.__TEXT.__text of /Users/LuoZhaohui/Library/Developer/Xcode/DerivedData/RunTimeSystem-anzdlhiwvlbizpfureuvenvmatnp/Build/Products/Debug/RunTimeSystem

比如 "info line *内存地址" 可以获取内存地址所在的代码行相关信息:

[cpp] view plaincopyprint?

(gdb) info line *0x00000001000017f7

Line 62 of "/Users/LuoZhaohui/Documents/Study/RunTimeSystem/RunTimeSystem/main.m" starts at address 0x1000017f7 <main+343> and ends at 0x10000180a <main+362>.

show 命令:显示 GDB 相关的信息。如:show version 显示GDB版本信息

[cpp] view plaincopyprint?

(gdb) show version

GNU gdb 6.3.50-20050815 (Apple version gdb-1708) (Mon Aug  8 20:32:45 UTC 2011)

Copyright 2004 Free Software Foundation, Inc.

GDB is free software, covered by the GNU General Public License, and you are

welcome to change it and/or distribute copies of it under certain conditions.

Type "show copying" to see the conditions.

There is absolutely no warranty for GDB.  Type "show warranty" for details.

This GDB was configured as "x86_64-apple-darwin".

help 命令:如果忘记某条命令的语法了,可以使用 help 命令名 来获取帮助信息。如:help info 显示 info 命令的用法。

[cpp] view plaincopyprint?

(gdb) help info

Generic command for showing things about the program being debugged.

List of info subcommands:

info address -- Describe where symbol SYM is stored

info all-registers -- List of all registers and their contents

info args -- Argument variables of current stack frame

info auxv -- Display the inferior‘s auxiliary vector

info breakpoints -- Status of user-settable breakpoints

info catch -- Exceptions that can be caught in the current stack frame

info checkpoints -- Help

info classes -- All Objective-C classes

......

Type "help info" followed by info subcommand name for full documentation.

Command name abbreviations are allowed if unambiguous.

(gdb)

在系统抛出异常处设置断点

有时候我们的程序不知道跑到哪个地方就 crash 了,而 crash 又很难重现。保守的做法是在系统抛出异常之前设置断点,具体来说是在 objc_exception_throw处设置断点。设置步骤为:首先在 XCode 按 CMD + 6,进入断点管理窗口;然后点击右下方的 +,增加新的 Symbolic Breakpoint,在 Symbol 一栏输入:objc_exception_throw,然后点击 done,完成。 这样在 Debug 模式下,如果程序即将抛出异常,就能在抛出异常处中断了。比如在前面的代码中,我让 [firstObjctcrashTest]; 抛出异常。在 objc_exception_throw 处设置断点之后,程序就能在该代码处中断了,我们从而知道代码在什么地方出问题了。

  1. 命 令                        解释
  2. break NUM               在指定的行上设置断点。
  3. bt                      显 示所有的调用栈帧。该命令可用来显示函数的调用顺序。
  4. clear                   删 除设置在特定源文件、特定行上的断点。其用法为:clear FILENAME:NUM。
  5. continue                继续执行正在调试的程序。该命令用在程序 由于处理信号或断点而
  6. 导致停止运行 时。
  7. display EXPR            每次程序停止后显示表达式的值。表达式由程序定 义的变量组成。
  8. file FILE               装载指定的可执行文件进行调试。
  9. help NAME               显 示指定命令的帮助信息。
  10. info break              显 示当前断点清单,包括到达断点处的次数等。
  11. info files              显 示被调试文件的详细信息。
  12. info func               显示所有的函数名称。
  13. info local              显 示当函数中的局部变量信息。
  14. info prog               显示被调试程序的执行状 态。
  15. info var                显示所有的全局和静态变量名称。
  16. kill                    终 止正被调试的程序。
  17. list                    显示源代码段。
  18. make                    在 不退出 gdb 的情况下运行 make 工具。
  19. next                    在 不单步执行进入其他函数的情况下,向前执行一行源代码。
  20. print EXPR              显 示表达式 EXPR 的值。
  21. print- object            打印一个对象
  22. print (int) name      打印一个类型
  23. print- object [artist description]   调用一个函数
  24. set artist = @"test"    设置变量值
  25. whatis                      查 看变理的数据类型

Crash的问题。Crash最多的无非就两种,一种就是signal SIGABRT,大概的意思就是发送Message出现问题,信号迷失了。这种的Crash其实是很好定位,Crash了后直接看Console里出的最后日志,比如这段:

2012-03-28 19:26:33.055 TableViewMenuDemo[3916:f803] *** Terminating app due to uncaught exception ‘NSInvalidArgumentException’, reason: ‘-[__NSArrayI replaceObjectAtIndex:withObject:]: unrecognized selector sent to instance 0x6a3f3d0′

*** First throw call stack:

找到reason字段,那就是原因,说NSArray 调用replaceObjectAtIndex:withObject:

这个方法是NSMutableArry的,NSArray并没有该方法。信号迷失掉了,所以Crash了。0x6a3f3d0 是出问题的内存地址,查下内存地址或搜下调用方法就比较好定位了。

Xcode4上还有个更好用的定位方法,就是设置一个Exception Breakpoint就好了。

看图在工程的左边栏中选择Breakpoint Navigator,点击下面的+号添加一个Exception Breakpoint,然后再运行试试,Crash后,是不是直接定位到了那行代码了?再根据Console里的日志进行定位修改就好了。

下面说说另一种Crash, EXC_BAD_ACCESS,这个比较头疼,因为Crash的时候,可能是比较早之前的某个变量释放了,现在访问时出问题。Console里也没显示什么日志。

这里光加入Exception Breakpoint是不够的了,XCode4还个可爱的地方,打开Scheme选项选择EditScheme。

然后按图勾上Enable Zombie Objects和Malloc Stack那两项,记住一般只有在定位EXC_BAD_ACCESS时候才勾选,别有事没事都勾上。

这样重新跑一下,如果是到Exception Breakpoint处停止了,可以在Console中输入:c(continue)按回车继续跑,直到Crash。看下Console是不是有跟SIGABRT类似的错误信息日志了,后面定位什么的你懂的。

如果还没有日志,在Console中输入po$eax$eax标志出错的地方,适用模拟器,真机用$r0(话说EXC_BAD_ACCESS这种错误模拟器定位就行),还可以输入比如:po[$eaxname]po[$eaxreason]等指令查看错误其他信息(注意方括号后没分号的)。然后,就没有然后了。

还要补充点,程序开发过程就要多关注左边栏中Issue Navigator里的警告信息,Xcode4不仅会警告,还多数给出解决建议,能避免后面不必要的Crash。

如果程序Crash,第一时间关注下debug Navigator里的执行信息,将滑块拉向右边可以看到更多调用信息,根据这个能大致设想是调用什么方法或进行什么操作时Crash的。

1、使用僵尸变量(NSZombieEnabled)

2、重写object的respondsToSelector方法

在iphone开发的时候EXC_BAD_ACCESS这个bug时不容易找到原因的。

首先说一下EXC_BAD_ACCESS 这个错误,可以这么说,90%的错误来源在于对一个已经释放的对象进行release操作,或者操作一个在循环代码中被修改的序列中的对象。虽然使用NSZombieEnabled变量可以帮助你找到问题所在,但有的时候,即使通过设置NSZombieEnabled变量,还是不能定位到问题所在,这个时候,你可以试试重写object的respondsToSelector方法,显示出现EXEC_BAD_ACCESS前访问的最后一个object,下面是具体的步骤:
a、在每个类并且在 other c flags中加入-D _FOR_DEBUG_(记住请只在Debug Configuration下加入此标记)。这样当你程序崩溃时,Xcode的console上就会准确地记录了最后运行的object的方法。的实现文件(.m,.mm)文件中,添加如下代码:
[cpp] 
-(BOOL) respondsToSelector : (SEL)aSelector { 
    printf("SELECTOR: %s\n", [NSStringFromSelector(aSelector) UTF8String]); 
    return [super respondsToSelector:aSelector]; 
}

b、并且在 other c flags中加入-D _FOR_DEBUG_(记住请只在Debug Configuration下加入此标记)。这样当你程序崩溃时,Xcode的console上就会准确地记录了最后运行的object的方法。

3、让XCode反馈足够多的信息

在Edit–>Scheme里面 找到Arguments ,在Environment Variables这里添加
把下面2个值设置成YES
NSAutoreleaseFreedObjectCheckEnabled
NSDebugEnabled
这种方法非常好用,建议在建立一个工程的时候,加入此设置

4、设置全局异常断点

在程序抛出异常时候,往往需要定位到异常
键入快捷键 cmd + 6 进入断点窗口,点击左下角的"+"按钮,选择弹出框的“Add Exception BreakPoint”项,如下图所示:

然后使用默认设置,点击"done"按钮,设置全局异常断点就完成了

时间: 2024-09-29 00:11:20

XCode的一些调试技巧搜集的相关文章

XCode的一些调试技巧

XCode 内置GDB,我们可以在命令行中使用 GDB 命令来调试我们的程序.下面将介绍一些常用的命令以及调试技巧. po 命令:为 print object 的缩写,显示对象的文本描述(显示从对象的 description 消息获得的字符串信息). 比如: 上图中,我使用 po 命令显示一个 NSDictionary 的内容.注意在左侧我们可以看到 dict 的一些信息:3 key/value pairs,显示该 dict 包含的数据量,而展开的信息显示 isa 层次体系(即class 和 m

5个Xcode开发调试技巧

转自Joywii的博客,原文:Four Tips for Debugging in XCode Like a Bro 1.Enable NSZombie Objects(开启僵尸对象) Enable NSZombie Objects可能是整个Xcode开发环境中最有用的调试技巧.这个技巧非常非常容易追踪到重复释放的问题.该技巧会以非常简洁的方式打印指出重复释放的类和该类的内存地址. 怎么开启僵尸对象呢?首先打开 Edit Scheme (或者通过热键?<),然后选择Diagnostics选项卡,

iOS开发——调试篇&amp;Xcode常用调试技巧

Xcode常用调试技巧 Enable NSZombie Objects(开启僵尸对象) Enable NSZombie Objects可能是整个Xcode开发环境中最有用的调试技巧.这个技巧非常非常容易追踪到重复释放的问题.该技巧会以非常简洁的方式打印指出重复释放的类和该类的内存地址. 怎么开启僵尸对象呢?首先打开“Edit Scheme”(或者通过热键?<),然后选择Diagnostics选项卡,勾选Enable NSZombie Objects选项. 现在我们可以关掉ARC来测试重复释放的问

xcode调试技巧

XCode 内置GDB,我们可以在命令行中使用 GDB 命令来调试我们的程序.下面将介绍一些常用的命令以及调试技巧. po 命令:为 print object 的缩写,显示对象的文本描述(显示从对象的 description 消息获得的字符串信息). 比如: 上图中,我使用 po 命令显示一个 NSDictionary 的内容.注意在左侧我们可以看到 dict 的一些信息:3 key/value pairs,显示该 dict 包含的数据量,而展开的信息显示 isa 层次体系(即class 和 m

xcode的调试技巧

转自:http://www.cnblogs.com/daiweilai/p/4421340.html#biyouji 目录 前言逼优鸡知己知彼 百战不殆抽刀断Bug 普通操作 全局断点(Global BreakPoint) 条件断点(Condational Breakpoints)打印的艺术 NSLog 开启僵尸对象(Enable NSZombie Objects)进击的码农 Console(lldb 命令) Profile(instruments) Xcode视图调试结语 前言 最近博主临近毕

(转)5个Xcode开发调试技巧

1.Enable NSZombie Objects(开启僵尸对象) Enable NSZombie Objects可能是整个Xcode开发环境中最有用的调试技巧.这个技巧非常非常容易追踪到重复释放的问题.该技巧会以非常简洁的方式打印指出重复释放的类和该类的内存地址. 怎么开启僵尸对象呢?首先打开“Edit Scheme”(或者通过热键?<),然后选择Diagnostics选项卡,勾选Enable NSZombie Objects选项. 现在我们可以关掉ARC来测试重复释放的问题.异常和更容易产生

Xcode断点调试技巧

本文转载自破船 在程序中,无论是你想弄清楚为什么数组中有3个对象而不是5个,或者为什么一个新的玩家开始之后,游戏在倒退——调试在这些处理过程中是比较重要的一部分.通过本文的学习,我们将知道在程序中,可以使用的大多数重要调试功能,并如何利用这些调试功能来帮助你以更少的时间解决bug. 本文将介绍如下内容: 使用控制台检查程序的状态 进行日志记录,并熟练的驾驭NSLog 利用对象的生命周期跟踪内存的使用 使用控制台进行检查 在进行调试程序的时候,可能Xcode底部的小黑框会是你最好的朋友.它能输出日

iOS开发之Xcode常用调试技巧总结

两种最常见最普通的方法: 1.NSLog,最简单的方法,查看变结 中是否有值,有什么值,是不是自己需要的值,然后找到bug. 2.po命令,在程序进入断点处,在控制台中输入po 变量名,也可以像NSLog一样查看变量是否有值,有什么值. 今天主要介绍点高大上的方法. 一.Memory Graph Xcode8新增:Memory Graph解决闭包引用循环问题 这个时候就进入了断点模式,可以查看issue面板,注意选择右边Runtime: 有很多叹号说明就有问题了.看内存中object的名字,有一

Xcode 调试技巧(很常用)

1.Enable NSZombie Objects(开启僵尸对象) 僵尸模式是整个Xcode开发环境中最有用的调试技巧.这个技巧非常非常容易追踪到重复释放的问题.该技巧会以非常简洁的方式打印指出重复释放的类和该类的内存地址. 那么怎么开启僵尸对象呢?首先打开"Edit Scheme"(或者通过热键?<),然后选择Diagnostics选项卡,勾选Enable NSZombie Objects选项. ARC重复释放的问题.异常和更容易产生的Crashs,但是即使开启ARC,重复释放