Skip to content

Commit 9ef4c41

Browse files
committed
std::rt: Check exchange count on exit
1 parent 3281f5b commit 9ef4c41

File tree

2 files changed

+37
-6
lines changed

2 files changed

+37
-6
lines changed

src/libstd/rt/global_heap.rs

Lines changed: 31 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ use c_malloc = libc::malloc;
1414
use c_free = libc::free;
1515
use managed::raw::{BoxHeaderRepr, BoxRepr};
1616
use cast::transmute;
17-
use unstable::intrinsics::{atomic_xadd,atomic_xsub};
17+
use unstable::intrinsics::{atomic_xadd,atomic_xsub, atomic_load};
1818
use ptr::null;
1919
use intrinsic::TyDesc;
2020

@@ -34,8 +34,7 @@ pub unsafe fn malloc(td: *TypeDesc, size: uint) -> *c_void {
3434
box.header.prev = null();
3535
box.header.next = null();
3636

37-
let exchange_count = &mut *exchange_count_ptr();
38-
atomic_xadd(exchange_count, 1);
37+
inc_count();
3938

4039
return transmute(box);
4140
}
@@ -48,21 +47,47 @@ pub unsafe fn malloc_raw(size: uint) -> *c_void {
4847
if p.is_null() {
4948
fail!("Failure in malloc_raw: result ptr is null");
5049
}
50+
inc_count();
5151
p
5252
}
5353

5454
pub unsafe fn free(ptr: *c_void) {
55-
let exchange_count = &mut *exchange_count_ptr();
56-
atomic_xsub(exchange_count, 1);
57-
5855
assert!(ptr.is_not_null());
56+
dec_count();
5957
c_free(ptr);
6058
}
6159
///Thin wrapper around libc::free, as with exchange_alloc::malloc_raw
6260
pub unsafe fn free_raw(ptr: *c_void) {
61+
assert!(ptr.is_not_null());
62+
dec_count();
6363
c_free(ptr);
6464
}
6565

66+
fn inc_count() {
67+
unsafe {
68+
let exchange_count = &mut *exchange_count_ptr();
69+
atomic_xadd(exchange_count, 1);
70+
}
71+
}
72+
73+
fn dec_count() {
74+
unsafe {
75+
let exchange_count = &mut *exchange_count_ptr();
76+
atomic_xsub(exchange_count, 1);
77+
}
78+
}
79+
80+
pub fn cleanup() {
81+
unsafe {
82+
let count_ptr = exchange_count_ptr();
83+
let allocations = atomic_load(&*count_ptr);
84+
if allocations != 0 {
85+
abort!("exchange heap not empty on exit\
86+
%i dangling allocations", allocations);
87+
}
88+
}
89+
}
90+
6691
fn get_box_size(body_size: uint, body_align: uint) -> uint {
6792
let header_size = size_of::<BoxHeaderRepr>();
6893
// FIXME (#2699): This alignment calculation is suspicious. Is it right?

src/libstd/rt/mod.rs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -176,6 +176,8 @@ pub fn start(_argc: int, _argv: **u8, crate_map: *u8, main: ~fn()) -> int {
176176
sched.enqueue_task(main_task);
177177
sched.run();
178178

179+
cleanup();
180+
179181
return 0;
180182
}
181183

@@ -185,6 +187,10 @@ pub fn init(crate_map: *u8) {
185187
logging::init(crate_map);
186188
}
187189

190+
pub fn cleanup() {
191+
global_heap::cleanup();
192+
}
193+
188194
/// Possible contexts in which Rust code may be executing.
189195
/// Different runtime services are available depending on context.
190196
/// Mostly used for determining if we're using the new scheduler

0 commit comments

Comments
 (0)