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