finsprings
finsprings

Reputation: 130

WebTryThreadLock SEGV

I'm seeing occasional crash reports in _WebTryThreadLock like these:

    Exception Type:  SIGSEGV
    Exception Codes: SEGV_ACCERR at 0xffffffffbbadbeef

    Thread 5 Crashed:
0   WebCore                             0x00005822 _WebTryThreadLock(bool) + 158
1   WebCore                             0x0000576f WebThreadLock + 47
2   UIKit                               0x001ae019 -[UIWebView dealloc] + 73
3   CoreFoundation                      0x00006f7b -[NSObject(NSObject) release] + 31
4   Foo                                 0x0000c001 -[FooViewController dealloc] (FooViewController.m:653)
5   CoreFoundation                      0x00006f7b -[NSObject(NSObject) release] + 31
6   CoreFoundation                      0x0000b3c9 CFRelease + 69
7   CoreFoundation                      0x0000a8df _CFAutoreleasePoolPop + 147
8   libSystem.B.dylib                   0x000d6c04 _dispatch_worker_thread2 + 228
9   libSystem.B.dylib                   0x0007b251 _pthread_wqthread + 265

or

Thread 1 Crashed:
0   WebCore                             0x34c263c8 _WebTryThreadLock(bool) + 112
1   WebCore                             0x34c281b1 WebThreadLock + 53
2   UIKit                               0x35a3765f -[UITextView dealloc] + 31
3   CoreFoundation                      0x30329c43 -[NSObject(NSObject) release] + 31
4   UIKit                               0x358ad5f5 -[UIView(Hierarchy) removeFromSuperview] + 365
5   UIKit                               0x359426cd -[UIScrollView removeFromSuperview] + 49
6   UIKit                               0x35a352f1 -[UITextView removeFromSuperview] + 73
7   UIKit                               0x358c0de3 -[UIView dealloc] + 155
8   CoreFoundation                      0x30329c43 -[NSObject(NSObject) release] + 31
9   UIKit                               0x3591900f -[UIViewController dealloc] + 175
10  Foo                                 0x0000c167 -[FooViewController dealloc] (FooViewController.m:646)
11  CoreFoundation                      0x30329c43 -[NSObject(NSObject) release] + 31
12  CoreFoundation                      0x3032a1a1 CFRelease + 69
13  CoreFoundation                      0x3032cebb _CFAutoreleasePoolPop + 147
14  libdispatch.dylib                   0x33d0b6a5 _dispatch_worker_thread2 + 373
15  libsystem_c.dylib                   0x33e0a591 _pthread_wqthread + 265

I'm unable to reproduce this in my own testing though, so I'm not sure what triggers it. It definitely doesn't happen very often. I've seen mention of crashes in WebThreadLock when trying to modify UIKit elements from threads other than the main one.

I think that must be what's going on here as _dispatch_worker_thread2 tells me this is one of the GCD threads versus the UIApplicationMain one. I must have something running on a GCD thread that's keeping the FooViewController around after the main thread lets go of it, and I guess the removeFromSuperview calls happening in this non-main thread are what's triggering the issue.

Upvotes: 1

Views: 2400

Answers (1)

finsprings
finsprings

Reputation: 130

I figured this out thanks to Rentzsch's release/retain debugging tip here:

http://rentzsch.tumblr.com/post/3895140826/retain-release-debugging

The problem was I made a call to [UINavigationController visibleViewController] from a GCD thread, which is causing that thread to call retain on my FooViewController:

0   Foo                                 0x00009d98 -[FooViewController retain] + 216
1   UIKit                               0x0049e5ad -[UINavigationController topViewController] + 61
2   UIKit                               0x0049e4ca -[UINavigationController visibleViewController] + 133
3   Foo                                 0x0003c0bd -[BarViewController updateStatus:animated:] + 147
4   Foo                                 0x0003799e -[BarViewController reallyProcessMetadata] + 229
5   Foo                                 0x0003650e __39-[BarViewController processMetadata]_block_invoke_0828 + 408
6   libdispatch_sim.dylib               0x01a63289 _dispatch_call_block_and_release + 16
7   libdispatch_sim.dylib               0x01a6658a _dispatch_worker_thread2 + 252
8   libSystem.B.dylib                   0x98d2bd21 _pthread_wqthread + 390
9   libSystem.B.dylib                   0x98d2bb66 start_wqthread + 30

When that thread's autorelease pool drains, and it's the last guy holding the FooViewController up it causes the crash If you're lucky enough to reproduce this in the debugger you'll see this in the console:

2011-05-06 19:34:40.651 Foo[59365:943b] bool _WebTryThreadLock(bool), 0x11393b30: Tried to obtain the web lock from a thread other than the main thread or the web thread. This may be a result of calling to UIKit from a secondary thread. Crashing now...
Program received signal:  “EXC_BAD_ACCESS”.

So the resolution in my case is to not use visibleViewController from this thread. I was previously just calling [UINavigationController viewControllers] and checking if my controller was the last object, and that never crashed.

Upvotes: 2

Related Questions