MCPcopy Create free account
hub / github.com/bytecodealliance/wasmtime / advance

Method advance

crates/unwinder/src/stackwalk.rs:177–272  ·  view source on GitHub ↗

Move to the next frame in this activation, if any. # Safety The `unwind` passed in must correspond to the host implementation from which this stack came.

(&mut self, unwind: &dyn Unwind)

Source from the content-addressed store, hash-verified

175 /// The `unwind` passed in must correspond to the host
176 /// implementation from which this stack came.
177 pub unsafe fn advance(&mut self, unwind: &dyn Unwind) {
178 // This logic will walk the linked list of frame pointers starting
179 // at `fp` and going up until `trampoline_fp`. We know that both
180 // `fp` and `trampoline_fp` are "trusted values" aka generated and
181 // maintained by Wasmtime. This means that it should be safe to
182 // walk the linked list of pointers and inspect Wasm frames.
183 //
184 // Note, though, that any frames outside of this range are not
185 // guaranteed to have valid frame pointers. For example native code
186 // might be using the frame pointer as a general purpose register. Thus
187 // we need to be careful to only walk frame pointers in this one
188 // contiguous linked list.
189 //
190 // To know when to stop iteration all architectures' stacks currently
191 // look something like this:
192 //
193 // | ... |
194 // | Native Frames |
195 // | ... |
196 // |-------------------|
197 // | ... | <-- Trampoline FP |
198 // | Trampoline Frame | |
199 // | ... | <-- Trampoline SP |
200 // |-------------------| Stack
201 // | Return Address | Grows
202 // | Previous FP | <-- Wasm FP Down
203 // | ... | |
204 // | Cranelift Frames | |
205 // | ... | V
206 //
207 // The trampoline records its own frame pointer (`trampoline_fp`),
208 // which is guaranteed to be above all Wasm code. To check when
209
210 // to check when the next frame pointer is equal to
211 // `trampoline_fp`. Once that's hit then we know that the entire
212 // linked list has been traversed.
213 //
214 // Note that it might be possible that this loop doesn't execute
215 // at all. For example if the entry trampoline called Wasm code
216 // which `return_call`'d an exit trampoline, then `fp ==
217 // trampoline_fp` on the entry of this function, meaning the loop
218 // won't actually execute anything.
219 if self.fp == self.trampoline_fp {
220 log::trace!("=== Done tracing contiguous sequence of Wasm frames ===");
221 return;
222 }
223
224 // At the start of each iteration of the loop, we know that
225 // `fp` is a frame pointer from Wasm code. Therefore, we know
226 // it is not being used as an extra general-purpose register,
227 // and it is safe dereference to get the PC and the next older
228 // frame pointer.
229 //
230 // The stack also grows down, and therefore any frame pointer
231 // we are dealing with should be less than the frame pointer
232 // on entry to Wasm code. Finally also assert that it's
233 // aligned correctly as an additional sanity check.
234 assert!(

Callers 5

frame_iteratorFunction · 0.80
poll_readMethod · 0.80
exit_frameMethod · 0.80
parentMethod · 0.80
poll_readMethod · 0.80

Calls 4

assert_fp_is_alignedMethod · 0.80
addMethod · 0.45

Tested by

no test coverage detected