Add std.dbg module for inspecting rust values in memory.
This commit is contained in:
parent
2dc3a37f93
commit
d9e3fb2c5d
42
src/lib/dbg.rs
Normal file
42
src/lib/dbg.rs
Normal file
@ -0,0 +1,42 @@
|
||||
/**
|
||||
* Unsafe debugging functions for inspecting values.
|
||||
*/
|
||||
|
||||
import std._vec;
|
||||
|
||||
native "rust" mod rustrt {
|
||||
fn debug_tydesc[T]();
|
||||
fn debug_opaque[T](&T x);
|
||||
fn debug_box[T](@T x);
|
||||
fn debug_tag[T](&T x);
|
||||
fn debug_obj[T](&T x, uint nmethods);
|
||||
fn debug_fn[T](&T x);
|
||||
}
|
||||
|
||||
fn debug_vec[T](vec[T] v) {
|
||||
_vec.print_debug_info[T](v);
|
||||
}
|
||||
|
||||
fn debug_tydesc[T]() {
|
||||
rustrt.debug_tydesc[T]();
|
||||
}
|
||||
|
||||
fn debug_opaque[T](&T x) {
|
||||
rustrt.debug_opaque[T](x);
|
||||
}
|
||||
|
||||
fn debug_box[T](@T x) {
|
||||
rustrt.debug_box[T](x);
|
||||
}
|
||||
|
||||
fn debug_tag[T](&T x) {
|
||||
rustrt.debug_tag[T](x);
|
||||
}
|
||||
|
||||
fn debug_obj[T](&T x, uint nmethods) {
|
||||
rustrt.debug_obj[T](x, nmethods);
|
||||
}
|
||||
|
||||
fn debug_fn[T](&T x) {
|
||||
rustrt.debug_fn[T](x);
|
||||
}
|
@ -29,6 +29,8 @@ auth _str = unsafe;
|
||||
auth _vec = unsafe;
|
||||
auth _task = unsafe;
|
||||
|
||||
auth dbg = unsafe;
|
||||
|
||||
auth _uint.next_power_of_two = unsafe;
|
||||
auth map.mk_hashmap = unsafe;
|
||||
auth rand.mk_rng = unsafe;
|
||||
@ -48,3 +50,4 @@ alt (target_os) {
|
||||
mod map;
|
||||
mod deque;
|
||||
mod rand;
|
||||
mod dbg;
|
||||
|
@ -235,6 +235,106 @@ task_sleep(rust_task *task, size_t time_in_us) {
|
||||
upcall_sleep(task, time_in_us);
|
||||
}
|
||||
|
||||
/* Debug builtins for std.dbg. */
|
||||
|
||||
static void
|
||||
debug_tydesc_helper(rust_task *task, type_desc *t)
|
||||
{
|
||||
task->log(rust_log::STDLIB,
|
||||
" size %" PRIdPTR ", align %" PRIdPTR
|
||||
", stateful %" PRIdPTR ", first_param 0x%" PRIxPTR,
|
||||
t->size, t->align, t->is_stateful, t->first_param);
|
||||
}
|
||||
|
||||
extern "C" CDECL void
|
||||
debug_tydesc(rust_task *task, type_desc *t)
|
||||
{
|
||||
task->log(rust_log::STDLIB, "debug_tydesc");
|
||||
debug_tydesc_helper(task, t);
|
||||
}
|
||||
|
||||
extern "C" CDECL void
|
||||
debug_opaque(rust_task *task, type_desc *t, uint8_t *front)
|
||||
{
|
||||
task->log(rust_log::STDLIB, "debug_opaque");
|
||||
debug_tydesc_helper(task, t);
|
||||
// FIXME may want to actually account for alignment. `front` may not
|
||||
// indeed be the front byte of the passed-in argument.
|
||||
for (uintptr_t i = 0; i < t->size; ++front, ++i) {
|
||||
task->log(rust_log::STDLIB,
|
||||
" byte %" PRIdPTR ": 0x%" PRIx8, i, *front);
|
||||
}
|
||||
}
|
||||
|
||||
struct rust_box : rc_base<rust_box> {
|
||||
// FIXME `data` could be aligned differently from the actual box body data
|
||||
uint8_t data[];
|
||||
};
|
||||
|
||||
extern "C" CDECL void
|
||||
debug_box(rust_task *task, type_desc *t, rust_box *box)
|
||||
{
|
||||
task->log(rust_log::STDLIB, "debug_box(0x%" PRIxPTR ")", box);
|
||||
debug_tydesc_helper(task, t);
|
||||
task->log(rust_log::STDLIB, " refcount %" PRIdPTR,
|
||||
box->ref_count - 1); // -1 because we ref'ed for this call
|
||||
for (uintptr_t i = 0; i < t->size; ++i) {
|
||||
task->log(rust_log::STDLIB,
|
||||
" byte %" PRIdPTR ": 0x%" PRIx8, i, box->data[i]);
|
||||
}
|
||||
}
|
||||
|
||||
struct rust_tag {
|
||||
uintptr_t discriminant;
|
||||
uint8_t variant[];
|
||||
};
|
||||
|
||||
extern "C" CDECL void
|
||||
debug_tag(rust_task *task, type_desc *t, rust_tag *tag)
|
||||
{
|
||||
task->log(rust_log::STDLIB, "debug_tag");
|
||||
debug_tydesc_helper(task, t);
|
||||
task->log(rust_log::STDLIB,
|
||||
" discriminant %" PRIdPTR, tag->discriminant);
|
||||
|
||||
for (uintptr_t i = 0; i < t->size - sizeof(tag->discriminant); ++i)
|
||||
task->log(rust_log::STDLIB,
|
||||
" byte %" PRIdPTR ": 0x%" PRIx8, i, tag->variant[i]);
|
||||
}
|
||||
|
||||
struct rust_obj {
|
||||
uintptr_t *vtbl;
|
||||
rust_box *body;
|
||||
};
|
||||
|
||||
extern "C" CDECL void
|
||||
debug_obj(rust_task *task, type_desc *t, rust_obj *obj, size_t nmethods)
|
||||
{
|
||||
task->log(rust_log::STDLIB,
|
||||
"debug_obj with %" PRIdPTR " methods", nmethods);
|
||||
debug_tydesc_helper(task, t);
|
||||
task->log(rust_log::STDLIB, " vtbl at 0x%" PRIxPTR, obj->vtbl);
|
||||
task->log(rust_log::STDLIB, " body at 0x%" PRIxPTR, obj->body);
|
||||
|
||||
for (uintptr_t *p = obj->vtbl; p < obj->vtbl + nmethods; ++p)
|
||||
task->log(rust_log::STDLIB, " vtbl word: 0x%" PRIxPTR, *p);
|
||||
}
|
||||
|
||||
struct rust_fn {
|
||||
uintptr_t *thunk;
|
||||
rust_box *closure;
|
||||
};
|
||||
|
||||
extern "C" CDECL void
|
||||
debug_fn(rust_task *task, type_desc *t, rust_fn *fn)
|
||||
{
|
||||
task->log(rust_log::STDLIB, "debug_fn");
|
||||
debug_tydesc_helper(task, t);
|
||||
task->log(rust_log::STDLIB, " thunk at 0x%" PRIxPTR, fn->thunk);
|
||||
task->log(rust_log::STDLIB, " closure at 0x%" PRIxPTR, fn->closure);
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// Local Variables:
|
||||
// mode: C++
|
||||
|
Loading…
x
Reference in New Issue
Block a user