[wasm] Set thread-in-wasm flag correctly after stack unwinding
In Isolate::UnwindAndFindHandler(), the thread-in-wasm flag was set before the destructor of some objects in that function got executed, e.g. the destructor of {WasmCodeRefScope}. On Windows-asan, these destructors could throw exceptions (asan on Windows uses exceptions for its memory access tracking), which get handled initially by the wasm trap handler, and would thereby invalidate the thread-in-wasm flag. With this CL a new scope gets introduced which makes sure that setting the thread-in-wasm flag is the last thing that happens in Isolate::UnwindAndFindHandler(). Bug: chromium:1195595 Change-Id: If9f5f486c55b3bc2718a1d5aee3e3bd290d0ff35 Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/2817598 Commit-Queue: Andreas Haas <ahaas@chromium.org> Reviewed-by: Jakob Kummerow <jkummerow@chromium.org> Cr-Commit-Position: refs/heads/master@{#73904}
This commit is contained in:
parent
02f84c745f
commit
15bf851978
@ -1672,10 +1672,36 @@ Object Isolate::ReThrow(Object exception) {
|
||||
return ReadOnlyRoots(heap()).exception();
|
||||
}
|
||||
|
||||
Object Isolate::UnwindAndFindHandler() {
|
||||
Object exception = pending_exception();
|
||||
namespace {
|
||||
// This scope will set the thread-in-wasm flag after the execution of all
|
||||
// destructors. The thread-in-wasm flag is only set when the scope gets enabled.
|
||||
class SetThreadInWasmFlagScope {
|
||||
public:
|
||||
SetThreadInWasmFlagScope() {
|
||||
DCHECK_IMPLIES(trap_handler::IsTrapHandlerEnabled(),
|
||||
!trap_handler::IsThreadInWasm());
|
||||
}
|
||||
|
||||
~SetThreadInWasmFlagScope() {
|
||||
if (enabled_) trap_handler::SetThreadInWasm();
|
||||
}
|
||||
|
||||
void Enable() { enabled_ = true; }
|
||||
|
||||
private:
|
||||
bool enabled_ = false;
|
||||
};
|
||||
} // namespace
|
||||
|
||||
Object Isolate::UnwindAndFindHandler() {
|
||||
// Create the {SetThreadInWasmFlagScope} first in this function so that its
|
||||
// destructor gets called after all the other destructors. It is important
|
||||
// that the destructor sets the thread-in-wasm flag after all other
|
||||
// destructors. The other destructors may cause exceptions, e.g. ASan on
|
||||
// Windows, which would invalidate the thread-in-wasm flag when the wasm trap
|
||||
// handler handles such non-wasm exceptions.
|
||||
SetThreadInWasmFlagScope set_thread_in_wasm_flag_scope;
|
||||
Object exception = pending_exception();
|
||||
|
||||
auto FoundHandler = [&](Context context, Address instruction_start,
|
||||
intptr_t handler_offset,
|
||||
@ -1768,9 +1794,10 @@ Object Isolate::UnwindAndFindHandler() {
|
||||
StandardFrameConstants::kFixedFrameSizeAboveFp -
|
||||
wasm_code->stack_slots() * kSystemPointerSize;
|
||||
|
||||
// This is going to be handled by Wasm, so we need to set the TLS flag.
|
||||
trap_handler::SetThreadInWasm();
|
||||
|
||||
// This is going to be handled by WebAssembly, so we need to set the TLS
|
||||
// flag. The {SetThreadInWasmFlagScope} will set the flag after all
|
||||
// destructors have been executed.
|
||||
set_thread_in_wasm_flag_scope.Enable();
|
||||
return FoundHandler(Context(), wasm_code->instruction_start(), offset,
|
||||
wasm_code->constant_pool(), return_sp, frame->fp());
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user