Skip to content

Commit

Permalink
hermesLog exceptions on Android
Browse files Browse the repository at this point in the history
Summary:
We've observed an issue where exception messages get lost across
the C++ to Java boundary in OSS builds. This is a temporary workaround to log
the exception message so it can be recovered from adb log if nothing else.

Reviewed By: mhorowitz

Differential Revision: D22743630

fbshipit-source-id: 22c7cd3ebb4cbe82634718c8fd2be447c388ddb8
  • Loading branch information
willholen authored and facebook-github-bot committed Jul 27, 2020
1 parent d3394bc commit 01906ad
Showing 1 changed file with 23 additions and 1 deletion.
24 changes: 23 additions & 1 deletion API/hermes/hermes.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,17 @@ int __llvm_profile_dump(void);
}
#endif

// Android OSS has a bug where exception data can get mangled when going via
// fbjni. This macro can be used to expose the root cause in adb log. It serves
// no purpose other than as a backup.
#ifdef __ANDROID__
#define LOG_EXCEPTION_CAUSE(...) hermesLog("HermesVM", __VA_ARGS__)
#else
#define LOG_EXCEPTION_CAUSE(...) \
do { \
} while (0)
#endif

// If a function body might throw C++ exceptions other than
// jsi::JSError from Hermes, it should be wrapped in this form:
//
Expand Down Expand Up @@ -162,6 +173,7 @@ jsi::JSError makeJSError(jsi::Runtime &rt, Args &&... args) {
std::string s;
llvh::raw_string_ostream os(s);
raw_ostream_append(os, std::forward<Args>(args)...);
LOG_EXCEPTION_CAUSE("JSError: %s", os.str().c_str());
return jsi::JSError(rt, os.str());
}

Expand Down Expand Up @@ -1122,12 +1134,14 @@ void HermesRuntime::loadSegment(
auto ret = hbc::BCProviderFromBuffer::createBCProviderFromBuffer(
std::make_unique<BufferAdapter>(std::move(buffer)));
if (!ret.first) {
LOG_EXCEPTION_CAUSE("Error evaluating javascript: %s", ret.second.c_str());
throw jsi::JSINativeException("Error evaluating javascript: " + ret.second);
}

auto requireContext = vm::Handle<vm::RequireContext>::dyn_vmcast(
impl(this)->vmHandleFromValue(context));
if (!requireContext) {
LOG_EXCEPTION_CAUSE("Error loading segment: Invalid context");
throw jsi::JSINativeException("Error loading segment: Invalid context");
}

Expand Down Expand Up @@ -1310,6 +1324,8 @@ HermesRuntimeImpl::prepareJavaScript(
os << " Buffer size " << bufSize << " starts with: ";
for (size_t i = 0; i < sizeof(bufPrefix) && i < bufSize; ++i)
os << llvh::format_hex_no_prefix(bufPrefix[i], 2);
LOG_EXCEPTION_CAUSE(
"Compiling JS failed: %s, %s", bcErr.second.c_str(), os.str().c_str());
throw jsi::JSINativeException(
"Compiling JS failed: " + std::move(bcErr.second) + os.str());
}
Expand Down Expand Up @@ -1844,6 +1860,8 @@ jsi::Value HermesRuntimeImpl::call(
vm::Handle<vm::Callable>::vmcast(&phv(func));
if (count > std::numeric_limits<uint32_t>::max() ||
!runtime_.checkAvailableStack((uint32_t)count)) {
LOG_EXCEPTION_CAUSE(
"HermesRuntimeImpl::call: Unable to call function: stack overflow");
throw jsi::JSINativeException(
"HermesRuntimeImpl::call: Unable to call function: stack overflow");
}
Expand Down Expand Up @@ -1882,6 +1900,8 @@ jsi::Value HermesRuntimeImpl::callAsConstructor(

if (count > std::numeric_limits<uint32_t>::max() ||
!runtime_.checkAvailableStack((uint32_t)count)) {
LOG_EXCEPTION_CAUSE(
"HermesRuntimeImpl::call: Unable to call function: stack overflow");
throw jsi::JSINativeException(
"HermesRuntimeImpl::call: Unable to call function: stack overflow");
}
Expand Down Expand Up @@ -2017,7 +2037,9 @@ void HermesRuntimeImpl::checkStatus(vm::ExecutionStatus status) {
// Here, we increment the depth to detect recursion in error handling.
vm::ScopedNativeDepthTracker depthTracker{&runtime_};
if (LLVM_LIKELY(!depthTracker.overflowed())) {
throw jsi::JSError(*this, std::move(exception));
auto ex = jsi::JSError(*this, std::move(exception));
LOG_EXCEPTION_CAUSE("JSI rethrowing JS exception: %s", ex.what());
throw ex;
}

runtime_.raiseStackOverflow(vm::Runtime::StackOverflowKind::NativeStack);
Expand Down

0 comments on commit 01906ad

Please sign in to comment.