/Users/buildslave/jenkins/workspace/coverage/llvm-project/lldb/include/lldb/Target/UnixSignals.h
Line | Count | Source |
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 <optional> |
14 | | #include <string> |
15 | | #include <vector> |
16 | | |
17 | | #include "lldb/Utility/ConstString.h" |
18 | | #include "lldb/lldb-private.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 | | llvm::StringRef GetSignalAsStringRef(int32_t signo) const; |
34 | | |
35 | | std::string |
36 | | GetSignalDescription(int32_t signo, |
37 | | std::optional<int32_t> code = std::nullopt, |
38 | | std::optional<lldb::addr_t> addr = std::nullopt, |
39 | | std::optional<lldb::addr_t> lower = std::nullopt, |
40 | | std::optional<lldb::addr_t> upper = std::nullopt) const; |
41 | | |
42 | | bool SignalIsValid(int32_t signo) const; |
43 | | |
44 | | int32_t GetSignalNumberFromName(const char *name) const; |
45 | | |
46 | | /// Gets the information for a particular signal |
47 | | /// |
48 | | /// GetSignalInfo takes a signal number and populates 3 out parameters |
49 | | /// describing how lldb should react when a particular signal is received in |
50 | | /// the inferior. |
51 | | /// |
52 | | /// \param[in] signo |
53 | | /// The signal number to get information about. |
54 | | /// \param[out] should_suppress |
55 | | /// Should we suppress this signal? |
56 | | /// \param[out] should_stop |
57 | | /// Should we stop if this signal is received? |
58 | | /// \param[out] should_notify |
59 | | /// Should we notify the user if this signal is received? |
60 | | /// |
61 | | /// \return |
62 | | /// Returns a boolean value. Returns true if the out parameters were |
63 | | /// successfully populated, false otherwise. |
64 | | bool GetSignalInfo(int32_t signo, bool &should_suppress, bool &should_stop, |
65 | | bool &should_notify) const; |
66 | | |
67 | | bool GetShouldSuppress(int32_t signo) const; |
68 | | |
69 | | bool SetShouldSuppress(int32_t signo, bool value); |
70 | | |
71 | | bool SetShouldSuppress(const char *signal_name, bool value); |
72 | | |
73 | | bool GetShouldStop(int32_t signo) const; |
74 | | |
75 | | bool SetShouldStop(int32_t signo, bool value); |
76 | | bool SetShouldStop(const char *signal_name, bool value); |
77 | | |
78 | | bool GetShouldNotify(int32_t signo) const; |
79 | | |
80 | | bool SetShouldNotify(int32_t signo, bool value); |
81 | | |
82 | | bool SetShouldNotify(const char *signal_name, bool value); |
83 | | |
84 | | bool ResetSignal(int32_t signo, bool reset_stop = true, |
85 | | bool reset_notify = true, bool reset_suppress = true); |
86 | | |
87 | | // These provide an iterator through the signals available on this system. |
88 | | // Call GetFirstSignalNumber to get the first entry, then iterate on |
89 | | // GetNextSignalNumber till you get back LLDB_INVALID_SIGNAL_NUMBER. |
90 | | int32_t GetFirstSignalNumber() const; |
91 | | |
92 | | int32_t GetNextSignalNumber(int32_t current_signal) const; |
93 | | |
94 | | int32_t GetNumSignals() const; |
95 | | |
96 | | int32_t GetSignalAtIndex(int32_t index) const; |
97 | | |
98 | | // We assume that the elements of this object are constant once it is |
99 | | // constructed, since a process should never need to add or remove symbols as |
100 | | // it runs. So don't call these functions anywhere but the constructor of |
101 | | // your subclass of UnixSignals or in your Process Plugin's GetUnixSignals |
102 | | // method before you return the UnixSignal object. |
103 | | |
104 | | void AddSignal(int signo, const char *name, bool default_suppress, |
105 | | bool default_stop, bool default_notify, |
106 | | const char *description, const char *alias = nullptr); |
107 | | |
108 | | enum SignalCodePrintOption { None, Address, Bounds }; |
109 | | |
110 | | // Instead of calling this directly, use a ADD_SIGCODE macro to get compile |
111 | | // time checks when on the native platform. |
112 | | void AddSignalCode( |
113 | | int signo, int code, const llvm::StringLiteral description, |
114 | | SignalCodePrintOption print_option = SignalCodePrintOption::None); |
115 | | |
116 | | void RemoveSignal(int signo); |
117 | | |
118 | | /// Track how many times signals are hit as stop reasons. |
119 | | void IncrementSignalHitCount(int signo); |
120 | | |
121 | | /// Get the hit count statistics for signals. |
122 | | /// |
123 | | /// Gettings statistics on the hit counts of signals can help explain why some |
124 | | /// debug sessions are slow since each stop takes a few hundred ms and some |
125 | | /// software use signals a lot and can cause slow debugging performance if |
126 | | /// they are used too often. Even if a signal is not stopped at, it will auto |
127 | | /// continue the process and a delay will happen. |
128 | | llvm::json::Value GetHitCountStatistics() const; |
129 | | |
130 | | // Returns a current version of the data stored in this class. Version gets |
131 | | // incremented each time Set... method is called. |
132 | | uint64_t GetVersion() const; |
133 | | |
134 | | // Returns a vector of signals that meet criteria provided in arguments. Each |
135 | | // should_[suppress|stop|notify] flag can be std::nullopt - no filtering by |
136 | | // this flag true - only signals that have it set to true are returned false - |
137 | | // only signals that have it set to true are returned |
138 | | std::vector<int32_t> GetFilteredSignals(std::optional<bool> should_suppress, |
139 | | std::optional<bool> should_stop, |
140 | | std::optional<bool> should_notify); |
141 | | |
142 | | protected: |
143 | | // Classes that inherit from UnixSignals can see and modify these |
144 | | |
145 | | struct SignalCode { |
146 | | const llvm::StringLiteral m_description; |
147 | | const SignalCodePrintOption m_print_option; |
148 | | }; |
149 | | |
150 | | struct Signal { |
151 | | ConstString m_name; |
152 | | ConstString m_alias; |
153 | | std::string m_description; |
154 | | std::map<int32_t, SignalCode> m_codes; |
155 | | uint32_t m_hit_count = 0; |
156 | | bool m_suppress : 1, m_stop : 1, m_notify : 1; |
157 | | bool m_default_suppress : 1, m_default_stop : 1, m_default_notify : 1; |
158 | | |
159 | | Signal(const char *name, bool default_suppress, bool default_stop, |
160 | | bool default_notify, const char *description, const char *alias); |
161 | | |
162 | 276k | ~Signal() = default; |
163 | | void Reset(bool reset_stop, bool reset_notify, bool reset_suppress); |
164 | | }; |
165 | | |
166 | | llvm::StringRef GetShortName(llvm::StringRef name) const; |
167 | | |
168 | | virtual void Reset(); |
169 | | |
170 | | typedef std::map<int32_t, Signal> collection; |
171 | | |
172 | | collection m_signals; |
173 | | |
174 | | // This version gets incremented every time something is changing in this |
175 | | // class, including when we call AddSignal from the constructor. So after the |
176 | | // object is constructed m_version is going to be > 0 if it has at least one |
177 | | // signal registered in it. |
178 | | uint64_t m_version = 0; |
179 | | |
180 | | // GDBRemote signals need to be copyable. |
181 | | UnixSignals(const UnixSignals &rhs); |
182 | | |
183 | | const UnixSignals &operator=(const UnixSignals &rhs) = delete; |
184 | | }; |
185 | | |
186 | | } // Namespace lldb |
187 | | #endif // LLDB_TARGET_UNIXSIGNALS_H |