// Copyright 2017 the V8 project authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. #include "include/v8.h" #include "src/trap-handler/trap-handler.h" #include "testing/gtest/include/gtest/gtest.h" #if V8_OS_POSIX #include #include #endif namespace { #if V8_TRAP_HANDLER_SUPPORTED void CrashOnPurpose() { *reinterpret_cast(42); } // When using V8::RegisterDefaultSignalHandler, we save the old one to fall back // on if V8 doesn't handle the signal. This allows tools like ASan to register a // handler early on during the process startup and still generate stack traces // on failures. class SignalHandlerFallbackTest : public ::testing::Test { protected: void SetUp() override { struct sigaction action; action.sa_sigaction = SignalHandler; sigemptyset(&action.sa_mask); action.sa_flags = SA_SIGINFO; sigaction(SIGSEGV, &action, &old_segv_action_); sigaction(SIGBUS, &action, &old_bus_action_); } void TearDown() override { // be a good citizen and restore the old signal handler. sigaction(SIGSEGV, &old_segv_action_, nullptr); sigaction(SIGBUS, &old_bus_action_, nullptr); } static sigjmp_buf continuation_; private: static void SignalHandler(int signal, siginfo_t* info, void*) { siglongjmp(continuation_, 1); } struct sigaction old_segv_action_; struct sigaction old_bus_action_; // We get SIGBUS on Mac sometimes. }; sigjmp_buf SignalHandlerFallbackTest::continuation_; TEST_F(SignalHandlerFallbackTest, DoTest) { const int save_sigs = 1; if (!sigsetjmp(continuation_, save_sigs)) { constexpr bool kUseDefaultTrapHandler = true; EXPECT_TRUE(v8::V8::EnableWebAssemblyTrapHandler(kUseDefaultTrapHandler)); CrashOnPurpose(); FAIL(); } else { // Our signal handler ran. v8::internal::trap_handler::RemoveTrapHandler(); SUCCEED(); return; } FAIL(); } #endif } // namespace