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