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.
This commit is contained in:
parent
a04117f955
commit
2760a0a7aa
2
build.rs
2
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"]);
|
||||
}
|
||||
|
|
|
@ -1,9 +1,11 @@
|
|||
use core::prelude::*;
|
||||
use arch::Registers;
|
||||
use stack;
|
||||
use debug::StackId;
|
||||
|
||||
pub struct Context<Stack: stack::Stack> {
|
||||
regs: Registers,
|
||||
_stack_id: StackId,
|
||||
stack: Stack
|
||||
}
|
||||
|
||||
|
@ -11,9 +13,11 @@ impl<Stack> Context<Stack> where Stack: stack::Stack {
|
|||
#[inline]
|
||||
pub unsafe fn new<F>(mut stack: Stack, f: F) -> Context<Stack>
|
||||
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
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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: stack::Stack>(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)
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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.
|
|
@ -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;
|
||||
|
|
11
src/os.rs
11
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())
|
||||
|
|
Loading…
Reference in New Issue