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