1 //===-- BreakpointOptions.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_BREAKPOINTOPTIONS_H 10 #define LLDB_BREAKPOINT_BREAKPOINTOPTIONS_H 11 12 #include <memory> 13 #include <string> 14 15 #include "lldb/Utility/Baton.h" 16 #include "lldb/Utility/Flags.h" 17 #include "lldb/Utility/StringList.h" 18 #include "lldb/Utility/StructuredData.h" 19 #include "lldb/lldb-private.h" 20 21 namespace lldb_private { 22 23 /// \class BreakpointOptions BreakpointOptions.h 24 /// "lldb/Breakpoint/BreakpointOptions.h" Class that manages the options on a 25 /// breakpoint or breakpoint location. 26 27 class BreakpointOptions { 28 friend class BreakpointLocation; 29 friend class BreakpointName; 30 friend class lldb_private::BreakpointOptionGroup; 31 friend class Breakpoint; 32 33 public: 34 enum OptionKind { 35 eCallback = 1 << 0, 36 eEnabled = 1 << 1, 37 eOneShot = 1 << 2, 38 eIgnoreCount = 1 << 3, 39 eThreadSpec = 1 << 4, 40 eCondition = 1 << 5, 41 eAutoContinue = 1 << 6, 42 eAllOptions = (eCallback | eEnabled | eOneShot | eIgnoreCount | eThreadSpec 43 | eCondition | eAutoContinue) 44 }; 45 struct CommandData { 46 CommandData() = default; 47 CommandDataCommandData48 CommandData(const StringList &user_source, lldb::ScriptLanguage interp) 49 : user_source(user_source), interpreter(interp), stop_on_error(true) {} 50 51 virtual ~CommandData() = default; 52 GetSerializationKeyCommandData53 static const char *GetSerializationKey() { return "BKPTCMDData"; } 54 55 StructuredData::ObjectSP SerializeToStructuredData(); 56 57 static std::unique_ptr<CommandData> 58 CreateFromStructuredData(const StructuredData::Dictionary &options_dict, 59 Status &error); 60 61 StringList user_source; 62 std::string script_source; 63 enum lldb::ScriptLanguage interpreter = 64 lldb::eScriptLanguageNone; // eScriptLanguageNone means command 65 // interpreter. 66 bool stop_on_error = true; 67 68 private: 69 enum class OptionNames : uint32_t { 70 UserSource = 0, 71 Interpreter, 72 StopOnError, 73 LastOptionName 74 }; 75 76 static const char 77 *g_option_names[static_cast<uint32_t>(OptionNames::LastOptionName)]; 78 GetKeyCommandData79 static const char *GetKey(OptionNames enum_value) { 80 return g_option_names[static_cast<uint32_t>(enum_value)]; 81 } 82 }; 83 84 class CommandBaton : public TypedBaton<CommandData> { 85 public: CommandBaton(std::unique_ptr<CommandData> Data)86 explicit CommandBaton(std::unique_ptr<CommandData> Data) 87 : TypedBaton(std::move(Data)) {} 88 89 void GetDescription(llvm::raw_ostream &s, lldb::DescriptionLevel level, 90 unsigned indentation) const override; 91 }; 92 93 typedef std::shared_ptr<CommandBaton> CommandBatonSP; 94 95 // Constructors and Destructors 96 97 /// This constructor allows you to specify all the breakpoint options except 98 /// the callback. That one is more complicated, and better to do by hand. 99 /// 100 /// \param[in] condition 101 /// The expression which if it evaluates to \b true if we are to stop 102 /// 103 /// \param[in] enabled 104 /// Is this breakpoint enabled. 105 /// 106 /// \param[in] ignore 107 /// How many breakpoint hits we should ignore before stopping. 108 /// 109 /// \param[in] one_shot 110 /// Should this breakpoint delete itself after being hit once. 111 /// 112 /// \param[in] auto_continue 113 /// Should this breakpoint auto-continue after running its commands. 114 /// 115 BreakpointOptions(const char *condition, bool enabled = true, 116 int32_t ignore = 0, bool one_shot = false, 117 bool auto_continue = false); 118 119 /// Breakpoints make options with all flags set. Locations and Names make 120 /// options with no flags set. 121 BreakpointOptions(bool all_flags_set); 122 BreakpointOptions(const BreakpointOptions &rhs); 123 124 virtual ~BreakpointOptions(); 125 126 static std::unique_ptr<BreakpointOptions> 127 CreateFromStructuredData(Target &target, 128 const StructuredData::Dictionary &data_dict, 129 Status &error); 130 131 virtual StructuredData::ObjectSP SerializeToStructuredData(); 132 GetSerializationKey()133 static const char *GetSerializationKey() { return "BKPTOptions"; } 134 135 // Operators 136 const BreakpointOptions &operator=(const BreakpointOptions &rhs); 137 138 /// Copy over only the options set in the incoming BreakpointOptions. 139 void CopyOverSetOptions(const BreakpointOptions &rhs); 140 141 // Callbacks 142 // 143 // Breakpoint callbacks come in two forms, synchronous and asynchronous. 144 // Synchronous callbacks will get run before any of the thread plans are 145 // consulted, and if they return false the target will continue "under the 146 // radar" of the thread plans. There are a couple of restrictions to 147 // synchronous callbacks: 148 // 1) They should NOT resume the target themselves. 149 // Just return false if you want the target to restart. 150 // 2) Breakpoints with synchronous callbacks can't have conditions 151 // (or rather, they can have them, but they won't do anything. 152 // Ditto with ignore counts, etc... You are supposed to control that all 153 // through the callback. 154 // Asynchronous callbacks get run as part of the "ShouldStop" logic in the 155 // thread plan. The logic there is: 156 // a) If the breakpoint is thread specific and not for this thread, continue 157 // w/o running the callback. 158 // NB. This is actually enforced underneath the breakpoint system, the 159 // Process plugin is expected to 160 // call BreakpointSite::IsValidForThread, and set the thread's StopInfo 161 // to "no reason". That way, 162 // thread displays won't show stops for breakpoints not for that 163 // thread... 164 // b) If the ignore count says we shouldn't stop, then ditto. 165 // c) If the condition says we shouldn't stop, then ditto. 166 // d) Otherwise, the callback will get run, and if it returns true we will 167 // stop, and if false we won't. 168 // The asynchronous callback can run the target itself, but at present that 169 // should be the last action the callback does. We will relax this condition 170 // at some point, but it will take a bit of plumbing to get that to work. 171 // 172 173 /// Adds a callback to the breakpoint option set. 174 /// 175 /// \param[in] callback 176 /// The function to be called when the breakpoint gets hit. 177 /// 178 /// \param[in] baton_sp 179 /// A baton which will get passed back to the callback when it is invoked. 180 /// 181 /// \param[in] synchronous 182 /// Whether this is a synchronous or asynchronous callback. See discussion 183 /// above. 184 void SetCallback(BreakpointHitCallback callback, 185 const lldb::BatonSP &baton_sp, bool synchronous = false); 186 187 void SetCallback(BreakpointHitCallback callback, 188 const BreakpointOptions::CommandBatonSP &command_baton_sp, 189 bool synchronous = false); 190 191 /// Returns the command line commands for the callback on this breakpoint. 192 /// 193 /// \param[out] command_list 194 /// The commands will be appended to this list. 195 /// 196 /// \return 197 /// \b true if the command callback is a command-line callback, 198 /// \b false otherwise. 199 bool GetCommandLineCallbacks(StringList &command_list); 200 201 /// Remove the callback from this option set. 202 void ClearCallback(); 203 204 // The rest of these functions are meant to be used only within the 205 // breakpoint handling mechanism. 206 207 /// Use this function to invoke the callback for a specific stop. 208 /// 209 /// \param[in] context 210 /// The context in which the callback is to be invoked. This includes the 211 /// stop event, the 212 /// execution context of the stop (since you might hit the same breakpoint 213 /// on multiple threads) and 214 /// whether we are currently executing synchronous or asynchronous 215 /// callbacks. 216 /// 217 /// \param[in] break_id 218 /// The breakpoint ID that owns this option set. 219 /// 220 /// \param[in] break_loc_id 221 /// The breakpoint location ID that owns this option set. 222 /// 223 /// \return 224 /// The callback return value. 225 bool InvokeCallback(StoppointCallbackContext *context, 226 lldb::user_id_t break_id, lldb::user_id_t break_loc_id); 227 228 /// Used in InvokeCallback to tell whether it is the right time to run this 229 /// kind of callback. 230 /// 231 /// \return 232 /// The synchronicity of our callback. IsCallbackSynchronous()233 bool IsCallbackSynchronous() const { return m_callback_is_synchronous; } 234 235 /// Fetch the baton from the callback. 236 /// 237 /// \return 238 /// The baton. 239 Baton *GetBaton(); 240 241 /// Fetch a const version of the baton from the callback. 242 /// 243 /// \return 244 /// The baton. 245 const Baton *GetBaton() const; 246 247 // Condition 248 /// Set the breakpoint option's condition. 249 /// 250 /// \param[in] condition 251 /// The condition expression to evaluate when the breakpoint is hit. 252 void SetCondition(const char *condition); 253 254 /// Return a pointer to the text of the condition expression. 255 /// 256 /// \return 257 /// A pointer to the condition expression text, or nullptr if no 258 // condition has been set. 259 const char *GetConditionText(size_t *hash = nullptr) const; 260 261 // Enabled/Ignore Count 262 263 /// Check the Enable/Disable state. 264 /// \return 265 /// \b true if the breakpoint is enabled, \b false if disabled. IsEnabled()266 bool IsEnabled() const { return m_enabled; } 267 268 /// If \a enable is \b true, enable the breakpoint, if \b false disable it. SetEnabled(bool enabled)269 void SetEnabled(bool enabled) { 270 m_enabled = enabled; 271 m_set_flags.Set(eEnabled); 272 } 273 274 /// Check the auto-continue state. 275 /// \return 276 /// \b true if the breakpoint is set to auto-continue, \b false otherwise. IsAutoContinue()277 bool IsAutoContinue() const { return m_auto_continue; } 278 279 /// Set the auto-continue state. SetAutoContinue(bool auto_continue)280 void SetAutoContinue(bool auto_continue) { 281 m_auto_continue = auto_continue; 282 m_set_flags.Set(eAutoContinue); 283 } 284 285 /// Check the One-shot state. 286 /// \return 287 /// \b true if the breakpoint is one-shot, \b false otherwise. IsOneShot()288 bool IsOneShot() const { return m_one_shot; } 289 290 /// If \a enable is \b true, enable the breakpoint, if \b false disable it. SetOneShot(bool one_shot)291 void SetOneShot(bool one_shot) { 292 m_one_shot = one_shot; 293 m_set_flags.Set(eOneShot); 294 } 295 296 /// Set the breakpoint to ignore the next \a count breakpoint hits. 297 /// \param[in] n 298 /// The number of breakpoint hits to ignore. SetIgnoreCount(uint32_t n)299 void SetIgnoreCount(uint32_t n) { 300 m_ignore_count = n; 301 m_set_flags.Set(eIgnoreCount); 302 } 303 304 /// Return the current Ignore Count. 305 /// \return 306 /// The number of breakpoint hits to be ignored. GetIgnoreCount()307 uint32_t GetIgnoreCount() const { return m_ignore_count; } 308 309 /// Return the current thread spec for this option. This will return nullptr 310 /// if the no thread specifications have been set for this Option yet. 311 /// \return 312 /// The thread specification pointer for this option, or nullptr if none 313 /// has 314 /// been set yet. 315 const ThreadSpec *GetThreadSpecNoCreate() const; 316 317 /// Returns a pointer to the ThreadSpec for this option, creating it. if it 318 /// hasn't been created already. This API is used for setting the 319 /// ThreadSpec items for this option. 320 ThreadSpec *GetThreadSpec(); 321 322 void SetThreadID(lldb::tid_t thread_id); 323 324 void GetDescription(Stream *s, lldb::DescriptionLevel level) const; 325 326 /// Check if the breakpoint option has a callback set. 327 /// 328 /// \return 329 /// If the breakpoint option has a callback, \b true otherwise \b false. 330 bool HasCallback() const; 331 332 /// This is the default empty callback. 333 static bool NullCallback(void *baton, StoppointCallbackContext *context, 334 lldb::user_id_t break_id, 335 lldb::user_id_t break_loc_id); 336 337 /// Set a callback based on BreakpointOptions::CommandData. \param[in] 338 /// cmd_data 339 /// A UP holding the new'ed CommandData object. 340 /// The breakpoint will take ownership of pointer held by this object. 341 void SetCommandDataCallback(std::unique_ptr<CommandData> &cmd_data); 342 343 void Clear(); 344 AnySet()345 bool AnySet() const { 346 return m_set_flags.AnySet(eAllOptions); 347 } 348 349 protected: 350 // Classes that inherit from BreakpointOptions can see and modify these IsOptionSet(OptionKind kind)351 bool IsOptionSet(OptionKind kind) 352 { 353 return m_set_flags.Test(kind); 354 } 355 356 enum class OptionNames { 357 ConditionText = 0, 358 IgnoreCount, 359 EnabledState, 360 OneShotState, 361 AutoContinue, 362 LastOptionName 363 }; 364 static const char *g_option_names[(size_t)OptionNames::LastOptionName]; 365 GetKey(OptionNames enum_value)366 static const char *GetKey(OptionNames enum_value) { 367 return g_option_names[(size_t)enum_value]; 368 } 369 370 static bool BreakpointOptionsCallbackFunction( 371 void *baton, StoppointCallbackContext *context, lldb::user_id_t break_id, 372 lldb::user_id_t break_loc_id); 373 374 void SetThreadSpec(std::unique_ptr<ThreadSpec> &thread_spec_up); 375 376 private: 377 /// For BreakpointOptions only 378 379 /// This is the callback function pointer 380 BreakpointHitCallback m_callback; 381 /// This is the client data for the callback 382 lldb::BatonSP m_callback_baton_sp; 383 bool m_baton_is_command_baton; 384 bool m_callback_is_synchronous; 385 bool m_enabled; 386 /// If set, the breakpoint delete itself after being hit once. 387 bool m_one_shot; 388 /// Number of times to ignore this breakpoint. 389 uint32_t m_ignore_count; 390 /// Thread for which this breakpoint will stop. 391 std::unique_ptr<ThreadSpec> m_thread_spec_up; 392 /// The condition to test. 393 std::string m_condition_text; 394 /// Its hash, so that locations know when the condition is updated. 395 size_t m_condition_text_hash; 396 /// If set, inject breakpoint condition into process. 397 bool m_inject_condition; 398 /// If set, auto-continue from breakpoint. 399 bool m_auto_continue; 400 /// Which options are set at this level. 401 /// Drawn from BreakpointOptions::SetOptionsFlags. 402 Flags m_set_flags; 403 }; 404 405 } // namespace lldb_private 406 407 #endif // LLDB_BREAKPOINT_BREAKPOINTOPTIONS_H 408