Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: disable sigaltstack on Android #901

Merged
merged 3 commits into from
Nov 10, 2023

Conversation

supervacuus
Copy link
Collaborator

I am creating this as a tracking branch for a pre-release. Disabling "our" sigaltstack on Android is probably not the solution that will end up in a release, but it should provide a sound basis for broader testing in the downstream SDKs.

Copy link
Member

@kahest kahest left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🔥

Copy link

codecov bot commented Nov 10, 2023

Codecov Report

Merging #901 (3c7f3f8) into master (406d418) will decrease coverage by 3.91%.
The diff coverage is 100.00%.

@@            Coverage Diff             @@
##           master     #901      +/-   ##
==========================================
- Coverage   86.49%   82.59%   -3.91%     
==========================================
  Files          40       53      +13     
  Lines        3674     7372    +3698     
  Branches        0     1185    +1185     
==========================================
+ Hits         3178     6089    +2911     
- Misses        496     1175     +679     
- Partials        0      108     +108     

Copy link
Member

@markushi markushi left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM!

g_signal_stack.ss_sp = sentry_malloc(SIGNAL_STACK_SIZE);
if (!g_signal_stack.ss_sp) {
return 1;
}
g_signal_stack.ss_size = SIGNAL_STACK_SIZE;
g_signal_stack.ss_flags = 0;
sigaltstack(&g_signal_stack, 0);

# endif
sigemptyset(&g_sigaction.sa_mask);
g_sigaction.sa_sigaction = handle_signal;
g_sigaction.sa_flags = SA_SIGINFO | SA_ONSTACK;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just double checking: We still should set the SA_ONSTACK flag, even if we don't allocate the altstack ourselves right?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, SA_ONSTACK tells the signal handler to use the alt stack or falls back to the process stack. Since the assumption is that every thread has an alt stack, we should be good.

@supervacuus supervacuus merged commit 02fe0c4 into master Nov 10, 2023
14 of 17 checks passed
@supervacuus supervacuus deleted the fix/disable_sigaltstack_on_android branch November 10, 2023 17:50
Copy link

Fails
🚫 Please consider adding a changelog entry for the next release.

Instructions and example for changelog

Please add an entry to CHANGELOG.md to the "Unreleased" section. Make sure the entry includes this PR's number.

Example:

## Unreleased

- disable sigaltstack on Android ([#901](https://github.com/getsentry/sentry-native/pull/901))

If none of the above apply, you can opt out of this check by adding #skip-changelog to the PR description.

Generated by 🚫 dangerJS against 71937b7

@etnlGD
Copy link

etnlGD commented Feb 9, 2024

Hello, our project has recently collected a lot of crashes related to Android signal handling. We happened to see this bug fix, which seems to be highly related to the crashes we encountered. However, I didn't find how this fix would cause a crash.

Android's bionic libc seems to allocate alternate signal handler stacks forevery thread and also references them from their internal maintenance structs.

As far as I know, the stacks allocated by bionic are only referenced for deallocating which should be harmless.

The way we currently set up our sigaltstack seems to interfere with this setup and causes crashes whenever an ART signal handler touches the thread that called sentry_init().

Could you please provide more details about these crashes? I haven't found any evidence to suggest that setting up stacks repeatedly would lead to a crash.

@supervacuus
Copy link
Collaborator Author

Hi @etnlGD,

Hello, our project has recently collected a lot of crashes related to Android signal handling. We happened to see this bug fix, which seems to be highly related to the crashes we encountered. However, I didn't find how this fix would cause a crash.

The most significant change to our previous implementation is that the default sigaltstack from the bionic thread implementation has a reduced stack size in the signal handler, which can be an issue if you allocate something big in either the before_send or on_crash handler. We generally recommend not to do that, but we do know that some frameworks expose very large crash-context structures that should be heap allocated.

Android's bionic libc seems to allocate alternate signal handler stacks forevery thread and also references them from their internal maintenance structs.

As far as I know, the stacks allocated by bionic are only referenced for deallocating which should be harmless.

Yeah, the reference is not the reason for crashes, but rather the way the sigaltstack is set up (separate mmap vs heap allocation, ignoring previously installed sigaltstacks, not creating a stack guard page, maybe even using incompatible flags). The previous sigaltstack configuration was not made with Android in mind, and since it was only configured for the thread on which sentry_init() was called, it was not a general solution anyway.

The way we currently set up our sigaltstack seems to interfere with this setup and causes crashes whenever an ART signal handler touches the thread that called sentry_init().

Could you please provide more details about these crashes? I haven't found any evidence to suggest that setting up stacks repeatedly would lead to a crash.

The ART team urged us not to set up a sigaltstack for any threads after we identified them as a potential culprit. We saw many crashes in the sigchain starting with the August 2023 Google Play System update on Android 12, 13, and 14. Repros tested against our previous sigaltstack setup were all fixed using the default Android sigaltstack configuration.

This doesn't mean we won't touch the topic again, but it would have to be a non-default behavior where users have more control over which threads should be configured with that stack.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

4 participants