swift-toolkit icon indicating copy to clipboard operation
swift-toolkit copied to clipboard

Crash when opening a book

Open grighakobian opened this issue 1 year ago • 17 comments
trafficstars

Describe the bug

We recently released a new version that included bug fixes for iOS 18. However, after the update, we noticed a significant drop in crash-free users—over 10%. In an attempt to resolve the issue, we downgraded the Readium version to 2.6.0, which previously did not cause any crashes. Unfortunately, this did not resolve the problem. Finally, we tried building the project with Xcode 15.4 instead of Xcode 16.0, and the crash issue was eliminated.

How to reproduce?

  1. Open a book

Readium version

2.6.0 ... 2.7.3

OS version

Mainly iOS 17 and 18

Testing device

Any Device

Environment

macOS: 15.0
platform: x86_64
carthage: 0.40.0
Xcode 16.0
Build version 16A242d

Additional context

Crashed: com.apple.root.default-qos 0 libsystem_platform.dylib 0x2a54 platform_memmove + 52 1 libxml2.2.dylib 0x18638 + 216 2 libxml2.2.dylib 0x6a58 xmlParserInputBufferCreateMem + 92 3 libxml2.2.dylib 0x67d4 xmlCreateMemoryParserCtxt + 72 4 libxml2.2.dylib 0x6610 xmlReadMemory + 60 5 0x101c55c XMLDocument.__allocating_init(string:encoding:) + 130 (Document.swift:130) 6 0x1171cb4 FuziXMLDocument.init(string:namespaces:) + 14 (Fuzi.swift:14) 7 0x1161dc8 MediaTypeSnifferContext.contentAsXML.getter + 74 (MediaTypeSnifferContext.swift:74) 8 0x115d170 specialized static MediaType.sniffHTML(context:) + 115 (MediaTypeSniffer.swift:115) 9 0x115b028 implicit closure #1 in variable initialization expression of static MediaType.sniffers + 32 10 0x115c704 specialized static MediaType.of(content:mediaTypes:fileExtensions:sniffers:) + 804 (Archive.swift:804) 11 0x115ca88 specialized static MediaType.of(:mediaTypes:fileExtensions:sniffers:) + 280 (MediaTypeSnifferContent.swift:280) 12 0x115a6e8 static MediaType.of(:mediaTypes:fileExtensions:sniffers:) + 28 (:28) 13 0x11c1a84 PublicationServer.resourceHandler(:) + 341 (PublicationServer.swift:341) 14 0xd81ddc thunk for @escaping @callee_guaranteed (@guaranteed GCDWebServerRequest) -> (@owned GCDWebServerResponse?) + 48 (:48) 15 0x122b680 __82-[GCDWebServer(Handlers) addHandlerForMethod:pathRegex:requestClass:processBlock:]_block_invoke + 923 (GCDWebServer.m:923) 16 0x122f704 -[GCDWebServerConnection(Subclassing) processRequest:completion:] + 762 (GCDWebServerConnection.m:762) 17 0x122cb94 -[GCDWebServerConnection _startProcessingRequest] + 152 (GCDWebServerConnection.m:152) 18 0x122d960 __45-[GCDWebServerConnection _readRequestHeaders]_block_invoke + 346 (GCDWebServerConnection.m:346) 19 0x122e2c8 __64-[GCDWebServerConnection(Read) readHeaders:withCompletionBlock:]_block_invoke + 461 (GCDWebServerConnection.m:461) 20 0x122e044 __68-[GCDWebServerConnection(Read) readData:withLength:completionBlock:]_block_invoke + 432 (GCDWebServerConnection.m:432) 21 libdispatch.dylib 0x31234 + 60 22 libdispatch.dylib 0x213c + 32 23 libdispatch.dylib 0x3dd4 + 20 24 libdispatch.dylib 0x15a6c + 864 25 libdispatch.dylib 0x1609c + 156 26 libsystem_pthread.dylib 0x48f8 _pthread_wqthread + 228 27 libsystem_pthread.dylib 0x10cc start_wqthread + 8

grighakobian avatar Sep 30 '24 11:09 grighakobian

You can download the crash reports here.

grighakobian avatar Sep 30 '24 11:09 grighakobian

We are experiencing the same issue. When building with Xcode 16, some users experience the same crash. Unfortunately(?), the crash is not consistant, for some users it never crashes. I have yet to have any workaround.

tnorbert avatar Oct 02 '24 10:10 tnorbert

I have new information about this "bug" It seems that the application only crashes in Relaese mode, so when downloaded from TestFlight. Building through xcode doesn't cause the code to crash. Any idea? I tried several combos, I tried using xcode 15.4, xcode 16, I tried using my iPhone 15 Plus and another iPhone x and even an iPhone 7. Maybe the problem is around the optimization level or something? I would be glad to hear any tip.

tnorbert avatar Oct 03 '24 07:10 tnorbert

Okay, I found the issue. For my defense, I got this project from others and it is an old one :) It looks like the library was updated from 2.2.0 to 2.6.0 at some point without doing the 2.5.0 migratin guide. Although it worked at that time, it looks like now this is causing this crash. I changed the implementation to use the GCDHTTPServer.shared as shown in the guide and the crash seems to go away.

tnorbert avatar Oct 03 '24 10:10 tnorbert

@grighakobian Was it the same issue as described by @tnorbert above for you?

mickael-menu avatar Oct 09 '24 08:10 mickael-menu

@mickael-menu We haven't migrated to 2.5.0 yet; we're currently using version 2.7.3. Everything works fine when building on Xcode 15.4, but we're encountering crashes when building on Xcode 16.

grighakobian avatar Oct 09 '24 10:10 grighakobian

@grighakobian Could you share your code creating an instance of EPUBNavigatorViewController? (Just all the parameters you pass to the constructor).

mickael-menu avatar Oct 09 '24 11:10 mickael-menu

@grighakobian @mickael-menu So, basically, my steps were to update the library to 2.7.3 and resolve every deprecated message. This includes using a new initializer in EPUBNavigatorViewController (and switching to GCDHTTPServer.shared) and reimplementing the user preferences (saving the preferences by our own logic and applying these values directly to the reader). After these steps, all our crashed went away. Although, these changes made us rework some of our epubs as the new reader did not apply several user preferences such as font sizes. It turned out that some epubs needed to be changed.

tnorbert avatar Oct 09 '24 13:10 tnorbert

@grighakobian Could you share your code creating an instance of EPUBNavigatorViewController? (Just all the parameters you pass to the constructor).

@mickael-menu Here is the EPUBNavigatorViewController initialization code.

let navigatorViewController = EPUBNavigatorViewController(publication: publication, initialLocation: initialLocation, resourcesServer: publicationServer)

Note that we are using the old PublicationServer API.

grighakobian avatar Oct 10 '24 06:10 grighakobian

Okay that's probably why this is crashing on Xcode 16. Let me know if you still have the issue after migrating the HTTP server.

mickael-menu avatar Oct 10 '24 08:10 mickael-menu

@mickael-menu Unfortunately, I started getting these crashes, too. At first, I though I solved this but it looks like I was wrong. Right now, I am getting the exact same crashes as @grighakobian. Any idea on that? The user's download it from TestFlight and when the device is fully offline (airplane mode and wifi off), the app crashes when trying to open an epub.

tnorbert avatar Oct 21 '24 14:10 tnorbert

No but it's actually crashing in one of our third-party dependencies. Maybe you can take a look on Fuzi's repository to see if something similar was mentioned, and/or open an issue there: https://github.com/cezheng/Fuzi

Please let me know if you do so I can track the answers.

mickael-menu avatar Oct 21 '24 16:10 mickael-menu

The project looks pretty dead actually. Maybe it's time to look for another XML parser.

If someone wants to contribute a solution with an alternative XML parser, you need to implement the following protocol: https://github.com/readium/swift-toolkit/blob/develop/Sources/Shared/Toolkit/XML/XML.swift

Here's an example using Fuzi: https://github.com/readium/swift-toolkit/blob/develop/Sources/Shared/Toolkit/XML/Fuzi.swift

And there are tests here, you just need to copy and adjust the FuziTests class: https://github.com/readium/swift-toolkit/blob/f53630f81f75c6201c35f40082021f2e4ed42f08/Tests/SharedTests/Toolkit/XML/XMLTests.swift#L94-L107

mickael-menu avatar Oct 21 '24 16:10 mickael-menu

@mickael-menu It looks like somebody opened a new issue here and it is the same fuzi crash as we are experiencing.

https://github.com/readium/swift-toolkit/issues/495

I think this is going to be a bigger issue now, I don't think that there is an easy solution but I am going to try to solve it somehow, without switching the parser (we kinda need it to be fixed asap as we are using this in production :) )

tnorbert avatar Oct 21 '24 18:10 tnorbert

What's your plan to fix it? I guess we can't without fixing the issue in Fuzi. Forking it in Readium is a possibility if you find the solution by modifying Fuzy directly.

mickael-menu avatar Oct 21 '24 19:10 mickael-menu

@mickael-menu I wrote a temporary solution in the other ticket but it is only a band aid for production crashes. @grighakobian What was your situation? Did you manage to solve this?

tnorbert avatar Oct 22 '24 08:10 tnorbert

@tnorbert We fixed the crash by compiling the project on Xcode 15.4.

grighakobian avatar Oct 24 '24 11:10 grighakobian

Hello everyone, Xcode 16.1 crash still happening.

I can't reproduce the crash on my device, I tried testflight builds and release build from Xcode. I tried many books of different sizes.

MelDev1 avatar Oct 29 '24 21:10 MelDev1

@grighakobian @tnorbert @mickael-menu @HadrienGardeur

I reproduced the crash on the old device (se 1 gen), Xcode 16.1, release scheme.

I tried to fix it here https://github.com/MelDev1/Fuzi

The problem was in the unsafe creation of UnsafeBufferPointer.

  public convenience init(cChars: [CChar]) throws {
    let buffer = cChars.withUnsafeBufferPointer { buffer in
        UnsafeBufferPointer(rebasing: buffer[0..<buffer.count])
    }
    try self.init(buffer: buffer)
  }

The documentation prohibits doing this.

Here is the quick solution:

  public convenience init(cChars: [CChar]) throws {
      let mutablebuffer = UnsafeMutableBufferPointer<CChar>.allocate(capacity: cChars.count)
      _ = mutablebuffer.initialize(from: cChars)
      
      defer {
          mutablebuffer.deallocate()
      }
      
      let buffer = UnsafeBufferPointer(mutablebuffer)
      try self.init(buffer: buffer)
  }

I released the application and for the second day there have been no crashes. Please check my fix.

MelDev1 avatar Nov 06 '24 15:11 MelDev1

@MelDev1 That's great thank you! I added a comment on your PR to Fuzi to add some weight, if we have no answers from the maintainers I think I will open a fork on the readium organization to release your fix.

mickael-menu avatar Nov 07 '24 15:11 mickael-menu

@MelDev1 Still no crash reports after your fix? I think it's time to consider doing a fork.

mickael-menu avatar Nov 13 '24 09:11 mickael-menu

@mickael-menu yep, no crashes

MelDev1 avatar Nov 13 '24 11:11 MelDev1

Could some of you try the branch fix-fuzi based off 2.7.3 and report whether the problem is fixed for you? Thank you!

cc @MelDev1 @grighakobian @tnorbert

mickael-menu avatar Nov 14 '24 12:11 mickael-menu

Not yet on 2.7.3 but changed just the Fuzi dependency to that fork and fix-tag. Playing around for about 30 minutes on two device < iOS 18 in release mode. Same scenario that was crashing constantly and pretty reliable before. So far works like a charm. ❤️👍👏

Gucky avatar Nov 14 '24 21:11 Gucky