IOS Crash总结

1、ARC中,对于调用私有函数调用中,返回值是void 或者参数本身是基本类型的,如果使用了id,因为ARC中会对参数和返回值进行retain,所以都会产生objc_retain的crash。

delloc函数是异步的:当对对象调用release的时候,即使该对象的retaincount = 0,

该对象的delloc函数也不是同步调用的。

例子:UIWebViewWk的destory函数的原因。

2、通用的情景是:观察者使用的时候。

A->B->C

A做为B的观察者向下传递,B中的C会回调到A中方法。

传统的A的delloc方法中销毁B,B的delloc方法中销毁C。在OC中由于

对象release之后,delloc方法是异步调用的,A delloc之后,B的retainCount = 0,但是当B的delloc函数还没有

调用的时候,C发生回调,就会因为A的野指针crash。

这个时候就要实现B的destory方法来销毁C。

这个destory方法在A的delloc方法中进行调用。这样就保证了A delloc的时候C也delloc了。

3、docmentView上面加入手势,网页内容发生改变,如页内的视频跳转之后,手势发生crash.

4、panGesture手势没有调用touchMove,而初始化的代码放在了touchMove中,导致变量没有初始化,成为了野指针

5、属性对象没有retain,delloc的时候crash.

以下是更改的具体案例:

7、crash发生在C代码中,很难追踪到栈:bilsonzhou 3.0以前

0 libsystem_kernel.dylib 0x3432132c __pthread_kill (in libsystem_kernel.dylib) 8

1 libsystem_c.dylib 0x32e1829e abort (in libsystem_c.dylib) 94

2 libc abi.dylib 0x37589f6a abort_message (in libc abi.dylib) 46

3 libc abi.dylib 0x3758734c _ZL17default_terminatev (in libc abi.dylib) 24

4 libobjc.A.dylib 0x3692b36e _objc_terminate (in libobjc.A.dylib) 170

5 libc abi.dylib 0x375873c4 _ZL19safe_handler_callerPFvvE (in libc abi.dylib) 76

6 libc abi.dylib 0x37587450 operator delete(void*) (in libc abi.dylib) 0

7 libc abi.dylib 0x37588824 __cxa_current_exception_type (in libc abi.dylib) 0

8 libobjc.A.dylib 0x3692b2a8 objc_exception_rethrow (in libobjc.A.dylib) 12

9 CoreFoundation 0x35d6450c CFRunLoopRunSpecific (in CoreFoundation) 404

10 CoreFoundation 0x35d6436c CFRunLoopRunInMode (in CoreFoundation) 104

11 GraphicsServices 0x322e8438 GSEventRunModal (in GraphicsServices) 136

12 UIKit 0x3634ccd4 UIApplicationMain (in UIKit) 1080

13 MttHD 0x0000377e main (in MttHD) (main.m:15)

这个栈已经存在很长时间了,根本的Crash原因是对dictionary插入了nil对象。

为什么栈变得这么丑,找不到挂的地方?

因为这句代码写在了C代码中:

void appScoreDataManager_Init(); //初始化评分管理信息

// whetherScoredFlag

NSNumber *numberObject = [g_AppScoreDataManager objectForKey:WHEHTER_SCORED_FLAG];

if (nil == numberObject)

{

[g_AppScoreDataManager setObject:MTTWhetherScoredFlag forKey:WHEHTER_SCORED_FLAG];

}

// APP_USED_COUNT

numberObject = [g_AppScoreDataManager objectForKey:APP_USED_COUNT];

if (nil == numberObject)

{

[g_AppScoreDataManager setObject:MTTAppUsedCount forKey:APP_USED_COUNT];

}

由于if语句中的代码很难被执行,所以一直没有发现。这个地方如果MTTWhetherScoredFlag不是等于0的话,会产生一个警告,

我们将warning作为error之后,这个地方就会编译不通过,而恰恰这个地方MTTWhetherScoredFlag = 0。被当成了一个nil对象,

所以不会产生warning导致编译不通过。

8、释放一个autorelease对象:bilsonzhou 3.0以前

#0 0x3374ec98 in objc_msgSend ()

#1 0x3702bc36 in CFGetRetainCount ()

#2 0x34dc9c0e in CA::release_root_if_unused ()

#3 0x34dc9bba in x_hash_table_remove_if ()

#4 0x34da8f9c in CA::Transaction::commit ()

#5 0x34da2054 in CA::Transaction::observer_callback ()

#6 0x3706aa34 in __CFRUNLOOP_IS_CALLING_OUT_TO_AN_OBSERVER_CALLBACK_FUNCTION__ ()

#7 0x3706c464 in __CFRunLoopDoObservers ()

#8 0x3706d75a in __CFRunLoopRun ()

#9 0x36ffdec2 in CFRunLoopRunSpecific ()

#10 0x36ffddca in CFRunLoopRunInMode ()

#11 0x3195641e in GSEventRunModal ()

#12 0x319564ca in GSEventRun ()

#13 0x30ff5d68 in -[UIApplication _run] ()

#14 0x30ff3806 in UIApplicationMain ()

#15 0x00003ede in main (argc=1, argv=0x2fdff880)

at /Users/bilsonzhou/Desktop/QQBrowserIPAD/src/MttHDBrowser_iPad/MttHD/MttHD/main.m:15

该bug在5.0以上系统很难重现,在4.3.3系统上面随机出现;

从这个栈看,没有我们的代码,也是鸟都看不出一个。

这是离线阅读引进的bug,由于时间较长,相关同事也离职,查找原因时花了较长时间。

通过4.3真机调试时发现了如下系统日志:

modifying layer that is being finalized - 0xd332410

基本上锁定为某个view进行了重复释放,通过对离线阅读中释放的对象一一排查,

最后锁定为:

m_btnDel = [UIButton buttonWithType:UIButtonTypeCustom];

在delloc中

[m_btnDel release];

这种crash虽然原因很简单,但是由于随机性和crash栈的信息有限,查找的难度很大。

9、内存被写坏导致随机crash,crash堆栈如下 3.0以前

Exception Type: EXC_BAD_ACCESS (SIGSEGV)

Exception Codes: KERN_INVALID_ADDRESS at 0x00000028

Crashed Thread: 0

Thread 0 name: Dispatch queue: com.apple.main-thread

Thread 0 Crashed:

0 WebKit 0x393cfe62 -[WebView(WebPrivate) _loadBackForwardListFromOtherView:] + 130

1 MttHD 0x0009e364 -[UIWebViewWK loadUrlFromOtherWK:] (UIWebViewWK.mm:4741)

2 MttHD 0x0001a432 -[UIMttBrowserView preloadUrls:] (UIMttBrowserView.m:6341)

3 Foundation 0x33408652 __NSFireDelayedPerform + 446

4 CoreFoundation 0x32ace854 __CFRUNLOOP_IS_CALLING_OUT_TO_A_TIMER_CALLBACK_FUNCTION__ + 12

5 CoreFoundation 0x32ace4fe __CFRunLoopDoTimer + 270

6 CoreFoundation 0x32acd172 __CFRunLoopRun + 1226

7 CoreFoundation 0x32a40238 CFRunLoopRunSpecific + 352

8 CoreFoundation 0x32a400c4 CFRunLoopRunInMode + 100

9 GraphicsServices 0x365fb336 GSEventRunModal + 70

10 UIKit 0x3495c2b4 UIApplicationMain + 1116

11 MttHD 0x00003982 main (main.m:15)

12 MttHD 0x00003934 0x1000 + 10548

从上面crash线程的堆栈很难找到问题,再往下下面其它线程的堆栈;

Thread 16 name: Dispatch queue: com.apple.root.low-priority

Thread 16:

0 libsystem_kernel.dylib 0x3ae66e30 mach_msg_trap + 20

1 libsystem_kernel.dylib 0x3ae66fd0 mach_msg + 48

2 CoreFoundation 0x32ace2b6 __CFRunLoopServiceMachPort + 126

3 CoreFoundation 0x32acd02c __CFRunLoopRun + 900

4 CoreFoundation 0x32a40238 CFRunLoopRunSpecific + 352

5 CoreFoundation 0x32a400c4 CFRunLoopRunInMode + 100

6 CFNetwork 0x327a1612 CFURLConnectionSendSynchronousRequest + 330

7 Foundation 0x334353da +[NSURLConnection sendSynchronousRequest:returningResponse:error:] + 242

8 MttHD 0x0019d76c __30-[MttSubscribeImage pullImage]_block_invoke_0 (MttSubscribeImage.m:310)

9 MttHD 0x0019eaca __41-[MttSubscribeTaskQueue dispatch:forKey:]_block_invoke_075 (MttSubscribeTaskQueue.m:161)

10 libdispatch.dylib 0x3ad9d790 _dispatch_call_block_and_release + 8

11 libdispatch.dylib 0x3ada1652 _dispatch_root_queue_drain + 274

12 libdispatch.dylib 0x3ada17d4 _dispatch_worker_thread2 + 88

13 libsystem_c.dylib 0x3adc57ee _pthread_wqthread + 358

14 libsystem_c.dylib 0x3adc5680 start_wqthread + 4

发现一个可疑的线程,该线程的堆栈正好跑完并等待中,恰好是有程序本身的代码,通过review堆栈中的代码发现,response变量没有初始化。

NSHTTPURLResponse *response ;

self.data = [NSURLConnection sendSynchronousRequest:request returningResponse:&response error: nil];

为什么没有初始化会导致crash呢?因为sendSynchronousRequest 的 returningResponse变量是out型变量,则函数会把结果写入returningResponse变量中,

当response没有初始化的时候系统默认会给它一个随机内存,sendSynchronousRequest 函数将内容写入这块随机内存程序以后的运行很可能会导致随机crash。

10、对象实例调用自身函数release自身实例导致crash 3.0以前

在MttVideoView类对象实例的dismissVideoView函数同步调用了closeVideoView将自身实例从UI树移除并release自身,从而导致随机crash,crash的堆栈

如下:

Exception Type: EXC_BAD_ACCESS (SIGSEGV)

Exception Codes: KERN_INVALID_ADDRESS at 0xc0000008

Crashed Thread: 0

Thread 0 name: Dispatch queue: com.apple.main-thread

Thread 0 Crashed:

0 libobjc.A.dylib 0x3358bc98 objc_msgSend + 16

1 CoreFoundation 0x36e33cd6 CFRetain + 62

2 CoreFoundation 0x36e3a176 +[__NSArrayI __new::] + 54

3 CoreFoundation 0x36e38a6e -[__NSPlaceholderArray initWithObjects:count:] + 122

4 QuartzCore 0x34c01db6 -[CALayerArray copyWithZone:] + 42

5 CoreFoundation 0x36e39b4a -[NSObject(NSObject) copy] + 10

6 UIKit 0x30e2bd7c -[UIView dealloc] + 52

7 MttHD 0x001e83e8 -[MttVideoView dealloc] (MttVideoView.m:378)

8 CoreFoundation 0x36e34c3c -[NSObject(NSObject) release] + 24

9 CoreFoundation 0x36e3519a CFRelease + 62

10 CoreFoundation 0x36e3aba2 -[__NSArrayM dealloc] + 86

11 CoreFoundation 0x36e34c3c -[NSObject(NSObject) release] + 24

12 CoreFoundation 0x36e3519a CFRelease + 62

13 CoreFoundation 0x36e37eb4 _CFAutoreleasePoolPop + 140

14 Foundation 0x33725bae NSPopAutoreleasePool + 2

15 Foundation 0x337aa73c __NSFireDelayedPerform + 472

16 CoreFoundation 0x36ea7a40 __CFRUNLOOP_IS_CALLING_OUT_TO_A_TIMER_CALLBACK_FUNCTION__ + 8

17 CoreFoundation 0x36ea9ec4 __CFRunLoopDoTimer + 844

18 CoreFoundation 0x36eaa83e __CFRunLoopRun + 1082

19 CoreFoundation 0x36e3aebc CFRunLoopRunSpecific + 224

20 CoreFoundation 0x36e3adc4 CFRunLoopRunInMode + 52

21 GraphicsServices 0x31793418 GSEventRunModal + 108

22 GraphicsServices 0x317934c4 GSEventRun + 56

23 UIKit 0x30e32d62 -[UIApplication _run] + 398

24 UIKit 0x30e30800 UIApplicationMain + 664

25 MttHD 0x00003800 main (main.m:15)

26 MttHD 0x000037b0 0x1000 + 10160

这个是手动点击删除小窗口按钮退出小窗口的,结合代码分析,删除这个实例的堆栈必须有函数closeVideoView ,但是从crash的堆栈上看,没有发现函数closeVideoView的堆栈,

觉得很诡异,不符合堆栈逻辑。为什么会出现上面的堆栈呢?是因为该实例的函数调用栈还没有完成退出就调用自身的dealloc函数将自己删除掉了,

导致栈上的地址出现随机错误。

解决总结:要删除实例自身,应该要用异步延时删除,不能同步删除。

11、加入手势的对象发生了变化 bilsonzhou 3.0以前

Thread 2 Crashed:

0 libsystem_kernel.dylib 0x33db3a1c __pthread_kill + 8

1 libsystem_c.dylib 0x34aa73b4 pthread_kill + 52

2 libsystem_c.dylib 0x34a9fb78 __abort + 80

3 libsystem_c.dylib 0x34a9fc18 abort + 104

4 libstdc++.6.dylib 0x35470a64 __gnu_cxx::__verbose_terminate_handler() + 376

5 libobjc.A.dylib 0x32ce706c _objc_terminate + 104

6 libstdc++.6.dylib 0x3546ee36 __cxxabiv1::__terminate(void (*)()) + 46

7 libstdc++.6.dylib 0x3546ee8a std::terminate() + 10

8 libstdc++.6.dylib 0x3546ef5a __cxa_throw + 78

9 libobjc.A.dylib 0x32ce5c84 objc_exception_throw + 64

10 CoreFoundation 0x36593062 -[__NSArrayM objectAtIndex:] + 178

11 CoreFoundation 0x365ba130 -[NSMutableArray removeObject:range:identical:] + 284

12 CoreFoundation 0x365b9ffa -[NSMutableArray removeObject:] + 46

13 UIKit 0x305e31fe -[UIView(UIViewGestures) removeGestureRecognizer:] + 54

14 UIKit 0x305e3004 -[UIWebSelectionAssistant setGestureRecognizers] + 48

15 UIKit 0x305e4408 -[UIWebSelectionAssistant setEnabled:] + 48

16 UIKit 0x30664c70 -[UIWebDocumentView loadRequest:] + 168

17 CoreFoundation 0x3662b79c __invoking___ + 60

18 CoreFoundation 0x365a3436 -[NSInvocation invoke] + 102

19 WebCore 0x35c29c36 _ZL11SendMessageP12NSInvocation + 10

20 WebCore 0x35c29c0e _ZL15HandleAPISourcePv + 66

21 CoreFoundation 0x365ffa72 __CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE0_PERFORM_FUNCTION__ + 6

22 CoreFoundation 0x36601758 __CFRunLoopDoSources0 + 376

23 CoreFoundation 0x366024e4 __CFRunLoopRun + 224

24 CoreFoundation 0x36592ebc CFRunLoopRunSpecific + 224

25 CoreFoundation 0x36592dc4 CFRunLoopRunInMode + 52

26 WebCore 0x35c2827e _ZL12RunWebThreadPv + 382

27 libsystem_c.dylib 0x34aa730a _pthread_start + 242

28 libsystem_c.dylib 0x34aa8bb4 thread_start + 0

这是个随机的bug,栈里面也没有我们的代码。幸好4.3系统在腾讯视频发生页内跳转之后该crash高概率出现了。

最后发现原因是;网页的双指单击手势加到了documentView上面,发生页内跳转之后documentView的内容发生了变化。在网页释放的时候就挂了。

修改方法是把手势加到了网页的scroll上面。

12、手势crash. bilsonzhou 3.0以前 3.1修复

0 libobjc.A.dylib 0x3b41c692 0x3b419000 13970

1 MttHD 0x000fce4c -[GestureDetectWindow handleOneFingerPan:] (in MttHD) (GestureDetectWindow.m:237)

2 UIKit 0x354a6d88 0x35386000 1183112

3 UIKit 0x3546e3f4 0x35386000 951284

4 UIKit 0x3565ba38 0x35386000 2972216

5 UIKit 0x3539282e 0x35386000 51246

6 UIKit 0x35391292 0x35386000 45714

7 UIKit 0x3539c1e6 0x35386000 90598

8 UIKit 0x3539bdb2 0x35386000 89522

9 UIKit 0x35389800 0x35386000 14336

10 UIKit 0x3538911a 0x35386000 12570

11 GraphicsServices 0x370925a2 0x3708c000 26018

12 GraphicsServices 0x370921d2 0x3708c000 25042

13 CoreFoundation 0x33556172 0x334bf000 618866

14 CoreFoundation 0x33556116 0x334bf000 618774

15 CoreFoundation 0x33554f98 0x334bf000 614296

16 CoreFoundation 0x334c7ebc 0x334bf000 36540

17 CoreFoundation 0x334c7d48 0x334bf000 36168

18 GraphicsServices 0x370912ea 0x3708c000 21226

19 UIKit 0x353dd300 0x35386000 357120

20 MttHD 0x0000331e main (in MttHD) (main.m:15)

该crash在以前版本一直有上报,3.0更改手势机制之后上报量突然增大。

在3.0灰度版本的时候就有上报,但是上报的栈指向的是MttBrowserView成了野指针。如果

browserview都成了野指针那整个浏览器都野了,因此灰度之后排查了browserView中成员变量。对照3.0以前相关crash附近手势的代码进行了更改。

结果发出去之后还是有大量的上报。后来通过打印大量日志后发现,panGesture手势的三个过程:

touch begin,move,end。不是每次调用都会进入move。而我们的变量初始化都放在了move当中,move没有调用导致变量没有初始化野指针crash.

这个地方日志上报的栈中的行数并不是确定的。

13、NSRange Exception crash bilsonzhou 3.2引入

0 CoreFoundation 0x36dde29e __exceptionPreprocess + 158

1 libobjc.A.dylib 0x3738697a objc_exception_throw + 26

2 CoreFoundation 0x36dde1c0 +[NSException raise:format:] + 100

3 Foundation 0x32ab175e -[NSData(NSData) subdataWithRange:] + 174

4 MttHD 0x002300bc -[MTTCommandTunnel _send] (MTTCommandTunnel.m:194)

5 MttHD 0x0022f950 -[MTTCommandTunnel streamHasSpaceAvailable:] (MTTCommandTunnel.m:126)

6 MttHD 0x0023025e -[MTTCommandTunnel stream:handleEvent:] (MTTCommandTunnel.m:239)

7 CoreFoundation 0x36d7b7ca _signalEventSync + 70

8 CoreFoundation 0x36d8161e _cfstream_solo_signalEventSync + 70

9 CoreFoundation 0x36d7b502 _CFStreamSignalEvent + 322

10 CFNetwork 0x32446862 CoreWriteStreamCFStreamSupport::coreStreamWriteEvent(__CoreWriteStream*, unsigned long) + 94

11 CFNetwork 0x32446218 CoreWriteStreamClient::coreStreamEventsAvailable(unsigned long) + 32

12 CFNetwork 0x324474c8 CoreStreamBase::_callClientNow() + 40

13 CFNetwork 0x3244725c CoreStreamBase::_streamSetEventAndScheduleDelivery(unsigned long, unsigned char) + 84

14 CFNetwork 0x32447662 CoreStreamBase::_streamInterface_SignalEvent(unsigned long, CFStreamError const*) + 30

15 CFNetwork 0x323b5c76 SocketStream::socketCallback(__CFSocket*, unsigned long, __CFData const*, void const*) + 130

16 CFNetwork 0x323b5bd6 SocketStream::_SocketCallBack_stream(__CFSocket*, unsigned long, __CFData const*, void const*, void*) + 70

17 CoreFoundation 0x36db5f18 __CFSocketPerformV0 + 792

18 CoreFoundation 0x36db367e __CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE0_PERFORM_FUNCTION__ + 10

19 CoreFoundation 0x36db2f7a __CFRunLoopDoSources0 + 358

20 CoreFoundation 0x36db1cb2 __CFRunLoopRun + 642

21 CoreFoundation 0x36d24eb8 CFRunLoopRunSpecific + 352

22 CoreFoundation 0x36d839b6 CFRunLoopRun + 94

23 MttHD 0x0022f7b6 -[MTTCommandTunnel tunnelThreadMain:] (MTTCommandTunnel.m:113)

24 Foundation 0x32b28678 __NSThread__main__ + 968

25 libsystem_c.dylib 0x337da30c _pthread_start + 304

26 libsystem_c.dylib 0x337da1d4 thread_start + 4

挂的原因是NSRange越界了。

NSInteger length = [self.outputStream write:self.sendBuffer.bytes maxLength:self.sendBuffer.length];

self.sendBuffer = [self.sendBuffer subdataWithRange:NSMakeRange(length, self.sendBuffer.length - length)].mutableCopy;

前一句代码的写动作出错了,返回-1,由于NSRange为无符号型的,最后就发生溢出,成为一个超大整数发生越界。

对于会抛出异常的代码,尤其是数组,字符串类操作比较多的代码,最后try catch 一下。再通过和MTTEXCEPTIONLOG()在catch中输出exception信息。

我添加了两个新的log宏定义MTTERRORLOG()和MTTEXCEPTIONLOG(),这两个宏在调试的时候会很显眼的输出错误信息,并且会将程序主动crash。

便于发现问题。发布版本不会收到影响。

14、initStringWithCString crash bilsonzhou 3.2引入

0 libsystem_c.dylib 0x31e43884 strlen + 12

1 CoreFoundation 0x329e4fa8 CFStringCreateWithCString + 12

2 MttHD 0x0022426e -[ShareView addFavoriteRequest:withPageURL:shareEntrance:] (ShareView.m:349)

3 MttHD 0x00223ac4 -[ShareView addFavoritePage] (ShareView.m:239)

4 MttHD 0x00223a64 -[ShareView canAddFavoritePage] (ShareView.m:231)

5 MttHD 0x002234e8 -[ShareView handleTouchUp:] (ShareView.m:118)

6 CoreFoundation 0x329e83f6 -[NSObject performSelector:withObject:withObject:] + 46

7 UIKit 0x34fb0e00 -[UIApplication sendAction:to:from:forEvent:] + 56

8 UIKit 0x34fb0dbc -[UIApplication sendAction:toTarget:fromSender:forEvent:] + 24

9 UIKit 0x34fb0d9a -[UIControl sendAction:to:forEvent:] + 38

10 UIKit 0x34fb0b0a -[UIControl(Internal) _sendActionsForEvents:withEvent:] + 486

11 UIKit 0x34fb1442 -[UIControl touchesEnded:withEvent:] + 470

12 UIKit 0x34faf924 -[UIWindow _sendTouchesForEvent:] + 312

13 UIKit 0x34faf312 -[UIWindow sendEvent:] + 374

14 DisplayRecorder.dylib 0x00bb5998 0xba9000 + 51608

15 UIKit 0x34f9568e -[UIApplication sendEvent:] + 350

16 UIKit 0x34f94f34 _UIApplicationHandleEvent + 5820

17 GraphicsServices 0x32b32224 PurpleEventCallback + 876

18 CoreFoundation 0x32a6251c __CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE1_PERFORM_FUNCTION__ + 32

19 CoreFoundation 0x32a624be __CFRunLoopDoSource1 + 134

20 CoreFoundation 0x32a6130c __CFRunLoopRun + 1364

21 CoreFoundation 0x329e449e CFRunLoopRunSpecific + 294

22 CoreFoundation 0x329e4366 CFRunLoopRunInMode + 98

23 GraphicsServices 0x32b31432 GSEventRunModal + 130

24 UIKit 0x34fc3cce UIApplicationMain + 1074

25 MttHD 0x00003700 main (main.m:15)

26 MttHD 0x000036b0 0x1000 + 9904

通常NSString的函数如果传入nil对象是会抛出异常的,但是initStringWithCString这个方法传入nil对象是badexec错误。再调用的时候要记得判断。

15 数据库的单列进行多线程访问 crash bilsonzhou 3.0以前引入

0 libsqlite3.dylib 0x3c321524 0x390a3524 (in libsqlite3.dylib) 5212

1 libsqlite3.dylib 0x3c31faae 0x390a1aae (in libsqlite3.dylib) 326

2 libsqlite3.dylib 0x3c317288 0x39099288 (in libsqlite3.dylib) 6288

3 libsqlite3.dylib 0x3c3060d0 0x390880d0 (in libsqlite3.dylib) 5776

4 libsqlite3.dylib 0x3c304980 0x39086980 (in libsqlite3.dylib) 244

5 libsqlite3.dylib 0x3c304144 0x39086144 (in libsqlite3.dylib) 300

6 libsqlite3.dylib 0x3c303c0e 0x39085c0e (in libsqlite3.dylib) 514

7 libsqlite3.dylib 0x3c30396e 0x3908596e (in libsqlite3.dylib) 262

8 libsqlite3.dylib 0x3c33a956 sqlite3_prepare_v2 (in libsqlite3.dylib) 30

9 MttHD 0x0020de14 -[FMDatabase executeQuery:withArgumentsInArray:orVAList:] (in MttHD) (FMDatabase.m:327)

10 MttHD 0x0020dfd8 -[FMDatabase executeQuery:] (in MttHD) (FMDatabase.m:432)

11 MttHD 0x0003fc0a -[MttHistoryManager mostVisitRecordByID:] (in MttHD) (MttHistoryManager.m:715)

12 MttHD 0x000410ce -[MttHistoryManager mostVisitStartPageRecord] (in MttHD) (MttHistoryManager.m:1141)

13 MttHD 0x001968f6 -[QuicklinkViewNew getUnLockItemCount] (in MttHD) (QuicklinkViewNew.m:1483)

14 MttHD 0x0012a490 -[MttHDStatInfo protocol] (in MttHD) (MttHDStatInfo.m:179)

15 MttHD 0x00114898 [MttSTStat(Adapter) mtthdInstance] (in MttHD) (MttSTStat Adapter.m:39)

16 MttHD 0x00122bec __52-[MttStatService statWithCompleteBlock:failedBlock:]_block_invoke_06 (in MttHD) (MttStatService.m:38)

17 libdispatch.dylib 0x3c52111e _dispatch_call_block_and_release (in libdispatch.dylib) 10

18 libdispatch.dylib 0x3c524ece _dispatch_queue_drain$VARIANT$mp (in libdispatch.dylib) 142

19 libdispatch.dylib 0x3c524dc0 _dispatch_queue_invoke$VARIANT$mp (in libdispatch.dylib) 40

20 libdispatch.dylib 0x3c52591c _dispatch_root_queue_drain (in libdispatch.dylib) 184

21 libdispatch.dylib 0x3c525ac0 _dispatch_worker_thread2 (in libdispatch.dylib) 84

22 libsystem_c.dylib 0x3c555a10 _pthread_wqthread (in libsystem_c.dylib) 360

多个线程都同时对数据库进行访问,造成冲突之后crash。

很多使用单例的地方,如果不做好同步,都有造成线程冲突crash的风险。

解决方法:由于子线程访问数据库的地方不多,将访问数据库都同步到了主线程。

16 进度条绘制和内核的图片绘制冲突 bilsonzhou 3.0以前引入

Thread 0 Crashed:

0 CoreGraphics 0x3732b1b0 DYLD-STUB$$ceilf + 0

1 CoreGraphics 0x3723cc86 CGRectIntegral + 86

2 CoreGraphics 0x3724bb82 CGImageBlockCreate + 106

3 ImageIO 0x3349fc70 copyImageBlockSetPNG + 1820

4 ImageIO 0x3349f35e ImageProviderCopyImageBlockSetCallback + 202

5 CoreGraphics 0x3724baf6 CGImageProviderCopyImageBlockSetWithOptions + 226

6 CoreGraphics 0x3724ba00 CGImageProviderCopyImageBlockSet + 32

7 CoreGraphics 0x3724b72e img_blocks_create + 182

8 CoreGraphics 0x37247140 img_data_lock + 1656

9 CoreGraphics 0x372463b8 CGSImageDataLock + 104

10 libRIP.A.dylib 0x3477f63c ripc_AcquireImage + 2676

11 libRIP.A.dylib 0x3477cc52 ripc_DrawImage + 462

12 CoreGraphics 0x37246284 CGContextDelegateDrawImage + 44

13 CoreGraphics 0x37246142 CGContextDrawImage + 250

14 MttHD 0x000256f4 -[AJProgressLayer drawInContext:] (UIMttBrowserAddressField.m:89)

15 QuartzCore 0x34cbdd24 _ZL16backing_callbackP9CGContextPv + 32

16 QuartzCore 0x34cbd776 CABackingStoreUpdate + 1226

17 QuartzCore 0x34cbd178 -[CALayer _display] + 724

18 QuartzCore 0x34cbce86 -[CALayer display] + 134

19 QuartzCore 0x34cb1706 CALayerDisplayIfNeeded + 178

20 QuartzCore 0x34cb11c6 CA::Context::commit_transaction(CA::Transaction*) + 214

21 QuartzCore 0x34cb0fd0 CA::Transaction::commit() + 184

22 QuartzCore 0x34caa04e CA::Transaction::observer_callback(__CFRunLoopObserver*, unsigned long, void*) + 50

23 CoreFoundation 0x36f72a2e __CFRUNLOOP_IS_CALLING_OUT_TO_AN_OBSERVER_CALLBACK_FUNCTION__ + 10

24 CoreFoundation 0x36f7445e __CFRunLoopDoObservers + 406

25 CoreFoundation 0x36f75754 __CFRunLoopRun + 848

26 CoreFoundation 0x36f05ebc CFRunLoopRunSpecific + 224

27 CoreFoundation 0x36f05dc4 CFRunLoopRunInMode + 52

28 GraphicsServices 0x3185e418 GSEventRunModal + 108

29 GraphicsServices 0x3185e4c4 GSEventRun + 56

30 UIKit 0x30efdd62 -[UIApplication _run] + 398

31 UIKit 0x30efb800 UIApplicationMain + 664

32 MttHD 0x00003578 main (main.m:15)

33 MttHD 0x00003528 0x1000 + 9512

mttf偶尔会有该栈的上报,老俞在访问百度贴吧很多图片的时候产生了该crash,在内核线程中也发现了drawInContext函数。

猜测CGContextDrawImage绘制图片和内核绘制图片产生了线程冲突。通过img的drawInRect函数重写了进度条的绘制进行了规避。

17 UIImageWriteToSavedPhotosAlbum 会产生异常 3.2以前引入

0 CoreFoundation 0x341ae8be __exceptionPreprocess (in CoreFoundation) 162

1 libobjc.A.dylib 0x358ca1e4 objc_exception_throw (in libobjc.A.dylib) 32

2 CoreData 0x33b7064a -[NSPersistentStoreCoordinator setMetadata:forPersistentStore:] (in CoreData) 410

3 PhotoLibraryServices 0x328efbb8 [PLManagedObjectContext(Private) recordVersion:forStore:] (in PhotoLibraryServices) 392

4 PhotoLibraryServices 0x328f0022 [PLManagedObjectContext(Private) configurePersistentStoreCoordinator:] (in PhotoLibraryServices) 1122

5 PhotoLibraryServices 0x328f069a __69 [PLManagedObjectContext(Protected) sharedPersistentStoreCoordinator]_block_invoke_0346 (in PhotoLibraryServices) 178

6 libdispatch.dylib 0x374907ea _dispatch_barrier_sync_f_invoke (in libdispatch.dylib) 22

7 libdispatch.dylib 0x3749065a dispatch_barrier_sync_f$VARIANT$up (in libdispatch.dylib) 62

8 libdispatch.dylib 0x3749028e dispatch_sync_f$VARIANT$up (in libdispatch.dylib) 18

9 libdispatch.dylib 0x37490910 dispatch_sync$VARIANT$up (in libdispatch.dylib) 32

10 PhotoLibraryServices 0x328f059a [PLManagedObjectContext(Protected) sharedPersistentStoreCoordinator] (in PhotoLibraryServices) 154

11 PhotoLibraryServices 0x328eed94 -[PLManagedObjectContext initWithConcurrencyType:useSharedPersistentStoreCoordinator:] (in PhotoLibraryServices) 120

12 PhotoLibraryServices 0x328eec72 [PLManagedObjectContext contextForPhotoLibrary:] (in PhotoLibraryServices) 114

13 PhotoLibraryServices 0x328ee894 -[PLPhotoLibrary(Protected) loadDatabase] (in PhotoLibraryServices) 236

14 PhotoLibraryServices 0x328b7184 -[PLPhotoLibrary initWithPath:canTriggerDatabaseUpdate:] (in PhotoLibraryServices) 304

15 PhotoLibraryServices 0x328fe1a4 __42 [PLSharedPhotoLibrary sharedPhotoLibrary]_block_invoke_0 (in PhotoLibraryServices) 60

16 libdispatch.dylib 0x37492576 dispatch_once_f$VARIANT$up (in libdispatch.dylib) 42

17 PhotoLibraryServices 0x328fe162 [PLSharedPhotoLibrary sharedPhotoLibrary] (in PhotoLibraryServices) 82

18 PhotoLibraryServices 0x328bf06e __withSavedPhotosAlbumUUID_block_invoke_0 (in PhotoLibraryServices) 50

19 libdispatch.dylib 0x37492576 dispatch_once_f$VARIANT$up (in libdispatch.dylib) 42

20 PhotoLibraryServices 0x328be436 withSavedPhotosAlbumUUID (in PhotoLibraryServices) 186

21 PhotoLibraryServices 0x328be378 PLSaveImageToCameraRoll (in PhotoLibraryServices) 76

22 UIKit 0x354831d4 UIImageWriteToSavedPhotosAlbum (in UIKit) 76

23 MttHD 0x001b0eb0 -[MttImageArticleMainView tapButton:] (in MttHD) (MttImageArticleMainVIew.m:983)

24 CoreFoundation 0x34108434 -[NSObject performSelector:withObject:withObject:] (in CoreFoundation) 52

25 UIKit 0x352369ea -[UIApplication sendAction:to:from:forEvent:] (in UIKit) 62

26 UIKit 0x352369a6 -[UIApplication sendAction:toTarget:fromSender:forEvent:] (in UIKit) 30

27 UIKit 0x35236984 -[UIControl sendAction:to:forEvent:] (in UIKit) 44

28 UIKit 0x352366f4 -[UIControl(Internal) _sendActionsForEvents:withEvent:] (in UIKit) 492

29 UIKit 0x3523702c -[UIControl touchesEnded:withEvent:] (in UIKit) 476

30 UIKit 0x3523550e -[UIWindow _sendTouchesForEvent:] (in UIKit) 318

31 UIKit 0x35234f00 -[UIWindow sendEvent:] (in UIKit) 380

32 UIKit 0x3521b4ec -[UIApplication sendEvent:] (in UIKit) 356

33 UIKit 0x3521ad2c _UIApplicationHandleEvent (in UIKit) 5808

34 GraphicsServices 0x35d45df2 PurpleEventCallback (in GraphicsServices) 882

35 CoreFoundation 0x34182552 __CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE1_PERFORM_FUNCTION__ (in CoreFoundation) 38

36 CoreFoundation 0x341824f4 __CFRunLoopDoSource1 (in CoreFoundation) 140

37 CoreFoundation 0x34181342 __CFRunLoopRun (in CoreFoundation) 1370

38 CoreFoundation 0x341044dc CFRunLoopRunSpecific (in CoreFoundation) 300

39 CoreFoundation 0x341043a4 CFRunLoopRunInMode (in CoreFoundation) 104

40 GraphicsServices 0x35d44fcc GSEventRunModal (in GraphicsServices) 156

41 UIKit 0x35249742 UIApplicationMain (in UIKit) 1090

42 MttHD 0x0000377e main (in MttHD) (main.m:15)

43 MttHD 0x00003730 start (in MttHD) 40

UIImageWriteToSavedPhotosAlbum这个函数会抛出异常,在网页图片那块保存到本地我就修改过一次。后来的同学估计不知道,又

没有捕获。看来分析还是很有必要的。

18、performSelector 操作会对对象本身retain一下。ranger bilsonzhou

由于异步操作会对对象本身进行一次retain,如果将异步操作放在delloc中cancel。会造成对象的延迟释放,如果这时候对观察者产生

回调的话就会有crash发生。

例如:

A->B->C

A做为B的观察者向下传递,B中的C会回调到A中方法。

传统的A的delloc方法中销毁B,B的delloc方法中销毁C。由于异步操作造成B延迟释放,

A delloc之后,B没有立即放生释放,这时候B产生回调或者C发生回调,就会因为A的野指针crash。

搜索框的crash的根本原因也是这个,下面是crash栈

Thread 0:

0 libobjc.A.dylib 0x33a54c98 objc_msgSend + 16

1 MttHD 0x000547e4 -[UIToolbarSearchInputPopMenuController onGetAssociationOfInput:data:] (UIToolbarSearchInputPopMenuController.m:574)

2 MttHD 0x00203380 __block_global_0 (MttGetAssociationalService.m:58)

3 libdispatch.dylib 0x338669c2 _dispatch_barrier_sync_f_slow_invoke + 62

4 libdispatch.dylib 0x338670e6 _dispatch_main_queue_callback_4CF$VARIANT$mp + 282

5 CoreFoundation 0x37373934 __CFRunLoopRun + 1328

6 CoreFoundation 0x37303ebc CFRunLoopRunSpecific + 224

7 CoreFoundation 0x37303dc4 CFRunLoopRunInMode + 52

8 GraphicsServices 0x31c5c418 GSEventRunModal + 108

9 GraphicsServices 0x31c5c4c4 GSEventRun + 56

10 UIKit 0x312fbd62 -[UIApplication _run] + 398

11 UIKit 0x312f9800 UIApplicationMain + 664

12 MttHD 0x00003740 main (main.m:15)

13 MttHD 0x000036f0 0x1000 + 9968

- (void)onGetAssociationOfInput:(NSString *)keyWord data:(NSArray *)result

{

NSString* lastSearchKeyWord = keyWord;

[NSObject cancelPreviousPerformRequestsWithTarget:self selector:@selector(loadSearchRecord) object:nil];

[[MttHDStatInfo theSpecial] statUserBehavior:MttHDUserBehavior_Receive_Associational];

NSString *searchString = self.searchString;

这个地方是搜索热词的回调代码,这里面的self在输入弹出框消失的时候会先进行一次释放,

[NSObject cancelPreviousPerformRequestsWithTarget:self selector:@selector(loadSearchRecord) object:nil];

这句代码会将异步对自身的retain再释放一次。如果网络情况差,热词回调慢于弹出框释放,上面

的代码的实际执行就会如下:

NSString* lastSearchKeyWord = keyWord;

[NSObject cancelPreviousPerformRequestsWithTarget:self selector:@selector(loadSearchRecord) object:nil];

[[MttHDStatInfo theSpecial] statUserBehavior:MttHDUserBehavior_Receive_Associational];

[self release];

[self delloc];

//这时候self已经野了,这句话以执行就会野指针挂掉

NSString *searchString = self.searchString;

这个crash的随机性很高,通常情况时热词先回来,弹出框再消失就不会发生,只有在网络回调慢的时候才会发生。

针对这种情况,需要对有异步操作的函数写一个destroy函数来cancel异步操作,在观察者发生释放的时候调用destroy函数。以达到同步释放

后续这块会对异步操作进行梳理。

19、代理对象被释放,delegate没有设置Nil,delegate回调野指针导致block发生crash. 3.2引入 bilsonzhou

0 libobjc.A.dylib 0x317dff78 objc_msgSend (in libobjc.A.dylib) 16

1 libdispatch.dylib 0x3491fc58 _dispatch_call_block_and_release (in libdispatch.dylib) 12

2 libdispatch.dylib 0x34921ee6 _dispatch_main_queue_callback_4CF$VARIANT$mp (in libdispatch.dylib) 194

3 CoreFoundation 0x377432ac __CFRunLoopRun (in CoreFoundation) 1268

4 CoreFoundation 0x376c64a4 CFRunLoopRunSpecific (in CoreFoundation) 300

5 CoreFoundation 0x376c636c CFRunLoopRunInMode (in CoreFoundation) 104

6 GraphicsServices 0x378bf438 GSEventRunModal (in GraphicsServices) 136

7 UIKit 0x308d2cd4 UIApplicationMain (in UIKit) 1080

8 MttHD 0x00003ace main (in MttHD) (main.m:15)

订阅第二屏subscribItem被释放了,但是wup回调的delegate没有被设置空。

在读取数据的轮询函数中,将

if(imageData == nil)

{

return;

}

注释掉了。

之后下面的:

[_subscribeWupManager release];

_sbuscribeWupManager = nil;

代码被调用,在弱网络环境下,wup的回调如果还没有回来,这个时候由于wup里面的block会retain _subscribeWupManager自身。

当 subscribItem delloc的时候调用 _subscribeWupManager.delegate = nil;这时候的_subscribeWupManager已经是一个指向

nil的指针。而真正的_subscribeWupManager此时并没有释放,但是它的delegate已经释放,这时候发生回调就发生Crash了.

时间: 2024-11-06 01:07:12

IOS Crash总结的相关文章

Overview of iOS Crash Reporting Tools: Part 1/2

Believe it or not, developers are not perfect, and every once in a while you might have a (gasp!) bug in your app. You will try your best to ship your apps with no bugs in them, but more often than not you realise afterwards that a bug has slipped th

iOS: Crash文件解析(一)

iOS Crash文件的解析(一) 开发程序的过程中不管我们已经如何小心,总是会在不经意间遇到程序闪退.脑补一下当你在一群人面前自信的拿着你的App做功能预演的时候,流畅的操作被无情地Crash打断.联想起老罗在发布Smartisan OS的时候说了,他准备了10个手机,如果一台有问题,就换一台,如果10台后挂了他就不做手机了.好了不闲扯了,今天就跟大家一起聊聊iOSCrash文件的组成以及常用的分析工具. 有一个WWDC 2010的视频推荐大家抽空看看,视频名称“Understanding C

iOS Crash 分析 符号化崩溃日志

参考: http://blog.csdn.net/diyagoanyhacker/article/details/41247367 http://blog.csdn.net/diyagoanyhacker/article/details/41247389 http://blog.csdn.net/diyagoanyhacker/article/details/41247411 http://www.cnblogs.com/smileEvday/p/Crash1.html 未符号化的崩溃日志就象一

符号化(Symbolicating) iOS Crash文件

今天有空研究一下如何分析iOS Crash文件. 看了一下网上的方法,有些行不通了.最后拿老大以前写的脚本,可以了. 然后理解了一下脚本,最后稍作修改.整理一下. 脚本(在Mac上面运行): echo dSYM uuid: xcrun dwarfdump --uuid $2.app.dSYM/Contents/Resources/DWARF/$2 echo crashlog uuid: grep $2' armv7' $1 | tr -s " " echo baseaddress: g

漫谈iOS Crash收集框架

漫谈iOS Crash收集框架 为了能够第一时间发现程序问题,应用程序需要实现自己的崩溃日志收集服务,成熟的开源项目很多,如 KSCrash,plcrashreporter,CrashKit 等.追求方便省心,对于保密性要求不高的程序来说,也可以选择各种一条龙Crash统计产品,如 Crashlytics,Hockeyapp ,友盟,Bugly 等等. 是否集成越多的Crash日志收集服务就越保险? 自己收集的Crash日志和系统生成的Crash日志有分歧,应该相信谁? 为什么有大量Crash日

iOS-----分析iOS Crash文件:符号化iOS Crash文件的3种方法

iOS Crash 分析(文一)- 开始 1. 名词解释 1. UUID 一个字符串,在iOS上每个可执行文件或库文件都包含至少一个UUID.目的是为了唯一识别这个文件. 2. dwarfdump 苹果提供的命令行工具,其中一些功能就是查看可执行文件件或库文件的UUID 3. symbolicatecrash 一个苹果提供的脚本.可以将crash日志符号化为可读的堆栈信息. 4. atosl 苹果提供的命令行工具,可以将crash的base_address和load_address转化为可读的堆

iOS crash log 解析

iOS开发中,经常遇到App在开发及测试时不会有问题,但是装在别人的设备中会出现各种不定时的莫名的 crash,因为iOS设备会保存应用的大部分的 crash Log,所以可以通过 crash Log 来定位 crash 原因. 一. 获取iOS设备上的 crash log 1. 将iOS设备连接到电脑上,打开 Xcode -> Organizer -> Devices,找到该台设备,在 Device logs 中找到 crash log(后缀为 .crash 的 log 文件),将其导出即可

iOS Crash 分析(文一)- 开始

iOS Crash 分析(文一)- 开始 1. 名词解释 1. UUID 一个字符串,在iOS上每个可执行文件或库文件都包含至少一个UUID.目的是为了唯一识别这个文件. 2. dwarfdump 苹果提供的命令行工具,其中一些功能就是查看可执行文件件或库文件的UUID 3. symbolicatecrash 一个苹果提供的脚本.可以将crash日志符号化为可读的堆栈信息. 4. atosl 苹果提供的命令行工具,可以将crash的base_address和load_address转化为可读的堆

iOS Crash 分析(文二)-崩溃日志组成

iOS Crash 分析(文二)-崩溃日志组成 现在我们看一个淘宝iOS主客崩溃的例子: ### 1.进程信息 ### Incident Identifier: E4201F10-6F5F-40F9-B938-BB3DA8ED7D50 CrashReporter Key: TODO Hardware Model: iPhone4,1 Process: Taobao4iPhone [3538] Path: /var/mobile/Applications/E3B51E77-D44D-4B3E-87

iOS Crash 分析(文三)- 符号化崩溃日志

iOS Crash 分析(文三)- 符号化崩溃日志 未符号化的崩溃日志就象一本天书,看不懂,更别谈分析崩溃原因了.所以我们在分析日志之前,要把日志翻译成我们可以看得懂的文字.这一步我们称之为符号化. 在iOS Crash分析(文一)中已经提到过符号化的两种方式: 1.利用Xcode符号化 2.利用symbolicatecrash脚本符号化 其实这两种分析方式都使用了同一个工具符号化:***atos***. atos是苹果提供的符号化工具,在Mac OS系统下默认安装. 使用***atos***符