I maintain offpdf, an open-source, offline PDF toolkit built with Tauri and Rust.
We are trying to support HEIC/HEIF-to-PDF conversion on Windows, but we have reached a native crash that we have not been able to explain yet.
What we know:
Two independent real-device HEIC files—one from an iPhone and one from an Android device—immediately terminate the packaged Windows 11 x64 application during import.
Both crashes produce exception code 0xc0000005 at the same executable offset: 0x0000000000809d06.
A synthetic HEIC/HEIF fixture successfully decodes and converts in the same Windows release workflow.
The decode path uses one bounded decoder, limits compressed and decoded size, validates dimensions before allocation, uses a single decoder thread, and serializes image conversions.
Rust tests, the Windows build, installation, startup smoke test, and Microsoft Defender scan all pass.
The failure happens before a PDF is produced and appears to cross the Rust/native-library boundary.
We are currently missing a symbolicated native stack trace and a shareable real-device fixture. The original test images contain personal metadata, so we will not publish them.
We would especially appreciate guidance on:
Capturing and symbolizing this kind of 0xc0000005 crash in a packaged Tauri/Rust application.
Checking for ABI, codec-plugin, or runtime-library mismatches in the Windows HEIC decoder.
Known differences in real-device HEIC files such as grids, orientation, auxiliary images, HDR or gain maps that synthetic fixtures may not exercise.
Tracking issue and implementation details:
We are happy to create a minimal standalone reproducer once we identify the most useful diagnostic path. Thanks for any pointers—and if our integration is wrong, we would genuinely like to understand and fix it properly.
0xc0000005 is basically the windows quivalent of a segfault on linux. in rust, it's most likely caused by a invalid raw pointer dereference, but can also be caused by any kind of UB, not directly related to pointers.
audit every unsafe block in your code that handles untrusted data parsing/decoding. if you are using ffi, first check all the ffi calls where a pointer is passed across ffi boundary.
Thanks — I followed your suggestion and audited every unsafe block and FFI pointer call in the Rust-side HEIC decode path. OffPDF itself has no unsafe code there, but heif-rs 26.7.0 used libheif’s deprecated integer-stride plane API and copied from the returned pointer without null, stride, or overflow checks. I patched those issues and completed 299 public-corpus decode attempts without a native crash. Unfortunately, the same Android and iPhone HEIC files still reproduce 0xc0000005 in the packaged Windows build, so those FFI issues were real but not the root cause.
I'm not using windows for a while, but I think you can get a peek of the call stack using a debugger, either launch the program under a debugger, or you can register a JIT debugger which will automatically attach to crashed processes.
even without the full debug symbols, a stack dump can still be helpful. you'll miss some of the frames, but you can still inspect the variables/arguments in frames above and below the unknown frames, and/or get a rough location before the crash happened.
if you don't have a debugger installed, personally I recommend x64dbg:
unlike source level debuggers such as visual studio, this one is optimized for binary debugging and reverse engineering, so understanding of assembly code is recommended.
You debug this like you debug a memory issue in C/C++.
If you have the source, either:
Run under sanitizers/valgrind (or Miri if you can, i.e. the code is Rust-only and Miri is fast enough).
Compile with debuginfo and run under a debugger (I recommend WinDbg).
If you don't have the source (and no separate PDB), your job is more complicated. You still run under a debugger but you won't jump into source code and might not even have a stack trace (if there are no symbols). You'll need to decipher the assembly.
Thanks. The missing artifact is indeed a symbolized first-chance crash trace. The failure only reproduces with private real-device samples on a remote tester’s Windows machine; our synthetic fixtures and 299 public-corpus decodes do not trigger it. We’ve already audited the Rust/FFI boundary, so we’ll provide an exact PDB-enabled build and capture the WinDbg stack and module map from the real reproduction. I’ll update the thread once we have the faulting frame.