class Stack
Defined at line 51 of file ../../src/developer/debug/zxdb/client/stack.h
Represents the stack of a thread that's suspended or blocked in an exception. If a thread is
running, blocked (not in an exception), or in any other state, the stack frames are not
available.
EMPTY, PARTIAL AND COMPLETE STACKS
----------------------------------
When a thread is suspended or blocked in an exception, it will UNUSUALLY have its top frame
available (the current IP and stack position) and the next (the calling frame) if possible.
Sometimes a thread might have an empty stack (and hence no current location) from an exception.
This is because exceptions are delivered from the kernel asynchronously, and by the time an
exception is handled in the debug agent, the thread may have been killed. This will result in
failred register reads for the thread and no stack or location. Code should never assume there
are any stack frames.
If the full backtrace is needed, SyncFrames() can be called which will compute the full backtrace
and issue the callback when complete. This backtrace will be cached until the thread is resumed.
INLINE FRAMES
-------------
The thread's current position can be in multiple inline frames at the same time (the first
address of an inline function is both the first instruction of that function, and the virtual
"call" of that function in the outer frame). This only applies to the topmost set of inline
frames since anything below the first physical frame is unambiguous).
To make stepping work as expected, code can adjust which of these ambiguous inline frames the
stack reports is the top, and inline frames above that are hidden from the normal size() and
operator[] functions.
Public Methods
bool has_all_frames ()
Returns whether the frames in this backtrace are all the frames or only the top 1-2 (see
class-level comment above).
Defined at line 95 of file ../../src/developer/debug/zxdb/client/stack.h
size_t size ()
Defined at line 97 of file ../../src/developer/debug/zxdb/client/stack.h
bool empty ()
Defined at line 98 of file ../../src/developer/debug/zxdb/client/stack.h
Frame * operator[] (size_t index)
Access into the individual frames. The topmost stack frame is index 0. There may be hidden
inline frames above index 0. Callers should always check the stack size() before accessing
since the stack is never guaranteed to have elements in it (even during processing an
exception -- see class comment above).
Defined at line 104 of file ../../src/developer/debug/zxdb/client/stack.h
const Frame * operator[] (size_t index)
Defined at line 107 of file ../../src/developer/debug/zxdb/client/stack.h
size_t hide_ambiguous_inline_frame_count ()
Defined at line 137 of file ../../src/developer/debug/zxdb/client/stack.h
void Stack (Delegate * delegate)
The delegate must outlive this class.
Defined at line 140 of file ../../src/developer/debug/zxdb/client/stack.cc
void ~Stack ()
Defined at line 142 of file ../../src/developer/debug/zxdb/client/stack.cc
size_t SizeIncludingHiddenInline ()
Queries the size and for frames at indices ignoring any hidden inline frames. With
FrameAtIndexIndcludingHiddenInline(), the 0th index is always the innermost inline frame and is
not affected by SetTopInlineFrameShowCount().
Defined at line 143 of file ../../src/developer/debug/zxdb/client/stack.h
fxl::WeakPtr<Stack> GetWeakPtr ()
Defined at line 144 of file ../../src/developer/debug/zxdb/client/stack.cc
Frame * FrameAtIndexIncludingHiddenInline (size_t index)
Defined at line 144 of file ../../src/developer/debug/zxdb/client/stack.h
std::optional<size_t> IndexForFrame (const Frame * frame)
Returns the index of the frame pointer in this stack if it is there.
Defined at line 146 of file ../../src/developer/debug/zxdb/client/stack.cc
size_t InlineDepthForIndex (size_t index)
Returns the inline depth of the frame at the given index. If the frame is a physical frame,
this will be 0.
Defined at line 154 of file ../../src/developer/debug/zxdb/client/stack.cc
FrameFingerprint GetFrameFingerprint (size_t frame_index)
Computes the stack frame fingerprint for the stack frame at the given index. The index must be
valid in the current set of frames in this stack object.
See frame_fingerprint.h for a discussion on fingerprints.
Defined at line 165 of file ../../src/developer/debug/zxdb/client/stack.cc
size_t GetAmbiguousInlineFrameCount ()
Sets the number of inline frames at the top of the stack to show. See the class-level comment
above for more.
Anything trimmed should have its current position at the beginning of a code range of an inline
function for this trimming to make logical sense. The number of inline frames at the top of the
stack can be modified.
The "top inline frame count" is the number of inline frames above the topmost physical frame
that exist in the stack. This does not change when the hide count is modified.
From 0 to "top inline frame count" of inline frames can be hidden or unhidden. By default they
are all visible (hide count = 0).
Defined at line 181 of file ../../src/developer/debug/zxdb/client/stack.cc
void SetHideAmbiguousInlineFrameCount (size_t hide_count)
Defined at line 195 of file ../../src/developer/debug/zxdb/client/stack.cc
void SyncFrames (const SyncFrameOptions & opts, fit::callback<void (const Err &)> callback)
Requests that all frame information be updated. This can be used to (asynchronously) populate
the frames when a Stack has only partial frame information, and it can be used to force an
update from the remote system in case anything changed.
Normally frame info is cached. Setting "force" will unconditionally clear all state. This will
invalidate any weak pointers into the stack and could change the frame indices in the
frontend.
If the stack is destroyed before the frames can be synced, the callback will be issued with an
error.
Defined at line 200 of file ../../src/developer/debug/zxdb/client/stack.cc
void SetFrames (debug_ipc::ThreadRecord::StackAmount amount, const std::vector<debug_ipc::StackFrame> & frames)
Provides a new set of frames computed by a backtrace in the debug_agent. In normal operation
this is called by the Thread.
This can be called in two cases: (1) when a thread stops to provide a new stack, and (2) when
updating a stack with more frames. If there are existing frames when SetFrames is called, it
will assume state (2) if possible (the stack could have changed out from under us) and will
attempt to preserve the ambiguous inline hide count, etc. consistent with updating an existing
stack.
If you don't want this behavior, call ClearFrames() first. ClearFrames() will be called whever
a thread is resumed so fresh stops should get this behavior by default.
Defined at line 206 of file ../../src/developer/debug/zxdb/client/stack.cc
void SetFramesForTest (std::vector<std::unique_ptr<Frame>> frames, bool has_all)
Sets the frames to a known set to provide synthetic stacks for tests.
Defined at line 264 of file ../../src/developer/debug/zxdb/client/stack.cc
void ClearFrames ()
Removes all frames. In normal operation this is called by the Thread when things happen that
invalidate all frames such as resuming the thread.
This should generally only be called by the Thread. Otherwise the thread state (whether it's
stopped, etc.) can diverge from the stack state (threads in certain stopped states are always
expected to have at least one stack frame).
Defined at line 271 of file ../../src/developer/debug/zxdb/client/stack.cc