Skip to content

Commit

Permalink
Add a fatal error handler for Hermes
Browse files Browse the repository at this point in the history
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
  • Loading branch information
dulinriley authored and kelset committed May 26, 2021
1 parent a6a4d33 commit a05d179
Showing 1 changed file with 15 additions and 0 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -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>
Expand All @@ -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 =
Expand Down Expand Up @@ -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));
}
Expand All @@ -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));
}
Expand Down

0 comments on commit a05d179

Please sign in to comment.