<html><head><meta http-equiv="Content-Type" content="text/html charset=utf-8"></head><body style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;" class=""><div class="">Ok, I've created a new bug with the instruments trace here:</div><div class=""><br class=""></div><div class=""><a href="https://bugs.webkit.org/show_bug.cgi?id=139654" class="">https://bugs.webkit.org/show_bug.cgi?id=139654</a></div><div class=""><br class=""></div><div class="">I'll see what I can do about a sample project soon.</div><div class=""><br class=""></div><div class="">I've also got a bit of new information to share. We released a new beta of the app in which this bug went from infrequent to very frequent (from 8 crashes in ~6k sessions to 160 crashes in ~5k sessions).</div><div class=""><br class=""></div><div class="">Very little in the app had changed - some CSS changes, some minor Javascript changes (animating a width change and a few more style changes in a completion callback), and a change to how we detect the initial document load is complete. However, that was enough for a huge spike in crashes.</div><div class=""><br class=""></div><div class="">This was interesting because while the stack trace of the crashed thread varied, 156 of the 160 crashes showed the same backtrace for the main thread:</div><div class=""><br class=""></div><div class=""><div class="">Thread : com.apple.main-thread</div><div class="">0 libsystem_kernel.dylib 0x2fe05ba8 __psynch_mutexwait + 24</div><div class="">1 libsystem_pthread.dylib 0x2fe8104b _pthread_mutex_lock + 398</div><div class="">2 WebCore 0x2d353b91 _WebTryThreadLock(bool) + 44</div><div class="">3 WebCore 0x2d3543ad WebThreadLock + 80</div><div class="">4 UIKit 0x2561ca69 -[UIWebDocumentView setDataDetectorTypes:] + 56</div><div class="">5 Boxer 0x000cc245 -[ConversationViewController renderConversation] (ConversationViewController.m:869)</div><div class="">6 libdispatch.dylib 0x2fd1f7bb _dispatch_call_block_and_release + 10</div><div class="">7 libdispatch.dylib 0x2fd1f7a7 _dispatch_client_callout + 22</div><div class="">8 libdispatch.dylib 0x2fd22fa3 _dispatch_main_queue_callback_4CF + 718</div><div class="">9 CoreFoundation 0x21fcf3b1 __CFRUNLOOP_IS_SERVICING_THE_MAIN_DISPATCH_QUEUE__ + 8</div><div class="">10 CoreFoundation 0x21fcdab1 __CFRunLoopRun + 1512</div><div class="">11 CoreFoundation 0x21f1b3c1 CFRunLoopRunSpecific + 476</div><div class="">12 CoreFoundation 0x21f1b1d3 CFRunLoopRunInMode + 106</div><div class="">13 GraphicsServices 0x293190a9 GSEventRunModal + 136</div><div class="">14 UIKit 0x2552afa1 UIApplicationMain + 1440</div><div class="">15 Boxer 0x000900a7 main (main.m:11)</div></div><div class=""><br class=""></div><div class="">(More details here: <a href="http://crashes.to/s/b1531e29971" class="">http://crashes.to/s/b1531e29971</a>)</div><div class=""><br class=""></div><div class="">It's an easy workaround to avoid this crash, but I think it may help tracking down whatever this race condition might be.</div><div class=""><br class=""></div><div class="">Hope this helps,</div><div class="">Ian</div><br class=""><div><blockquote type="cite" class=""><div class="">On Dec 15, 2014, at 1:51 PM, Geoffrey Garen <<a href="mailto:ggaren@apple.com" class="">ggaren@apple.com</a>> wrote:</div><br class="Apple-interchange-newline"><div class="">Can you attach the Instruments trace leading up to the crash, and/or a reduced copy of the app that can reproduce the crash, to bugzilla?<br class=""><br class="">Thanks,<br class="">Geoff<br class=""><br class=""><blockquote type="cite" class="">On Dec 11, 2014, at 7:34 PM, Ian Ragsdale <<a href="mailto:ian.ragsdale@gmail.com" class="">ian.ragsdale@gmail.com</a>> wrote:<br class=""><br class="">Actually, looking again, I was running the profile on the device, not the simulator as I had meant to.<br class=""><br class="">One other thing I meant to mention is that I keep three instances of the UIWebView loaded, and I trigger it by paging between them quickly, so perhaps it's an issue with multiple instances? There is always one on screen, and paging from one to the next allocates a new one while an old one is discarded. They all appear to share the same WebThread & JavaScript threads, so I could see that being problematic.<br class=""><br class="">- Ian<br class=""><br class="">On Dec 11, 2014, at 9:25 PM, Ian Ragsdale <<a href="mailto:ian.ragsdale@gmail.com" class="">ian.ragsdale@gmail.com</a>> wrote:<br class=""><blockquote type="cite" class=""><br class="">Hi Geoff, thanks for the quick response!<br class=""><br class="">I don't believe I'm making any use of SPI, aside from whatever underlying use there is in UIWebView - I'm pretty sure that's not exposed to normal iOS apps (at least not that I'm aware of).<br class=""><br class="">As predicted, setting JSC_slowPathAllocsBetweenGCs does appear to make it easier to trigger the crash. I did that and then did an Instruments sample using the iOS simulator, and got the crash to happen pretty quickly. However, I'm not really sure what to look for, since I'm a newbie to WebKit internals. Any suggestions for what to look for in the call tree?<br class=""><br class="">Thanks again,<br class="">Ian<br class=""><br class=""><blockquote type="cite" class="">On Dec 11, 2014, at 8:11 PM, Geoffrey Garen <<a href="mailto:ggaren@apple.com" class="">ggaren@apple.com</a>> wrote:<br class=""><br class="">Hi Ian.<br class=""><br class=""><blockquote type="cite" class="">From looking at the source, it tries to drop all locks from the current javascript VM before calling the delegate, and when it does that it asserts if the VM is busy garbage collecting.<br class=""></blockquote><br class="">That’s right.<br class=""><br class=""><blockquote type="cite" class="">I'm guessing there needs to be some sort of guard there to make sure the VM isn't doing GC before dropping the locks?<br class=""></blockquote><br class="">In JavaScriptCore, garbage collection is an atomic operation that must run to completion before the next allocation.<br class=""><br class="">The reason this is an assertion — and can’t be a guard — is that, if we called out to a delegate in the middle of garbage collection, we would definitely corrupt the heap. So, there’s nothing you can guard against: the game is already lost.<br class=""><br class="">The bug here happened earlier: Somehow, the collector was left thinking that it was in the busy state, even though — as we can see from the backtrace — it wasn’t actually doing anything.<br class=""><br class=""><blockquote type="cite" class="">I'm pretty positive I'm not calling into the UIWebView from any thread other than the main thread, and I don't think I have any control over the WebThread or the GC threads, so I'm not sure if there's anything I can do, but I do have a fairly reliable repro, so if there's something it makes sense for me to test, I can do so.<br class=""></blockquote><br class="">Does you app make any use of WebKit SPI? If it does, the SPI might not be thread-safe even if called from the main thread, and so you might be corrupting the heap.<br class=""><br class="">One technique that might make this bug more reproducible is to set the environment variable JSC_slowPathAllocsBetweenGCs to a low number (as low as possible without making your app unusable) — that will trigger collection more frequently.<br class=""><br class="">Another thing you can try is to record an Instruments time profile of the app as you go through the steps to make the app crash. That will give us an overview of what the app was doing leading up to the crash, whether it used UIWebView from a secondary thread or invoked SPI, and so on.<br class=""><br class="">Geoff<br class=""></blockquote><br class=""></blockquote><br class=""></blockquote><br class=""></div></blockquote></div><br class=""></body></html>