Invalid stacktrace on macOS with PACE wrapping
Description
I've integrated Sentry native for a client of mine in their standalone applications. It's working great and has proven very valuable to improve the quality of our products.
However after wrapping the binaries with the PACE protection and licensing system, we fail to get any form of stack trace on macOS, whereas Windows is fine. Unfortunately I cannot give any details about the wrapping process publicly, as per the terms of the NDA we've signed with PACE.
I've contacted both parties to investigate this issue which is left unadressed after several email exchanges.
This anti-piracy solution is quite ubiquitous in the pro-audio software segment, so I'd like to reach out here to other developers and companies using both PACE and Sentry, to join forces and come up with a solution.
When does the problem happen
- [ ] During build
- [ ] During run-time
- [x] When capturing a hard crash
Environment
- OS: macOS
- Compiler: Apple clang
- Sentry backend: crashpad
Looking into this a bit, and seeing that the code does not seem to belong to any loaded module/library.
I think what happens is that PACE is decrypting/decompressing the code in memory and jumping to it.
This is probably the same problem that executable packers working in memory, or JIT code would have.
If this is indeed the way that PACE works, you might have luck changing the memory offsets of the debug_meta definitions in the before_send hook. However that hook is not compatible with the crashpad backend, and I don’t know of any way from the top of my head how to make crashpad work around these limitations.
Depending on how PACE works, and I must admit I have no idea, it might be possible to configure it to use temporary files instead of work in-memory.
Yes the problem indeed seems to be related to PACE decrypting code into memory before calling the original main().
If I understand correctly you're saying that the function pointer offsets are expected to be relative to that original main(), and that the decryption / wrapping process modifies those. So if PACE gaves us the offset of the wrapped main w.r.t original main we could compensate for that by manually shifting the offsets used by the stack trace walker ? Provided there is a way to do that in crashpad and/or OS symbolication functions of course.
I don't think temp files are an option as I believe that would defeat their whole encryption process.
I have looked through the crashpad API again, but I don’t see a way to manually register a "module". I wonder what happens when you attach a debugger to that process. Can it correctly figure all that stuff out, or does it have the same issues as crashpad has?
Hi! I am encountering the same issue here. Answering your question, @Swatinem , the debugger can figure out symbols correctly even after PACE wrapping.
@lmdsp Did you have any luck demangling the stack trace?