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