1//===-- UnixSignalsTest.cpp -----------------------------------------------===//
2//
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
6//
7//===----------------------------------------------------------------------===//
8#include <string>
9
10#include "gtest/gtest.h"
11
12#include "lldb/Target/UnixSignals.h"
13#include "llvm/Support/FormatVariadic.h"
14
15using namespace lldb;
16using namespace lldb_private;
17
18class TestSignals : public UnixSignals {
19public:
20 TestSignals() {
21 m_signals.clear();
22 AddSignal(signo: 2, name: "SIG2", default_suppress: false, default_stop: true, default_notify: true, description: "DESC2");
23 AddSignal(signo: 4, name: "SIG4", default_suppress: true, default_stop: false, default_notify: true, description: "DESC4");
24 AddSignal(signo: 8, name: "SIG8", default_suppress: true, default_stop: true, default_notify: true, description: "DESC8");
25 AddSignal(signo: 16, name: "SIG16", default_suppress: true, default_stop: false, default_notify: false, description: "DESC16");
26 AddSignalCode(signo: 16, code: 1, description: "a specific type of SIG16");
27 AddSignalCode(signo: 16, code: 2, description: "SIG16 with a fault address",
28 print_option: SignalCodePrintOption::Address);
29 AddSignalCode(signo: 16, code: 3, description: "bounds violation", print_option: SignalCodePrintOption::Bounds);
30 AddSignalCode(signo: 16, code: -6, description: "sent by tkill system call",
31 print_option: SignalCodePrintOption::Sender);
32 }
33};
34
35void ExpectEqArrays(llvm::ArrayRef<int32_t> expected,
36 llvm::ArrayRef<int32_t> observed, const char *file,
37 int line) {
38 std::string location = llvm::formatv(Fmt: "{0}:{1}", Vals&: file, Vals&: line);
39 ASSERT_EQ(expected.size(), observed.size()) << location;
40
41 for (size_t i = 0; i < observed.size(); ++i) {
42 ASSERT_EQ(expected[i], observed[i])
43 << "array index: " << i << "location:" << location;
44 }
45}
46
47#define EXPECT_EQ_ARRAYS(expected, observed) \
48 ExpectEqArrays((expected), (observed), __FILE__, __LINE__);
49
50TEST(UnixSignalsTest, Iteration) {
51 TestSignals signals;
52
53 EXPECT_EQ(4, signals.GetNumSignals());
54 EXPECT_EQ(2, signals.GetFirstSignalNumber());
55 EXPECT_EQ(4, signals.GetNextSignalNumber(2));
56 EXPECT_EQ(8, signals.GetNextSignalNumber(4));
57 EXPECT_EQ(16, signals.GetNextSignalNumber(8));
58 EXPECT_EQ(LLDB_INVALID_SIGNAL_NUMBER, signals.GetNextSignalNumber(16));
59}
60
61TEST(UnixSignalsTest, Reset) {
62 TestSignals signals;
63 bool stop_val = signals.GetShouldStop(signo: 2);
64 bool notify_val = signals.GetShouldNotify(signo: 2);
65 bool suppress_val = signals.GetShouldSuppress(signo: 2);
66
67 // Change two, then reset one and make sure only that one was reset:
68 EXPECT_EQ(true, signals.SetShouldNotify(2, !notify_val));
69 EXPECT_EQ(true, signals.SetShouldSuppress(2, !suppress_val));
70 EXPECT_EQ(true, signals.ResetSignal(2, false, true, false));
71 EXPECT_EQ(stop_val, signals.GetShouldStop(2));
72 EXPECT_EQ(notify_val, signals.GetShouldStop(2));
73 EXPECT_EQ(!suppress_val, signals.GetShouldNotify(2));
74
75 // Make sure reset with no arguments resets them all:
76 EXPECT_EQ(true, signals.SetShouldSuppress(2, !suppress_val));
77 EXPECT_EQ(true, signals.SetShouldNotify(2, !notify_val));
78 EXPECT_EQ(true, signals.ResetSignal(2));
79 EXPECT_EQ(stop_val, signals.GetShouldStop(2));
80 EXPECT_EQ(notify_val, signals.GetShouldNotify(2));
81 EXPECT_EQ(suppress_val, signals.GetShouldSuppress(2));
82}
83
84TEST(UnixSignalsTest, GetInfo) {
85 TestSignals signals;
86
87 bool should_suppress = false, should_stop = false, should_notify = false;
88 int32_t signo = 4;
89 bool success =
90 signals.GetSignalInfo(signo, should_suppress, should_stop, should_notify);
91 ASSERT_TRUE(success);
92 EXPECT_EQ(true, should_suppress);
93 EXPECT_EQ(false, should_stop);
94 EXPECT_EQ(true, should_notify);
95
96 EXPECT_EQ(true, signals.GetShouldSuppress(signo));
97 EXPECT_EQ(false, signals.GetShouldStop(signo));
98 EXPECT_EQ(true, signals.GetShouldNotify(signo));
99}
100
101TEST(UnixSignalsTest, GetAsStringRef) {
102 TestSignals signals;
103
104 ASSERT_EQ(llvm::StringRef(), signals.GetSignalAsStringRef(100));
105 ASSERT_EQ("SIG16", signals.GetSignalAsStringRef(16));
106}
107
108TEST(UnixSignalsTest, GetAsString) {
109 TestSignals signals;
110
111 ASSERT_EQ("", signals.GetSignalDescription(100, std::nullopt));
112 ASSERT_EQ("SIG16", signals.GetSignalDescription(16, std::nullopt));
113 ASSERT_EQ("", signals.GetSignalDescription(100, 100));
114 ASSERT_EQ("SIG16", signals.GetSignalDescription(16, 100));
115 ASSERT_EQ("SIG16: a specific type of SIG16",
116 signals.GetSignalDescription(16, 1));
117
118 // Unknown code, won't use the address.
119 ASSERT_EQ("SIG16", signals.GetSignalDescription(16, 100, 0xCAFEF00D));
120 // Known code, that shouldn't print fault address.
121 ASSERT_EQ("SIG16: a specific type of SIG16",
122 signals.GetSignalDescription(16, 1, 0xCAFEF00D));
123 // Known code that should.
124 ASSERT_EQ("SIG16: SIG16 with a fault address (fault address=0xcafef00d)",
125 signals.GetSignalDescription(16, 2, 0xCAFEF00D));
126 // No address given just print the code description.
127 ASSERT_EQ("SIG16: SIG16 with a fault address",
128 signals.GetSignalDescription(16, 2));
129 // TKill, but with no sender
130 ASSERT_EQ("SIG16: sent by tkill system call",
131 signals.GetSignalDescription(16, -6, 0xCAFEF00D));
132 // TKill, but with no sender
133 ASSERT_EQ("SIG16: sent by tkill system call (sender pid=912, uid=99)",
134 signals.GetSignalDescription(16, -6, 0xCAFEF00D, std::nullopt,
135 std::nullopt, 912, 99));
136
137 const char *expected = "SIG16: bounds violation";
138 // Must pass all needed info to get full output.
139 ASSERT_EQ(expected, signals.GetSignalDescription(16, 3));
140 ASSERT_EQ(expected, signals.GetSignalDescription(16, 3, 0xcafef00d));
141 ASSERT_EQ(expected, signals.GetSignalDescription(16, 3, 0xcafef00d, 0x1234));
142
143 ASSERT_EQ("SIG16: upper bound violation (fault address=0x5679, lower bound="
144 "0x1234, upper bound=0x5678)",
145 signals.GetSignalDescription(16, 3, 0x5679, 0x1234, 0x5678));
146 ASSERT_EQ("SIG16: lower bound violation (fault address=0x1233, lower bound="
147 "0x1234, upper bound=0x5678)",
148 signals.GetSignalDescription(16, 3, 0x1233, 0x1234, 0x5678));
149}
150
151TEST(UnixSignalsTest, VersionChange) {
152 TestSignals signals;
153
154 int32_t signo = 8;
155 uint64_t ver = signals.GetVersion();
156 EXPECT_GT(ver, 0ull);
157 EXPECT_EQ(true, signals.GetShouldSuppress(signo));
158 EXPECT_EQ(true, signals.GetShouldStop(signo));
159 EXPECT_EQ(true, signals.GetShouldNotify(signo));
160
161 EXPECT_EQ(signals.GetVersion(), ver);
162
163 signals.SetShouldSuppress(signo, value: false);
164 EXPECT_LT(ver, signals.GetVersion());
165 ver = signals.GetVersion();
166
167 signals.SetShouldStop(signo, value: true);
168 EXPECT_LT(ver, signals.GetVersion());
169 ver = signals.GetVersion();
170
171 signals.SetShouldNotify(signo, value: false);
172 EXPECT_LT(ver, signals.GetVersion());
173 ver = signals.GetVersion();
174
175 EXPECT_EQ(false, signals.GetShouldSuppress(signo));
176 EXPECT_EQ(true, signals.GetShouldStop(signo));
177 EXPECT_EQ(false, signals.GetShouldNotify(signo));
178
179 EXPECT_EQ(ver, signals.GetVersion());
180}
181
182TEST(UnixSignalsTest, GetFilteredSignals) {
183 TestSignals signals;
184
185 auto all_signals =
186 signals.GetFilteredSignals(should_suppress: std::nullopt, should_stop: std::nullopt, should_notify: std::nullopt);
187 std::vector<int32_t> expected = {2, 4, 8, 16};
188 EXPECT_EQ_ARRAYS(expected, all_signals);
189
190 auto supressed = signals.GetFilteredSignals(should_suppress: true, should_stop: std::nullopt, should_notify: std::nullopt);
191 expected = {4, 8, 16};
192 EXPECT_EQ_ARRAYS(expected, supressed);
193
194 auto not_supressed =
195 signals.GetFilteredSignals(should_suppress: false, should_stop: std::nullopt, should_notify: std::nullopt);
196 expected = {2};
197 EXPECT_EQ_ARRAYS(expected, not_supressed);
198
199 auto stopped = signals.GetFilteredSignals(should_suppress: std::nullopt, should_stop: true, should_notify: std::nullopt);
200 expected = {2, 8};
201 EXPECT_EQ_ARRAYS(expected, stopped);
202
203 auto not_stopped =
204 signals.GetFilteredSignals(should_suppress: std::nullopt, should_stop: false, should_notify: std::nullopt);
205 expected = {4, 16};
206 EXPECT_EQ_ARRAYS(expected, not_stopped);
207
208 auto notified = signals.GetFilteredSignals(should_suppress: std::nullopt, should_stop: std::nullopt, should_notify: true);
209 expected = {2, 4, 8};
210 EXPECT_EQ_ARRAYS(expected, notified);
211
212 auto not_notified =
213 signals.GetFilteredSignals(should_suppress: std::nullopt, should_stop: std::nullopt, should_notify: false);
214 expected = {16};
215 EXPECT_EQ_ARRAYS(expected, not_notified);
216
217 auto signal4 = signals.GetFilteredSignals(should_suppress: true, should_stop: false, should_notify: true);
218 expected = {4};
219 EXPECT_EQ_ARRAYS(expected, signal4);
220}
221

Provided by KDAB

Privacy Policy
Learn to use CMake with our Intro Training
Find out more

source code of lldb/unittests/Signals/UnixSignalsTest.cpp