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(ndk): Ensure 64-bit devices running 32-bit binaries do not use 32-bit device unwinding logic #383

Merged
merged 2 commits into from
Nov 8, 2018

Conversation

kattrali
Copy link
Contributor

@kattrali kattrali commented Nov 3, 2018

Small refactor of the API 21+ stack unwinding logic to restrict 32-bit
unwinding style from 64-bit devices.

While the stack enhancements added in #378 are intended only to be run
on 32-bit devices and gated to the arm build, when 64-bit devices
are running the 32-bit library, the stacktraces for those devices were
unintentionally affected.

This is the case when an app is configured to only run 32-bit binaries
(Android cannot run both 64-bit and 32-bit binaries at once), and many
popular libraries (e.g. React Native) only distribute 32-bit libraries.

Added additional improvement to the 32-bit stacktrace resolution by
switching to nongnu libunwind only for those devices. This significantly
improves the number of frames which can be unwound without risk of a
segfault.

Tests

  • Tested against ARM 32-/64-bit devices against raise(signum), abort(), floating point exceptions, and invalid casts. With the exception of abort() the stacktrace is improved.
  • Sanity checked against x86/x64 to ensure the logic is restricted correctly

To reproduce the original problem add ABI filters to an apps gradle config to only load 32-bit binaries:

android {
  // ...
  defaultConfig {
    // Ensure no 64-bit libs are loaded/preferred over the 32-bit counterparts
    packagingOptions {
        exclude "lib/arm64-v8a/libbugsnag-ndk.so"
        // Add `exclude` lines for any other included library
    }

    ndk {
      abiFilters "armeabi-v7a", "x86"
    }
  }
}

Discussion

Linked issues

Fixes #382
Related to #380

Review

For the pull request reviewer(s), this changeset has been reviewed for:

  • Testing additional esoteric C crashes to compare the unwinding results across devices/architectures
  • Consistency between the changeset and the goal stated above
  • Performance and complexity - are there any cases of unexpected O(n^3) when iterating, recursing, flat mapping, etc?
  • Thoroughness of added tests and any missing edge cases
  • Idiomatic use of the language

@kattrali kattrali force-pushed the kattrali/switch-by-wordsize branch 2 times, most recently from 933c5b0 to 1e9d8a9 Compare November 7, 2018 01:28
nongnu libunwind is available on armeabi and armeabi-v7a, and produces a
more consistent and stable result. Provided we can conditionally switch
based on the device ABI, we will no longer need the single frame mode to
avoid segfaults from unwind for thread kill events.
Uses the ABI list to conditionally switch unwinders on ARM.

While the stack enhancements added in #378 are intended only to be run
on 32-bit devices and gated to the __arm__ build, when 64-bit devices
are running the 32-bit library, the stacktraces for those devices were
unintentionally affected. This is the case when an app is configured to
only run 32-bit binaries (Android cannot run both 64-bit and 32-bit
binaries at once), and many popular libraries (e.g. React Native) only
distribute 32-bit libraries.

To further improve the stack quality on 32-bit, switches the underlying
unwinder from gnu unwind to non-gnu libunwind. Improves frame resolution
and does not have the crash in unwind when setting registers.

Fixes #382
@kattrali kattrali force-pushed the kattrali/switch-by-wordsize branch from 1e9d8a9 to 16c8cf9 Compare November 7, 2018 01:33
@kattrali
Copy link
Contributor Author

kattrali commented Nov 7, 2018

Reworked the implementation a bit to:

  1. Add additional inline documentation
  2. Use the ABI list we already have to switch unwinding logic. Its better than linking an additional dependency.

@kattrali kattrali merged commit cbdd572 into master Nov 8, 2018
@kattrali kattrali deleted the kattrali/switch-by-wordsize branch November 8, 2018 01:06
@ellsworthrw
Copy link

This version no longer sends reports for native crashes.

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.

3 participants