occasional crashes in CGContext.drawPDFPage

Hi,


in our app we render PDF pages with a CATiledLayer to screen. We have occasional crashes mostly on iPads. Every time it crashes there are two or three concurrent threads rendering the page. I'm not able to reproduce it.


Any idea how to fix this?


Code looks like this:


    override func draw(_ layer: CALayer, in ctx: CGContext) {
        guard let page = self.page else {
            return
        }

        ctx.setFillColor(red: 1.0,green: 1.0,blue: 1.0,alpha: 1.0)
        ctx.fill(ctx.boundingBoxOfClipPath)
    
        let layerSize = layer.bounds.size

        // Flip the context so that the PDF page is rendered right side up.
        ctx.translateBy(x: 0.0, y: layerSize.height)
        ctx.scaleBy(x: 1.0, y: -1.0)
        let pageMediaBox = page.getBoxRect(.mediaBox)
        let fillWithPDFPageVerticalProportion = layerSize.height / pageMediaBox.height
        let fillWithPDFPageHorizontalProportion = layerSize.width / pageMediaBox.width
        let fillWithPDFPageProportion = min(fillWithPDFPageVerticalProportion, fillWithPDFPageHorizontalProportion)
    
        ctx.translateBy(
            x: -(pageMediaBox.width * fillWithPDFPageProportion - layerSize.width) / 2,
            y: -(pageMediaBox.height * fillWithPDFPageProportion - layerSize.height) / 2
        )
        ctx.scaleBy(x: fillWithPDFPageProportion, y: fillWithPDFPageProportion)
        ctx.drawPDFPage(page)
    }


This is a stack trace from the crashing thread:


#8. Crashed: com.apple.root.default-qos

0 libobjc.A.dylib 0x185a8c1a0 objc_retain + 16

1 ImageIO 0x1888dd5cc IIOImageRead::IIOImageRead(CGDataProvider*, bool) + 88

2 ImageIO 0x1888df93c CGImageReadCreateWithProvider + 196

3 ImageIO 0x18874ac6c IIOImageSource::IIOImageSource(CGDataProvider*, IIODictionary*) + 96

4 ImageIO 0x18874ec50 CGImageSourceCreateWithDataProvider + 172

5 CoreGraphics 0x18803a464 CGImageCreateWithJPEGDataProvider3 + 84

6 CoreGraphics 0x187fb7264 create_image_for_image + 188

7 CoreGraphics 0x187fb713c CGPDFImageCreateImage + 184

8 CoreGraphics 0x1880256f8 CGPDFDrawingContextDrawImage + 40

9 CoreGraphics 0x1880de03c op_Do + 104

10 CoreGraphics 0x1882e6684 pdf_scanner_handle_xname + 144

11 CoreGraphics 0x1882e5f0c CGPDFScannerScan + 368

12 CoreGraphics 0x1882f0170 CGPDFDrawingContextDrawPage + 516

13 CoreGraphics 0x1880c0a04 pdf_page_draw_in_context + 132

14 CoreGraphics 0x187fa763c CGContextDrawPDFPageWithDrawingCallbacks + 76

15 CoreGraphics 0x187fa7310 CGContextDrawPDFPage + 32

16 myApp 0x1009e8cf0 specialized PDFTiledView.draw(CALayer, in : CGContext) -> () (PDFTiledView.swift:59)

17 myApp 0x1009e88ec @objc PDFTiledView.draw(CALayer, in : CGContext) -> () (PDFTiledView.swift)

18 QuartzCore 0x18a86b51c -[CALayer drawInContext:] + 296

19 QuartzCore 0x18a79c780 tiled_layer_render(_CAImageProvider*, unsigned int, unsigned int, unsigned int, unsigned int, void*) + 1532

20 QuartzCore 0x18a836448 CAImageProviderThread(unsigned int*, bool) + 812

21 libdispatch.dylib 0x1861a6a14 _dispatch_client_callout + 16

22 libdispatch.dylib 0x1861adbc8 _dispatch_queue_override_invoke$VARIANT$mp + 716

23 libdispatch.dylib 0x1861b3cf4 _dispatch_root_queue_drain + 600

24 libdispatch.dylib 0x1861b3a38 _dispatch_worker_thread3 + 120

25 libsystem_pthread.dylib 0x18644f06c _pthread_wqthread + 1268

26 libsystem_pthread.dylib 0x18644eb6c start_wqthread + 4


There are two threads with this stack trace:


#9. com.apple.root.default-qos

0 libsystem_kernel.dylib 0x18633c138 __psynch_mutexwait + 8

1 libsystem_pthread.dylib 0x186453660 _pthread_mutex_lock_wait + 96

2 libsystem_pthread.dylib 0x1864535a4 _pthread_mutex_lock_slow$VARIANT$mp + 264

3 CoreGraphics 0x187fb70ac CGPDFImageCreateImage + 40

4 CoreGraphics 0x1880256f8 CGPDFDrawingContextDrawImage + 40

5 CoreGraphics 0x1880de03c op_Do + 104

6 CoreGraphics 0x1882e6684 pdf_scanner_handle_xname + 144

7 CoreGraphics 0x1882e5f0c CGPDFScannerScan + 368

8 CoreGraphics 0x1882f0170 CGPDFDrawingContextDrawPage + 516

9 CoreGraphics 0x1880c0a04 pdf_page_draw_in_context + 132

10 CoreGraphics 0x187fa763c CGContextDrawPDFPageWithDrawingCallbacks + 76

11 CoreGraphics 0x187fa7310 CGContextDrawPDFPage + 32

12 myApp 0x1009e8cf0 specialized PDFTiledView.draw(CALayer, in : CGContext) -> () (PDFTiledView.swift:59)

13 myApp 0x1009e88ec @objc PDFTiledView.draw(CALayer, in : CGContext) -> () (PDFTiledView.swift)

14 QuartzCore 0x18a86b51c -[CALayer drawInContext:] + 296

15 QuartzCore 0x18a79c780 tiled_layer_render(_CAImageProvider*, unsigned int, unsigned int, unsigned int, unsigned int, void*) + 1532

16 QuartzCore 0x18a836448 CAImageProviderThread(unsigned int*, bool) + 812

17 libdispatch.dylib 0x1861a6a14 _dispatch_client_callout + 16

18 libdispatch.dylib 0x1861adbc8 _dispatch_queue_override_invoke$VARIANT$mp + 716

19 libdispatch.dylib 0x1861b3cf4 _dispatch_root_queue_drain + 600

20 libdispatch.dylib 0x1861b3a38 _dispatch_worker_thread3 + 120

21 libsystem_pthread.dylib 0x18644f06c _pthread_wqthread + 1268

22 libsystem_pthread.dylib 0x18644eb6c start_wqthread + 4



Thanks,

Snert

Replies

Hello Snert,

We're experiencing a similar problem in our app but can't figure out how to fix it, did you finally find a solution?

Thanks!

Roger

Having a similar problem here. We discovered that this is a bug in the CGContext, and only occurs with some images in some PDFs and not others.

Interestingly, it doesn't ALWAYS crash either.

Still no solution and we're at the point where we may just end up writing our own renderer using Metal. CGContext PDF stuff goes waaaay back and any other open source code we look at, (event PSPDFKit) will have the same issue.