xref: /llvm-project/lldb/unittests/Signals/UnixSignalsTest.cpp (revision 9ba308f71c92a228120f084ba0fa740b4c61247f)
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 
15 using namespace lldb;
16 using namespace lldb_private;
17 
18 class TestSignals : public UnixSignals {
19 public:
20   TestSignals() {
21     m_signals.clear();
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   }
27 };
28 
29 void ExpectEqArrays(llvm::ArrayRef<int32_t> expected,
30                     llvm::ArrayRef<int32_t> observed, const char *file,
31                     int line) {
32   std::string location = llvm::formatv("{0}:{1}", file, line);
33   ASSERT_EQ(expected.size(), observed.size()) << location;
34 
35   for (size_t i = 0; i < observed.size(); ++i) {
36     ASSERT_EQ(expected[i], observed[i])
37         << "array index: " << i << "location:" << location;
38   }
39 }
40 
41 #define EXPECT_EQ_ARRAYS(expected, observed)                                   \
42   ExpectEqArrays((expected), (observed), __FILE__, __LINE__);
43 
44 TEST(UnixSignalsTest, Iteration) {
45   TestSignals signals;
46 
47   EXPECT_EQ(4, signals.GetNumSignals());
48   EXPECT_EQ(2, signals.GetFirstSignalNumber());
49   EXPECT_EQ(4, signals.GetNextSignalNumber(2));
50   EXPECT_EQ(8, signals.GetNextSignalNumber(4));
51   EXPECT_EQ(16, signals.GetNextSignalNumber(8));
52   EXPECT_EQ(LLDB_INVALID_SIGNAL_NUMBER, signals.GetNextSignalNumber(16));
53 }
54 
55 TEST(UnixSignalsTest, Reset) {
56   TestSignals signals;
57   bool stop_val     = signals.GetShouldStop(2);
58   bool notify_val   = signals.GetShouldNotify(2);
59   bool suppress_val = signals.GetShouldSuppress(2);
60 
61   // Change two, then reset one and make sure only that one was reset:
62   EXPECT_EQ(true, signals.SetShouldNotify(2, !notify_val));
63   EXPECT_EQ(true, signals.SetShouldSuppress(2, !suppress_val));
64   EXPECT_EQ(true, signals.ResetSignal(2, false, true, false));
65   EXPECT_EQ(stop_val, signals.GetShouldStop(2));
66   EXPECT_EQ(notify_val, signals.GetShouldStop(2));
67   EXPECT_EQ(!suppress_val, signals.GetShouldNotify(2));
68 
69   // Make sure reset with no arguments resets them all:
70   EXPECT_EQ(true, signals.SetShouldSuppress(2, !suppress_val));
71   EXPECT_EQ(true, signals.SetShouldNotify(2, !notify_val));
72   EXPECT_EQ(true, signals.ResetSignal(2));
73   EXPECT_EQ(stop_val, signals.GetShouldStop(2));
74   EXPECT_EQ(notify_val, signals.GetShouldNotify(2));
75   EXPECT_EQ(suppress_val, signals.GetShouldSuppress(2));
76 }
77 
78 TEST(UnixSignalsTest, GetInfo) {
79   TestSignals signals;
80 
81   bool should_suppress = false, should_stop = false, should_notify = false;
82   int32_t signo = 4;
83   std::string name =
84       signals.GetSignalInfo(signo, should_suppress, should_stop, should_notify);
85   EXPECT_EQ("SIG4", name);
86   EXPECT_EQ(true, should_suppress);
87   EXPECT_EQ(false, should_stop);
88   EXPECT_EQ(true, should_notify);
89 
90   EXPECT_EQ(true, signals.GetShouldSuppress(signo));
91   EXPECT_EQ(false, signals.GetShouldStop(signo));
92   EXPECT_EQ(true, signals.GetShouldNotify(signo));
93   EXPECT_EQ(name, signals.GetSignalAsCString(signo));
94 }
95 
96 TEST(UnixSignalsTest, VersionChange) {
97   TestSignals signals;
98 
99   int32_t signo = 8;
100   uint64_t ver = signals.GetVersion();
101   EXPECT_GT(ver, 0ull);
102   EXPECT_EQ(true, signals.GetShouldSuppress(signo));
103   EXPECT_EQ(true, signals.GetShouldStop(signo));
104   EXPECT_EQ(true, signals.GetShouldNotify(signo));
105 
106   EXPECT_EQ(signals.GetVersion(), ver);
107 
108   signals.SetShouldSuppress(signo, false);
109   EXPECT_LT(ver, signals.GetVersion());
110   ver = signals.GetVersion();
111 
112   signals.SetShouldStop(signo, true);
113   EXPECT_LT(ver, signals.GetVersion());
114   ver = signals.GetVersion();
115 
116   signals.SetShouldNotify(signo, false);
117   EXPECT_LT(ver, signals.GetVersion());
118   ver = signals.GetVersion();
119 
120   EXPECT_EQ(false, signals.GetShouldSuppress(signo));
121   EXPECT_EQ(true, signals.GetShouldStop(signo));
122   EXPECT_EQ(false, signals.GetShouldNotify(signo));
123 
124   EXPECT_EQ(ver, signals.GetVersion());
125 }
126 
127 TEST(UnixSignalsTest, GetFilteredSignals) {
128   TestSignals signals;
129 
130   auto all_signals =
131       signals.GetFilteredSignals(std::nullopt, std::nullopt, std::nullopt);
132   std::vector<int32_t> expected = {2, 4, 8, 16};
133   EXPECT_EQ_ARRAYS(expected, all_signals);
134 
135   auto supressed = signals.GetFilteredSignals(true, std::nullopt, std::nullopt);
136   expected = {4, 8, 16};
137   EXPECT_EQ_ARRAYS(expected, supressed);
138 
139   auto not_supressed =
140       signals.GetFilteredSignals(false, std::nullopt, std::nullopt);
141   expected = {2};
142   EXPECT_EQ_ARRAYS(expected, not_supressed);
143 
144   auto stopped = signals.GetFilteredSignals(std::nullopt, true, std::nullopt);
145   expected = {2, 8};
146   EXPECT_EQ_ARRAYS(expected, stopped);
147 
148   auto not_stopped =
149       signals.GetFilteredSignals(std::nullopt, false, std::nullopt);
150   expected = {4, 16};
151   EXPECT_EQ_ARRAYS(expected, not_stopped);
152 
153   auto notified = signals.GetFilteredSignals(std::nullopt, std::nullopt, true);
154   expected = {2, 4, 8};
155   EXPECT_EQ_ARRAYS(expected, notified);
156 
157   auto not_notified =
158       signals.GetFilteredSignals(std::nullopt, std::nullopt, false);
159   expected = {16};
160   EXPECT_EQ_ARRAYS(expected, not_notified);
161 
162   auto signal4 = signals.GetFilteredSignals(true, false, true);
163   expected = {4};
164   EXPECT_EQ_ARRAYS(expected, signal4);
165 }
166