前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >XCode LLDB调试小技巧基础篇提高篇汇编篇

XCode LLDB调试小技巧基础篇提高篇汇编篇

作者头像
MelonTeam
发布2018-01-04 16:22:34
4.6K0
发布2018-01-04 16:22:34
举报
文章被收录于专栏:MelonTeam专栏MelonTeam专栏

导语: 记录平时用到的XCode LLDB调试小技巧

工欲善其事必先利其器,介绍一些LLDB调试的命令和小技巧~

基础篇

1.print命令

p 输出基本类型,例如double,int po 输出对象类型,例如NSObject 当然po也是可以输出基本类型的 p命令默认是按10进制输出的,如果想输出非十进制可以用以下方法

二进制

代码语言:javascript
复制
(lldb) p/t 10
(int) $2 = 0b00000000000000000000000000001010

八进制

代码语言:javascript
复制
(lldb) p/o 10
(int) $3 = 012

十六进制

代码语言:javascript
复制
(lldb) p/x 10
(int) $4 = 0x0000000a

更加详细的格式控制可以点击这里查看

2.expression命令

顾名思义这个是命令可以在控制台执行一条语句 比如 expr i = 5,把5赋值给i 还有一种方式 po i = 5,也是有一样的效果的,都是让i的值变成5

3.设置断点

给某个类的某个OC方法下断点 br set -n “方法描述”

代码语言:javascript
复制
(lldb) br set -n "[NSString stringWithFormat:]"
Breakpoint 2: where = Foundation`+[NSString stringWithFormat:], address = 0x000000010e292832

给所有类的某一SELECTOR下断点 br set -S selector

代码语言:javascript
复制
(lldb) br set -S initWithFrame:
Breakpoint 4: 260 locations.

断点列表查看 br list

代码语言:javascript
复制
(lldb) br list
Current breakpoints:
5: name = 'initWithFrame:', locations = 260, resolved = 260, hit count = 0
  5.1: where = UIKit`-[_UIPickerViewTopFrame initWithFrame:], address = x000000010ec60584, resolved, hit count = 0 
  5.2: where = UIKit`-[_UIOnePartImageView initWithFrame:], address = x000000010ec60a53, resolved, hit count = 0 
  5.3: where = UIKit`-[_UIPickerViewSelectionBar initWithFrame:], address = x000000010ec60c6c, resolved, hit count = 0 
  5.4: where = UIKit`-[_UIPickerWheelView initWithFrame:], address = x000000010ec60e3a, resolved, hit count = 0 
  5.5: where = UIKit`-[UIPickerView initWithFrame:], address = x000000010ec61bdf, resolved, hit count = 0 
  5.6: where = UIKit`-[_UIParallaxDimmingView initWithFrame:], address = x000000010ec70137, resolved, hit count = 0

删除全部断点 br del

代码语言:javascript
复制
(lldb) br del
About to delete all breakpoints, do you want to do that?: [Y/n] Y
All breakpoints removed. (4 breakpoints)

删除某个断点 br del 断点index(断点list里前面的x.x,例如6.1)

代码语言:javascript
复制
(lldb) br delete 6.1
0 breakpoints deleted; 1 breakpoint locations disabled.

也可以按组删除,直接输入组号就可以

代码语言:javascript
复制
(lldb) br delete 6
1 breakpoints deleted; 0 breakpoint locations disabled.

4.设置观察点

我们有时候想知道某个变量是否发生改变了,可以通过设置观察点的方式监控

代码语言:javascript
复制
(lldb) watchpoint set var self->_testA
Watchpoint created: Watchpoint 1: addr = 0x7fda62504708 size = 4 state = enabled type = w
    watchpoint spec = 'self->_testA'
    new value: 0

这样当有变化的时候便会断下来,控制台会输出如下

代码语言:javascript
复制
Watchpoint 1 hit:
old value: 0
new value: 5

默认的命令只监测write,如果读也想监测的话可以这样

代码语言:javascript
复制
(lldb) watchpoint set var -w read_write self->_testA
Watchpoint created: Watchpoint 1: addr = 0x7fc181c04238 size = 4 state = enabled type = rw
    watchpoint spec = 'self->_testA'
    new value: 0

当然也可以管理watchpoint watchpoint list //列出所有的watchpoint watchpoint del //删除所有的watchpoint

5.打印当前显示的ViewController

po [[[UIApplication sharedApplication] keyWindow] recursiveDescription]

6.打印当前屏幕上的View

po [[[[UIApplication sharedApplication] keyWindow] rootViewController] _printHierarchy]

7.沙盒路径

po NSHomeDirectory()

8.某些时候无法print frame

p (CGRect)[self.view frame]

9.Thread命令

有时候我们想让某个函数在调试的时候直接返回YES 可以断点到函数开头,然后执行以下语句 thread return YES

提高篇

1.image命令使用

平常我们出现crash的时候总会有如下输出

代码语言:javascript
复制
2017-06-24 18:21:49.053 test[2419:11812168] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[NSObject xxx:]: unrecognized selector sent to instance 0x61000000c130'
*** First throw call stack:
(
    0   CoreFoundation                      0x000000010c870b0b __exceptionPreprocess + 171
    1   libobjc.A.dylib                     0x000000010a40b141 objc_exception_throw + 48
    2   CoreFoundation                      0x000000010c8e0134 -[NSObject(NSObject) doesNotRecognizeSelector:] + 132
    3   CoreFoundation                      0x000000010c7f7840 ___forwarding___ + 1024
    4   CoreFoundation                      0x000000010c7f73b8 _CF_forwarding_prep_0 + 120
    5   test                                0x0000000109e3d74c -[ViewController viewDidLoad] + 108
    6   UIKit                               0x000000010aa8001a -[UIViewController loadViewIfRequired] + 1235
    7   UIKit                               0x000000010aa8045a -[UIViewController view] + 27
    8   UIKit                               0x000000010a94898a -[UIWindow addRootViewControllerViewIfPossible] + 65
    9   UIKit                               0x000000010a949070 -[UIWindow _setHidden:forced:] + 294
    10  UIKit                               0x000000010a95bebe -[UIWindow makeKeyAndVisible] + 42
    11  UIKit                               0x000000010a8d537f -[UIApplication _callInitializationDelegatesForMainScene:transitionContext:] + 4346
    12  UIKit                               0x000000010a8db5e4 -[UIApplication _runWithMainScene:transitionContext:completion:] + 1709
    13  UIKit                               0x000000010a8d87f3 -[UIApplication workspaceDidEndTransaction:] + 182
    14  FrontBoardServices                  0x000000010df805f6 __FBSSERIALQUEUE_IS_CALLING_OUT_TO_A_BLOCK__ + 24
    15  FrontBoardServices                  0x000000010df8046d -[FBSSerialQueue _performNext] + 186
    16  FrontBoardServices                  0x000000010df807f6 -[FBSSerialQueue _performNextFromRunLoopSource] + 45
    17  CoreFoundation                      0x000000010c816c01 __CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE0_PERFORM_FUNCTION__ + 17
    18  CoreFoundation                      0x000000010c7fc0cf __CFRunLoopDoSources0 + 527
    19  CoreFoundation                      0x000000010c7fb5ff __CFRunLoopRun + 911
    20  CoreFoundation                      0x000000010c7fb016 CFRunLoopRunSpecific + 406
    21  UIKit                               0x000000010a8d708f -[UIApplication _run] + 468
    22  UIKit                               0x000000010a8dd134 UIApplicationMain + 159
    23  test                                0x0000000109e3da7f main + 111
    24  libdyld.dylib                       0x000000010d81065d start + 1
    25  ???                                 0x0000000000000001 0x0 + 1
)
libc++abi.dylib: terminating with uncaught exception of type NSException

我们可能一眼看不出是-[ViewController viewDidLoad]的第几行Crash了,这个时候我们可以使用image lookup命令

代码语言:javascript
复制
(lldb) image lookup -a 0x0000000109e3d74c
      Address: test[0x000000010000174c] (test.__TEXT.__text + 108)
      Summary: test`-[ViewController viewDidLoad] + 108 at ViewController.m:22

这样子就很容易看出是第22行Crash了

2.野指针调试

一般野指针调试大家可能都是用Zombie Objects,但AutoreleasePool里面的crash用Zombie可能看不出来问题 这里我们介绍另外一种野指针调试方法Malloc History Malloc History可以输出某一地址的malloc和free记录,从中我们可以得到一些有用信息帮助我们定位问题,比如MRC下赋值的时候没有retain导致用的时候野指针了。

首先要打开Malloc Stack选项

然后我们写个简单的程序

代码语言:javascript
复制
- (void)viewDidLoad {
    [super viewDidLoad];
    NSDate *date = [[NSDate new] autorelease];
    [date release];
}

执行一下

如我们所料Crash了,但看堆栈和错误log好像没什么线索

我们查看左边Crash栈的第0帧

代码语言:javascript
复制
#0    0x00000001034abd5b in objc_release ()

在控制台输入 p/x $rdi($rdi在x64模拟器上是第一个寄存器,也就是指向OC方法中的Self)

代码语言:javascript
复制
(lldb) p/x $rdi
(unsigned long) $1 = 0x0000600000005750

现在我们拿到Self指针了,然后就可以用Malloc History来追查了

在控制台中输入 command script import lldb.macosx.heap,开启相关命令

代码语言:javascript
复制
(lldb) command script import lldb.macosx.heap
"malloc_info", "ptr_refs", "cstr_refs", "find_variable", and "objc_refs" commands have been installed, use the "--help" options on these commands for detailed help.

然后输入 malloc_info —stack-history xxxxxxx(xxxx是地址) 来查看相应地址的分配记录 这里我们输入malloc_info —stack-history 0x0000600000005750

代码语言:javascript
复制
(lldb) malloc_info --stack-history 0x0000600000005750
0x0000600000005750: malloc(    16) -> 0x600000005750
stack[0]: addr = 0x600000005750, type=malloc, frames:
     [0] 0x0000000106a7844a libsystem_malloc.dylib`malloc + 24
     [1] 0x0000000103967ef2 CoreFoundation`-[__NSArrayM insertObject:atIndex:] + 242
     [2] 0x0000000102f823c3 Foundation`setProtocolMetadataWithSignature + 1051
     [3] 0x0000000102f82323 Foundation`setProtocolMetadataWithSignature + 891
     [4] 0x0000000102f81f47 Foundation`setProtocolMetdataWithMethods + 370
     [5] 0x0000000102f81d87 Foundation`setProtocolMetadata + 194
     [6] 0x0000000102f81cb8 Foundation`-[NSXPCInterface setProtocol:] + 87
     [7] 0x0000000102f81be7 Foundation`+[NSXPCInterface interfaceWithProtocol:] + 56
     [8] 0x000000010fc5dd56 libMobileGestaltExtensions.dylib`___lldb_unnamed_symbol104$$libMobileGestaltExtensions.dylib + 144
     [9] 0x000000010fc5df4f libMobileGestaltExtensions.dylib`___lldb_unnamed_symbol110$$libMobileGestaltExtensions.dylib + 34
     [10] 0x000000010fc5e41b libMobileGestaltExtensions.dylib`___lldb_unnamed_symbol125$$libMobileGestaltExtensions.dylib + 121
     [11] 0x000000010659ca9d libMobileGestalt.dylib`___lldb_unnamed_symbol61$$libMobileGestalt.dylib + 445
     [12] 0x00000001065a5847 libMobileGestalt.dylib`___lldb_unnamed_symbol688$$libMobileGestalt.dylib + 97
     [13] 0x000000010659ca16 libMobileGestalt.dylib`___lldb_unnamed_symbol61$$libMobileGestalt.dylib + 310
     [14] 0x000000010659fbd9 libMobileGestalt.dylib`___lldb_unnamed_symbol302$$libMobileGestalt.dylib + 66
     [15] 0x000000010659ca16 libMobileGestalt.dylib`___lldb_unnamed_symbol61$$libMobileGestalt.dylib + 310
     [16] 0x000000010709795f BaseBoard`__18-[BSPlatform init]_block_invoke + 29
     [17] 0x000000010685105c libdispatch.dylib`_dispatch_client_callout + 8
     [18] 0x00000001068369a1 libdispatch.dylib`dispatch_once_f + 503
     [19] 0x0000000107097940 BaseBoard`-[BSPlatform init] + 89
     [20] 0x00000001070978d9 BaseBoard`__28+[BSPlatform sharedInstance]_block_invoke + 41
     [21] 0x000000010685105c libdispatch.dylib`_dispatch_client_callout + 8
     [22] 0x00000001068369a1 libdispatch.dylib`dispatch_once_f + 503
     [23] 0x00000001070978ad BaseBoard`+[BSPlatform sharedInstance] + 41
     [24] 0x0000000103e665d1 UIKit`-[UIApplication _setClassicMode:] + 122
     [25] 0x0000000103e66bc5 UIKit`-[UIApplication _fetchInfoPlistFlags] + 328
     [26] 0x0000000103e4ad5a UIKit`-[UIApplication init] + 997
     [27] 0x0000000103e56f80 UIKit`UIApplicationInstantiateSingleton + 321
     [28] 0x0000000103e574af UIKit`_UIApplicationMainPreparations + 833
     [29] 0x0000000103e57104 UIKit`UIApplicationMain + 111
     [30] 0x0000000102ecaac3 test`main + 99 at main.m:14:9
     [31] 0x000000010689d65d libdyld.dylib`start + 1

......

stack[12]: addr = 0x600000005750, type=malloc, frames:
     [0] 0x0000000106a78485 libsystem_malloc.dylib`calloc + 30
     [1] 0x00000001034a2ba1 libobjc.A.dylib`class_createInstance + 85
     [2] 0x000000010397ddd1 CoreFoundation`__CFAllocateObject + 17
     [3] 0x000000010397dda2 CoreFoundation`+[__NSDate __new:] + 18
     [4] 0x0000000102eca8cc test`-[ViewController viewDidLoad] + 76 at ViewController.m:21:20
     [5] 0x0000000103ffa01a UIKit`-[UIViewController loadViewIfRequired] + 1235
     [6] 0x0000000103ffa45a UIKit`-[UIViewController view] + 27
     [7] 0x0000000103ec298a UIKit`-[UIWindow addRootViewControllerViewIfPossible] + 65
     [8] 0x0000000103ec3070 UIKit`-[UIWindow _setHidden:forced:] + 294
     [9] 0x0000000103ed5ebe UIKit`-[UIWindow makeKeyAndVisible] + 42
     [10] 0x0000000103e4f37f UIKit`-[UIApplication _callInitializationDelegatesForMainScene:transitionContext:] + 4346
     [11] 0x0000000103e555e4 UIKit`-[UIApplication _runWithMainScene:transitionContext:completion:] + 1709
     [12] 0x0000000103e527f3 UIKit`-[UIApplication workspaceDidEndTransaction:] + 182
     [13] 0x000000010700d5f6 FrontBoardServices`__FBSSERIALQUEUE_IS_CALLING_OUT_TO_A_BLOCK__ + 24
     [14] 0x000000010700d46d FrontBoardServices`-[FBSSerialQueue _performNext] + 186
     [15] 0x000000010700d7f6 FrontBoardServices`-[FBSSerialQueue _performNextFromRunLoopSource] + 45
     [16] 0x00000001039d9c01 CoreFoundation`__CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE0_PERFORM_FUNCTION__ + 17
     [17] 0x00000001039bf0cf CoreFoundation`__CFRunLoopDoSources0 + 527
     [18] 0x00000001039be5ff CoreFoundation`__CFRunLoopRun + 911
     [19] 0x00000001039be016 CoreFoundation`CFRunLoopRunSpecific + 406
     [20] 0x0000000103e5108f UIKit`-[UIApplication _run] + 468
     [21] 0x0000000103e57134 UIKit`UIApplicationMain + 159
     [22] 0x0000000102ecaac3 test`main + 99 at main.m:14:9
     [23] 0x000000010689d65d libdyld.dylib`start + 1

stack[13]: addr = 0x600000005750, type=free, frames:
     [0] 0x00000001034a2d6e libobjc.A.dylib`object_dispose + 30
     [1] 0x000000010399c4a7 CoreFoundation`-[__NSDate dealloc] + 39
     [2] 0x00000001034acb8e libobjc.A.dylib`objc_object::sidetable_release(bool) + 202
     [3] 0x0000000102eca8f2 test`-[ViewController viewDidLoad] + 114 at ViewController.m:23:1
     [4] 0x0000000103ffa01a UIKit`-[UIViewController loadViewIfRequired] + 1235
     [5] 0x0000000103ffa45a UIKit`-[UIViewController view] + 27
     [6] 0x0000000103ec298a UIKit`-[UIWindow addRootViewControllerViewIfPossible] + 65
     [7] 0x0000000103ec3070 UIKit`-[UIWindow _setHidden:forced:] + 294
     [8] 0x0000000103ed5ebe UIKit`-[UIWindow makeKeyAndVisible] + 42
     [9] 0x0000000103e4f37f UIKit`-[UIApplication _callInitializationDelegatesForMainScene:transitionContext:] + 4346
     [10] 0x0000000103e555e4 UIKit`-[UIApplication _runWithMainScene:transitionContext:completion:] + 1709
     [11] 0x0000000103e527f3 UIKit`-[UIApplication workspaceDidEndTransaction:] + 182
     [12] 0x000000010700d5f6 FrontBoardServices`__FBSSERIALQUEUE_IS_CALLING_OUT_TO_A_BLOCK__ + 24
     [13] 0x000000010700d46d FrontBoardServices`-[FBSSerialQueue _performNext] + 186
     [14] 0x000000010700d7f6 FrontBoardServices`-[FBSSerialQueue _performNextFromRunLoopSource] + 45
     [15] 0x00000001039d9c01 CoreFoundation`__CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE0_PERFORM_FUNCTION__ + 17
     [16] 0x00000001039bf0cf CoreFoundation`__CFRunLoopDoSources0 + 527
     [17] 0x00000001039be5ff CoreFoundation`__CFRunLoopRun + 911
     [18] 0x00000001039be016 CoreFoundation`CFRunLoopRunSpecific + 406
     [19] 0x0000000103e5108f UIKit`-[UIApplication _run] + 468
     [20] 0x0000000103e57134 UIKit`UIApplicationMain + 159
     [21] 0x0000000102ecaac3 test`main + 99 at main.m:14:9
     [22] 0x000000010689d65d libdyld.dylib`start + 1

stack[14]: addr = 0x600000005750, type=malloc, frames:
     [0] 0x0000000106a7844a libsystem_malloc.dylib`malloc + 24
     [1] 0x0000000103961f45 CoreFoundation`__CFDataInit + 613
     [2] 0x0000000102fba6c9 Foundation`-[NSISObjectiveLinearExpression init] + 154
     [3] 0x0000000102fba2f0 Foundation`-[NSISEngine init] + 419
     [4] 0x000000010481a8db UIKit`-[UIView(AdditionalLayoutSupport) _initializeHostedLayoutEngine] + 359
     [5] 0x000000010480d499 UIKit`-[UIView(UIConstraintBasedLayout) _layoutEngine_windowDidChange] + 130
     [6] 0x0000000103f13909 UIKit`-[UIView(Internal) _didMoveFromWindow:toWindow:] + 209
     [7] 0x0000000103f06b96 UIKit`__45-[UIView(Hierarchy) _postMovedFromSuperview:]_block_invoke + 151
     [8] 0x0000000103f06a7d UIKit`-[UIView(Hierarchy) _postMovedFromSuperview:] + 828
     [9] 0x0000000103f16a0a UIKit`-[UIView(Internal) _addSubview:positioned:relativeTo:] + 1927
     [10] 0x0000000103f04cf8 UIKit`-[UIView(Hierarchy) addSubview:] + 838
     [11] 0x0000000103ec2c6f UIKit`-[UIWindow addRootViewControllerViewIfPossible] + 806
     [12] 0x0000000103ec3070 UIKit`-[UIWindow _setHidden:forced:] + 294
     [13] 0x0000000103ed5ebe UIKit`-[UIWindow makeKeyAndVisible] + 42
     [14] 0x0000000103e4f37f UIKit`-[UIApplication _callInitializationDelegatesForMainScene:transitionContext:] + 4346
     [15] 0x0000000103e555e4 UIKit`-[UIApplication _runWithMainScene:transitionContext:completion:] + 1709
     [16] 0x0000000103e527f3 UIKit`-[UIApplication workspaceDidEndTransaction:] + 182
     [17] 0x000000010700d5f6 FrontBoardServices`__FBSSERIALQUEUE_IS_CALLING_OUT_TO_A_BLOCK__ + 24
     [18] 0x000000010700d46d FrontBoardServices`-[FBSSerialQueue _performNext] + 186
     [19] 0x000000010700d7f6 FrontBoardServices`-[FBSSerialQueue _performNextFromRunLoopSource] + 45
     [20] 0x00000001039d9c01 CoreFoundation`__CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE0_PERFORM_FUNCTION__ + 17
     [21] 0x00000001039bf0cf CoreFoundation`__CFRunLoopDoSources0 + 527
     [22] 0x00000001039be5ff CoreFoundation`__CFRunLoopRun + 911
     [23] 0x00000001039be016 CoreFoundation`CFRunLoopRunSpecific + 406
     [24] 0x0000000103e5108f UIKit`-[UIApplication _run] + 468
     [25] 0x0000000103e57134 UIKit`UIApplicationMain + 159
     [26] 0x0000000102ecaac3 test`main + 99 at main.m:14:9
     [27] 0x000000010689d65d libdyld.dylib`start + 1

我们会发现这个地址的分配记录很多,但我主要关心我们自己程序的

代码语言:javascript
复制
stack[12]: addr = 0x600000005750, type=malloc, frames:
     [0] 0x0000000106a78485 libsystem_malloc.dylib`calloc + 30
     [1] 0x00000001034a2ba1 libobjc.A.dylib`class_createInstance + 85
     [2] 0x000000010397ddd1 CoreFoundation`__CFAllocateObject + 17
     [3] 0x000000010397dda2 CoreFoundation`+[__NSDate __new:] + 18
     [4] 0x0000000102eca8cc test`-[ViewController viewDidLoad] + 76 at ViewController.m:21:20
     [5] 0x0000000103ffa01a UIKit`-[UIViewController loadViewIfRequired] + 1235
     [6] 0x0000000103ffa45a UIKit`-[UIViewController view] + 27
     [7] 0x0000000103ec298a UIKit`-[UIWindow addRootViewControllerViewIfPossible] + 65
     [8] 0x0000000103ec3070 UIKit`-[UIWindow _setHidden:forced:] + 294
     [9] 0x0000000103ed5ebe UIKit`-[UIWindow makeKeyAndVisible] + 42
     [10] 0x0000000103e4f37f UIKit`-[UIApplication _callInitializationDelegatesForMainScene:transitionContext:] + 4346
     [11] 0x0000000103e555e4 UIKit`-[UIApplication _runWithMainScene:transitionContext:completion:] + 1709
     [12] 0x0000000103e527f3 UIKit`-[UIApplication workspaceDidEndTransaction:] + 182
     [13] 0x000000010700d5f6 FrontBoardServices`__FBSSERIALQUEUE_IS_CALLING_OUT_TO_A_BLOCK__ + 24
     [14] 0x000000010700d46d FrontBoardServices`-[FBSSerialQueue _performNext] + 186
     [15] 0x000000010700d7f6 FrontBoardServices`-[FBSSerialQueue _performNextFromRunLoopSource] + 45
     [16] 0x00000001039d9c01 CoreFoundation`__CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE0_PERFORM_FUNCTION__ + 17
     [17] 0x00000001039bf0cf CoreFoundation`__CFRunLoopDoSources0 + 527
     [18] 0x00000001039be5ff CoreFoundation`__CFRunLoopRun + 911
     [19] 0x00000001039be016 CoreFoundation`CFRunLoopRunSpecific + 406
     [20] 0x0000000103e5108f UIKit`-[UIApplication _run] + 468
     [21] 0x0000000103e57134 UIKit`UIApplicationMain + 159
     [22] 0x0000000102ecaac3 test`main + 99 at main.m:14:9
     [23] 0x000000010689d65d libdyld.dylib`start + 1

看[4]可以发现在-[ViewController viewDidLoad]的第21行malloc了一个对象

代码语言:javascript
复制
stack[13]: addr = 0x600000005750, type=free, frames:
     [0] 0x00000001034a2d6e libobjc.A.dylib`object_dispose + 30
     [1] 0x000000010399c4a7 CoreFoundation`-[__NSDate dealloc] + 39
     [2] 0x00000001034acb8e libobjc.A.dylib`objc_object::sidetable_release(bool) + 202
     [3] 0x0000000102eca8f2 test`-[ViewController viewDidLoad] + 114 at ViewController.m:23:1
     [4] 0x0000000103ffa01a UIKit`-[UIViewController loadViewIfRequired] + 1235
     [5] 0x0000000103ffa45a UIKit`-[UIViewController view] + 27
     [6] 0x0000000103ec298a UIKit`-[UIWindow addRootViewControllerViewIfPossible] + 65
     [7] 0x0000000103ec3070 UIKit`-[UIWindow _setHidden:forced:] + 294
     [8] 0x0000000103ed5ebe UIKit`-[UIWindow makeKeyAndVisible] + 42
     [9] 0x0000000103e4f37f UIKit`-[UIApplication _callInitializationDelegatesForMainScene:transitionContext:] + 4346
     [10] 0x0000000103e555e4 UIKit`-[UIApplication _runWithMainScene:transitionContext:completion:] + 1709
     [11] 0x0000000103e527f3 UIKit`-[UIApplication workspaceDidEndTransaction:] + 182
     [12] 0x000000010700d5f6 FrontBoardServices`__FBSSERIALQUEUE_IS_CALLING_OUT_TO_A_BLOCK__ + 24
     [13] 0x000000010700d46d FrontBoardServices`-[FBSSerialQueue _performNext] + 186
     [14] 0x000000010700d7f6 FrontBoardServices`-[FBSSerialQueue _performNextFromRunLoopSource] + 45
     [15] 0x00000001039d9c01 CoreFoundation`__CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE0_PERFORM_FUNCTION__ + 17
     [16] 0x00000001039bf0cf CoreFoundation`__CFRunLoopDoSources0 + 527
     [17] 0x00000001039be5ff CoreFoundation`__CFRunLoopRun + 911
     [18] 0x00000001039be016 CoreFoundation`CFRunLoopRunSpecific + 406
     [19] 0x0000000103e5108f UIKit`-[UIApplication _run] + 468
     [20] 0x0000000103e57134 UIKit`UIApplicationMain + 159
     [21] 0x0000000102ecaac3 test`main + 99 at main.m:14:9
     [22] 0x000000010689d65d libdyld.dylib`start + 1

看[3]发现我们在-[ViewController viewDidLoad]的第23行free了

我们看看对应代码

可以明显看出是21行加了一个autorelease,22行又release了导致出问题的

当然这是个简单的demo,实际情况会复杂的多,使用Malloc History也只是能提供更多信息来追查相应问题,不能保证一定能找出导致野指针的地方。

汇编篇

1.寄存器

在我们在调试的时候有时候查看寄存器会有很多有用的信息,我们先介绍下函数调用约定 x64模拟器:

  • %rax 作为函数返回值使用。
  • %rsp 栈指针寄存器,指向栈顶
  • %rdi,%rsi,%rdx,%rcx,%r8,%r9 用作函数参数,依次对应第1参数,第2参数。。。
  • %rbx,%rbp,%r12,%r13,%14,%15 用作数据存储,遵循被调用者使用规则,简单说就是随便用,调用子函数之前要备份它,以防他被修改
  • %r10,%r11 用作数据存储,遵循调用者使用规则,简单说就是使用之前要先保存原值

ARM64: arm64有32个64bit长度的通用寄存器x0~x30还有一个SP寄存器,因为arm64兼容32位所以可以只使用其中的低32bit别名w0~w30

  • r0-r7:参数/结果寄存器,r0存储返回值
  • r8:Indirect result location寄存器(直接结果位置寄存器;)
  • r9-r15:临时寄存器,存储函数的局部变量。
  • r16:IP0 第1个intra-procedure-call scratch寄存器(第1个内部过程调用寄存器或临时寄存器IP0;)
  • r17:IP1 第2个intra-procedure-call 临时寄存器 (可能被调用者 和 PLT代码是用);
  • r18:平台寄存器(如果需要的话);否则,就是一个临时寄存器
  • r19-r28:由被调用者 保存的寄存器
  • r29:FP栈帧指针
  • r30:LR链接寄存器
  • SP:栈寄存器

我们常用的一般都是传递前几个参数的寄存器,在OC方法里,一般第一个参数是Self,第二个参数是Selector,所以我们最常见的寄存器是rdi,rsi,x0,x1。 上面我们在查找野指针的时候po $rdi,也就是查看第一个寄存器也就是Self的值。

2.X命令

X命令是直接输出内存内容,非常好使

命令格式 x/nfu

参数解释: n,表示要显示的内存单元的个数 f,表示显示方式, 可取如下值:

参数

含义

x

按十六进制格式显示变量

d

按十进制格式显示变量

u

按十进制格式显示无符号整型

o

按八进制格式显示变量

t

按二进制格式显示变量

a

按十六进制格式显示变量

i

指令地址格式

c

按字符格式显示变量

f

按浮点数格式显示变量

u,表示一个地址单元的长度:

参数

含义

b

按单字节分段输出

h

按双字节分段输出

w

按四字节分段输出

g

按八字节分段输出

,表示内存地址,可以是变量名,也可以是内存地址。 更加详细的说明可以看这里

一些常用的组合: x/16xb self 会显示 self 指针地址内容,16 个字节,16 进制。 x/16cb charArray 会显示地址 charArray 地址的内容,16 个字节,按字符格式显示。

比如我们定义 char *charArray = “0123456789ABCDEF”; 分别试下两种输出

代码语言:javascript
复制
(lldb) x/16xb charArray
0x10b16155a: 0x30 0x31 0x32 0x33 0x34 0x35 0x36 0x37
0x10b161562: 0x38 0x39 0x41 0x42 0x43 0x44 0x45 0x46
(lldb) x/16cb charArray
0x10b16155a: 0123456789ABCDEF

可以看出第一种输出的是Ascii码,第二种直接输出字符了。输出查看的时候有一点要注意,arm是小端存储,低地址存放的是低位~

PS:有时候Crash的时候输出下x/16a $rsp,会看到一些额外信息~

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2017-06-26,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 基础篇
    • 1.print命令
      • 2.expression命令
        • 3.设置断点
          • 4.设置观察点
            • 5.打印当前显示的ViewController
              • 6.打印当前屏幕上的View
                • 7.沙盒路径
                  • 8.某些时候无法print frame
                    • 9.Thread命令
                    • 提高篇
                      • 1.image命令使用
                        • 2.野指针调试
                        • 汇编篇
                          • 1.寄存器
                            • 2.X命令
                            相关产品与服务
                            对象存储
                            对象存储(Cloud Object Storage,COS)是由腾讯云推出的无目录层次结构、无数据格式限制,可容纳海量数据且支持 HTTP/HTTPS 协议访问的分布式存储服务。腾讯云 COS 的存储桶空间无容量上限,无需分区管理,适用于 CDN 数据分发、数据万象处理或大数据计算与分析的数据湖等多种场景。
                            领券
                            问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档