Commit dc499db7 authored by Eric Holk's avatar Eric Holk Committed by Commit Bot

Give V8 a chance to handle faults in stack dump crash handler

V8 has the ability to use guard regions and signal handlers to do WebAssembly
bounds checks on x86_64 Linux. This requires any in-process signal handlers to
let V8 try to handle the signal first. This CL adds support for this to the
stack dump signal handler.

Bug: chromium:722585, v8:5277
Change-Id: Iccb72b66118c743f78b3ddbaf7887728b213ddb2
Reviewed-on: https://chromium-review.googlesource.com/541956Reviewed-by: default avatarJochen Eisinger <jochen@chromium.org>
Reviewed-by: default avatarMark Mentovai <mark@chromium.org>
Commit-Queue: Eric Holk <eholk@chromium.org>
Cr-Commit-Position: refs/heads/master@{#487153}
parent a31c717d
...@@ -38,6 +38,12 @@ namespace debug { ...@@ -38,6 +38,12 @@ namespace debug {
// done in official builds because it has security implications). // done in official builds because it has security implications).
BASE_EXPORT bool EnableInProcessStackDumping(); BASE_EXPORT bool EnableInProcessStackDumping();
#if defined(OS_POSIX)
BASE_EXPORT void SetStackDumpFirstChanceCallback(bool (*handler)(int,
void*,
void*));
#endif
// Returns end of the stack, or 0 if we couldn't get it. // Returns end of the stack, or 0 if we couldn't get it.
#if BUILDFLAG(CAN_UNWIND_WITH_FRAME_POINTERS) #if BUILDFLAG(CAN_UNWIND_WITH_FRAME_POINTERS)
BASE_EXPORT uintptr_t GetStackEnd(); BASE_EXPORT uintptr_t GetStackEnd();
......
...@@ -59,6 +59,8 @@ namespace { ...@@ -59,6 +59,8 @@ namespace {
volatile sig_atomic_t in_signal_handler = 0; volatile sig_atomic_t in_signal_handler = 0;
bool (*try_handle_signal)(int, void*, void*) = nullptr;
#if !defined(USE_SYMBOLIZE) #if !defined(USE_SYMBOLIZE)
// The prefix used for mangled symbols, per the Itanium C++ ABI: // The prefix used for mangled symbols, per the Itanium C++ ABI:
// http://www.codesourcery.com/cxx-abi/abi.html#mangling // http://www.codesourcery.com/cxx-abi/abi.html#mangling
...@@ -216,6 +218,27 @@ void StackDumpSignalHandler(int signal, siginfo_t* info, void* void_context) { ...@@ -216,6 +218,27 @@ void StackDumpSignalHandler(int signal, siginfo_t* info, void* void_context) {
// NOTE: This code MUST be async-signal safe. // NOTE: This code MUST be async-signal safe.
// NO malloc or stdio is allowed here. // NO malloc or stdio is allowed here.
// Give a registered callback a chance to recover from this signal
//
// V8 uses guard regions to guarantee memory safety in WebAssembly. This means
// some signals might be expected if they originate from Wasm code while
// accessing the guard region. We give V8 the chance to handle and recover
// from these signals first.
if (try_handle_signal != nullptr &&
try_handle_signal(signal, info, void_context)) {
// The first chance handler took care of this. The SA_RESETHAND flag
// replaced this signal handler upon entry, but we want to stay
// installed. Thus, we reinstall ourselves before returning.
struct sigaction action;
memset(&action, 0, sizeof(action));
action.sa_flags = SA_RESETHAND | SA_SIGINFO;
action.sa_sigaction = &StackDumpSignalHandler;
sigemptyset(&action.sa_mask);
sigaction(signal, &action, NULL);
return;
}
// Record the fact that we are in the signal handler now, so that the rest // Record the fact that we are in the signal handler now, so that the rest
// of StackTrace can behave in an async-signal-safe manner. // of StackTrace can behave in an async-signal-safe manner.
in_signal_handler = 1; in_signal_handler = 1;
...@@ -717,6 +740,11 @@ bool EnableInProcessStackDumping() { ...@@ -717,6 +740,11 @@ bool EnableInProcessStackDumping() {
return success; return success;
} }
void SetStackDumpFirstChanceCallback(bool (*handler)(int, void*, void*)) {
DCHECK(try_handle_signal == nullptr || handler == nullptr);
try_handle_signal = handler;
}
StackTrace::StackTrace(size_t count) { StackTrace::StackTrace(size_t count) {
// NOTE: This code MUST be async-signal safe (it's used by in-process // NOTE: This code MUST be async-signal safe (it's used by in-process
// stack dumping signal handler). NO malloc or stdio is allowed here. // stack dumping signal handler). NO malloc or stdio is allowed here.
......
...@@ -21,6 +21,7 @@ ...@@ -21,6 +21,7 @@
#include "base/command_line.h" #include "base/command_line.h"
#include "base/compiler_specific.h" #include "base/compiler_specific.h"
#include "base/debug/crash_logging.h" #include "base/debug/crash_logging.h"
#include "base/debug/stack_trace.h"
#include "base/feature_list.h" #include "base/feature_list.h"
#include "base/memory/ptr_util.h" #include "base/memory/ptr_util.h"
#include "base/sys_info.h" #include "base/sys_info.h"
...@@ -144,10 +145,16 @@ RenderProcessImpl::RenderProcessImpl( ...@@ -144,10 +145,16 @@ RenderProcessImpl::RenderProcessImpl(
SetV8FlagIfFeature(features::kAsmJsToWebAssembly, "--validate-asm"); SetV8FlagIfFeature(features::kAsmJsToWebAssembly, "--validate-asm");
SetV8FlagIfNotFeature(features::kWebAssembly, SetV8FlagIfNotFeature(features::kWebAssembly,
"--wasm-disable-structured-cloning"); "--wasm-disable-structured-cloning");
SetV8FlagIfFeature(features::kWebAssemblyTrapHandler, "--wasm-trap-handler");
SetV8FlagIfFeature(features::kSharedArrayBuffer, SetV8FlagIfFeature(features::kSharedArrayBuffer,
"--harmony-sharedarraybuffer"); "--harmony-sharedarraybuffer");
SetV8FlagIfFeature(features::kWebAssemblyTrapHandler, "--wasm-trap-handler");
#if defined(OS_LINUX) && defined(ARCH_CPU_X86_64) && !defined(OS_ANDROID)
if (base::FeatureList::IsEnabled(features::kWebAssemblyTrapHandler)) {
base::debug::SetStackDumpFirstChanceCallback(v8::V8::TryHandleSignal);
}
#endif
const base::CommandLine& command_line = const base::CommandLine& command_line =
*base::CommandLine::ForCurrentProcess(); *base::CommandLine::ForCurrentProcess();
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment