core: Start on a stack walker
This commit is contained in:
@@ -201,7 +201,7 @@ mod extfmt;
|
|||||||
mod unicode;
|
mod unicode;
|
||||||
mod priv;
|
mod priv;
|
||||||
mod cmath;
|
mod cmath;
|
||||||
|
mod stackwalk;
|
||||||
|
|
||||||
// Local Variables:
|
// Local Variables:
|
||||||
// mode: rust;
|
// mode: rust;
|
||||||
|
|||||||
54
src/libcore/stackwalk.rs
Normal file
54
src/libcore/stackwalk.rs
Normal file
@@ -0,0 +1,54 @@
|
|||||||
|
import libc::uintptr_t;
|
||||||
|
|
||||||
|
class frame {
|
||||||
|
let fp: uintptr_t;
|
||||||
|
|
||||||
|
new(fp: uintptr_t) {
|
||||||
|
self.fp = fp;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn walk_stack(visit: fn(frame) -> bool) {
|
||||||
|
frame_address { |frame_pointer|
|
||||||
|
let frame_address = unsafe {
|
||||||
|
unsafe::reinterpret_cast(frame_pointer)
|
||||||
|
};
|
||||||
|
visit(frame(frame_address));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test() {
|
||||||
|
for walk_stack { |frame|
|
||||||
|
#debug("frame: %x", frame.fp);
|
||||||
|
// breakpoint();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn breakpoint() {
|
||||||
|
rustrt::rust_dbg_breakpoint()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn frame_address(f: fn(*u8)) {
|
||||||
|
rusti::frame_address(f)
|
||||||
|
}
|
||||||
|
|
||||||
|
native mod rustrt {
|
||||||
|
fn rust_dbg_breakpoint();
|
||||||
|
}
|
||||||
|
|
||||||
|
// FIXME: Unconditionalize after snapshot
|
||||||
|
#[cfg(stage1)]
|
||||||
|
#[cfg(stage2)]
|
||||||
|
#[cfg(stage3)]
|
||||||
|
#[abi = "rust-intrinsic"]
|
||||||
|
native mod rusti {
|
||||||
|
fn frame_address(f: fn(*u8));
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(stage0)]
|
||||||
|
mod rusti {
|
||||||
|
fn frame_address(_f: fn(*u8)) {
|
||||||
|
fail;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -875,7 +875,27 @@ fn trans_intrinsic(ccx: @crate_ctxt, decl: ValueRef, item: @ast::native_item,
|
|||||||
"frame_address" {
|
"frame_address" {
|
||||||
let frameaddress = ccx.intrinsics.get("llvm.frameaddress");
|
let frameaddress = ccx.intrinsics.get("llvm.frameaddress");
|
||||||
let frameaddress_val = Call(bcx, frameaddress, [C_i32(0i32)]);
|
let frameaddress_val = Call(bcx, frameaddress, [C_i32(0i32)]);
|
||||||
Store(bcx, frameaddress_val, fcx.llretptr);
|
let fty = ty::mk_fn(bcx.tcx(), {
|
||||||
|
purity: ast::impure_fn,
|
||||||
|
proto: ast::proto_any,
|
||||||
|
inputs: [{
|
||||||
|
mode: ast::expl(ast::by_val),
|
||||||
|
ty: ty::mk_imm_ptr(
|
||||||
|
bcx.tcx(),
|
||||||
|
ty::mk_mach_uint(bcx.tcx(), ast::ty_u8))
|
||||||
|
}],
|
||||||
|
output: ty::mk_nil(bcx.tcx()),
|
||||||
|
ret_style: ast::return_val,
|
||||||
|
constraints: []
|
||||||
|
});
|
||||||
|
bcx = trans_call_inner(bcx, none, fty, ty::mk_nil(bcx.tcx()),
|
||||||
|
{ |bcx|
|
||||||
|
lval_no_env(
|
||||||
|
bcx,
|
||||||
|
get_param(decl, first_real_arg),
|
||||||
|
temporary)
|
||||||
|
},
|
||||||
|
arg_vals([frameaddress_val]), ignore);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
build_return(bcx);
|
build_return(bcx);
|
||||||
|
|||||||
@@ -2318,7 +2318,20 @@ fn check_intrinsic_type(ccx: @crate_ctxt, it: @ast::native_item) {
|
|||||||
(1u, [arg(ast::by_ref, visitor_iface)], ty::mk_nil(tcx))
|
(1u, [arg(ast::by_ref, visitor_iface)], ty::mk_nil(tcx))
|
||||||
}
|
}
|
||||||
"frame_address" {
|
"frame_address" {
|
||||||
(0u, [], ty::mk_imm_ptr(tcx, ty::mk_mach_uint(tcx, ast::ty_u8)))
|
let fty = ty::mk_fn(ccx.tcx, {
|
||||||
|
purity: ast::impure_fn,
|
||||||
|
proto: ast::proto_any,
|
||||||
|
inputs: [{
|
||||||
|
mode: ast::expl(ast::by_val),
|
||||||
|
ty: ty::mk_imm_ptr(
|
||||||
|
ccx.tcx,
|
||||||
|
ty::mk_mach_uint(ccx.tcx, ast::ty_u8))
|
||||||
|
}],
|
||||||
|
output: ty::mk_nil(ccx.tcx),
|
||||||
|
ret_style: ast::return_val,
|
||||||
|
constraints: []
|
||||||
|
});
|
||||||
|
(0u, [arg(ast::by_ref, fty)], ty::mk_nil(tcx))
|
||||||
}
|
}
|
||||||
other {
|
other {
|
||||||
tcx.sess.span_err(it.span, "unrecognized intrinsic function: `" +
|
tcx.sess.span_err(it.span, "unrecognized intrinsic function: `" +
|
||||||
|
|||||||
@@ -1,8 +1,10 @@
|
|||||||
#[abi = "rust-intrinsic"]
|
#[abi = "rust-intrinsic"]
|
||||||
native mod rusti {
|
native mod rusti {
|
||||||
fn frame_address() -> *u8;
|
fn frame_address(f: fn(*u8));
|
||||||
}
|
}
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
assert rusti::frame_address().is_not_null();
|
rusti::frame_address {|addr|
|
||||||
|
assert addr.is_not_null();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user