From 291cc95cc9e3c8e37fc7f2160d4eacd91b1c72be Mon Sep 17 00:00:00 2001 From: Riley Dulin Date: Mon, 11 Jan 2021 11:30:11 -0800 Subject: [PATCH] Add a fatal error handler for Hermes Summary: Hermes has a way to set up a callback that is invoked when a fatal error such as Out of Memory occurs. It is a static API that should be called at most once, so it uses `std::call_once` to achieve that. The fatal error handler is simple, it just uses glog to log an error message to logcat, then aborts (using `__android_log_assert`). The reason is typically very helpful for understanding why `hermes_fatal` was called. Changelog: [Android][Internal] - Print a logcat message when Hermes has a fatal error Reviewed By: mhorowitz Differential Revision: D25792805 fbshipit-source-id: 45de70d71e9bd8eaa880526d8835b4e32aab8fe3 --- .../com/facebook/hermes/reactexecutor/OnLoad.cpp | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/ReactAndroid/src/main/java/com/facebook/hermes/reactexecutor/OnLoad.cpp b/ReactAndroid/src/main/java/com/facebook/hermes/reactexecutor/OnLoad.cpp index 0e666e328e0..56a9f589490 100644 --- a/ReactAndroid/src/main/java/com/facebook/hermes/reactexecutor/OnLoad.cpp +++ b/ReactAndroid/src/main/java/com/facebook/hermes/reactexecutor/OnLoad.cpp @@ -7,7 +7,9 @@ #include <../instrumentation/HermesMemoryDumper.h> #include +#include #include +#include #include #include #include @@ -21,6 +23,13 @@ namespace facebook { namespace react { +static void hermesFatalHandler(const std::string &reason) { + LOG(ERROR) << "Hermes Fatal: " << reason << "\n"; + __android_log_assert(nullptr, "Hermes", "%s", reason.c_str()); +} + +static std::once_flag flag; + static ::hermes::vm::RuntimeConfig makeRuntimeConfig(jlong heapSizeMB) { namespace vm = ::hermes::vm; auto gcConfigBuilder = @@ -62,6 +71,9 @@ class HermesExecutorHolder jni::alias_ref) { JReactMarker::setLogPerfMarkerIfNeeded(); + std::call_once(flag, []() { + facebook::hermes::HermesRuntime::setFatalHandler(hermesFatalHandler); + }); return makeCxxInstance( std::make_unique(installBindings)); } @@ -71,6 +83,9 @@ class HermesExecutorHolder jlong heapSizeMB) { JReactMarker::setLogPerfMarkerIfNeeded(); auto runtimeConfig = makeRuntimeConfig(heapSizeMB); + std::call_once(flag, []() { + facebook::hermes::HermesRuntime::setFatalHandler(hermesFatalHandler); + }); return makeCxxInstance(std::make_unique( installBindings, JSIExecutor::defaultTimeoutInvoker, runtimeConfig)); }