Xcode断点调试之变量概览 - summary

移动开发 iOS
在Xcode中断点调试时,鼠标停留在变量上,就能看到变量的信息。但对于自定义对象,通常Xcode提供的直接信息非常有限。

问题描述

在Xcode中断点调试时,鼠标停留在变量上,就能看到变量的信息。但对于自定义对象,通常Xcode提供的直接信息非常有限,像这样

请输入图片描述

想要了解这个对象具体的内容,需要展开左边的箭头

请输入图片描述

当开发者想要知道该对象具体某个成员(很可能也是一个对象,即对象的成员的成员.....)的值时,就不得不反复展开多个箭头,平添了不少debug时的焦躁=。=

解决方案

其实LLDB的设计者并非没有考虑到这种情况,他们设计了一种机制,允许在浮动窗口和变量窗口中显示自定义类型对象的概览,称之为summary。

没错,就是浮动窗口上***一行显示的summary,我们再看一次

请输入图片描述

Summary的原理很简单,就是保存一个"对象类型->概览"的映射表,在调试时查表进行显示。在console中输入

type summary list 
  • 1.

可以查看当前LLDB支持的所有语言/平台的所有类型的summary,比如OC下的NSArray

type summary list NSArray 
  • 1.

输出的结果里,可以找到

请输入图片描述

和平常使用过程中的情况一致。

LLDB支持为自定义类型添加summary。

解决示例

直观起见,这里将写一个简单的对象并为之添加summary,下面请演员入场

@interface Rectangle : NSObject 

    NSInteger _width; 
    NSInteger _height; 

 
@property (nonatomic, assign) NSInteger width; 
@property (nonatomic, assign) NSInteger height; 
 
@end 
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.

对于这个矩形类的实例,我希望能够直接看到它的面积。

Summary可以简单地设置对象的概览为静态字符串,也可以设置为动态的如正则表达式,甚至可以设置为Python function(事实上LLDB就是使用了Python作为映射的)。

在这里,嗯。。。。。Python,就决定是你啦!

请输入图片描述

方便起见不直接在console里写入,而是把function单独放在一个文件里

def Rectangle_summary (valobj,internal_dict):      
height_val = valobj.GetChildMemberWithName('_height')      
width_val = valobj.GetChildMemberWithName('_width')      
height = height_val.GetValueAsUnsigned(0)      
width = width_val.GetValueAsUnsigned(0)      
area = height*width      
return 'Area: ' + str(area) 
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.

保存成summarys.py

保存起来而不是直接在console里写,将来就可以方便地添加其他自定义类型的summary,也可以将这个文件和开发组的成员共享:)

接下来导入到LLDB中

command script import /Users/XXX/Desktop/TypeSummaryTest/TypeSummaryTest/summarys.py 
  • 1.

P.S:这个命令目测只支持full path,请允许我在这里可耻地匿了=。=

然后将导入的function指定为映射即可

type summary add Rectangle -F summarys.Rectangle_summary 
  • 1.

这时再次查看变量,Summary已经有内容啦:)

请输入图片描述

[[117605]]

假如有多个自定义类型的summary,都可以如法炮制。进一步地,可以让Xcode自动加载summary。首先,把加载function这步也写入脚本

import lldb 
 
def Rectangle_summary (valobj,internal_dict): 
    height_val = valobj.GetChildMemberWithName('_height'
    width_val = valobj.GetChildMemberWithName('_width'
    height = height_val.GetValueAsUnsigned(0) 
    width = width_val.GetValueAsUnsigned(0) 
    area = height*width 
    return 'Area: ' + str(area) 
 
def __lldb_init_module(debugger, dict): 
    debugger.HandleCommand('type summary add Rectangle -F summarys.Rectangle_summary'
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.

然后,让Xcode在启动时自动导入这个文件。在~/下新建一个.lldbinit文件,并在其中写入command script import来导入summary文件

command script import /Users/XXX/Desktop/TypeSummaryTest/TypeSummaryTest/summarys.py 
  • 1.

.lldbinit这个技巧来自于Facebook的chisel,是一个FB扩展的LLDB命令集

That's all for today, have fun~

[[117606]]

 

参考资料

LLDB Tutorial

LLDB Data Formatters

Advanced Debugging with LLDB

LLDB Python Reference

 

责任编辑:闫佳明 来源: blog.segmentfault
相关推荐

2013-04-18 09:55:56

iOS开发Xcode调试断点

2021-04-19 20:36:06

存储Rust变量

2011-07-26 14:31:47

XCode 调试 全局

2011-07-28 14:31:55

Xcode 调试 异常

2011-10-08 14:09:27

JavaScript

2019-04-18 09:31:07

iOS项目开发断点代码

2021-08-26 05:04:53

JavaScript调试技巧

2017-04-19 10:25:01

JS断点调试

2011-07-26 14:44:53

调试 Xcode

2013-04-18 10:19:40

iOS开发Xcode调试

2009-07-14 11:34:42

MyEclipse断点JavaScript

2015-07-30 12:41:13

断点BreakPoint

2022-09-22 07:31:14

Java变量计算

2009-12-07 10:37:48

PHP预定义变量数组

2012-05-21 10:13:05

XCode调试技巧

2013-03-29 13:17:53

XCode调试技巧iOS开发

2023-10-30 23:38:03

Rust编程基础

2011-08-05 11:03:53

Xcode 证书 调试

2011-07-19 16:34:01

Xcode 证书

2022-10-13 13:21:58

系统httpsCharles
点赞
收藏

51CTO技术栈公众号