Line data Source code
1 : // Copyright 2017 the V8 project authors. All rights reserved.
2 : // Use of this source code is governed by a BSD-style license that can be
3 : // found in the LICENSE file.
4 :
5 : #include "include/v8.h"
6 : #include "src/trap-handler/trap-handler.h"
7 : #include "testing/gtest/include/gtest/gtest.h"
8 :
9 : #if V8_OS_POSIX
10 : #include <setjmp.h>
11 : #include <signal.h>
12 : #endif
13 :
14 : namespace {
15 :
16 : #if V8_TRAP_HANDLER_SUPPORTED
17 :
18 0 : void CrashOnPurpose() { *reinterpret_cast<volatile int*>(42); }
19 :
20 : // When using V8::RegisterDefaultSignalHandler, we save the old one to fall back
21 : // on if V8 doesn't handle the signal. This allows tools like ASan to register a
22 : // handler early on during the process startup and still generate stack traces
23 : // on failures.
24 2 : class SignalHandlerFallbackTest : public ::testing::Test {
25 : protected:
26 1 : void SetUp() override {
27 : struct sigaction action;
28 1 : action.sa_sigaction = SignalHandler;
29 1 : sigemptyset(&action.sa_mask);
30 1 : action.sa_flags = SA_SIGINFO;
31 1 : sigaction(SIGSEGV, &action, &old_segv_action_);
32 1 : sigaction(SIGBUS, &action, &old_bus_action_);
33 1 : }
34 :
35 1 : void TearDown() override {
36 : // be a good citizen and restore the old signal handler.
37 1 : sigaction(SIGSEGV, &old_segv_action_, nullptr);
38 1 : sigaction(SIGBUS, &old_bus_action_, nullptr);
39 1 : }
40 :
41 : static sigjmp_buf continuation_;
42 :
43 : private:
44 1 : static void SignalHandler(int signal, siginfo_t* info, void*) {
45 1 : siglongjmp(continuation_, 1);
46 : }
47 : struct sigaction old_segv_action_;
48 : struct sigaction old_bus_action_; // We get SIGBUS on Mac sometimes.
49 : };
50 : sigjmp_buf SignalHandlerFallbackTest::continuation_;
51 :
52 15444 : TEST_F(SignalHandlerFallbackTest, DoTest) {
53 : const int save_sigs = 1;
54 2 : if (!sigsetjmp(continuation_, save_sigs)) {
55 : constexpr bool use_default_signal_handler = true;
56 1 : CHECK(v8::V8::EnableWebAssemblyTrapHandler(use_default_signal_handler));
57 : CrashOnPurpose();
58 0 : FAIL();
59 : } else {
60 : // Our signal handler ran.
61 1 : v8::internal::trap_handler::RemoveTrapHandler();
62 2 : SUCCEED();
63 1 : return;
64 : }
65 : FAIL();
66 : }
67 :
68 : #endif
69 :
70 9264 : } // namespace
|