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