Coverage Report

Created: 2023-11-11 10:31

/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