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

feat: Add C++ exception handler #412

Merged
merged 3 commits into from Jan 22, 2019
Merged

feat: Add C++ exception handler #412

merged 3 commits into from Jan 22, 2019

Conversation

kattrali
Copy link
Contributor

Handles C++ exceptions in the std::set_terminate function rather than
waiting for the exception to propagate to the signal handler. Improves
the quality of stacktraces by working around issues in abort(), adds the
C++ exception type name as the error class and a description of the
thrown object as the message.

Design

Added a new handler alongside the signal handler to catch C++ exceptions earlier.

  • Parses the exception name via the C++ ABI
  • Parses the exception message by rethrowing the object and then coercing the result into a string description. For std::exception instances, this is the message.

Tests

Added new end-to-end tests for handling throwing a C++ exception and throwing a random thing. Checks that the report is valid, the stacktrace is reasonable, and the error class and message match.

@kattrali kattrali force-pushed the kattrali/cpp-handler branch 2 times, most recently from 5e1f9dd to 9e41b69 Compare January 15, 2019 16:53
ndk/src/main/jni/handlers/cpp_handler.cpp Outdated Show resolved Hide resolved
ndk/src/main/jni/handlers/cpp_handler.cpp Outdated Show resolved Hide resolved
Handles C++ exceptions in the std::set_terminate function rather than
waiting for the exception to propagate to the signal handler. Improves
the quality of stacktraces by working around issues in abort(), adds the
C++ exception type name as the error class and a description of the
thrown object as the message.
For the C++ handler in particular, once handling is complete, it 
uninstalls itself and calls the previous handler. The default previous
handler abort()s the app which would then trigger the signal handler.
This introduces a check whether handling is completed and if so, calls
the default/previous signal handler, terminating the application 
cleanly.
@kattrali kattrali force-pushed the kattrali/cpp-handler branch 2 times, most recently from dc3fd25 to bb1a2a6 Compare January 21, 2019 16:49
*
* References:
* * https://docs.microsoft.com/en-us/cpp/c-runtime-library/reference/set-terminate-crt
*/
Copy link
Contributor

Choose a reason for hiding this comment

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

These are great docs 👍

When capturing a stacktrace from a signal handler or C++ terminate
handler different unwinders deadlock on different architectures and/or
Android API levels. This change uses different unwinders based on
whether async signal safety is required or not, by supported API levels.

It introduces libunwindstack as the signal-safe unwinder for API 15+ on
ARM64 and x86/x64 devices. For notify()/C++ exceptions, use libunwind,
nongnu libunwind, or libcorkscrew depending on the API level.

* libcorkscrew hangs when unwinding from a C++ exception on ARM 32-bit.
* libunwind hangs on ARM64 from a signal handler
* nongnu libunwind hangs on ARM32 from a signal handler if raise() is
  called directly
@kattrali kattrali merged commit 31d7590 into master Jan 22, 2019
@kattrali kattrali deleted the kattrali/cpp-handler branch January 22, 2019 14:12
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

3 participants