core: More stack walking
This commit is contained in:
@@ -1,30 +1,69 @@
|
|||||||
import libc::uintptr_t;
|
// NB: Don't rely on other core mods here as this has to move into the rt
|
||||||
|
|
||||||
|
import unsafe::reinterpret_cast;
|
||||||
|
import ptr::offset;
|
||||||
|
import sys::size_of;
|
||||||
|
|
||||||
|
type word = uint;
|
||||||
|
|
||||||
class frame {
|
class frame {
|
||||||
let fp: uintptr_t;
|
let fp: *word;
|
||||||
|
|
||||||
new(fp: uintptr_t) {
|
new(fp: *word) {
|
||||||
self.fp = fp;
|
self.fp = fp;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn walk_stack(visit: fn(frame) -> bool) {
|
fn walk_stack(visit: fn(frame) -> bool) {
|
||||||
|
|
||||||
|
#debug("beginning stack walk");
|
||||||
|
|
||||||
frame_address { |frame_pointer|
|
frame_address { |frame_pointer|
|
||||||
let frame_address = unsafe {
|
let mut frame_address: *word = unsafe {
|
||||||
unsafe::reinterpret_cast(frame_pointer)
|
reinterpret_cast(frame_pointer)
|
||||||
};
|
};
|
||||||
visit(frame(frame_address));
|
loop {
|
||||||
|
let frame = frame(frame_address);
|
||||||
|
|
||||||
|
#debug("frame: %x", unsafe { reinterpret_cast(frame.fp) });
|
||||||
|
visit(frame);
|
||||||
|
|
||||||
|
unsafe {
|
||||||
|
let next_fp: **word = reinterpret_cast(frame_address);
|
||||||
|
frame_address = *next_fp;
|
||||||
|
if *frame_address == 0u {
|
||||||
|
#debug("encountered task_start_wrapper. ending walk");
|
||||||
|
// This is the task_start_wrapper_frame. There is
|
||||||
|
// no stack beneath it and it is a native frame.
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test() {
|
fn test_simple() {
|
||||||
for walk_stack { |frame|
|
for walk_stack { |frame|
|
||||||
#debug("frame: %x", frame.fp);
|
|
||||||
// breakpoint();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_simple_deep() {
|
||||||
|
fn run(i: int) {
|
||||||
|
if i == 0 { ret }
|
||||||
|
|
||||||
|
for walk_stack { |frame|
|
||||||
|
unsafe {
|
||||||
|
breakpoint();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
run(i - 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
run(10);
|
||||||
|
}
|
||||||
|
|
||||||
fn breakpoint() {
|
fn breakpoint() {
|
||||||
rustrt::rust_dbg_breakpoint()
|
rustrt::rust_dbg_breakpoint()
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user