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

Records