1 //===-- UnixSignals.h -------------------------------------------*- C++ -*-===//
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 
9 #ifndef LLDB_TARGET_UNIXSIGNALS_H
10 #define LLDB_TARGET_UNIXSIGNALS_H
11 
12 #include <map>
13 #include <string>
14 #include <vector>
15 
16 #include "lldb/Utility/ConstString.h"
17 #include "lldb/lldb-private.h"
18 #include "llvm/ADT/Optional.h"
19 #include "llvm/Support/JSON.h"
20 
21 namespace lldb_private {
22 
23 class UnixSignals {
24 public:
25   static lldb::UnixSignalsSP Create(const ArchSpec &arch);
26   static lldb::UnixSignalsSP CreateForHost();
27 
28   // Constructors and Destructors
29   UnixSignals();
30 
31   virtual ~UnixSignals();
32 
33   const char *GetSignalAsCString(int32_t signo) const;
34 
35   bool SignalIsValid(int32_t signo) const;
36 
37   int32_t GetSignalNumberFromName(const char *name) const;
38 
39   const char *GetSignalInfo(int32_t signo, bool &should_suppress,
40                             bool &should_stop, bool &should_notify) const;
41 
42   bool GetShouldSuppress(int32_t signo) const;
43 
44   bool SetShouldSuppress(int32_t signo, bool value);
45 
46   bool SetShouldSuppress(const char *signal_name, bool value);
47 
48   bool GetShouldStop(int32_t signo) const;
49 
50   bool SetShouldStop(int32_t signo, bool value);
51   bool SetShouldStop(const char *signal_name, bool value);
52 
53   bool GetShouldNotify(int32_t signo) const;
54 
55   bool SetShouldNotify(int32_t signo, bool value);
56 
57   bool SetShouldNotify(const char *signal_name, bool value);
58 
59   // These provide an iterator through the signals available on this system.
60   // Call GetFirstSignalNumber to get the first entry, then iterate on
61   // GetNextSignalNumber till you get back LLDB_INVALID_SIGNAL_NUMBER.
62   int32_t GetFirstSignalNumber() const;
63 
64   int32_t GetNextSignalNumber(int32_t current_signal) const;
65 
66   int32_t GetNumSignals() const;
67 
68   int32_t GetSignalAtIndex(int32_t index) const;
69 
70   ConstString GetShortName(ConstString name) const;
71 
72   // We assume that the elements of this object are constant once it is
73   // constructed, since a process should never need to add or remove symbols as
74   // it runs.  So don't call these functions anywhere but the constructor of
75   // your subclass of UnixSignals or in your Process Plugin's GetUnixSignals
76   // method before you return the UnixSignal object.
77 
78   void AddSignal(int signo, const char *name, bool default_suppress,
79                  bool default_stop, bool default_notify,
80                  const char *description, const char *alias = nullptr);
81 
82   void RemoveSignal(int signo);
83 
84   /// Track how many times signals are hit as stop reasons.
85   void IncrementSignalHitCount(int signo);
86 
87   /// Get the hit count statistics for signals.
88   ///
89   /// Gettings statistics on the hit counts of signals can help explain why some
90   /// debug sessions are slow since each stop takes a few hundred ms and some
91   /// software use signals a lot and can cause slow debugging performance if
92   /// they are used too often. Even if a signal is not stopped at, it will auto
93   /// continue the process and a delay will happen.
94   llvm::json::Value GetHitCountStatistics() const;
95 
96   // Returns a current version of the data stored in this class. Version gets
97   // incremented each time Set... method is called.
98   uint64_t GetVersion() const;
99 
100   // Returns a vector of signals that meet criteria provided in arguments. Each
101   // should_[suppress|stop|notify] flag can be None  - no filtering by this
102   // flag true  - only signals that have it set to true are returned false -
103   // only signals that have it set to true are returned
104   std::vector<int32_t> GetFilteredSignals(llvm::Optional<bool> should_suppress,
105                                           llvm::Optional<bool> should_stop,
106                                           llvm::Optional<bool> should_notify);
107 
108 protected:
109   // Classes that inherit from UnixSignals can see and modify these
110 
111   struct Signal {
112     ConstString m_name;
113     ConstString m_alias;
114     std::string m_description;
115     uint32_t m_hit_count = 0;
116     bool m_suppress : 1, m_stop : 1, m_notify : 1;
117 
118     Signal(const char *name, bool default_suppress, bool default_stop,
119            bool default_notify, const char *description, const char *alias);
120 
121     ~Signal() = default;
122   };
123 
124   virtual void Reset();
125 
126   typedef std::map<int32_t, Signal> collection;
127 
128   collection m_signals;
129 
130   // This version gets incremented every time something is changing in this
131   // class, including when we call AddSignal from the constructor. So after the
132   // object is constructed m_version is going to be > 0 if it has at least one
133   // signal registered in it.
134   uint64_t m_version = 0;
135 
136   // GDBRemote signals need to be copyable.
137   UnixSignals(const UnixSignals &rhs);
138 
139   const UnixSignals &operator=(const UnixSignals &rhs) = delete;
140 };
141 
142 } // Namespace lldb
143 #endif // LLDB_TARGET_UNIXSIGNALS_H
144