StackFrameList.h 5.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161
  1. //===-- StackFrameList.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. #ifndef LLDB_TARGET_STACKFRAMELIST_H
  9. #define LLDB_TARGET_STACKFRAMELIST_H
  10. #include <memory>
  11. #include <mutex>
  12. #include <vector>
  13. #include "lldb/Target/StackFrame.h"
  14. namespace lldb_private {
  15. class StackFrameList {
  16. public:
  17. // Constructors and Destructors
  18. StackFrameList(Thread &thread, const lldb::StackFrameListSP &prev_frames_sp,
  19. bool show_inline_frames);
  20. ~StackFrameList();
  21. /// Get the number of visible frames. Frames may be created if \p can_create
  22. /// is true. Synthetic (inline) frames expanded from the concrete frame #0
  23. /// (aka invisible frames) are not included in this count.
  24. uint32_t GetNumFrames(bool can_create = true);
  25. /// Get the frame at index \p idx. Invisible frames cannot be indexed.
  26. lldb::StackFrameSP GetFrameAtIndex(uint32_t idx);
  27. /// Get the first concrete frame with index greater than or equal to \p idx.
  28. /// Unlike \ref GetFrameAtIndex, this cannot return a synthetic frame.
  29. lldb::StackFrameSP GetFrameWithConcreteFrameIndex(uint32_t unwind_idx);
  30. /// Retrieve the stack frame with the given ID \p stack_id.
  31. lldb::StackFrameSP GetFrameWithStackID(const StackID &stack_id);
  32. /// Mark a stack frame as the currently selected frame and return its index.
  33. uint32_t SetSelectedFrame(lldb_private::StackFrame *frame);
  34. /// Get the currently selected frame index.
  35. uint32_t GetSelectedFrameIndex() const;
  36. /// Mark a stack frame as the currently selected frame using the frame index
  37. /// \p idx. Like \ref GetFrameAtIndex, invisible frames cannot be selected.
  38. bool SetSelectedFrameByIndex(uint32_t idx);
  39. /// If the current inline depth (i.e the number of invisible frames) is valid,
  40. /// subtract it from \p idx. Otherwise simply return \p idx.
  41. uint32_t GetVisibleStackFrameIndex(uint32_t idx) {
  42. if (m_current_inlined_depth < UINT32_MAX)
  43. return idx - m_current_inlined_depth;
  44. else
  45. return idx;
  46. }
  47. /// Calculate and set the current inline depth. This may be used to update
  48. /// the StackFrameList's set of inline frames when execution stops, e.g when
  49. /// a breakpoint is hit.
  50. void CalculateCurrentInlinedDepth();
  51. /// If the currently selected frame comes from the currently selected thread,
  52. /// point the default file and line of the thread's target to the location
  53. /// specified by the frame.
  54. void SetDefaultFileAndLineToSelectedFrame();
  55. /// Clear the cache of frames.
  56. void Clear();
  57. void Dump(Stream *s);
  58. /// If \p stack_frame_ptr is contained in this StackFrameList, return its
  59. /// wrapping shared pointer.
  60. lldb::StackFrameSP
  61. GetStackFrameSPForStackFramePtr(StackFrame *stack_frame_ptr);
  62. size_t GetStatus(Stream &strm, uint32_t first_frame, uint32_t num_frames,
  63. bool show_frame_info, uint32_t num_frames_with_source,
  64. bool show_unique = false,
  65. const char *frame_marker = nullptr);
  66. protected:
  67. friend class Thread;
  68. bool SetFrameAtIndex(uint32_t idx, lldb::StackFrameSP &frame_sp);
  69. void GetFramesUpTo(uint32_t end_idx);
  70. void GetOnlyConcreteFramesUpTo(uint32_t end_idx, Unwind &unwinder);
  71. void SynthesizeTailCallFrames(StackFrame &next_frame);
  72. bool GetAllFramesFetched() { return m_concrete_frames_fetched == UINT32_MAX; }
  73. void SetAllFramesFetched() { m_concrete_frames_fetched = UINT32_MAX; }
  74. bool DecrementCurrentInlinedDepth();
  75. void ResetCurrentInlinedDepth();
  76. uint32_t GetCurrentInlinedDepth();
  77. void SetCurrentInlinedDepth(uint32_t new_depth);
  78. typedef std::vector<lldb::StackFrameSP> collection;
  79. typedef collection::iterator iterator;
  80. typedef collection::const_iterator const_iterator;
  81. /// The thread this frame list describes.
  82. Thread &m_thread;
  83. /// The old stack frame list.
  84. // TODO: The old stack frame list is used to fill in missing frame info
  85. // heuristically when it's otherwise unavailable (say, because the unwinder
  86. // fails). We should have stronger checks to make sure that this is a valid
  87. // source of information.
  88. lldb::StackFrameListSP m_prev_frames_sp;
  89. /// A mutex for this frame list.
  90. // TODO: This mutex may not always be held when required. In particular, uses
  91. // of the StackFrameList APIs in lldb_private::Thread look suspect. Consider
  92. // passing around a lock_guard reference to enforce proper locking.
  93. mutable std::recursive_mutex m_mutex;
  94. /// A cache of frames. This may need to be updated when the program counter
  95. /// changes.
  96. collection m_frames;
  97. /// The currently selected frame.
  98. uint32_t m_selected_frame_idx;
  99. /// The number of concrete frames fetched while filling the frame list. This
  100. /// is only used when synthetic frames are enabled.
  101. uint32_t m_concrete_frames_fetched;
  102. /// The number of synthetic function activations (invisible frames) expanded
  103. /// from the concrete frame #0 activation.
  104. // TODO: Use an optional instead of UINT32_MAX to denote invalid values.
  105. uint32_t m_current_inlined_depth;
  106. /// The program counter value at the currently selected synthetic activation.
  107. /// This is only valid if m_current_inlined_depth is valid.
  108. // TODO: Use an optional instead of UINT32_MAX to denote invalid values.
  109. lldb::addr_t m_current_inlined_pc;
  110. /// Whether or not to show synthetic (inline) frames. Immutable.
  111. const bool m_show_inlined_frames;
  112. private:
  113. StackFrameList(const StackFrameList &) = delete;
  114. const StackFrameList &operator=(const StackFrameList &) = delete;
  115. };
  116. } // namespace lldb_private
  117. #endif // LLDB_TARGET_STACKFRAMELIST_H