core: Start on a stack walker
This commit is contained in:
parent
231097960c
commit
5f4837ad6a
|
@ -201,7 +201,7 @@ mod extfmt;
|
|||
mod unicode;
|
||||
mod priv;
|
||||
mod cmath;
|
||||
|
||||
mod stackwalk;
|
||||
|
||||
// Local Variables:
|
||||
// mode: rust;
|
||||
|
|
|
@ -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" {
|
||||
let frameaddress = ccx.intrinsics.get("llvm.frameaddress");
|
||||
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);
|
||||
|
|
|
@ -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))
|
||||
}
|
||||
"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 {
|
||||
tcx.sess.span_err(it.span, "unrecognized intrinsic function: `" +
|
||||
|
|
|
@ -1,8 +1,10 @@
|
|||
#[abi = "rust-intrinsic"]
|
||||
native mod rusti {
|
||||
fn frame_address() -> *u8;
|
||||
fn frame_address(f: fn(*u8));
|
||||
}
|
||||
|
||||
fn main() {
|
||||
assert rusti::frame_address().is_not_null();
|
||||
rusti::frame_address {|addr|
|
||||
assert addr.is_not_null();
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue