Quantcast

Crashes in WebKit: Dodge or Parry?

I love WebKit. It allows you to embed an HTML view anywhere in your app. It’s an HTML view that behaves exactly like Safari because …. well, Safari uses WebKit. Having a fully functional HTML view is an important part of almost any modern application. Unfortunately though there are some bugs, some of them crashing bugs, especially if you use WebKit in a way that is outside the common path that Safari uses. And these bugs won’t be fixed for most users until Leopard ships next year.

Here is an example. I was debugging this for many hours. Somewhere a piece of the WebView is getting over-released and causing a crash. This type of bug is notoriously hard to analyze and fix. I thought it was in my code, but it turns out it was in WebKit.

2005-07-24 01:29:26.070 macbook[4264] *** Selector 'release' sent to dealloced instance 0x8faf1e0 of class WebHTMLView.
Break at '-[_NSZombie release]' to debug.
2005-07-24 01:29:26.086 macbook[4264] *** -[NSAutoreleasePool dealloc]: Exception ignored while releasing an object in an autorelease pool: *** Selector 'release' sent to dealloced instance 0x8faf1e0 of class WebHTMLView

So what can I do? A major feature of my application is downloading a load of web pages and converting them to PDF files. WebKit is a great way to do this. Well, really it’s the only way to do it. Except for the crashing part. So after giving up on fixing this over-release crash, I split out my html-to-pdf code into a separate, small command line program. It works great, and is just the thing for “defensive programming.” For example if some random web page I load has a plugin that crashes webkit, it will only crash my helper program, not the app itself. iChat uses a similar technique for video conferencing (look around for “vencoder”). My command line webkit program size is 68kb.

So to any other developers seeing this crash, or to anyone thinking about using WebKit as a data processing tool rather than a web browser: fork off a separate process. It will save you a lot of heartache and make your application crash much less.

Link to the WebKit Homepage

Update! … rajbot sez:

The great thing about WebKit being Open Sores is that you can embed the latest versions of the frameworks in your app, and set the right env variables to tell WebKit to use those instead, like the nightly Safari builds do..

That’s a good point. I might just do that. And that way I can just fix the bugs myself if I need to… yay! :-)

5 Responses to “Crashes in WebKit: Dodge or Parry?”

  1. September 29th, 2006 | 5:09 pm

    Is the bug fixed the subversion repository? I come across tons of WebKit bugs that are fixed in the repository. The great thing about WebKit being Open Sores is that you can embed the latest versions of the frameworks in your app, and set the right env variables to tell WebKit to use those instead, like the nightly Safari builds do..

  2. September 29th, 2006 | 5:11 pm

    P.S. WTF is wrong with our templates? Nothing is rendering correctly.

  3. September 29th, 2006 | 5:39 pm

    I used the <code> tag which apparently doesn’t work very well. <tt> to the rescue!

  4. September 30th, 2006 | 3:10 pm

    We’d appreciate it if you could check if the bug still exists with a recent nightly of WebKit, and if so, report it at http://bugs.webkit.org/

  5. October 23rd, 2007 | 8:25 pm

    I found the problem, I think. Ok so I am a little late.

    When you do the offscreen webview thing, you need to call

    [_webView setHostWindow:someWindow] on your webview. That is in the docs
    what I found was that I got your exact problem until I added the webview as a subview of the window:
    [[someWindow contentView] addSubview:_webView];
    [_webView setHostWindow:someWindow];

    Then in dealloc, remember to release everything (i was using a shared stub window so I only call removeFromSuperView.
    dealloc –

    [[NSNotificationCenter defaultCenter] removeObserver:self];

    [_webView setFrameLoadDelegate:nil];

    // remove the subview from the host window:
    [_webView removeFromSuperview];
    [_webView setHostWindow:nil];
    [_webView release];

    Also like the seperate task idea. My problem was that I am already in a ‘helper’ task!

    –Tom

Leave a reply