SIGSEGV (Segfault) in sentry__value_new_addr / __vsnprintf_chk on Android
Integration
sentry-android
Build System
Gradle
AGP Version
8.12.0
Proguard
Enabled
Version
8.23.0
Steps to Reproduce
- Download TomTomApp from the playStore.
- Integrate sentry-android and/or sentry-android-ndk in the app.
- Run the app on an arm64 device.
- A native crash occurs and Sentry attempts to capture it.
- Instead of capturing, Sentry itself crashes with SIGSEGV during signal handling.
This was first observed in production.
Example of latest 3 logs attached:
sentry.logcat.zip sentry.logcat(1).zip sentry.logcat(2).zip
SIGSEGV: Segfault ?, in __vfprintf ?, in vsnprintf ?, in __vsnprintf_chk File "stdio.h", line 82, in _ZL8snprintfPcU17pass_object_size1mPKcz File "sentry_value.c", line 1180, in sentry__value_new_addr ... (140 additional frame(s) were not displayed)
Expected Result
Sentry should handle and capture the native crash, report it to Sentry.io, and not crash during its own signal handling.
Actual Result
Stacktrace appearing under the sentry issue:
libc +0x060040 __vfprintf libc +0x08032c vsnprintf libc +0x0494b8 __vsnprintf_chk split_config.arm64_v8a.apk +0x048120 _ZL8snprintfPcU17pass_object_size1mPKcz (stdio.h:82) split_config.arm64_v8a.apk +0x047fec sentry__value_new_addr (sentry_value.c:1180) split_config.arm64_v8a.apk +0x04912c sentry_value_new_stacktrace (sentry_value.c:1399) split_config.arm64_v8a.apk +0x04e8ec make_signal_event (sentry_backend_inproc.c:504) split_config.arm64_v8a.apk +0x04e8ec handle_ucontext (sentry_backend_inproc.c:581) split_config.arm64_v8a.apk +0x04e650 handle_signal (sentry_backend_inproc.c:648) linker64 +0x1446a0 __kernel_rt_sigreturn libc +0x021d90 abort split_config.arm64_v8a.apk +0x04f16c sentry__unwind_stack_libunwindstack (sentry_unwinder_libunwindstack.cpp:46) split_config.arm64_v8a.apk +0x04e89c make_signal_event (sentry_backend_inproc.c:492) split_config.arm64_v8a.apk +0x04e89c handle_ucontext (sentry_backend_inproc.c:581) split_config.arm64_v8a.apk +0x04e650 handle_signal (sentry_backend_inproc.c:648) app_process64 +0x00d05c <unknown> linker64 +0x1446a0 __kernel_rt_sigreturn libc +0x06003c __vfprintf libc +0x08032c vsnprintf libc +0x0494b8 __vsnprintf_chk split_config.arm64_v8a.apk +0x048120 _ZL8snprintfPcU17pass_object_size1mPKcz (stdio.h:82) split_config.arm64_v8a.apk +0x047fec sentry__value_new_addr (sentry_value.c:1180) split_config.arm64_v8a.apk +0x04912c sentry_value_new_stacktrace (sentry_value.c:1399) split_config.arm64_v8a.apk +0x04e8ec make_signal_event (sentry_backend_inproc.c:504) split_config.arm64_v8a.apk +0x04e8ec handle_ucontext (sentry_backend_inproc.c:581) split_config.arm64_v8a.apk +0x04e650 handle_signal (sentry_backend_inproc.c:648) linker64 +0x1446a0 __kernel_rt_sigreturn libc +0x021d90 abort split_config.arm64_v8a.apk +0x04f16c sentry__unwind_stack_libunwindstack (sentry_unwinder_libunwindstack.cpp:46) split_config.arm64_v8a.apk +0x04e89c make_signal_event (sentry_backend_inproc.c:492) split_config.arm64_v8a.apk +0x04e89c handle_ucontext (sentry_backend_inproc.c:581) split_config.arm64_v8a.apk +0x04e650 handle_signal (sentry_backend_inproc.c:648) app_process64 +0x00d05c <unknown> linker64 +0x1446a0 __kernel_rt_sigreturn libc +0x06003c __vfprintf libc +0x08032c vsnprintf libc +0x0494b8 __vsnprintf_chk split_config.arm64_v8a.apk +0x048120 _ZL8snprintfPcU17pass_object_size1mPKcz (stdio.h:82) split_config.arm64_v8a.apk +0x047fec sentry__value_new_addr (sentry_value.c:1180) split_config.arm64_v8a.apk +0x04912c sentry_value_new_stacktrace (sentry_value.c:1399) split_config.arm64_v8a.apk +0x04e8ec make_signal_event (sentry_backend_inproc.c:504) split_config.arm64_v8a.apk +0x04e8ec handle_ucontext (sentry_backend_inproc.c:581) split_config.arm64_v8a.apk +0x04e650 handle_signal (sentry_backend_inproc.c:648) linker64 +0x1446a0 __kernel_rt_sigreturn libc +0x021d90 abort split_config.arm64_v8a.apk +0x04f16c sentry__unwind_stack_libunwindstack (sentry_unwinder_libunwindstack.cpp:46) split_config.arm64_v8a.apk +0x04e89c make_signal_event (sentry_backend_inproc.c:492) split_config.arm64_v8a.apk +0x04e89c handle_ucontext (sentry_backend_inproc.c:581) split_config.arm64_v8a.apk +0x04e650 handle_signal (sentry_backend_inproc.c:648) app_process64 +0x00d05c <unknown> linker64 +0x1446a0 __kernel_rt_sigreturn libc +0x06003c __vfprintf libc +0x08032c vsnprintf libc +0x0494b8 __vsnprintf_chk split_config.arm64_v8a.apk +0x048120 _ZL8snprintfPcU17pass_object_size1mPKcz (stdio.h:82) split_config.arm64_v8a.apk +0x047fec sentry__value_new_addr (sentry_value.c:1180) split_config.arm64_v8a.apk +0x04912c sentry_value_new_stacktrace (sentry_value.c:1399) split_config.arm64_v8a.apk +0x04e8ec make_signal_event (sentry_backend_inproc.c:504) split_config.arm64_v8a.apk +0x04e8ec handle_ucontext (sentry_backend_inproc.c:581) split_config.arm64_v8a.apk +0x04e650 handle_signal (sentry_backend_inproc.c:648) linker64 +0x1446a0 __kernel_rt_sigreturn libc +0x021d90 abort split_config.arm64_v8a.apk +0x04f16c sentry__unwind_stack_libunwindstack (sentry_unwinder_libunwindstack.cpp:46) split_config.arm64_v8a.apk +0x04e89c make_signal_event (sentry_backend_inproc.c:492) split_config.arm64_v8a.apk +0x04e89c handle_ucontext (sentry_backend_inproc.c:581) split_config.arm64_v8a.apk +0x04e650 handle_signal (sentry_backend_inproc.c:648) app_process64 +0x00d05c <unknown> linker64 +0x1446a0 __kernel_rt_sigreturn libc +0x06003c __vfprintf libc +0x08032c vsnprintf libc +0x0494b8 __vsnprintf_chk split_config.arm64_v8a.apk +0x048120 _ZL8snprintfPcU17pass_object_size1mPKcz (stdio.h:82) split_config.arm64_v8a.apk +0x047fec sentry__value_new_addr (sentry_value.c:1180) split_config.arm64_v8a.apk +0x04912c sentry_value_new_stacktrace (sentry_value.c:1399) split_config.arm64_v8a.apk +0x04e8ec make_signal_event (sentry_backend_inproc.c:504) split_config.arm64_v8a.apk +0x04e8ec handle_ucontext (sentry_backend_inproc.c:581) split_config.arm64_v8a.apk +0x04e650 handle_signal (sentry_backend_inproc.c:648) linker64 +0x1446a0 __kernel_rt_sigreturn libc +0x021d90 abort split_config.arm64_v8a.apk +0x04f16c sentry__unwind_stack_libunwindstack (sentry_unwinder_libunwindstack.cpp:46) split_config.arm64_v8a.apk +0x04e89c make_signal_event (sentry_backend_inproc.c:492) split_config.arm64_v8a.apk +0x04e89c handle_ucontext (sentry_backend_inproc.c:581) split_config.arm64_v8a.apk +0x04e650 handle_signal (sentry_backend_inproc.c:648) app_process64 +0x00d05c <unknown> linker64 +0x1446a0 __kernel_rt_sigreturn libc +0x06003c __vfprintf libc +0x08032c vsnprintf libc +0x0494b8 __vsnprintf_chk split_config.arm64_v8a.apk +0x048120 _ZL8snprintfPcU17pass_object_size1mPKcz (stdio.h:82) split_config.arm64_v8a.apk +0x047fec sentry__value_new_addr (sentry_value.c:1180) split_config.arm64_v8a.apk +0x04912c sentry_value_new_stacktrace (sentry_value.c:1399) split_config.arm64_v8a.apk +0x04e8ec make_signal_event (sentry_backend_inproc.c:504) split_config.arm64_v8a.apk +0x04e8ec handle_ucontext (sentry_backend_inproc.c:581) split_config.arm64_v8a.apk +0x04e650 handle_signal (sentry_backend_inproc.c:648) linker64 +0x1446a0 __kernel_rt_sigreturn libc +0x021d90 abort split_config.arm64_v8a.apk +0x04f16c sentry__unwind_stack_libunwindstack (sentry_unwinder_libunwindstack.cpp:46) split_config.arm64_v8a.apk +0x04e89c make_signal_event (sentry_backend_inproc.c:492) split_config.arm64_v8a.apk +0x04e89c handle_ucontext (sentry_backend_inproc.c:581) split_config.arm64_v8a.apk +0x04e650 handle_signal (sentry_backend_inproc.c:648) app_process64 +0x00d05c <unknown> linker64 +0x1446a0 __kernel_rt_sigreturn libc +0x06003c __vfprintf libc +0x08032c vsnprintf libc +0x0494b8 __vsnprintf_chk split_config.arm64_v8a.apk +0x048120 _ZL8snprintfPcU17pass_object_size1mPKcz (stdio.h:82) split_config.arm64_v8a.apk +0x047fec sentry__value_new_addr (sentry_value.c:1180) split_config.arm64_v8a.apk +0x04912c sentry_value_new_stacktrace (sentry_value.c:1399) split_config.arm64_v8a.apk +0x04e8ec make_signal_event (sentry_backend_inproc.c:504) split_config.arm64_v8a.apk +0x04e8ec handle_ucontext (sentry_backend_inproc.c:581) split_config.arm64_v8a.apk +0x04e650 handle_signal (sentry_backend_inproc.c:648) linker64 +0x1446a0 __kernel_rt_sigreturn libc +0x021d90 abort split_config.arm64_v8a.apk +0x04f16c sentry__unwind_stack_libunwindstack (sentry_unwinder_libunwindstack.cpp:46) split_config.arm64_v8a.apk +0x04e89c make_signal_event (sentry_backend_inproc.c:492) split_config.arm64_v8a.apk +0x04e89c handle_ucontext (sentry_backend_inproc.c:581) split_config.arm64_v8a.apk +0x04e650 handle_signal (sentry_backend_inproc.c:648) app_process64 +0x00d05c <unknown> linker64 +0x1446a0 __kernel_rt_sigreturn libc +0x06003c __vfprintf libc +0x08032c vsnprintf libc +0x0494b8 __vsnprintf_chk split_config.arm64_v8a.apk +0x048120 _ZL8snprintfPcU17pass_object_size1mPKcz (stdio.h:82) split_config.arm64_v8a.apk +0x047fec sentry__value_new_addr (sentry_value.c:1180) split_config.arm64_v8a.apk +0x04912c sentry_value_new_stacktrace (sentry_value.c:1399) split_config.arm64_v8a.apk +0x04e8ec make_signal_event (sentry_backend_inproc.c:504) split_config.arm64_v8a.apk +0x04e8ec handle_ucontext (sentry_backend_inproc.c:581) split_config.arm64_v8a.apk +0x04e650 handle_signal (sentry_backend_inproc.c:648) linker64 +0x1446a0 __kernel_rt_sigreturn libc +0x021d90 abort split_config.arm64_v8a.apk +0x04f16c sentry__unwind_stack_libunwindstack (sentry_unwinder_libunwindstack.cpp:46) split_config.arm64_v8a.apk +0x04e89c make_signal_event (sentry_backend_inproc.c:492) split_config.arm64_v8a.apk +0x04e89c handle_ucontext (sentry_backend_inproc.c:581) split_config.arm64_v8a.apk +0x04e650 handle_signal (sentry_backend_inproc.c:648) app_process64 +0x00d05c <unknown> linker64 +0x1446a0 __kernel_rt_sigreturn libc +0x06003c __vfprintf libc +0x08032c vsnprintf libc +0x0494b8 __vsnprintf_chk split_config.arm64_v8a.apk +0x048120 _ZL8snprintfPcU17pass_object_size1mPKcz (stdio.h:82) split_config.arm64_v8a.apk +0x047fec sentry__value_new_addr (sentry_value.c:1180) split_config.arm64_v8a.apk +0x04912c sentry_value_new_stacktrace (sentry_value.c:1399) split_config.arm64_v8a.apk +0x04e8ec make_signal_event (sentry_backend_inproc.c:504) split_config.arm64_v8a.apk +0x04e8ec handle_ucontext (sentry_backend_inproc.c:581) split_config.arm64_v8a.apk +0x04e650 handle_signal (sentry_backend_inproc.c:648)
Thanks for the report @AlessandroSemeraro-tomtom!
It looks like the immediate cause in the Native SDK is the use of a vfprintf descendant to format addresses within the signal handler. In particular, it seems that vfprintf tries to deallocate an internal buffer using a pointer that doesn't point to an allocated region:
Abort message: 'Invalid address 0x7cf576b080 passed to free: value not allocated'
The most likely cause in that context is that vfprintf isn't signal safe, so it shouldn't be called from a signal handler. I will replace this with a signal-safe implementation.
Note: while this is the most likely scenario, there could be another underlying environmental cause (memory corruption). Since any signal-unsafe functions should be removed from the signal handlers anyway, I would start with this first.
Btw, the logcat logs show two types of crashes:
- one that reflects what you posted and which supports my described cause above
- one that seems to be a general invalid dereference where your APK is at the top of the backtrace
Am I right to assume that those are the initial native crashes that the crashing handler received?
Hey @supervacuus thanks for following up.
I think that the invalid dereference traces where our APK is at the top of the backtrace correspond to the original native crashes that the Sentry handler was trying to process.
The recursive SIGSEGV (with vfprintf / snprintf in sentry__value_new_addr) occurs afterwards, during Sentry’s own signal handling. I think we first get our app’s native crash, and then Sentry crashes while attempting to capture it.
I also noticed that sometimes Sentry groups unrelated native crashes under the same issue, which might be why you’re seeing a mix of both types of traces in the logs, but the main crash here should be the vfprintf call inside the signal handler.
Hey @AlessandroSemeraro-tomtom, I pinged you in mail asking about an example event we can check. No need to put it on the GH issue here if you don't want to as it's public. Feel free to respond on the email
I think that the invalid dereference traces where our APK is at the top of the backtrace correspond to the original native crashes that the Sentry handler was trying to process.
The recursive SIGSEGV (with vfprintf / snprintf in sentry__value_new_addr) occurs afterwards, during Sentry’s own signal handling. I think we first get our app’s native crash, and then Sentry crashes while attempting to capture it.
Thanks for verifying @AlessandroSemeraro-tomtom! That is what i expected.
I also noticed that sometimes Sentry groups unrelated native crashes under the same issue, which might be why you’re seeing a mix of both types of traces in the logs, but the main crash here should be the vfprintf call inside the signal handler.
I saw the other native crashes in the logcat output you attached to this issue. I currently have no access to your events.
I any case, I am working on a fix for this. There is trivial solution and one that eliminates the bug class , which is bit more involved, especially to test.
Do you have a stable local repro, that would allow running either of those fixes, so that we might be able to release according to their urgency (immediate fix first, more general fix later)? Thx!
@Angelodaniel @supervacuus Please find this link that should allow external engineers to access the issue -> https://tomtom-navapp.sentry.io/share/issue/a1195882a76647d8910c4dc3bcf5a0fa/
We also had a duplicate ticket of what I think is exactly the same issue, but I'm sharing the link to it in case it can give more insights -> https://tomtom-navapp.sentry.io/share/issue/09be2035eb5c457bb6e175ceb0e214d2/
Do you have a stable local repro, that would allow running either of those fixes, so that we might be able to release according to their urgency (immediate fix first, more general fix later)?
I need to check with my team, let me come back to you regarding this one.
In the meantime thanks a lot for your efforts guys!
@supervacuus I've checked with my team and the best option here is to just intake the next Sentry's version in our App with the potential fix. The bug is quite difficult to reproduce (native crash on our side) and we had only around 50 events for 40 users during one full month.
What I can do is to monitor if the fix is effective once it reaches production, and keep you posted under this thread. WDYT?
Thanks @AlessandroSemeraro-tomtom for the event data and the feedback regarding severity/urgency and release strategy.
I think the suggested approach makes sense and we will just release the fixes when ready, keep you posted here and you signal if you see any changes once you deployed one of the fix releases or when the topic escalates unexpectedly.