1 //===-- UnixSignalsTest.cpp -----------------------------------------------===//
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7 //===----------------------------------------------------------------------===//
10 #include "gtest/gtest.h"
12 #include "lldb/Target/UnixSignals.h"
13 #include "llvm/Support/FormatVariadic.h"
16 using namespace lldb_private
;
18 class TestSignals
: public UnixSignals
{
22 AddSignal(2, "SIG2", false, true, true, "DESC2");
23 AddSignal(4, "SIG4", true, false, true, "DESC4");
24 AddSignal(8, "SIG8", true, true, true, "DESC8");
25 AddSignal(16, "SIG16", true, false, false, "DESC16");
26 AddSignalCode(16, 1, "a specific type of SIG16");
27 AddSignalCode(16, 2, "SIG16 with a fault address",
28 SignalCodePrintOption::Address
);
29 AddSignalCode(16, 3, "bounds violation", SignalCodePrintOption::Bounds
);
33 void ExpectEqArrays(llvm::ArrayRef
<int32_t> expected
,
34 llvm::ArrayRef
<int32_t> observed
, const char *file
,
36 std::string location
= llvm::formatv("{0}:{1}", file
, line
);
37 ASSERT_EQ(expected
.size(), observed
.size()) << location
;
39 for (size_t i
= 0; i
< observed
.size(); ++i
) {
40 ASSERT_EQ(expected
[i
], observed
[i
])
41 << "array index: " << i
<< "location:" << location
;
45 #define EXPECT_EQ_ARRAYS(expected, observed) \
46 ExpectEqArrays((expected), (observed), __FILE__, __LINE__);
48 TEST(UnixSignalsTest
, Iteration
) {
51 EXPECT_EQ(4, signals
.GetNumSignals());
52 EXPECT_EQ(2, signals
.GetFirstSignalNumber());
53 EXPECT_EQ(4, signals
.GetNextSignalNumber(2));
54 EXPECT_EQ(8, signals
.GetNextSignalNumber(4));
55 EXPECT_EQ(16, signals
.GetNextSignalNumber(8));
56 EXPECT_EQ(LLDB_INVALID_SIGNAL_NUMBER
, signals
.GetNextSignalNumber(16));
59 TEST(UnixSignalsTest
, Reset
) {
61 bool stop_val
= signals
.GetShouldStop(2);
62 bool notify_val
= signals
.GetShouldNotify(2);
63 bool suppress_val
= signals
.GetShouldSuppress(2);
65 // Change two, then reset one and make sure only that one was reset:
66 EXPECT_EQ(true, signals
.SetShouldNotify(2, !notify_val
));
67 EXPECT_EQ(true, signals
.SetShouldSuppress(2, !suppress_val
));
68 EXPECT_EQ(true, signals
.ResetSignal(2, false, true, false));
69 EXPECT_EQ(stop_val
, signals
.GetShouldStop(2));
70 EXPECT_EQ(notify_val
, signals
.GetShouldStop(2));
71 EXPECT_EQ(!suppress_val
, signals
.GetShouldNotify(2));
73 // Make sure reset with no arguments resets them all:
74 EXPECT_EQ(true, signals
.SetShouldSuppress(2, !suppress_val
));
75 EXPECT_EQ(true, signals
.SetShouldNotify(2, !notify_val
));
76 EXPECT_EQ(true, signals
.ResetSignal(2));
77 EXPECT_EQ(stop_val
, signals
.GetShouldStop(2));
78 EXPECT_EQ(notify_val
, signals
.GetShouldNotify(2));
79 EXPECT_EQ(suppress_val
, signals
.GetShouldSuppress(2));
82 TEST(UnixSignalsTest
, GetInfo
) {
85 bool should_suppress
= false, should_stop
= false, should_notify
= false;
88 signals
.GetSignalInfo(signo
, should_suppress
, should_stop
, should_notify
);
90 EXPECT_EQ(true, should_suppress
);
91 EXPECT_EQ(false, should_stop
);
92 EXPECT_EQ(true, should_notify
);
94 EXPECT_EQ(true, signals
.GetShouldSuppress(signo
));
95 EXPECT_EQ(false, signals
.GetShouldStop(signo
));
96 EXPECT_EQ(true, signals
.GetShouldNotify(signo
));
99 TEST(UnixSignalsTest
, GetAsStringRef
) {
102 ASSERT_EQ(llvm::StringRef(), signals
.GetSignalAsStringRef(100));
103 ASSERT_EQ("SIG16", signals
.GetSignalAsStringRef(16));
106 TEST(UnixSignalsTest
, GetAsString
) {
109 ASSERT_EQ("", signals
.GetSignalDescription(100, std::nullopt
));
110 ASSERT_EQ("SIG16", signals
.GetSignalDescription(16, std::nullopt
));
111 ASSERT_EQ("", signals
.GetSignalDescription(100, 100));
112 ASSERT_EQ("SIG16", signals
.GetSignalDescription(16, 100));
113 ASSERT_EQ("SIG16: a specific type of SIG16",
114 signals
.GetSignalDescription(16, 1));
116 // Unknown code, won't use the address.
117 ASSERT_EQ("SIG16", signals
.GetSignalDescription(16, 100, 0xCAFEF00D));
118 // Known code, that shouldn't print fault address.
119 ASSERT_EQ("SIG16: a specific type of SIG16",
120 signals
.GetSignalDescription(16, 1, 0xCAFEF00D));
121 // Known code that should.
122 ASSERT_EQ("SIG16: SIG16 with a fault address (fault address: 0xcafef00d)",
123 signals
.GetSignalDescription(16, 2, 0xCAFEF00D));
124 // No address given just print the code description.
125 ASSERT_EQ("SIG16: SIG16 with a fault address",
126 signals
.GetSignalDescription(16, 2));
128 const char *expected
= "SIG16: bounds violation";
129 // Must pass all needed info to get full output.
130 ASSERT_EQ(expected
, signals
.GetSignalDescription(16, 3));
131 ASSERT_EQ(expected
, signals
.GetSignalDescription(16, 3, 0xcafef00d));
132 ASSERT_EQ(expected
, signals
.GetSignalDescription(16, 3, 0xcafef00d, 0x1234));
134 ASSERT_EQ("SIG16: upper bound violation (fault address: 0x5679, lower bound: "
135 "0x1234, upper bound: 0x5678)",
136 signals
.GetSignalDescription(16, 3, 0x5679, 0x1234, 0x5678));
137 ASSERT_EQ("SIG16: lower bound violation (fault address: 0x1233, lower bound: "
138 "0x1234, upper bound: 0x5678)",
139 signals
.GetSignalDescription(16, 3, 0x1233, 0x1234, 0x5678));
142 TEST(UnixSignalsTest
, VersionChange
) {
146 uint64_t ver
= signals
.GetVersion();
147 EXPECT_GT(ver
, 0ull);
148 EXPECT_EQ(true, signals
.GetShouldSuppress(signo
));
149 EXPECT_EQ(true, signals
.GetShouldStop(signo
));
150 EXPECT_EQ(true, signals
.GetShouldNotify(signo
));
152 EXPECT_EQ(signals
.GetVersion(), ver
);
154 signals
.SetShouldSuppress(signo
, false);
155 EXPECT_LT(ver
, signals
.GetVersion());
156 ver
= signals
.GetVersion();
158 signals
.SetShouldStop(signo
, true);
159 EXPECT_LT(ver
, signals
.GetVersion());
160 ver
= signals
.GetVersion();
162 signals
.SetShouldNotify(signo
, false);
163 EXPECT_LT(ver
, signals
.GetVersion());
164 ver
= signals
.GetVersion();
166 EXPECT_EQ(false, signals
.GetShouldSuppress(signo
));
167 EXPECT_EQ(true, signals
.GetShouldStop(signo
));
168 EXPECT_EQ(false, signals
.GetShouldNotify(signo
));
170 EXPECT_EQ(ver
, signals
.GetVersion());
173 TEST(UnixSignalsTest
, GetFilteredSignals
) {
177 signals
.GetFilteredSignals(std::nullopt
, std::nullopt
, std::nullopt
);
178 std::vector
<int32_t> expected
= {2, 4, 8, 16};
179 EXPECT_EQ_ARRAYS(expected
, all_signals
);
181 auto supressed
= signals
.GetFilteredSignals(true, std::nullopt
, std::nullopt
);
182 expected
= {4, 8, 16};
183 EXPECT_EQ_ARRAYS(expected
, supressed
);
186 signals
.GetFilteredSignals(false, std::nullopt
, std::nullopt
);
188 EXPECT_EQ_ARRAYS(expected
, not_supressed
);
190 auto stopped
= signals
.GetFilteredSignals(std::nullopt
, true, std::nullopt
);
192 EXPECT_EQ_ARRAYS(expected
, stopped
);
195 signals
.GetFilteredSignals(std::nullopt
, false, std::nullopt
);
197 EXPECT_EQ_ARRAYS(expected
, not_stopped
);
199 auto notified
= signals
.GetFilteredSignals(std::nullopt
, std::nullopt
, true);
200 expected
= {2, 4, 8};
201 EXPECT_EQ_ARRAYS(expected
, notified
);
204 signals
.GetFilteredSignals(std::nullopt
, std::nullopt
, false);
206 EXPECT_EQ_ARRAYS(expected
, not_notified
);
208 auto signal4
= signals
.GetFilteredSignals(true, false, true);
210 EXPECT_EQ_ARRAYS(expected
, signal4
);