IOS error inside UIGraphicsBeginPDFPageWithInfo
Context: Xcode 5, iOS 7.1.
I have code that creates a PDF with the ability to embed an existing PDF in it, using PSPDFKit to display the pages of an existing PDF. 99% of the time, the code works fine; but reproducibly 1% of the time I get a crash (exc_bad_access). I can't explain what is different when I reproduce the crash - usually I have to force the application to generate the PDF N times (where today N = 5, other days N = 2) and then it crashes.
The code just makes these two calls in a loop:
CGSize pageSize = CGSizeMake(612*3, 792*3);
{
UIGraphicsBeginPDFPageWithInfo(CGRectMake(0, 0, size.width, size.height), nil);
NSError *error = nil;
[pdfDoc renderPage:innerPageNum
inContext:UIGraphicsGetCurrentContext();
withSize:size
clippedToRect:CGRectZero
withAnnotations:nil
options:nil
error:&error];
}
And sometimes it fails in UIGraphicsBeginPDFPageWithInfo, always at a point below in assembly code. Has anyone ever seen anything like this or had any hints for debugging? Without access to the UIKit source, I don't quite know.
CoreGraphics`CGPDFSecurityHandlerIsUnlocked:
0x41559ff: pushl %ebp
0x4155a00: movl %esp, %ebp
0x4155a02: xorb %al, %al
0x4155a04: movl 0x8(%ebp), %ecx
0x4155a07: testl %ecx, %ecx
0x4155a09: je 0x4155a12 ; CGPDFSecurityHandlerIsUnlocked + 19
0x4155a0b: cmpb $0x0, 0x7c(%ecx) <<< Thread 1: EXC_BAD_ACCESS (code=2, address=0xde)
0x4155a0f: setne %al
0x4155a12: movzbl %al, %eax
0x4155a15: popl %ebp
0x4155a16: ret
which, if I could attach an image to show the stack trace, I believe it will show that this function eventually reached 21 levels of hidden stacks in depth from this call:
UIKit`UIGraphicsBeginPDFPageWithInfo:
0x431914f: pushl %ebp
0x4319150: movl %esp, %ebp
0x4319152: pushl %ebx
0x4319153: pushl %edi
0x4319154: pushl %esi
0x4319155: subl $0x5c, %esp
0x4319158: calll 0x431915d ; UIGraphicsBeginPDFPageWithInfo + 14
0x431915d: popl %esi
0x431915e: movl $0x2, %ecx
0x4319163: calll 0x4318cb7 ; GetCurrentContext
0x4319168: movl %eax, %edi
0x431916a: movl $0x2, %ecx
0x431916f: calll 0x4318ce1 ; GetCurrentContextAuxInfo
0x4319174: testl %edi, %edi
0x4319176: je 0x43192cb ; UIGraphicsBeginPDFPageWithInfo + 380
0x431917c: testl %eax, %eax
0x431917e: je 0x43192cb ; UIGraphicsBeginPDFPageWithInfo + 380
0x4319184: movl $0x2, %ecx
0x4319189: calll 0x4318ce1 ; GetCurrentContextAuxInfo
0x431918e: testl %eax, %eax
0x4319190: je 0x43192bd ; UIGraphicsBeginPDFPageWithInfo + 366
0x4319196: cmpb $0x0, 0x20(%eax)
0x431919a: movl %eax, %ebx
0x431919c: je 0x43191a6 ; UIGraphicsBeginPDFPageWithInfo + 87
0x431919e: movl %edi, (%esp)
0x43191a1: calll 0x4aaa848 ; symbol stub for: CGPDFContextEndPage
0x43191a6: leal 0x8(%ebp), %eax <<< Thread 1: EXC_BAD_ACCESS (code=2, address=0xde)
source to share
I'm not sure if this is the same, but I answered a similar sound problem: UIGraphicsBeginPDFPage () crashes accidentally on 64 bit devices (CGPDFSecurityManagerCreateDecryptor ())
The gist of the solution was to defer the call CGPDFDocumentRelease
for any PDFs used in the target PDF until the target PDF was closed with UIGraphicsEndPDFContext
. For me, this meant that, unfortunately, I did not free the memory until the end of the process, although I could have done it, but it does work.
source to share
For me this happened when I also tried to release it (aka currentContext) with CGContextRelease after:
UIGraphicsEndPDFContext();
CGContextRelease(pdfContext);//<-comment this out to solve
It turns out I only needed UIGraphicsEndPDFContext();
and for some reason (which I can only guess using an asynchronous call), even calling the CGContextRelease AFTER, calling EndPDFContext, was still calling EXC_BAD_ACCESS on the line EndPDFContext
.
source to share