5

My iPad app encounters an EXC_BAD_ACCESS message within the call to CGPDFContextClose in the following method. It happens only for certain pages, and only for one document so far (which happens to be our help document, unfortunately).

- (CGPDFDocumentRef)newSinglePageDocumentFromDocument:(CGPDFDocumentRef)document page:(NSInteger)pageNumber
{
    CGPDFDocumentRef sourceDocument = CGPDFDocumentRetain(document);
    CGPDFDocumentRef newDocument = NULL;

    CFMutableDataRef consumerData = CFDataCreateMutable(kCFAllocatorDefault, 0);
    CGDataConsumerRef contextConsumer = CGDataConsumerCreateWithCFData(consumerData);

    CGPDFPageRef page = CGPDFDocumentGetPage(sourceDocument, pageNumber);
    const CGRect mediaBox = CGPDFPageGetBoxRect(page, kCGPDFCropBox);
    CGContextRef ctx = CGPDFContextCreate(contextConsumer, &mediaBox, NULL);

    if (ctx)
    {
        if (page)
        {
            CGPDFContextBeginPage(ctx, NULL);
            CGContextDrawPDFPage(ctx, page);
            CGPDFContextEndPage(ctx);
        }
        //EXC_BAD_ACCESS thrown here
        CGPDFContextClose(ctx);
        CGContextRelease(ctx);

        CGDataProviderRef provider = CGDataProviderCreateWithCFData((CFDataRef)consumerData);
        newDocument = CGPDFDocumentCreateWithProvider(provider);
        CGDataProviderRelease(provider);
    }
    CGDataConsumerRelease(contextConsumer);
    CFRelease(consumerData);
    CGPDFDocumentRelease(sourceDocument);

    return newDocument;
}

The document which fails can be opened by Preview on the Mac. I can't visually identify anything distinct between the pages that fail and the ones that succeed.

Can anyone see what is wrong with the code, or suggestions for uncovering the issue?

EDIT: EXC_BAD_ACCESS is thrown within the CGPDFContextClose method, see below:

0x00e93d0e  <+0000>  push   %ebp
0x00e93d0f  <+0001>  mov    %esp,%ebp
0x00e93d11  <+0003>  sub    $0x18,%esp
0x00e93d14  <+0006>  call   0xe93d19 <CGPDFContextClose+11>
0x00e93d19  <+0011>  pop    %eax
0x00e93d1a  <+0012>  mov    0x8(%ebp),%ecx
0x00e93d1d  <+0015>  test   %ecx,%ecx
0x00e93d1f  <+0017>  je     0xe93d30 <CGPDFContextClose+34>
0x00e93d21  <+0019>  cmpl   $0x43545854,0x8(%ecx)
0x00e93d28  <+0026>  jne    0xe93d30 <CGPDFContextClose+34>
0x00e93d2a  <+0028>  cmpl   $0x1,0x10(%ecx)
0x00e93d2e  <+0032>  je     0xe93d4e <CGPDFContextClose+64>
0x00e93d30  <+0034>  mov    %ecx,0x8(%esp)
0x00e93d34  <+0038>  lea    0xc393b(%eax),%ecx
0x00e93d3a  <+0044>  mov    %ecx,0x4(%esp)
0x00e93d3e  <+0048>  lea    0xad9eb(%eax),%ecx
0x00e93d44  <+0054>  mov    %ecx,(%esp)
0x00e93d47  <+0057>  call   0xe7176c <CGPostError>
0x00e93d4c  <+0062>  jmp    0xe93d59 <CGPDFContextClose+75>
0x00e93d4e  <+0064>  mov    0x18(%ecx),%eax
0x00e93d51  <+0067>  mov    %eax,(%esp)
0x00e93d54  <+0070>  call   0xdb25af <CGContextDelegateFinalize>
0x00e93d59  <+0075>  add    $0x18,%esp //EXC_BAD_ACCESS thrown here
0x00e93d5c  <+0078>  pop    %ebp
0x00e93d5d  <+0079>  ret 
Robert Gowland
  • 7,677
  • 6
  • 40
  • 58

2 Answers2

3

Set NSZombieEnabled, MallocStackLogging, and guard malloc in the debugger. Then, when your App crashes, type this in the gdb console:

(gdb) info malloc-history 0x543216

Replace 0x543216 with the address of the object that caused the crash, and you will get a much more useful stack trace and it should help you pinpoint the exact line in your code that is causing the problem.

See this article for more detailed instructions.


One thing to also do is to set "Strip Debug Symbols" to "No" so that if you test on your device, you will be able to read crash logs:

1

2

chown
  • 51,908
  • 16
  • 134
  • 170
  • If the source of the exception is within library code, will turning on these options show me any useful information? – Robert Gowland Nov 10 '11 at 15:10
  • For those using Xcode 4, all three of these options are now available as check boxes: edit your scheme, select Run from the left-hand list, select the Diagnostics tab, check the ones you want. – Robert Gowland Nov 10 '11 at 15:12
  • @RobertGowland If it's your library and you have the source for it, then this should show you a useful stack trace even in that library. One thing to also do is to set "Strip Debug Symbols" to "No". Check my updates. – chown Nov 10 '11 at 15:28
  • Thanks for the update. The exception is thrown within CGPDF code, so I can only see the assembly. See my edit. – Robert Gowland Nov 10 '11 at 17:47
1

We ended up submitting a bug to Apple (ID 10555351) and removing the caching functionality.

Robert Gowland
  • 7,677
  • 6
  • 40
  • 58