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
This commit is contained in:
Riley Dulin
2021-01-11 11:30:11 -08:00
committed by Facebook GitHub Bot
parent 2d64dde3e6
commit 291cc95cc9
@@ -7,7 +7,9 @@
#include <../instrumentation/HermesMemoryDumper.h>
#include <HermesExecutorFactory.h>
#include <android/log.h>
#include <fbjni/fbjni.h>
#include <glog/logging.h>
#include <hermes/Public/GCConfig.h>
#include <hermes/Public/RuntimeConfig.h>
#include <jni.h>
@@ -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<jclass>) {
JReactMarker::setLogPerfMarkerIfNeeded();
std::call_once(flag, []() {
facebook::hermes::HermesRuntime::setFatalHandler(hermesFatalHandler);
});
return makeCxxInstance(
std::make_unique<HermesExecutorFactory>(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<HermesExecutorFactory>(
installBindings, JSIExecutor::defaultTimeoutInvoker, runtimeConfig));
}