diff options
| author | Brian Anderson <banderson@mozilla.com> | 2012-06-11 22:44:55 -0700 |
|---|---|---|
| committer | Brian Anderson <banderson@mozilla.com> | 2012-06-11 22:44:55 -0700 |
| commit | 07bba397c5b46c96cfb8de23c34b9bae47e07947 (patch) | |
| tree | 1badf71f2fed70f1080d41cf156ee7cb2111e7e8 | |
| parent | 41df9cbb448ab7b4fd352d64776cdfd02ed83a56 (diff) | |
| download | rust-07bba397c5b46c96cfb8de23c34b9bae47e07947.tar.gz rust-07bba397c5b46c96cfb8de23c34b9bae47e07947.zip | |
core: More stack walking
| -rw-r--r-- | src/libcore/stackwalk.rs | 57 |
1 files changed, 48 insertions, 9 deletions
diff --git a/src/libcore/stackwalk.rs b/src/libcore/stackwalk.rs index 6900509f213..321fa605f48 100644 --- a/src/libcore/stackwalk.rs +++ b/src/libcore/stackwalk.rs @@ -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 { - let fp: uintptr_t; + let fp: *word; - new(fp: uintptr_t) { + new(fp: *word) { self.fp = fp; } } fn walk_stack(visit: fn(frame) -> bool) { + + #debug("beginning stack walk"); + frame_address { |frame_pointer| - let frame_address = unsafe { - unsafe::reinterpret_cast(frame_pointer) + let mut frame_address: *word = unsafe { + 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] -fn test() { +fn test_simple() { 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() { rustrt::rust_dbg_breakpoint() } |
