Andrew Walbran | 3d2c197 | 2020-04-07 12:24:26 +0100 | [diff] [blame] | 1 | //===-- StackFrame.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 liblldb_StackFrame_h_ |
| 10 | #define liblldb_StackFrame_h_ |
| 11 | |
| 12 | #include <memory> |
| 13 | #include <mutex> |
| 14 | |
| 15 | #include "lldb/Utility/Flags.h" |
| 16 | |
| 17 | #include "lldb/Core/ValueObjectList.h" |
| 18 | #include "lldb/Symbol/SymbolContext.h" |
| 19 | #include "lldb/Target/ExecutionContextScope.h" |
| 20 | #include "lldb/Target/StackID.h" |
| 21 | #include "lldb/Utility/Scalar.h" |
| 22 | #include "lldb/Utility/Status.h" |
| 23 | #include "lldb/Utility/StreamString.h" |
| 24 | #include "lldb/Utility/UserID.h" |
| 25 | |
| 26 | namespace lldb_private { |
| 27 | |
| 28 | /// \class StackFrame StackFrame.h "lldb/Target/StackFrame.h" |
| 29 | /// |
| 30 | /// This base class provides an interface to stack frames. |
| 31 | /// |
| 32 | /// StackFrames may have a Canonical Frame Address (CFA) or not. |
| 33 | /// A frame may have a plain pc value or it may indicate a specific point in |
| 34 | /// the debug session so the correct section load list is used for |
| 35 | /// symbolication. |
| 36 | /// |
| 37 | /// Local variables may be available, or not. A register context may be |
| 38 | /// available, or not. |
| 39 | |
| 40 | class StackFrame : public ExecutionContextScope, |
| 41 | public std::enable_shared_from_this<StackFrame> { |
| 42 | public: |
| 43 | enum ExpressionPathOption { |
| 44 | eExpressionPathOptionCheckPtrVsMember = (1u << 0), |
| 45 | eExpressionPathOptionsNoFragileObjcIvar = (1u << 1), |
| 46 | eExpressionPathOptionsNoSyntheticChildren = (1u << 2), |
| 47 | eExpressionPathOptionsNoSyntheticArrayRange = (1u << 3), |
| 48 | eExpressionPathOptionsAllowDirectIVarAccess = (1u << 4), |
| 49 | eExpressionPathOptionsInspectAnonymousUnions = (1u << 5) |
| 50 | }; |
| 51 | |
| 52 | enum class Kind { |
| 53 | /// A regular stack frame with access to registers and local variables. |
| 54 | Regular, |
| 55 | |
| 56 | /// A historical stack frame -- possibly without CFA or registers or |
| 57 | /// local variables. |
| 58 | History, |
| 59 | |
| 60 | /// An artificial stack frame (e.g. a synthesized result of inferring |
| 61 | /// missing tail call frames from a backtrace) with limited support for |
| 62 | /// local variables. |
| 63 | Artificial |
| 64 | }; |
| 65 | |
| 66 | /// Construct a StackFrame object without supplying a RegisterContextSP. |
| 67 | /// |
| 68 | /// This is the one constructor that doesn't take a RegisterContext |
| 69 | /// parameter. This ctor may be called when creating a history StackFrame; |
| 70 | /// these are used if we've collected a stack trace of pc addresses at some |
| 71 | /// point in the past. We may only have pc values. We may have a CFA, |
| 72 | /// or more likely, we won't. |
| 73 | /// |
| 74 | /// \param [in] thread_sp |
| 75 | /// The Thread that this frame belongs to. |
| 76 | /// |
| 77 | /// \param [in] frame_idx |
| 78 | /// This StackFrame's frame index number in the Thread. If inlined stack |
| 79 | /// frames are being created, this may differ from the concrete_frame_idx |
| 80 | /// which is the frame index without any inlined stack frames. |
| 81 | /// |
| 82 | /// \param [in] concrete_frame_idx |
| 83 | /// The StackFrame's frame index number in the Thread without any inlined |
| 84 | /// stack frames being included in the index. |
| 85 | /// |
| 86 | /// \param [in] cfa |
| 87 | /// The Canonical Frame Address (this terminology from DWARF) for this |
| 88 | /// stack frame. The CFA for a stack frame does not change over the |
| 89 | /// span of the stack frame's existence. It is often the value of the |
| 90 | /// caller's stack pointer before the call instruction into this frame's |
| 91 | /// function. It is usually not the same as the frame pointer register's |
| 92 | /// value. |
| 93 | /// |
| 94 | /// \param [in] cfa_is_valid |
| 95 | /// A history stack frame may not have a CFA value collected. We want to |
| 96 | /// distinguish between "no CFA available" and a CFA of |
| 97 | /// LLDB_INVALID_ADDRESS. |
| 98 | /// |
| 99 | /// \param [in] pc |
| 100 | /// The current pc value of this stack frame. |
| 101 | /// |
| 102 | /// \param [in] frame_kind |
| 103 | /// |
| 104 | /// \param [in] sc_ptr |
| 105 | /// Optionally seed the StackFrame with the SymbolContext information that |
| 106 | /// has |
| 107 | /// already been discovered. |
| 108 | StackFrame(const lldb::ThreadSP &thread_sp, lldb::user_id_t frame_idx, |
| 109 | lldb::user_id_t concrete_frame_idx, lldb::addr_t cfa, |
| 110 | bool cfa_is_valid, lldb::addr_t pc, Kind frame_kind, |
| 111 | const SymbolContext *sc_ptr); |
| 112 | |
| 113 | StackFrame(const lldb::ThreadSP &thread_sp, lldb::user_id_t frame_idx, |
| 114 | lldb::user_id_t concrete_frame_idx, |
| 115 | const lldb::RegisterContextSP ®_context_sp, lldb::addr_t cfa, |
| 116 | lldb::addr_t pc, const SymbolContext *sc_ptr); |
| 117 | |
| 118 | StackFrame(const lldb::ThreadSP &thread_sp, lldb::user_id_t frame_idx, |
| 119 | lldb::user_id_t concrete_frame_idx, |
| 120 | const lldb::RegisterContextSP ®_context_sp, lldb::addr_t cfa, |
| 121 | const Address &pc, const SymbolContext *sc_ptr); |
| 122 | |
| 123 | ~StackFrame() override; |
| 124 | |
| 125 | lldb::ThreadSP GetThread() const { return m_thread_wp.lock(); } |
| 126 | |
| 127 | StackID &GetStackID(); |
| 128 | |
| 129 | /// Get an Address for the current pc value in this StackFrame. |
| 130 | /// |
| 131 | /// May not be the same as the actual PC value for inlined stack frames. |
| 132 | /// |
| 133 | /// \return |
| 134 | /// The Address object set to the current PC value. |
| 135 | const Address &GetFrameCodeAddress(); |
| 136 | |
| 137 | /// Change the pc value for a given thread. |
| 138 | /// |
| 139 | /// Change the current pc value for the frame on this thread. |
| 140 | /// |
| 141 | /// \param[in] pc |
| 142 | /// The load address that the pc will be set to. |
| 143 | /// |
| 144 | /// \return |
| 145 | /// true if the pc was changed. false if this failed -- possibly |
| 146 | /// because this frame is not a live StackFrame. |
| 147 | bool ChangePC(lldb::addr_t pc); |
| 148 | |
| 149 | /// Provide a SymbolContext for this StackFrame's current pc value. |
| 150 | /// |
| 151 | /// The StackFrame maintains this SymbolContext and adds additional |
| 152 | /// information to it on an as-needed basis. This helps to avoid different |
| 153 | /// functions looking up symbolic information for a given pc value multiple |
| 154 | /// times. |
| 155 | /// |
| 156 | /// \params [in] resolve_scope |
| 157 | /// Flags from the SymbolContextItem enumerated type which specify what |
| 158 | /// type of symbol context is needed by this caller. |
| 159 | /// |
| 160 | /// \return |
| 161 | /// A SymbolContext reference which includes the types of information |
| 162 | /// requested by resolve_scope, if they are available. |
| 163 | const SymbolContext &GetSymbolContext(lldb::SymbolContextItem resolve_scope); |
| 164 | |
| 165 | /// Return the Canonical Frame Address (DWARF term) for this frame. |
| 166 | /// |
| 167 | /// The CFA is typically the value of the stack pointer register before the |
| 168 | /// call invocation is made. It will not change during the lifetime of a |
| 169 | /// stack frame. It is often not the same thing as the frame pointer |
| 170 | /// register value. |
| 171 | /// |
| 172 | /// Live StackFrames will always have a CFA but other types of frames may |
| 173 | /// not be able to supply one. |
| 174 | /// |
| 175 | /// \param [out] value |
| 176 | /// The address of the CFA for this frame, if available. |
| 177 | /// |
| 178 | /// \param [out] error_ptr |
| 179 | /// If there is an error determining the CFA address, this may contain a |
| 180 | /// string explaining the failure. |
| 181 | /// |
| 182 | /// \return |
| 183 | /// Returns true if the CFA value was successfully set in value. Some |
| 184 | /// frames may be unable to provide this value; they will return false. |
| 185 | bool GetFrameBaseValue(Scalar &value, Status *error_ptr); |
| 186 | |
| 187 | /// Get the DWARFExpression corresponding to the Canonical Frame Address. |
| 188 | /// |
| 189 | /// Often a register (bp), but sometimes a register + offset. |
| 190 | /// |
| 191 | /// \param [out] error_ptr |
| 192 | /// If there is an error determining the CFA address, this may contain a |
| 193 | /// string explaining the failure. |
| 194 | /// |
| 195 | /// \return |
| 196 | /// Returns the corresponding DWARF expression, or NULL. |
| 197 | DWARFExpression *GetFrameBaseExpression(Status *error_ptr); |
| 198 | |
| 199 | /// Get the current lexical scope block for this StackFrame, if possible. |
| 200 | /// |
| 201 | /// If debug information is available for this stack frame, return a pointer |
| 202 | /// to the innermost lexical Block that the frame is currently executing. |
| 203 | /// |
| 204 | /// \return |
| 205 | /// A pointer to the current Block. nullptr is returned if this can |
| 206 | /// not be provided. |
| 207 | Block *GetFrameBlock(); |
| 208 | |
| 209 | /// Get the RegisterContext for this frame, if possible. |
| 210 | /// |
| 211 | /// Returns a shared pointer to the RegisterContext for this stack frame. |
| 212 | /// Only a live StackFrame object will be able to return a RegisterContext - |
| 213 | /// callers must be prepared for an empty shared pointer being returned. |
| 214 | /// |
| 215 | /// Even a live StackFrame RegisterContext may not be able to provide all |
| 216 | /// registers. Only the currently executing frame (frame 0) can reliably |
| 217 | /// provide every register in the register context. |
| 218 | /// |
| 219 | /// \return |
| 220 | /// The RegisterContext shared point for this frame. |
| 221 | lldb::RegisterContextSP GetRegisterContext(); |
| 222 | |
| 223 | const lldb::RegisterContextSP &GetRegisterContextSP() const { |
| 224 | return m_reg_context_sp; |
| 225 | } |
| 226 | |
| 227 | /// Retrieve the list of variables that are in scope at this StackFrame's |
| 228 | /// pc. |
| 229 | /// |
| 230 | /// A frame that is not live may return an empty VariableList for a given |
| 231 | /// pc value even though variables would be available at this point if it |
| 232 | /// were a live stack frame. |
| 233 | /// |
| 234 | /// \param[in] get_file_globals |
| 235 | /// Whether to also retrieve compilation-unit scoped variables |
| 236 | /// that are visible to the entire compilation unit (e.g. file |
| 237 | /// static in C, globals that are homed in this CU). |
| 238 | /// |
| 239 | /// \return |
| 240 | /// A pointer to a list of variables. |
| 241 | VariableList *GetVariableList(bool get_file_globals); |
| 242 | |
| 243 | /// Retrieve the list of variables that are in scope at this StackFrame's |
| 244 | /// pc. |
| 245 | /// |
| 246 | /// A frame that is not live may return an empty VariableListSP for a |
| 247 | /// given pc value even though variables would be available at this point if |
| 248 | /// it were a live stack frame. |
| 249 | /// |
| 250 | /// \param[in] get_file_globals |
| 251 | /// Whether to also retrieve compilation-unit scoped variables |
| 252 | /// that are visible to the entire compilation unit (e.g. file |
| 253 | /// static in C, globals that are homed in this CU). |
| 254 | /// |
| 255 | /// \return |
| 256 | /// A pointer to a list of variables. |
| 257 | lldb::VariableListSP |
| 258 | GetInScopeVariableList(bool get_file_globals, |
| 259 | bool must_have_valid_location = false); |
| 260 | |
| 261 | /// Create a ValueObject for a variable name / pathname, possibly including |
| 262 | /// simple dereference/child selection syntax. |
| 263 | /// |
| 264 | /// \param[in] var_expr |
| 265 | /// The string specifying a variable to base the VariableObject off |
| 266 | /// of. |
| 267 | /// |
| 268 | /// \param[in] use_dynamic |
| 269 | /// Whether the correct dynamic type of an object pointer should be |
| 270 | /// determined before creating the object, or if the static type is |
| 271 | /// sufficient. One of the DynamicValueType enumerated values. |
| 272 | /// |
| 273 | /// \param[in] options |
| 274 | /// An unsigned integer of flags, values from |
| 275 | /// StackFrame::ExpressionPathOption |
| 276 | /// enum. |
| 277 | /// \param[in] var_sp |
| 278 | /// A VariableSP that will be set to the variable described in the |
| 279 | /// var_expr path. |
| 280 | /// |
| 281 | /// \param[in] error |
| 282 | /// Record any errors encountered while evaluating var_expr. |
| 283 | /// |
| 284 | /// \return |
| 285 | /// A shared pointer to the ValueObject described by var_expr. |
| 286 | lldb::ValueObjectSP GetValueForVariableExpressionPath( |
| 287 | llvm::StringRef var_expr, lldb::DynamicValueType use_dynamic, |
| 288 | uint32_t options, lldb::VariableSP &var_sp, Status &error); |
| 289 | |
| 290 | /// Determine whether this StackFrame has debug information available or not |
| 291 | /// |
| 292 | /// \return |
| 293 | // true if debug information is available for this frame (function, |
| 294 | // compilation unit, block, etc.) |
| 295 | bool HasDebugInformation(); |
| 296 | |
| 297 | /// Return the disassembly for the instructions of this StackFrame's |
| 298 | /// function as a single C string. |
| 299 | /// |
| 300 | /// \return |
| 301 | // C string with the assembly instructions for this function. |
| 302 | const char *Disassemble(); |
| 303 | |
| 304 | /// Print a description for this frame using the frame-format formatter |
| 305 | /// settings. |
| 306 | /// |
| 307 | /// \param [in] strm |
| 308 | /// The Stream to print the description to. |
| 309 | /// |
| 310 | /// \param [in] show_unique |
| 311 | /// Whether to print the function arguments or not for backtrace unique. |
| 312 | /// |
| 313 | /// \param [in] frame_marker |
| 314 | /// Optional string that will be prepended to the frame output description. |
| 315 | void DumpUsingSettingsFormat(Stream *strm, bool show_unique = false, |
| 316 | const char *frame_marker = nullptr); |
| 317 | |
| 318 | /// Print a description for this frame using a default format. |
| 319 | /// |
| 320 | /// \param [in] strm |
| 321 | /// The Stream to print the description to. |
| 322 | /// |
| 323 | /// \param [in] show_frame_index |
| 324 | /// Whether to print the frame number or not. |
| 325 | /// |
| 326 | /// \param [in] show_fullpaths |
| 327 | /// Whether to print the full source paths or just the file base name. |
| 328 | void Dump(Stream *strm, bool show_frame_index, bool show_fullpaths); |
| 329 | |
| 330 | /// Print a description of this stack frame and/or the source |
| 331 | /// context/assembly for this stack frame. |
| 332 | /// |
| 333 | /// \param[in] strm |
| 334 | /// The Stream to send the output to. |
| 335 | /// |
| 336 | /// \param[in] show_frame_info |
| 337 | /// If true, print the frame info by calling DumpUsingSettingsFormat(). |
| 338 | /// |
| 339 | /// \param[in] show_source |
| 340 | /// If true, print source or disassembly as per the user's settings. |
| 341 | /// |
| 342 | /// \param[in] show_unique |
| 343 | /// If true, print using backtrace unique style, without function |
| 344 | /// arguments as per the user's settings. |
| 345 | /// |
| 346 | /// \param[in] frame_marker |
| 347 | /// Passed to DumpUsingSettingsFormat() for the frame info printing. |
| 348 | /// |
| 349 | /// \return |
| 350 | /// Returns true if successful. |
| 351 | bool GetStatus(Stream &strm, bool show_frame_info, bool show_source, |
| 352 | bool show_unique = false, const char *frame_marker = nullptr); |
| 353 | |
| 354 | /// Query whether this frame is a concrete frame on the call stack, or if it |
| 355 | /// is an inlined frame derived from the debug information and presented by |
| 356 | /// the debugger. |
| 357 | /// |
| 358 | /// \return |
| 359 | /// true if this is an inlined frame. |
| 360 | bool IsInlined(); |
| 361 | |
| 362 | /// Query whether this frame is part of a historical backtrace. |
| 363 | bool IsHistorical() const; |
| 364 | |
| 365 | /// Query whether this frame is artificial (e.g a synthesized result of |
| 366 | /// inferring missing tail call frames from a backtrace). Artificial frames |
| 367 | /// may have limited support for inspecting variables. |
| 368 | bool IsArtificial() const; |
| 369 | |
| 370 | /// Query this frame to find what frame it is in this Thread's |
| 371 | /// StackFrameList. |
| 372 | /// |
| 373 | /// \return |
| 374 | /// StackFrame index 0 indicates the currently-executing function. Inline |
| 375 | /// frames are included in this frame index count. |
| 376 | uint32_t GetFrameIndex() const; |
| 377 | |
| 378 | /// Set this frame's synthetic frame index. |
| 379 | void SetFrameIndex(uint32_t index) { m_frame_index = index; } |
| 380 | |
| 381 | /// Query this frame to find what frame it is in this Thread's |
| 382 | /// StackFrameList, not counting inlined frames. |
| 383 | /// |
| 384 | /// \return |
| 385 | /// StackFrame index 0 indicates the currently-executing function. Inline |
| 386 | /// frames are not included in this frame index count; their concrete |
| 387 | /// frame index will be the same as the concrete frame that they are |
| 388 | /// derived from. |
| 389 | uint32_t GetConcreteFrameIndex() const { return m_concrete_frame_index; } |
| 390 | |
| 391 | /// Create a ValueObject for a given Variable in this StackFrame. |
| 392 | /// |
| 393 | /// \params [in] variable_sp |
| 394 | /// The Variable to base this ValueObject on |
| 395 | /// |
| 396 | /// \params [in] use_dynamic |
| 397 | /// Whether the correct dynamic type of the variable should be |
| 398 | /// determined before creating the ValueObject, or if the static type |
| 399 | /// is sufficient. One of the DynamicValueType enumerated values. |
| 400 | /// |
| 401 | /// \return |
| 402 | // A ValueObject for this variable. |
| 403 | lldb::ValueObjectSP |
| 404 | GetValueObjectForFrameVariable(const lldb::VariableSP &variable_sp, |
| 405 | lldb::DynamicValueType use_dynamic); |
| 406 | |
| 407 | /// Add an arbitrary Variable object (e.g. one that specifics a global or |
| 408 | /// static) to a StackFrame's list of ValueObjects. |
| 409 | /// |
| 410 | /// \params [in] variable_sp |
| 411 | /// The Variable to base this ValueObject on |
| 412 | /// |
| 413 | /// \params [in] use_dynamic |
| 414 | /// Whether the correct dynamic type of the variable should be |
| 415 | /// determined before creating the ValueObject, or if the static type |
| 416 | /// is sufficient. One of the DynamicValueType enumerated values. |
| 417 | /// |
| 418 | /// \return |
| 419 | // A ValueObject for this variable. |
| 420 | lldb::ValueObjectSP TrackGlobalVariable(const lldb::VariableSP &variable_sp, |
| 421 | lldb::DynamicValueType use_dynamic); |
| 422 | |
| 423 | /// Query this frame to determine what the default language should be when |
| 424 | /// parsing expressions given the execution context. |
| 425 | /// |
| 426 | /// \return |
| 427 | /// The language of the frame if known, else lldb::eLanguageTypeUnknown. |
| 428 | lldb::LanguageType GetLanguage(); |
| 429 | |
| 430 | // similar to GetLanguage(), but is allowed to take a potentially incorrect |
| 431 | // guess if exact information is not available |
| 432 | lldb::LanguageType GuessLanguage(); |
| 433 | |
| 434 | /// Attempt to econstruct the ValueObject for a given raw address touched by |
| 435 | /// the current instruction. The ExpressionPath should indicate how to get |
| 436 | /// to this value using "frame variable." |
| 437 | /// |
| 438 | /// \params [in] addr |
| 439 | /// The raw address. |
| 440 | /// |
| 441 | /// \return |
| 442 | /// The ValueObject if found. If valid, it has a valid ExpressionPath. |
| 443 | lldb::ValueObjectSP GuessValueForAddress(lldb::addr_t addr); |
| 444 | |
| 445 | /// Attempt to reconstruct the ValueObject for the address contained in a |
| 446 | /// given register plus an offset. The ExpressionPath should indicate how |
| 447 | /// to get to this value using "frame variable." |
| 448 | /// |
| 449 | /// \params [in] reg |
| 450 | /// The name of the register. |
| 451 | /// |
| 452 | /// \params [in] offset |
| 453 | /// The offset from the register. Particularly important for sp... |
| 454 | /// |
| 455 | /// \return |
| 456 | /// The ValueObject if found. If valid, it has a valid ExpressionPath. |
| 457 | lldb::ValueObjectSP GuessValueForRegisterAndOffset(ConstString reg, |
| 458 | int64_t offset); |
| 459 | |
| 460 | /// Attempt to reconstruct the ValueObject for a variable with a given \a name |
| 461 | /// from within the current StackFrame, within the current block. The search |
| 462 | /// for the variable starts in the deepest block corresponding to the current |
| 463 | /// PC in the stack frame and traverse through all parent blocks stopping at |
| 464 | /// inlined function boundaries. |
| 465 | /// |
| 466 | /// \params [in] name |
| 467 | /// The name of the variable. |
| 468 | /// |
| 469 | /// \return |
| 470 | /// The ValueObject if found. |
| 471 | lldb::ValueObjectSP FindVariable(ConstString name); |
| 472 | |
| 473 | // lldb::ExecutionContextScope pure virtual functions |
| 474 | lldb::TargetSP CalculateTarget() override; |
| 475 | |
| 476 | lldb::ProcessSP CalculateProcess() override; |
| 477 | |
| 478 | lldb::ThreadSP CalculateThread() override; |
| 479 | |
| 480 | lldb::StackFrameSP CalculateStackFrame() override; |
| 481 | |
| 482 | void CalculateExecutionContext(ExecutionContext &exe_ctx) override; |
| 483 | |
| 484 | lldb::RecognizedStackFrameSP GetRecognizedFrame(); |
| 485 | |
| 486 | protected: |
| 487 | friend class StackFrameList; |
| 488 | |
| 489 | void SetSymbolContextScope(SymbolContextScope *symbol_scope); |
| 490 | |
| 491 | void UpdateCurrentFrameFromPreviousFrame(StackFrame &prev_frame); |
| 492 | |
| 493 | void UpdatePreviousFrameFromCurrentFrame(StackFrame &curr_frame); |
| 494 | |
| 495 | bool HasCachedData() const; |
| 496 | |
| 497 | private: |
| 498 | // For StackFrame only |
| 499 | lldb::ThreadWP m_thread_wp; |
| 500 | uint32_t m_frame_index; |
| 501 | uint32_t m_concrete_frame_index; |
| 502 | lldb::RegisterContextSP m_reg_context_sp; |
| 503 | StackID m_id; |
| 504 | Address m_frame_code_addr; // The frame code address (might not be the same as |
| 505 | // the actual PC for inlined frames) as a |
| 506 | // section/offset address |
| 507 | SymbolContext m_sc; |
| 508 | Flags m_flags; |
| 509 | Scalar m_frame_base; |
| 510 | Status m_frame_base_error; |
| 511 | bool m_cfa_is_valid; // Does this frame have a CFA? Different from CFA == |
| 512 | // LLDB_INVALID_ADDRESS |
| 513 | Kind m_stack_frame_kind; |
| 514 | lldb::VariableListSP m_variable_list_sp; |
| 515 | ValueObjectList m_variable_list_value_objects; // Value objects for each |
| 516 | // variable in |
| 517 | // m_variable_list_sp |
| 518 | lldb::RecognizedStackFrameSP m_recognized_frame_sp; |
| 519 | StreamString m_disassembly; |
| 520 | std::recursive_mutex m_mutex; |
| 521 | |
| 522 | DISALLOW_COPY_AND_ASSIGN(StackFrame); |
| 523 | }; |
| 524 | |
| 525 | } // namespace lldb_private |
| 526 | |
| 527 | #endif // liblldb_StackFrame_h_ |