Programatically created WebView crashes

  • I'm working on some code whose purpose is to take an array of NSURLs
    and save them as PDFs.  I have all the pieces in place, but I'm
    getting very strange crashes and I'm just not sure how to proceed.
    The issue appears to be related to referencing already released
    objects, but since the problem seems to pop up in the middle of an
    NSRunLoop, I don't know how to correct or even analyze it.

    I've stripped everything down to the bare lines that will result in a
    crash and included them below along with some crash information.  I
    realize it's a lot to sift through, but if anyone could point out
    what I'm doing wrong or even just give me a hint on a way to figure
    it out on my own, I'd be very grateful.

    ----Begin Stripped-Down Code----

    @implementation J38URL2PDF

    NSString *pageTitle;
    BOOL loadComplete;

    // WebView Delegates

    - (void)webView:(WebView *)sender didReceiveTitle:(NSString *)title
    forFrame:(WebFrame *)frame
    {
        if ([sender mainFrame] == frame) {
            NSLog(@"didReceiveTitle for mainFrame -- %@",title);
            pageTitle = title;
        }
    }

    - (void)webView:(WebView*)webView didFinishLoadForFrame:(WebFrame*)frame
    {
        if ([webView mainFrame] == frame)
            NSLog(@"didFinishLoadForFrame for mainFrame");
            loadComplete = YES;
    }

    - (void)webView:(WebView *)sender didFailProvisionalLoadWithError:
    (NSError *)error forFrame:(WebFrame *)frame
    {
        NSLog(@"didFailProvisionalLoadWithError -- %@ - %@", [error
    localizedFailureReason], [error localizedDescription]);
    }

    - (void)webView:(WebView *)sender didFailLoadWithError:(NSError *)
    error forFrame:(WebFrame *)frame
    {
        NSLog(@"didFailProvisionalLoadWithError -- %@ - %@", [error
    localizedFailureReason], [error localizedDescription]);
    }

    // This is where the action is.

    - (id)convertURLs:(id)input
    {

        WebView* fakeWebView;
        fakeWebView = [[WebView alloc] initWithFrame: NSMakeRect
    (0,0,612,792)];
        [fakeWebView setFrameLoadDelegate:self];

        [[fakeWebView preferences] setShouldPrintBackgrounds:YES];
        [[fakeWebView preferences] setPlugInsEnabled:NO];
        [[fakeWebView preferences] setJavaScriptEnabled:NO];
        [[fakeWebView preferences] setJavaEnabled:NO];

        NSMutableArray *output = [NSMutableArray arrayWithCapacity:
    [input count]];
        NSEnumerator *enumerate = [input objectEnumerator];
        NSURL *curURL;

        while (curURL = [enumerate nextObject]) {
            NSLog(@"Trying %@...",[curURL absoluteString]);

            [[fakeWebView mainFrame] loadRequest:[NSURLRequest
    requestWithURL:curURL]];

            pageTitle = nil;
            loadComplete = NO;
            bool isRunning;
            do {
                NSDate* next = [NSDate dateWithTimeIntervalSinceNow:1.0];
                isRunning = [[NSRunLoop currentRunLoop]
    runMode:NSDefaultRunLoopMode beforeDate:next];
            } while (!loadComplete && isRunning);

            // This is where I start to get the PDF data.
            // For whatever reason, including that pdfData assignment is
    what causes the program
            // to start crashing consistently, though that is *not*
    where the crash occurs.

            NSView *documentView = [[[fakeWebView mainFrame] frameView]
    documentView];
            NSData *pdfData = [[NSData alloc] initWithData:[documentView
    dataWithPDFInsideRect:[documentView frame]]];

            [output addObject:pageTitle];

            [pdfData release];

        }

        [fakeWebView release];

        return (output);
    }

    @end

    ----End Stripped-Down Code----

    ----Begin Sample Input Array----

        NSArray *input = [[NSArray alloc] initWithObjects:
            [NSURL URLWithString: @"http://telegraph.co.uk/"],
            [NSURL URLWithString: @"http://thesun.co.uk/"],
            [NSURL URLWithString: @"http://guardian.co.uk/"],
            [NSURL URLWithString: @"http://mirror.co.uk/"],
            [NSURL URLWithString: @"http://news.bbc.co.uk/cbbcnews/"],
            [NSURL URLWithString: @"http://news.bbc.co.uk/"],
            nil];

    ----End Sample Input Array----

    ----Begin Debugger Console Output----

    2005-07-23 22:54:22.936 browsish[4036] Trying http://zvon.org/...
    2005-07-23 22:54:23.124 browsish[4036] didReceiveTitle for mainFrame
    -- ZVON.org - ZVON
    2005-07-23 22:54:23.659 browsish[4036] didFinishLoadForFrame for
    mainFrame
    2005-07-23 22:54:23.978 browsish[4036] Trying http://
    www.tonymarston.net/...
    2005-07-23 22:54:23.994 browsish[4036] didReceiveTitle for mainFrame
    -- Tony Marston's Home Page
    2005-07-23 22:54:24.215 browsish[4036] didFinishLoadForFrame for
    mainFrame
    2005-07-23 22:54:24.650 browsish[4036] Trying http://yogajournal.com/...

    browsish has exited due to signal 5 (SIGTRAP)..

    ----End Debugger Console Output----

    ----Begin system.log Output----

    Jul 23 22:54:24 echo /Users/scott/files/code/objective-c/browsish/
    build/Debug/browsish.app/Contents/MacOS/browsish: objc: FREED(id):
    message release sent to freed object=0x745c400

    ----End system.log Output----

    ----Begin Browsish.crash.log Output----

    Thread 0 Crashed:
    0  libobjc.A.dylib                  0x909b6cc0 _objc_trap + 0
    1  libobjc.A.dylib                  0x909b6c34 _objc_error + 76
    2  libobjc.A.dylib                  0x909b6bc4 __objc_error + 64
    3  com.apple.Foundation            0x92859708 NSPopAutoreleasePool
    + 536
    4  com.apple.Foundation            0x928ada88 -[NSURLConnection
    (NSURLConnectionInternal) _sendCallbacks] + 660
    5  com.apple.Foundation            0x928ad778 _sendCallbacks + 156
    6  com.apple.CoreFoundation        0x9074bd2c __CFRunLoopDoSources0
    + 384
    7  com.apple.CoreFoundation        0x9074b25c __CFRunLoopRun + 452
    8  com.apple.CoreFoundation        0x9074acdc CFRunLoopRunSpecific
    + 268
    9  com.apple.Foundation            0x9288bec4 -[NSRunLoop
    runMode:beforeDate:] + 172
    10  J38URL2PDF.ob                    0x000328b4 -[J38URL2PDF
    convertURLs:] + 1012 (J38URL2PDF.m:72)

    ----End Browsish.crash.log Output----
  • On Jul 24, 2005, at 01:18, Scott Anguish wrote:

    >> - (void)webView:(WebView*)webView didFinishLoadForFrame:(WebFrame*)
    >> frame
    >> {
    >> if ([webView mainFrame] == frame)
    >> NSLog(@"didFinishLoadForFrame for mainFrame");
    >>
    >
    > should there be paren braces around something here?
    >
    >
    >> loadComplete = YES;
    >> }

    Oops, looks like I overstripped a little when preparing the block for
    email.  You're correct--it should read:

    - (void)webView:(WebView*)webView didFinishLoadForFrame:(WebFrame*)frame
    {
        if ([webView mainFrame] == frame) {
            NSLog(@"didFinishLoadForFrame for mainFrame");
            loadComplete = YES;
        }
    }

    A little more information:  After playing with the Zombie features of
    NSDebug, I now get this  on the Debugger Console:

    2005-07-24 01:29:21.840 browsish[4264] Trying http://news.bbc.co.uk/...
    2005-07-24 01:29:22.302 browsish[4264] didReceiveTitle for mainFrame
    -- BBC NEWS | News Front Page
    2005-07-24 01:29:23.831 browsish[4264] didFinishLoadForFrame for
    mainFrame
    2005-07-24 01:29:26.070 browsish[4264] *** Selector 'release' sent to
    dealloced instance 0x8faf1e0 of class WebHTMLView.
    Break at '-[_NSZombie release]' to debug.
    2005-07-24 01:29:26.086 browsish[4264] *** -[NSAutoreleasePool
    dealloc]: Exception ignored while releasing an object in an
    autorelease pool: *** Selector 'release' sent to dealloced instance
    0x8faf1e0 of class WebHTMLView.
  • Apple has a separate discussion list for WebKit:

    <webkitsdk-dev...>

    You probably won't get an answer, but you should try posting there.

    Regarding strange crashes when using WebKit: Yes, they have been reported.
    For example, see the message I posted there on July 14, subject: MiniBrowser
    Crashes On Load Failures.

    You should prepare your project plans for the possibility that this bug is
    in WebKit.