forked from envoyproxy/envoy
-
Notifications
You must be signed in to change notification settings - Fork 0
/
signals_test.cc
127 lines (110 loc) · 3.43 KB
/
signals_test.cc
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
#include <signal.h>
#include <sys/mman.h>
#include "exe/signal_action.h"
#include "test/test_common/utility.h"
#include "gtest/gtest.h"
namespace Envoy {
#if defined(__has_feature)
#if __has_feature(address_sanitizer)
#define ASANITIZED /* Sanitized by Clang */
#endif
#endif
#if defined(__SANITIZE_ADDRESS__)
#define ASANITIZED /* Sanitized by GCC */
#endif
// Death tests that expect a particular output are disabled under address sanitizer.
// The sanitizer does its own special signal handling and prints messages that are
// not ours instead of what this test expects. As of latest Clang this appears
// to include abort() as well.
#ifndef ASANITIZED
TEST(SignalsDeathTest, InvalidAddressDeathTest) {
SignalAction actions;
EXPECT_DEATH_LOG_TO_STDERR(
[]() -> void {
// Oops!
volatile int* nasty_ptr = reinterpret_cast<int*>(0x0);
*(nasty_ptr) = 0;
}(),
"backtrace.*Segmentation fault");
}
TEST(SignalsDeathTest, BusDeathTest) {
SignalAction actions;
EXPECT_DEATH_LOG_TO_STDERR(
[]() -> void {
// Bus error is tricky. There's one way that can work on POSIX systems
// described below but it depends on mmaping a file. Just make it easy and
// raise a bus.
//
// FILE *f = tmpfile();
// int *p = mmap(0, 4, PROT_WRITE, MAP_PRIVATE, fileno(f), 0);
// *p = 0;
raise(SIGBUS);
}(),
"backtrace.*Bus");
}
TEST(SignalsDeathTest, BadMathDeathTest) {
SignalAction actions;
EXPECT_DEATH_LOG_TO_STDERR(
[]() -> void {
// It turns out to be really hard to not have the optimizer get rid of a
// division by zero. Just raise the signal for this test.
raise(SIGFPE);
}(),
"backtrace.*Floating point");
}
#if defined(__x86_64__) || defined(__i386__)
// Unfortunately we don't have a reliable way to do this on other platforms
TEST(SignalsDeathTest, IllegalInstructionDeathTest) {
SignalAction actions;
EXPECT_DEATH_LOG_TO_STDERR(
[]() -> void {
// Intel defines the "ud2" opcode to be an invalid instruction:
__asm__("ud2");
}(),
"backtrace.*Illegal");
}
#endif
TEST(SignalsDeathTest, AbortDeathTest) {
SignalAction actions;
EXPECT_DEATH_LOG_TO_STDERR([]() -> void { abort(); }(), "backtrace.*Abort(ed)?");
}
TEST(SignalsDeathTest, RestoredPreviousHandlerDeathTest) {
SignalAction action;
{
SignalAction inner_action;
// Test case for a previously encountered misfeature:
// We should restore the previous SignalAction when the inner action
// goes out of scope, NOT the default.
}
// Outer SignalAction should be active again:
EXPECT_DEATH_LOG_TO_STDERR([]() -> void { abort(); }(), "backtrace.*Abort(ed)?");
}
#endif
TEST(SignalsDeathTest, IllegalStackAccessDeathTest) {
SignalAction actions;
EXPECT_DEATH(actions.tryEvilAccessForTest(false), "");
EXPECT_DEATH(actions.tryEvilAccessForTest(true), "");
}
TEST(Signals, LegalTest) {
// Don't do anything wrong.
{ SignalAction actions; }
// Nothing should happen...
}
TEST(Signals, RaiseNonFatalTest) {
{
SignalAction actions;
// I urgently request that you do nothing please!
raise(SIGURG);
}
// Nothing should happen...
}
TEST(Signals, LegalStackAccessTest) {
SignalAction actions;
actions.doGoodAccessForTest();
}
TEST(Signals, HandlerTest) {
siginfo_t fake_si;
fake_si.si_addr = nullptr;
SignalAction::sigHandler(SIGURG, &fake_si, nullptr);
}
} // namespace Envoy