gpus_ReturnNotPermittedKillClient causing huge number of crashes

95% of our app's crashes involve gpus_ReturnNotPermittedKillClient.


Here's a sample stack trace:

Thread 12 Crashed:
0   libGPUSupportMercury.dylib           0x000000018f439f08 gpus_ReturnNotPermittedKillClient + 12
1   libGPUSupportMercury.dylib           0x000000018f43aec4 gpusSubmitDataBuffers + 168
2   WebCore                              0x00000001972db820 WebCore::GraphicsContext3D::reshape(int, int) + 524
3   WebCore                              0x0000000197be55c8 WebCore::WebGLRenderingContextBase::initializeNewContext() + 636
4   WebCore                              0x0000000197be506c WebCore::WebGLRenderingContextBase::WebGLRenderingContextBase(WebCore::HTMLCanvasElement*, ***::PassRefPtr, WebCore::GraphicsContext3D::Attributes) + 512
5   WebCore                              0x0000000197bde53c WebCore::WebGLRenderingContext::WebGLRenderingContext(WebCore::HTMLCanvasElement*, ***::PassRefPtr, WebCore::GraphicsContext3D::Attributes) + 36
6   WebCore                              0x0000000197be4840 WebCore::WebGLRenderingContextBase::create(WebCore::HTMLCanvasElement*, WebCore::WebGLContextAttributes*, ***::String const&) + 1276
7   WebCore                              0x0000000196f9fa24 WebCore::HTMLCanvasElement::getContext(***::String const&, WebCore::CanvasContextAttributes*) + 344
8   WebCore                              0x0000000196f9f7e4 WebCore::JSHTMLCanvasElement::getContext(JSC::ExecState*) + 208
9   JavaScriptCore                       0x00000001864da330 llint_entry + 25052
10  JavaScriptCore                       0x00000001864d9db4 llint_entry + 23648
11  JavaScriptCore                       0x00000001864d9db4 llint_entry + 23648
12  JavaScriptCore                       0x00000001864d9db4 llint_entry + 23648
13  JavaScriptCore                       0x00000001864d3f38 vmEntryToJavaScript + 308
14  JavaScriptCore                       0x0000000186400c84 JSC::JITCode::execute(JSC::VM*, JSC::ProtoCallFrame*) + 176
15  JavaScriptCore                       0x000000018608231c JSC::Interpreter::execute(JSC::ProgramExecutable*, JSC::ExecState*, JSC::JSObject*) + 8200
16  JavaScriptCore                       0x00000001861da568 JSC::evaluate(JSC::ExecState*, JSC::SourceCode const&, JSC::JSValue, ***::NakedPtr&) + 436
17  WebCore                              0x00000001979ca9cc WebCore::ScriptController::evaluateInWorld(WebCore::ScriptSourceCode const&, WebCore::DOMWrapperWorld&) + 288
18  WebCore                              0x0000000196e1a49c WebCore::ScriptElement::executeScript(WebCore::ScriptSourceCode const&) + 336
19  WebCore                              0x0000000196ea1388 WebCore::HTMLScriptRunner::executePendingScriptAndDispatchEvent(WebCore::PendingScript&) + 220
20  WebCore                              0x0000000196e9af68 WebCore::HTMLScriptRunner::executeParsingBlockingScripts() + 280
21  WebCore                              0x00000001973191d8 non-virtual thunk to WebCore::HTMLDocumentParser::notifyFinished(WebCore::CachedResource*) + 68
22  WebCore                              0x0000000196e9d734 WebCore::CachedResource::checkNotify() + 280
23  WebCore                              0x0000000196e9d500 WebCore::SubresourceLoader::didFinishLoading(double) + 1016
24  CFNetwork                            0x0000000184137488 ___ZN27URLConnectionClient_Classic26_delegate_didFinishLoadingEU13block_pointerFvvE_block_invoke + 96
25  CFNetwork                            0x0000000184225ad4 ___ZN27URLConnectionClient_Classic18_withDelegateAsyncEPKcU13block_pointerFvP16_CFURLConnectionPK33CFURLConnectionClientCurrent_VMaxE_block_invoke_2 + 104
26  libdispatch.dylib                    0x000000019a711770 _dispatch_client_callout + 12
27  libdispatch.dylib                    0x000000019a71aa54 _dispatch_block_invoke + 536
28  CFNetwork                            0x0000000184123c70 RunloopBlockContext::_invoke_block(void const*, void*) + 32
29  CoreFoundation                       0x00000001849187ec CFArrayApplyFunction + 64
30  CFNetwork                            0x0000000184123b54 RunloopBlockContext::perform() + 132
31  CFNetwork                            0x0000000184123a14 MultiplexerSource::perform() + 308
32  CFNetwork                            0x0000000184123840 MultiplexerSource::_perform(void*) + 64
33  CoreFoundation                       0x00000001849ec5a4 __CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE0_PERFORM_FUNCTION__ + 20
34  CoreFoundation                       0x00000001849ec038 __CFRunLoopDoSources0 + 536
35  CoreFoundation                       0x00000001849e9d38 __CFRunLoopRun + 720
36  CoreFoundation                       0x0000000184918dc0 CFRunLoopRunSpecific + 380
37  WebCore                              0x0000000196e51aa0 RunWebThread(void*) + 452
38  libsystem_pthread.dylib              0x000000019a927b3c _pthread_body + 152
39  libsystem_pthread.dylib              0x000000019a927aa0 _pthread_start + 152
40  libsystem_pthread.dylib              0x000000019a925030 thread_start + 0


All the crashes occur within WebCore, but the only UIWebViews/WKWebViews in the app are ads. I'm not surprised, since ad libraries are almost always garbage. However, all of the crashes are on devices running iOS 9.x.


Any idea what is going on? We are doing our best to kill ads when the app is backgrounded, which is what appears to cause this crash.

Replies

Hi Senior,


I've got nearly the same crash stack trace as you. I get about 100 or so crashes per day from my 60k daily active users. It is one of my top issues. I believe I'm in the same boat as you, I don't know what is causing it, but I was thinking that maybe we can share what it is that we're doing with webviews in our apps and triangulate based upon what we have in common.


I'll start: My code doesn't use any webviews itself (WKWebView or UIWebView), however, I do have several interstitial and banner ad providers integrated. We have server controls over the ad provider prioritization, but my monetization folks won't be all too thrilled if I remove them systematically to see when crashes decrease. However, if forced to guess (based on what I know and I'd love to get your input as well), I'd say that the cause is a webview created by an ad provider. I also have facebook login which presents what appears to be a webview as well, so it could be that.


Can you let me know (A) if you have any ad providers integrated into your app, (B) which one(s), and (C) if you support facebook login?


Thanks,

Paul


P.S. EDIT: Sorry, I didn't notice your comment below your stack trace until after I replied. So most of what I asked I learned already by reading your post more fully. Still, which ad provider(s) are you using? Thanks.

In your webview controller

add this function

typedef void (*CallFuc)(id, SEL, BOOL);
typedef BOOL (*GetFuc)(id, SEL);
-(BOOL)webView:(UIWebView*)view enableGL:(BOOL)bEnable
{
BOOL bRet = NO;
do
{
Ivar internalVar = class_getInstanceVariable([view class], "_internal");
if (!internalVar)
{
NSLog(@"enable GL _internal invalid!");
break;
}

UIWebViewInternal* internalObj = object_getIvar(view, internalVar);
Ivar browserVar = class_getInstanceVariable(object_getClass(internalObj), "browserView");
if (!browserVar)
{
NSLog(@"enable GL browserView invalid!");
break;
}

id webbrowser = object_getIvar(internalObj, browserVar);
Ivar webViewVar = class_getInstanceVariable(object_getClass(webbrowser), "_webView");
if (!webViewVar)
{
NSLog(@"enable GL _webView invalid!");
break;
}

id webView = object_getIvar(webbrowser, webViewVar);
if (!webView)
{
NSLog(@"enable GL webView obj nil!");
}

if(object_getClass(webView) != NSClassFromString(@"WebView"))
{
NSLog(@"enable GL webView not WebView!");
break;
}

SEL selector = NSSelectorFromString(@"_setWebGLEnabled:");
IMP impSet = [webView methodForSelector:selector];
CallFuc func = (CallFuc)impSet;
func(webView, selector, bEnable);

SEL selectorGet = NSSelectorFromString(@"_webGLEnabled");
IMP impGet = [webView methodForSelector:selectorGet];
GetFuc funcGet = (GetFuc)impGet;
BOOL val = funcGet(webView, selector);

bRet = (val == bEnable);

}while(NO);

return bRet;
}

call it before UIWebView loadRequest and set bEnable = NO. will resolve this crash

there is also another way, monitor application backgroud and forceground event. when enter background call webView:(UIWebView*)view enableGL: NO and when forceground call it with YES

look my anwser


May help you

Hey Paul,

Sorry for the slow response. The ad library that is causing this for me is MoPub.

you can try my way. if ad library use webview, you can swilling UIWebView loadRequest method, before call org loadRequest, call webView:(UIWebView*)view enableGL:NO

This is great! Thank you for sharing it.

Is this acceptible for App Store release ?

I think it can be acceptable. Because apple do not want to fix UIWebview bugs. I told them this way can fix problem. so, they said , just do it!

Add the changes below to your mopubSDK. The link below has the full change.


MoPubSDK/Internal/Banners/MPBannerAdManager.m

  self.requestingAdapterAdContentView = nil;
  [self.communicator cancel];
+
+ if(self.appIsInBackground)
+ {
+ MPLogInfo(@"Banner view (%@) not loading due to app being in background", [self.delegate adUnitId]);
+ return;


https://github.com/mopub/mopub-ios-sdk/pull/111/files#r25650124

Hi Paul


We also expirience this crash and have interstitial Ad integrated via Firebase's AdMob.


From what I have learned from reading this thread is that the crash occurs when the application goes to background during and/or after Ad interstitial presentation.


I will try out things suggested here.

Have you tested this in a production version? I'm unable to repro the crash internally no matter what I try, but I 100% agree that this is ad related.


We have a fairly large userbase and we've seen 100K of these crashes on previous versions. I've finally talked my monetization manager to disable banner ad fill as much as possible for a short period of time and we now average ~50 a day instead of multiple hundreds.


We have just about every adapter available included so it's hard to tell if one is worse than the others.


My only doubt about the fix mentioned in that pull request is that the crash logs I get, as well as the one originally posted here, are from a background thread. Not just while the application is backgrounded.

Hi levili,


I tried your workaround. But it didn't work for me.

This was very useful! Do you have an equivalent fix for WKWebView now that UIWebView is deprecated?

This has worked perfectly for UIWebView. Do you happen to know the code that works same for WKWebView? I need it very much! Thanks.