/Users/buildslave/jenkins/workspace/coverage/llvm-project/lldb/include/lldb/Breakpoint/BreakpointResolver.h
Line | Count | Source (jump to first uncovered line) |
1 | | //===-- BreakpointResolver.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_BREAKPOINT_BREAKPOINTRESOLVER_H |
10 | | #define LLDB_BREAKPOINT_BREAKPOINTRESOLVER_H |
11 | | |
12 | | #include "lldb/Breakpoint/Breakpoint.h" |
13 | | #include "lldb/Core/Address.h" |
14 | | #include "lldb/Core/SearchFilter.h" |
15 | | #include "lldb/Utility/ConstString.h" |
16 | | #include "lldb/Utility/FileSpec.h" |
17 | | #include "lldb/Utility/RegularExpression.h" |
18 | | #include "lldb/lldb-private.h" |
19 | | #include <optional> |
20 | | |
21 | | namespace lldb_private { |
22 | | |
23 | | /// \class BreakpointResolver BreakpointResolver.h |
24 | | /// "lldb/Breakpoint/BreakpointResolver.h" This class works with SearchFilter |
25 | | /// to resolve logical breakpoints to their of concrete breakpoint locations. |
26 | | |
27 | | /// General Outline: |
28 | | /// The BreakpointResolver is a Searcher. In that protocol, the SearchFilter |
29 | | /// asks the question "At what depth of the symbol context descent do you want |
30 | | /// your callback to get called?" of the filter. The resolver answers this |
31 | | /// question (in the GetDepth method) and provides the resolution callback. |
32 | | /// Each Breakpoint has a BreakpointResolver, and it calls either |
33 | | /// ResolveBreakpoint or ResolveBreakpointInModules to tell it to look for new |
34 | | /// breakpoint locations. |
35 | | |
36 | | class BreakpointResolver : public Searcher { |
37 | | friend class Breakpoint; |
38 | | |
39 | | public: |
40 | | /// The breakpoint resolver need to have a breakpoint for "ResolveBreakpoint |
41 | | /// to make sense. It can be constructed without a breakpoint, but you have |
42 | | /// to call SetBreakpoint before ResolveBreakpoint. |
43 | | /// |
44 | | /// \param[in] bkpt |
45 | | /// The breakpoint that owns this resolver. |
46 | | /// \param[in] resolverType |
47 | | /// The concrete breakpoint resolver type for this breakpoint. |
48 | | BreakpointResolver(const lldb::BreakpointSP &bkpt, |
49 | | unsigned char resolverType, |
50 | | lldb::addr_t offset = 0); |
51 | | |
52 | | /// The Destructor is virtual, all significant breakpoint resolvers derive |
53 | | /// from this class. |
54 | | ~BreakpointResolver() override; |
55 | | |
56 | | /// This sets the breakpoint for this resolver. |
57 | | /// |
58 | | /// \param[in] bkpt |
59 | | /// The breakpoint that owns this resolver. |
60 | | void SetBreakpoint(const lldb::BreakpointSP &bkpt); |
61 | | |
62 | | /// This gets the breakpoint for this resolver. |
63 | 180k | lldb::BreakpointSP GetBreakpoint() const { |
64 | 180k | auto breakpoint_sp = m_breakpoint.expired() ? lldb::BreakpointSP()0 : |
65 | 180k | m_breakpoint.lock(); |
66 | 180k | assert(breakpoint_sp); |
67 | 180k | return breakpoint_sp; |
68 | 180k | } |
69 | | |
70 | | /// This updates the offset for this breakpoint. All the locations |
71 | | /// currently set for this breakpoint will have their offset adjusted when |
72 | | /// this is called. |
73 | | /// |
74 | | /// \param[in] offset |
75 | | /// The offset to add to all locations. |
76 | | void SetOffset(lldb::addr_t offset); |
77 | | |
78 | 5 | lldb::addr_t GetOffset() const { return m_offset; } |
79 | | |
80 | | /// In response to this method the resolver scans all the modules in the |
81 | | /// breakpoint's target, and adds any new locations it finds. |
82 | | /// |
83 | | /// \param[in] filter |
84 | | /// The filter that will manage the search for this resolver. |
85 | | virtual void ResolveBreakpoint(SearchFilter &filter); |
86 | | |
87 | | /// In response to this method the resolver scans the modules in the module |
88 | | /// list \a modules, and adds any new locations it finds. |
89 | | /// |
90 | | /// \param[in] filter |
91 | | /// The filter that will manage the search for this resolver. |
92 | | virtual void ResolveBreakpointInModules(SearchFilter &filter, |
93 | | ModuleList &modules); |
94 | | |
95 | | /// Prints a canonical description for the breakpoint to the stream \a s. |
96 | | /// |
97 | | /// \param[in] s |
98 | | /// Stream to which the output is copied. |
99 | | void GetDescription(Stream *s) override = 0; |
100 | | |
101 | | /// Standard "Dump" method. At present it does nothing. |
102 | | virtual void Dump(Stream *s) const = 0; |
103 | | |
104 | | /// This section handles serializing and deserializing from StructuredData |
105 | | /// objects. |
106 | | |
107 | | static lldb::BreakpointResolverSP |
108 | | CreateFromStructuredData(const StructuredData::Dictionary &resolver_dict, |
109 | | Status &error); |
110 | | |
111 | 3 | virtual StructuredData::ObjectSP SerializeToStructuredData() { |
112 | 3 | return StructuredData::ObjectSP(); |
113 | 3 | } |
114 | | |
115 | 70 | static const char *GetSerializationKey() { return "BKPTResolver"; } |
116 | | |
117 | 70 | static const char *GetSerializationSubclassKey() { return "Type"; } |
118 | | |
119 | 70 | static const char *GetSerializationSubclassOptionsKey() { return "Options"; } |
120 | | |
121 | | StructuredData::DictionarySP |
122 | | WrapOptionsDict(StructuredData::DictionarySP options_dict_sp); |
123 | | |
124 | | /// An enumeration for keeping track of the concrete subclass that is |
125 | | /// actually instantiated. Values of this enumeration are kept in the |
126 | | /// BreakpointResolver's SubclassID field. They are used for concrete type |
127 | | /// identification. |
128 | | enum ResolverTy { |
129 | | FileLineResolver = 0, // This is an instance of BreakpointResolverFileLine |
130 | | AddressResolver, // This is an instance of BreakpointResolverAddress |
131 | | NameResolver, // This is an instance of BreakpointResolverName |
132 | | FileRegexResolver, |
133 | | PythonResolver, |
134 | | ExceptionResolver, |
135 | | LastKnownResolverType = ExceptionResolver, |
136 | | UnknownResolver |
137 | | }; |
138 | | |
139 | | // Translate the Ty to name for serialization, the "+2" is one for size vrs. |
140 | | // index, and one for UnknownResolver. |
141 | | static const char *g_ty_to_name[LastKnownResolverType + 2]; |
142 | | |
143 | | /// getResolverID - Return an ID for the concrete type of this object. This |
144 | | /// is used to implement the LLVM classof checks. This should not be used |
145 | | /// for any other purpose, as the values may change as LLDB evolves. |
146 | 22 | unsigned getResolverID() const { return SubclassID; } |
147 | | |
148 | 51 | enum ResolverTy GetResolverTy() { |
149 | 51 | if (SubclassID > ResolverTy::LastKnownResolverType) |
150 | 0 | return ResolverTy::UnknownResolver; |
151 | 51 | else |
152 | 51 | return (enum ResolverTy)SubclassID; |
153 | 51 | } |
154 | | |
155 | 51 | const char *GetResolverName() { return ResolverTyToName(GetResolverTy()); } |
156 | | |
157 | | static const char *ResolverTyToName(enum ResolverTy); |
158 | | |
159 | | static ResolverTy NameToResolverTy(llvm::StringRef name); |
160 | | |
161 | | virtual lldb::BreakpointResolverSP |
162 | | CopyForBreakpoint(lldb::BreakpointSP &breakpoint) = 0; |
163 | | |
164 | | protected: |
165 | | // Used for serializing resolver options: |
166 | | // The options in this enum and the strings in the g_option_names must be |
167 | | // kept in sync. |
168 | | enum class OptionNames : uint32_t { |
169 | | AddressOffset = 0, |
170 | | ExactMatch, |
171 | | FileName, |
172 | | Inlines, |
173 | | LanguageName, |
174 | | LineNumber, |
175 | | Column, |
176 | | ModuleName, |
177 | | NameMaskArray, |
178 | | Offset, |
179 | | PythonClassName, |
180 | | RegexString, |
181 | | ScriptArgs, |
182 | | SectionName, |
183 | | SearchDepth, |
184 | | SkipPrologue, |
185 | | SymbolNameArray, |
186 | | LastOptionName |
187 | | }; |
188 | | static const char |
189 | | *g_option_names[static_cast<uint32_t>(OptionNames::LastOptionName)]; |
190 | | |
191 | 14.5k | virtual void NotifyBreakpointSet() {}; |
192 | | |
193 | | public: |
194 | 349 | static const char *GetKey(OptionNames enum_value) { |
195 | 349 | return g_option_names[static_cast<uint32_t>(enum_value)]; |
196 | 349 | } |
197 | | |
198 | | protected: |
199 | | /// Takes a symbol context list of matches which supposedly represent the |
200 | | /// same file and line number in a CU, and find the nearest actual line |
201 | | /// number that matches, and then filter down the matching addresses to |
202 | | /// unique entries, and skip the prologue if asked to do so, and then set |
203 | | /// breakpoint locations in this breakpoint for all the resultant addresses. |
204 | | /// When \p column is nonzero the \p line and \p column args are used to |
205 | | /// filter the results to find the first breakpoint >= (line, column). |
206 | | void SetSCMatchesByLine(SearchFilter &filter, SymbolContextList &sc_list, |
207 | | bool skip_prologue, llvm::StringRef log_ident, |
208 | | uint32_t line = 0, |
209 | | std::optional<uint16_t> column = std::nullopt); |
210 | | void SetSCMatchesByLine(SearchFilter &, SymbolContextList &, bool, |
211 | | const char *) = delete; |
212 | | |
213 | | lldb::BreakpointLocationSP AddLocation(Address loc_addr, |
214 | | bool *new_location = nullptr); |
215 | | |
216 | | private: |
217 | | /// Helper for \p SetSCMatchesByLine. |
218 | | void AddLocation(SearchFilter &filter, const SymbolContext &sc, |
219 | | bool skip_prologue, llvm::StringRef log_ident); |
220 | | |
221 | | lldb::BreakpointWP m_breakpoint; // This is the breakpoint we add locations to. |
222 | | lldb::addr_t m_offset; // A random offset the user asked us to add to any |
223 | | // breakpoints we set. |
224 | | |
225 | | // Subclass identifier (for llvm isa/dyn_cast) |
226 | | const unsigned char SubclassID; |
227 | | BreakpointResolver(const BreakpointResolver &) = delete; |
228 | | const BreakpointResolver &operator=(const BreakpointResolver &) = delete; |
229 | | }; |
230 | | |
231 | | } // namespace lldb_private |
232 | | |
233 | | #endif // LLDB_BREAKPOINT_BREAKPOINTRESOLVER_H |