[Lldb-commits] [lldb] r297231 - Make LLDB skip server-client roundtrip for signals that don't require any actions

Eugene Zemtsov via lldb-commits lldb-commits at lists.llvm.org
Tue Mar 7 13:34:40 PST 2017


Author: eugene
Date: Tue Mar  7 15:34:40 2017
New Revision: 297231

URL: http://llvm.org/viewvc/llvm-project?rev=297231&view=rev
Log:
Make LLDB skip server-client roundtrip for signals that don't require any actions

If QPassSignals packaet is supported by lldb-server, lldb-client will
utilize it and ask the server to ignore signals that don't require stops
or notifications.
Such signals will be immediately re-injected into inferior to continue
normal execution.

Differential Revision: https://reviews.llvm.org/D30520

Added:
    lldb/trunk/unittests/Signals/
    lldb/trunk/unittests/Signals/CMakeLists.txt
    lldb/trunk/unittests/Signals/UnixSignalsTest.cpp
Modified:
    lldb/trunk/include/lldb/Target/Process.h
    lldb/trunk/include/lldb/Target/UnixSignals.h
    lldb/trunk/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp
    lldb/trunk/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.h
    lldb/trunk/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp
    lldb/trunk/source/Plugins/Process/gdb-remote/ProcessGDBRemote.h
    lldb/trunk/source/Target/Process.cpp
    lldb/trunk/source/Target/UnixSignals.cpp
    lldb/trunk/unittests/CMakeLists.txt
    lldb/trunk/unittests/Process/gdb-remote/GDBRemoteCommunicationClientTest.cpp

Modified: lldb/trunk/include/lldb/Target/Process.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Target/Process.h?rev=297231&r1=297230&r2=297231&view=diff
==============================================================================
--- lldb/trunk/include/lldb/Target/Process.h (original)
+++ lldb/trunk/include/lldb/Target/Process.h Tue Mar  7 15:34:40 2017
@@ -2607,7 +2607,7 @@ public:
   bool RunPreResumeActions();
 
   void ClearPreResumeActions();
-  
+
   void ClearPreResumeAction(PreResumeActionCallback callback, void *baton);
 
   ProcessRunLock &GetRunLock();
@@ -3145,6 +3145,8 @@ protected:
 
   Error StopForDestroyOrDetach(lldb::EventSP &exit_event_sp);
 
+  virtual Error UpdateAutomaticSignalFiltering();
+
   bool StateChangedIsExternallyHijacked();
 
   void LoadOperatingSystemPlugin(bool flush);

Modified: lldb/trunk/include/lldb/Target/UnixSignals.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Target/UnixSignals.h?rev=297231&r1=297230&r2=297231&view=diff
==============================================================================
--- lldb/trunk/include/lldb/Target/UnixSignals.h (original)
+++ lldb/trunk/include/lldb/Target/UnixSignals.h Tue Mar  7 15:34:40 2017
@@ -14,11 +14,13 @@
 // C++ Includes
 #include <map>
 #include <string>
+#include <vector>
 
 // Other libraries and framework includes
 // Project includes
 #include "lldb/Utility/ConstString.h"
 #include "lldb/lldb-private.h"
+#include "llvm/ADT/Optional.h"
 
 namespace lldb_private {
 
@@ -88,6 +90,19 @@ public:
 
   void RemoveSignal(int signo);
 
+  // Returns a current version of the data stored in this class.
+  // Version gets incremented each time Set... method is called.
+  uint64_t GetVersion() const;
+
+  // Returns a vector of signals that meet criteria provided in arguments.
+  // Each should_[suppress|stop|notify] flag can be
+  // None  - no filtering by this flag
+  // true  - only signals that have it set to true are returned
+  // false - only signals that have it set to true are returned
+  std::vector<int32_t> GetFilteredSignals(llvm::Optional<bool> should_suppress,
+                                          llvm::Optional<bool> should_stop,
+                                          llvm::Optional<bool> should_notify);
+
 protected:
   //------------------------------------------------------------------
   // Classes that inherit from UnixSignals can see and modify these
@@ -111,6 +126,12 @@ protected:
 
   collection m_signals;
 
+  // This version gets incremented every time something is changing in
+  // this class, including when we call AddSignal from the constructor.
+  // So after the object is constructed m_version is going to be > 0
+  // if it has at least one signal registered in it.
+  uint64_t m_version = 0;
+
   // GDBRemote signals need to be copyable.
   UnixSignals(const UnixSignals &rhs);
 

Modified: lldb/trunk/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp?rev=297231&r1=297230&r2=297231&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp (original)
+++ lldb/trunk/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp Tue Mar  7 15:34:40 2017
@@ -87,6 +87,7 @@ GDBRemoteCommunicationClient::GDBRemoteC
       m_supports_jThreadExtendedInfo(eLazyBoolCalculate),
       m_supports_jLoadedDynamicLibrariesInfos(eLazyBoolCalculate),
       m_supports_jGetSharedCacheInfo(eLazyBoolCalculate),
+      m_supports_QPassSignals(eLazyBoolCalculate),
       m_supports_qProcessInfoPID(true), m_supports_qfProcessInfo(true),
       m_supports_qUserName(true), m_supports_qGroupName(true),
       m_supports_qThreadStopInfo(true), m_supports_z0(true),
@@ -150,6 +151,13 @@ bool GDBRemoteCommunicationClient::GetEc
   return m_supports_qEcho == eLazyBoolYes;
 }
 
+bool GDBRemoteCommunicationClient::GetQPassSignalsSupported() {
+  if (m_supports_QPassSignals == eLazyBoolCalculate) {
+    GetRemoteQSupported();
+  }
+  return m_supports_QPassSignals == eLazyBoolYes;
+}
+
 bool GDBRemoteCommunicationClient::GetAugmentedLibrariesSVR4ReadSupported() {
   if (m_supports_augmented_libraries_svr4_read == eLazyBoolCalculate) {
     GetRemoteQSupported();
@@ -419,6 +427,11 @@ void GDBRemoteCommunicationClient::GetRe
     else
       m_supports_qEcho = eLazyBoolNo;
 
+    if (::strstr(response_cstr, "QPassSignals+"))
+      m_supports_QPassSignals = eLazyBoolYes;
+    else
+      m_supports_QPassSignals = eLazyBoolNo;
+
     const char *packet_size_str = ::strstr(response_cstr, "PacketSize=");
     if (packet_size_str) {
       StringExtractorGDBRemote packet_response(packet_size_str +
@@ -3570,6 +3583,26 @@ GDBRemoteCommunicationClient::GetSupport
              : nullptr;
 }
 
+Error GDBRemoteCommunicationClient::SendSignalsToIgnore(
+    llvm::ArrayRef<int32_t> signals) {
+  // Format packet:
+  // QPassSignals:<hex_sig1>;<hex_sig2>...;<hex_sigN>
+  auto range = llvm::make_range(signals.begin(), signals.end());
+  std::string packet = formatv("QPassSignals:{0:$[;]@(x-2)}", range).str();
+
+  StringExtractorGDBRemote response;
+  auto send_status = SendPacketAndWaitForResponse(packet, response, false);
+
+  if (send_status != GDBRemoteCommunication::PacketResult::Success)
+    return Error("Sending QPassSignals packet failed");
+
+  if (response.IsOKResponse()) {
+    return Error();
+  } else {
+    return Error("Unknown error happened during sending QPassSignals packet.");
+  }
+}
+
 Error GDBRemoteCommunicationClient::ConfigureRemoteStructuredData(
     const ConstString &type_name, const StructuredData::ObjectSP &config_sp) {
   Error error;

Modified: lldb/trunk/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.h?rev=297231&r1=297230&r2=297231&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.h (original)
+++ lldb/trunk/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.h Tue Mar  7 15:34:40 2017
@@ -347,6 +347,8 @@ public:
 
   bool GetEchoSupported();
 
+  bool GetQPassSignalsSupported();
+
   bool GetAugmentedLibrariesSVR4ReadSupported();
 
   bool GetQXferFeaturesReadSupported();
@@ -450,6 +452,9 @@ public:
 
   void ServeSymbolLookups(lldb_private::Process *process);
 
+  // Sends QPassSignals packet to the server with given signals to ignore.
+  Error SendSignalsToIgnore(llvm::ArrayRef<int32_t> signals);
+
   //------------------------------------------------------------------
   /// Return the feature set supported by the gdb-remote server.
   ///
@@ -527,6 +532,7 @@ protected:
   LazyBool m_supports_jThreadExtendedInfo;
   LazyBool m_supports_jLoadedDynamicLibrariesInfos;
   LazyBool m_supports_jGetSharedCacheInfo;
+  LazyBool m_supports_QPassSignals;
 
   bool m_supports_qProcessInfoPID : 1, m_supports_qfProcessInfo : 1,
       m_supports_qUserName : 1, m_supports_qGroupName : 1,

Modified: lldb/trunk/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp?rev=297231&r1=297230&r2=297231&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp (original)
+++ lldb/trunk/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp Tue Mar  7 15:34:40 2017
@@ -80,8 +80,8 @@
 #include "lldb/Host/Host.h"
 
 #include "llvm/ADT/StringSwitch.h"
-#include "llvm/Support/raw_ostream.h"
 #include "llvm/Support/Threading.h"
+#include "llvm/Support/raw_ostream.h"
 
 #define DEBUGSERVER_BASENAME "debugserver"
 using namespace lldb;
@@ -3739,6 +3739,43 @@ bool ProcessGDBRemote::NewThreadNotifyBr
   return false;
 }
 
+Error ProcessGDBRemote::UpdateAutomaticSignalFiltering() {
+  Log *log(ProcessGDBRemoteLog::GetLogIfAllCategoriesSet(GDBR_LOG_PROCESS));
+  LLDB_LOG(log, "Check if need to update ignored signals");
+
+  // QPassSignals package is not supported by the server,
+  // there is no way we can ignore any signals on server side.
+  if (!m_gdb_comm.GetQPassSignalsSupported())
+    return Error();
+
+  // No signals, nothing to send.
+  if (m_unix_signals_sp == nullptr)
+    return Error();
+
+  // Signals' version hasn't changed, no need to send anything.
+  uint64_t new_signals_version = m_unix_signals_sp->GetVersion();
+  if (new_signals_version == m_last_signals_version) {
+    LLDB_LOG(log, "Signals' version hasn't changed. version={0}",
+             m_last_signals_version);
+    return Error();
+  }
+
+  auto signals_to_ignore =
+      m_unix_signals_sp->GetFilteredSignals(false, false, false);
+  Error error = m_gdb_comm.SendSignalsToIgnore(signals_to_ignore);
+
+  LLDB_LOG(log,
+           "Signals' version changed. old version={0}, new version={1}, "
+           "signals ignored={2}, update result={3}",
+           m_last_signals_version, new_signals_version,
+           signals_to_ignore.size(), error);
+
+  if (error.Success())
+    m_last_signals_version = new_signals_version;
+
+  return error;
+}
+
 bool ProcessGDBRemote::StartNoticingNewThreads() {
   Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_STEP));
   if (m_thread_create_bp_sp) {

Modified: lldb/trunk/source/Plugins/Process/gdb-remote/ProcessGDBRemote.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Process/gdb-remote/ProcessGDBRemote.h?rev=297231&r1=297230&r2=297231&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/Process/gdb-remote/ProcessGDBRemote.h (original)
+++ lldb/trunk/source/Plugins/Process/gdb-remote/ProcessGDBRemote.h Tue Mar  7 15:34:40 2017
@@ -397,12 +397,15 @@ protected:
                                      lldb::addr_t base_addr,
                                      bool value_is_offset);
 
+  Error UpdateAutomaticSignalFiltering() override;
+
 private:
   //------------------------------------------------------------------
   // For ProcessGDBRemote only
   //------------------------------------------------------------------
   std::string m_partial_profile_data;
   std::map<uint64_t, uint32_t> m_thread_id_to_used_usec_map;
+  uint64_t m_last_signals_version = 0;
 
   static bool NewThreadNotifyBreakpointHit(void *baton,
                                            StoppointCallbackContext *context,

Modified: lldb/trunk/source/Target/Process.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Target/Process.cpp?rev=297231&r1=297230&r2=297231&view=diff
==============================================================================
--- lldb/trunk/source/Target/Process.cpp (original)
+++ lldb/trunk/source/Target/Process.cpp Tue Mar  7 15:34:40 2017
@@ -2778,6 +2778,10 @@ Error Process::Launch(ProcessLaunchInfo
             if (!m_os_ap)
                 LoadOperatingSystemPlugin(false);
 
+            // We successfully launched the process and stopped,
+            // now it the right time to set up signal filters before resuming.
+            UpdateAutomaticSignalFiltering();
+
             // Note, the stop event was consumed above, but not handled. This
             // was done
             // to give DidLaunch a chance to run. The target is either stopped
@@ -3257,6 +3261,10 @@ Error Process::PrivateResume() {
                 m_mod_id.GetStopID(), StateAsCString(m_public_state.GetValue()),
                 StateAsCString(m_private_state.GetValue()));
 
+  // If signals handing status changed we might want to update
+  // our signal filters before resuming.
+  UpdateAutomaticSignalFiltering();
+
   Error error(WillResume());
   // Tell the process it is about to resume before the thread list
   if (error.Success()) {
@@ -6219,3 +6227,9 @@ bool Process::RouteAsyncStructuredData(
   find_it->second->HandleArrivalOfStructuredData(*this, type_name, object_sp);
   return true;
 }
+
+Error Process::UpdateAutomaticSignalFiltering() {
+  // Default implementation does nothign.
+  // No automatic signal filtering to speak of.
+  return Error();
+}

Modified: lldb/trunk/source/Target/UnixSignals.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Target/UnixSignals.cpp?rev=297231&r1=297230&r2=297231&view=diff
==============================================================================
--- lldb/trunk/source/Target/UnixSignals.cpp (original)
+++ lldb/trunk/source/Target/UnixSignals.cpp Tue Mar  7 15:34:40 2017
@@ -123,12 +123,14 @@ void UnixSignals::AddSignal(int signo, c
   Signal new_signal(name, default_suppress, default_stop, default_notify,
                     description, alias);
   m_signals.insert(std::make_pair(signo, new_signal));
+  ++m_version;
 }
 
 void UnixSignals::RemoveSignal(int signo) {
   collection::iterator pos = m_signals.find(signo);
   if (pos != m_signals.end())
     m_signals.erase(pos);
+  ++m_version;
 }
 
 const char *UnixSignals::GetSignalAsCString(int signo) const {
@@ -217,6 +219,7 @@ bool UnixSignals::SetShouldSuppress(int
   collection::iterator pos = m_signals.find(signo);
   if (pos != m_signals.end()) {
     pos->second.m_suppress = value;
+    ++m_version;
     return true;
   }
   return false;
@@ -240,6 +243,7 @@ bool UnixSignals::SetShouldStop(int sign
   collection::iterator pos = m_signals.find(signo);
   if (pos != m_signals.end()) {
     pos->second.m_stop = value;
+    ++m_version;
     return true;
   }
   return false;
@@ -263,6 +267,7 @@ bool UnixSignals::SetShouldNotify(int si
   collection::iterator pos = m_signals.find(signo);
   if (pos != m_signals.end()) {
     pos->second.m_notify = value;
+    ++m_version;
     return true;
   }
   return false;
@@ -284,3 +289,37 @@ int32_t UnixSignals::GetSignalAtIndex(in
   std::advance(it, index);
   return it->first;
 }
+
+uint64_t UnixSignals::GetVersion() const { return m_version; }
+
+std::vector<int32_t>
+UnixSignals::GetFilteredSignals(llvm::Optional<bool> should_suppress,
+                                llvm::Optional<bool> should_stop,
+                                llvm::Optional<bool> should_notify) {
+  std::vector<int32_t> result;
+  for (int32_t signo = GetFirstSignalNumber();
+       signo != LLDB_INVALID_SIGNAL_NUMBER;
+       signo = GetNextSignalNumber(signo)) {
+
+    bool signal_suppress = false;
+    bool signal_stop = false;
+    bool signal_notify = false;
+    GetSignalInfo(signo, signal_suppress, signal_stop, signal_notify);
+
+    // If any of filtering conditions are not met,
+    // we move on to the next signal.
+    if (should_suppress.hasValue() &&
+        signal_suppress != should_suppress.getValue())
+      continue;
+
+    if (should_stop.hasValue() && signal_stop != should_stop.getValue())
+      continue;
+
+    if (should_notify.hasValue() && signal_notify != should_notify.getValue())
+      continue;
+
+    result.push_back(signo);
+  }
+
+  return result;
+}

Modified: lldb/trunk/unittests/CMakeLists.txt
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/unittests/CMakeLists.txt?rev=297231&r1=297230&r2=297231&view=diff
==============================================================================
--- lldb/trunk/unittests/CMakeLists.txt (original)
+++ lldb/trunk/unittests/CMakeLists.txt Tue Mar  7 15:34:40 2017
@@ -63,6 +63,7 @@ add_subdirectory(ObjectFile)
 add_subdirectory(Platform)
 add_subdirectory(Process)
 add_subdirectory(ScriptInterpreter)
+add_subdirectory(Signals)
 add_subdirectory(Symbol)
 add_subdirectory(SymbolFile)
 add_subdirectory(Target)

Modified: lldb/trunk/unittests/Process/gdb-remote/GDBRemoteCommunicationClientTest.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/unittests/Process/gdb-remote/GDBRemoteCommunicationClientTest.cpp?rev=297231&r1=297230&r2=297231&view=diff
==============================================================================
--- lldb/trunk/unittests/Process/gdb-remote/GDBRemoteCommunicationClientTest.cpp (original)
+++ lldb/trunk/unittests/Process/gdb-remote/GDBRemoteCommunicationClientTest.cpp Tue Mar  7 15:34:40 2017
@@ -307,3 +307,27 @@ TEST_F(GDBRemoteCommunicationClientTest,
       << ss.GetString();
   ASSERT_EQ(10, num_packets);
 }
+
+TEST_F(GDBRemoteCommunicationClientTest, SendSignalsToIgnore) {
+  TestClient client;
+  MockServer server;
+  Connect(client, server);
+  if (HasFailure())
+    return;
+
+  const lldb::tid_t tid = 0x47;
+  const uint32_t reg_num = 4;
+  std::future<Error> result = std::async(std::launch::async, [&] {
+    return client.SendSignalsToIgnore({2, 3, 5, 7, 0xB, 0xD, 0x11});
+  });
+
+  HandlePacket(server, "QPassSignals:02;03;05;07;0b;0d;11", "OK");
+  EXPECT_TRUE(result.get().Success());
+
+  result = std::async(std::launch::async, [&] {
+    return client.SendSignalsToIgnore(std::vector<int32_t>());
+  });
+
+  HandlePacket(server, "QPassSignals:", "OK");
+  EXPECT_TRUE(result.get().Success());
+}

Added: lldb/trunk/unittests/Signals/CMakeLists.txt
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/unittests/Signals/CMakeLists.txt?rev=297231&view=auto
==============================================================================
--- lldb/trunk/unittests/Signals/CMakeLists.txt (added)
+++ lldb/trunk/unittests/Signals/CMakeLists.txt Tue Mar  7 15:34:40 2017
@@ -0,0 +1,6 @@
+add_lldb_unittest(SignalsTests
+  UnixSignalsTest.cpp
+
+  LINK_LIBS
+    lldbTarget
+  )

Added: lldb/trunk/unittests/Signals/UnixSignalsTest.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/unittests/Signals/UnixSignalsTest.cpp?rev=297231&view=auto
==============================================================================
--- lldb/trunk/unittests/Signals/UnixSignalsTest.cpp (added)
+++ lldb/trunk/unittests/Signals/UnixSignalsTest.cpp Tue Mar  7 15:34:40 2017
@@ -0,0 +1,140 @@
+//===-- UnixSignalsTest.cpp -------------------------------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+#include <string>
+
+#include "gtest/gtest.h"
+
+#include "lldb/Target/UnixSignals.h"
+#include "llvm/Support/FormatVariadic.h"
+
+using namespace lldb;
+using namespace lldb_private;
+using llvm::None;
+
+class TestSignals : public UnixSignals {
+public:
+  TestSignals() {
+    m_signals.clear();
+    AddSignal(2, "SIG2", false, true, true, "DESC2");
+    AddSignal(4, "SIG4", true, false, true, "DESC4");
+    AddSignal(8, "SIG8", true, true, true, "DESC8");
+    AddSignal(16, "SIG16", true, false, false, "DESC16");
+  }
+};
+
+void ExpectEqArrays(llvm::ArrayRef<int32_t> expected,
+                    llvm::ArrayRef<int32_t> observed, const char *file,
+                    int line) {
+  std::string location = llvm::formatv("{0}:{1}", file, line);
+  ASSERT_EQ(expected.size(), observed.size()) << location;
+
+  for (size_t i = 0; i < observed.size(); ++i) {
+    ASSERT_EQ(expected[i], observed[i])
+        << "array index: " << i << "location:" << location;
+  }
+}
+
+#define EXPECT_EQ_ARRAYS(expected, observed)                                   \
+  ExpectEqArrays((expected), (observed), __FILE__, __LINE__);
+
+TEST(UnixSignalsTest, Iteration) {
+  TestSignals signals;
+
+  EXPECT_EQ(4, signals.GetNumSignals());
+  EXPECT_EQ(2, signals.GetFirstSignalNumber());
+  EXPECT_EQ(4, signals.GetNextSignalNumber(2));
+  EXPECT_EQ(8, signals.GetNextSignalNumber(4));
+  EXPECT_EQ(16, signals.GetNextSignalNumber(8));
+  EXPECT_EQ(LLDB_INVALID_SIGNAL_NUMBER, signals.GetNextSignalNumber(16));
+}
+
+TEST(UnixSignalsTest, GetInfo) {
+  TestSignals signals;
+
+  bool should_suppress = false, should_stop = false, should_notify = false;
+  int32_t signo = 4;
+  std::string name =
+      signals.GetSignalInfo(signo, should_suppress, should_stop, should_notify);
+  EXPECT_EQ("SIG4", name);
+  EXPECT_EQ(true, should_suppress);
+  EXPECT_EQ(false, should_stop);
+  EXPECT_EQ(true, should_notify);
+
+  EXPECT_EQ(true, signals.GetShouldSuppress(signo));
+  EXPECT_EQ(false, signals.GetShouldStop(signo));
+  EXPECT_EQ(true, signals.GetShouldNotify(signo));
+  EXPECT_EQ(name, signals.GetSignalAsCString(signo));
+}
+
+TEST(UnixSignalsTest, VersionChange) {
+  TestSignals signals;
+
+  int32_t signo = 8;
+  uint64_t ver = signals.GetVersion();
+  EXPECT_GT(ver, 0ull);
+  EXPECT_EQ(true, signals.GetShouldSuppress(signo));
+  EXPECT_EQ(true, signals.GetShouldStop(signo));
+  EXPECT_EQ(true, signals.GetShouldNotify(signo));
+
+  EXPECT_EQ(signals.GetVersion(), ver);
+
+  signals.SetShouldSuppress(signo, false);
+  EXPECT_LT(ver, signals.GetVersion());
+  ver = signals.GetVersion();
+
+  signals.SetShouldStop(signo, true);
+  EXPECT_LT(ver, signals.GetVersion());
+  ver = signals.GetVersion();
+
+  signals.SetShouldNotify(signo, false);
+  EXPECT_LT(ver, signals.GetVersion());
+  ver = signals.GetVersion();
+
+  EXPECT_EQ(false, signals.GetShouldSuppress(signo));
+  EXPECT_EQ(true, signals.GetShouldStop(signo));
+  EXPECT_EQ(false, signals.GetShouldNotify(signo));
+
+  EXPECT_EQ(ver, signals.GetVersion());
+}
+
+TEST(UnixSignalsTest, GetFilteredSignals) {
+  TestSignals signals;
+
+  auto all_signals = signals.GetFilteredSignals(None, None, None);
+  std::vector<int32_t> expected = {2, 4, 8, 16};
+  EXPECT_EQ_ARRAYS(expected, all_signals);
+
+  auto supressed = signals.GetFilteredSignals(true, None, None);
+  expected = {4, 8, 16};
+  EXPECT_EQ_ARRAYS(expected, supressed);
+
+  auto not_supressed = signals.GetFilteredSignals(false, None, None);
+  expected = {2};
+  EXPECT_EQ_ARRAYS(expected, not_supressed);
+
+  auto stopped = signals.GetFilteredSignals(None, true, None);
+  expected = {2, 8};
+  EXPECT_EQ_ARRAYS(expected, stopped);
+
+  auto not_stopped = signals.GetFilteredSignals(None, false, None);
+  expected = {4, 16};
+  EXPECT_EQ_ARRAYS(expected, not_stopped);
+
+  auto notified = signals.GetFilteredSignals(None, None, true);
+  expected = {2, 4, 8};
+  EXPECT_EQ_ARRAYS(expected, notified);
+
+  auto not_notified = signals.GetFilteredSignals(None, None, false);
+  expected = {16};
+  EXPECT_EQ_ARRAYS(expected, not_notified);
+
+  auto signal4 = signals.GetFilteredSignals(true, false, true);
+  expected = {4};
+  EXPECT_EQ_ARRAYS(expected, signal4);
+}




More information about the lldb-commits mailing list