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