From 2760a0a7aa145d606c01f5406e56ef39724d0f5e Mon Sep 17 00:00:00 2001 From: edef Date: Thu, 16 Apr 2015 02:30:10 -0400 Subject: [PATCH] move Valgrind handling into Context fix #3 This takes all Valgrind functionality private again. Valgrind stack registrations are now associated with a Context, not with a Stack. This makes sense, since it's only actually a stack when a Context is running on it. Perhaps Valgrind will even be able to detect early stack frees now. --- build.rs | 2 +- src/context.rs | 4 ++++ src/debug/mod.rs | 24 ++++++++++++++++++++++++ src/{ => debug}/valgrind.c | 0 src/{ => debug}/valgrind.rs | 5 ----- src/lib.rs | 3 ++- src/os.rs | 11 ++--------- 7 files changed, 33 insertions(+), 16 deletions(-) create mode 100644 src/debug/mod.rs rename src/{ => debug}/valgrind.c (100%) rename src/{ => debug}/valgrind.rs (78%) diff --git a/build.rs b/build.rs index d7a9096..7fb9751 100644 --- a/build.rs +++ b/build.rs @@ -1,5 +1,5 @@ extern crate gcc; fn main() { - gcc::compile_library("libvalgrind.a", &["src/valgrind.c"]); + gcc::compile_library("libvalgrind.a", &["src/debug/valgrind.c"]); } diff --git a/src/context.rs b/src/context.rs index 51362fb..ffb6dc5 100644 --- a/src/context.rs +++ b/src/context.rs @@ -1,9 +1,11 @@ use core::prelude::*; use arch::Registers; use stack; +use debug::StackId; pub struct Context { regs: Registers, + _stack_id: StackId, stack: Stack } @@ -11,9 +13,11 @@ impl Context where Stack: stack::Stack { #[inline] pub unsafe fn new(mut stack: Stack, f: F) -> Context where F: FnOnce() + Send + 'static { + let stack_id = StackId::register(&mut stack); let regs = Registers::new(&mut stack, f); Context { regs: regs, + _stack_id: stack_id, stack: stack } } diff --git a/src/debug/mod.rs b/src/debug/mod.rs new file mode 100644 index 0000000..9e34b2d --- /dev/null +++ b/src/debug/mod.rs @@ -0,0 +1,24 @@ +use core::prelude::*; +use stack; + +mod valgrind; + +pub struct StackId(valgrind::stack_id_t); + +impl StackId { + #[inline(always)] + pub fn register(stack: &mut Stack) -> StackId { + StackId(unsafe { + valgrind::stack_register(stack.limit(), stack.top()) + }) + } +} + +impl Drop for StackId { + #[inline(always)] + fn drop(&mut self) { + unsafe { + valgrind::stack_deregister(self.0) + } + } +} diff --git a/src/valgrind.c b/src/debug/valgrind.c similarity index 100% rename from src/valgrind.c rename to src/debug/valgrind.c diff --git a/src/valgrind.rs b/src/debug/valgrind.rs similarity index 78% rename from src/valgrind.rs rename to src/debug/valgrind.rs index 37848ff..add3929 100644 --- a/src/valgrind.rs +++ b/src/debug/valgrind.rs @@ -12,11 +12,6 @@ extern "C" { /// `start < end`. pub fn stack_register(start: *const u8, end: *const u8) -> stack_id_t; - #[link_name = "valgrind_stack_change"] - /// Change the size or location of a stack registered with Valgrind. - /// `start < end`. - pub fn stack_change(id: stack_id_t, start: *const u8, end: *const u8) -> stack_id_t; - #[link_name = "valgrind_stack_deregister"] /// Deregister a stack from Valgrind. Takes the integer ID that was returned /// on registration. diff --git a/src/lib.rs b/src/lib.rs index f2fdacb..ae117ea 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -18,7 +18,8 @@ mod std { pub use core::*; } pub mod context; pub mod stack; -pub mod valgrind; + +mod debug; #[cfg(target_arch = "x86_64")] mod arch; diff --git a/src/os.rs b/src/os.rs index 2785db0..a2c416c 100644 --- a/src/os.rs +++ b/src/os.rs @@ -2,7 +2,6 @@ extern crate std; use core::prelude::*; use self::std::io::Error as IoError; use stack; -use valgrind; #[cfg(unix)] #[path = "os/unix.rs"] mod sys; @@ -11,8 +10,7 @@ use valgrind; #[derive(Debug)] pub struct Stack { ptr: *mut u8, - len: usize, - valgrind_id: valgrind::stack_id_t + len: usize } pub struct StackSource; @@ -55,11 +53,7 @@ impl Stack { Some(ptr) => ptr }; - let valgrind_id = - valgrind::stack_register(ptr as *const _, - ptr.offset(len as isize) as *const _); - - Stack { ptr: ptr as *mut u8, len: len, valgrind_id: valgrind_id } + Stack { ptr: ptr as *mut u8, len: len } }; unsafe { @@ -76,7 +70,6 @@ impl Stack { impl Drop for Stack { fn drop(&mut self) { unsafe { - valgrind::stack_deregister(self.valgrind_id); if !sys::unmap_stack(self.ptr, self.len) { panic!("munmap for stack {:p} of size {} failed: {}", self.ptr, self.len, IoError::last_os_error())