立方 发表于 2013-2-4 02:20:30

XCode的一些调试技巧

po 命令:为 print object 的缩写,显示对象的文本描述(显示从对象的 description 消息获得的字符串信息)。
比如:
http://images.51cto.com/files/uploadimg/20120521/1020570.gif
上图中,我使用 po 命令显示一个 NSDictionary 的内容。注意在左侧我们可以看到 dict 的一些信息:3 key/value pairs,显示该 dict 包含的数据量,而展开的信息显示 isa 层次体系(即class 和 metaclass结构关系)。我们可以右击左侧的 dict,选中“Print Description of "dict"”,则可以在控制台输出 dict 的详细信息:


view plaincopyprint?

   
[*]Printing description of dict:      
[*]<CFBasicHash 0x1001149e0 >{type = immutable dict, count = 3,      
[*]entries =>      
[*]    0 : <CFString 0x100002458 >{contents = "first"} = <CFString 0x100002438 >{contents = "one"}      
[*]    1 : <CFString 0x100002498 >{contents = "second"} = <CFString 0x100002478 >{contents = "two"}      
[*]    2 : <CFString 0x1000024d8 >{contents = "third"} = <CFString 0x1000024b8 >{contents = "three"}      
[*]}      
[*](gdb)   

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

如:


view plaincopyprint?

   
[*](gdb) print (char *)[ cStringUsingEncoding:4]      
[*]$1 = 0x1001159c0 "{\n    first = one;\n    second = two;\n    third = three;\n}"      
[*](gdb) print (int)      
[*]$2 = 1      
[*](gdb)   

注:4是 NSUTF8StringEncoding 的值。
info 命令:我们可以查看内存地址所在信息
比如 "info symbol 内存地址" 可以获取内存地址所在的 symbol 相关信息:


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 *内存地址" 可以获取内存地址所在的代码行相关信息:


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版本信息


view plaincopyprint?

   
[*](gdb) show version      
[*]GNU gdb 6.3.50-20050815 (Apple version gdb-1708) (Mon Aug8 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 命令的用法。



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 模式下,如果程序即将抛出异常,就能在抛出异常处中断了。比如在前面的代码中,我让 ; 抛出异常。在 objc_exception_throw 处设置断点之后,程序就能在该代码处中断了,我们从而知道代码在什么地方出问题了。
【编辑推荐】

[*]XCode下的iOS单元测试
页: [1]
查看完整版本: XCode的一些调试技巧