Skip to content

Commit 0623fb5

Browse files
committed
Add debug printouts to malloc/annihilation. These should get compiled
out unless you explicitly enable them when compiling.
1 parent 3290110 commit 0623fb5

File tree

2 files changed

+52
-4
lines changed

2 files changed

+52
-4
lines changed

src/libcore/cleanup.rs

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -159,7 +159,7 @@ fn debug_mem() -> bool {
159159
#[cfg(notest)]
160160
#[lang="annihilate"]
161161
pub unsafe fn annihilate() {
162-
use unstable::lang::local_free;
162+
use unstable::lang::{local_free, debug_ptr};
163163
use io::WriterUtil;
164164
use io;
165165
use libc;
@@ -176,24 +176,31 @@ pub unsafe fn annihilate() {
176176
for each_live_alloc |box, uniq| {
177177
stats.n_total_boxes += 1;
178178
if uniq {
179+
debug_ptr("Managed-uniq: ", &*box);
179180
stats.n_unique_boxes += 1;
180181
} else {
182+
debug_ptr("Immortalizing: ", &*box);
181183
(*box).header.ref_count = managed::raw::RC_IMMORTAL;
182184
}
183185
}
184186

185187
// Pass 2: Drop all boxes.
186188
for each_live_alloc |box, uniq| {
187189
if !uniq {
190+
debug_ptr("Invoking tydesc/glue on: ", &*box);
188191
let tydesc: *TypeDesc = transmute(copy (*box).header.type_desc);
189192
let drop_glue: DropGlue = transmute(((*tydesc).drop_glue, 0));
193+
debug_ptr("Box data: ", &(*box).data);
194+
debug_ptr("Type descriptor: ", tydesc);
190195
drop_glue(to_unsafe_ptr(&tydesc), transmute(&(*box).data));
196+
debug_ptr("Dropped ", &*box);
191197
}
192198
}
193199

194200
// Pass 3: Free all boxes.
195201
for each_live_alloc |box, uniq| {
196202
if !uniq {
203+
debug_ptr("About to free: ", &*box);
197204
stats.n_bytes_freed +=
198205
(*((*box).header.type_desc)).size
199206
+ sys::size_of::<BoxRepr>();

src/libcore/unstable/lang.rs

Lines changed: 44 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
//! Runtime calls emitted by the compiler.
1212
1313
use cast::transmute;
14-
use libc::{c_char, c_uchar, c_void, size_t, uintptr_t, c_int};
14+
use libc::{c_char, c_uchar, c_void, size_t, uintptr_t, c_int, STDERR_FILENO};
1515
use managed::raw::BoxRepr;
1616
use str;
1717
use sys;
@@ -74,7 +74,44 @@ pub fn fail_borrowed() {
7474
#[lang="exchange_malloc"]
7575
#[inline(always)]
7676
pub unsafe fn exchange_malloc(td: *c_char, size: uintptr_t) -> *c_char {
77-
transmute(exchange_alloc::malloc(transmute(td), transmute(size)))
77+
let result = transmute(exchange_alloc::malloc(transmute(td), transmute(size)));
78+
debug_ptr("exchange_malloc: ", result);
79+
return result;
80+
}
81+
82+
/// Because this code is so perf. sensitive, use a static constant so that
83+
/// debug printouts are compiled out most of the time.
84+
static ENABLE_DEBUG_PTR: bool = false;
85+
86+
#[inline]
87+
pub fn debug_ptr<T>(tag: &'static str, p: *T) {
88+
//! A useful debugging function that prints a pointer + tag + newline
89+
//! without allocating memory.
90+
91+
if ENABLE_DEBUG_PTR && ::rt::env::get().debug_mem {
92+
debug_ptr_slow(tag, p);
93+
}
94+
95+
fn debug_ptr_slow<T>(tag: &'static str, p: *T) {
96+
use io;
97+
let dbg = STDERR_FILENO as io::fd_t;
98+
let letters = ['0', '1', '2', '3', '4', '5', '6', '7', '8',
99+
'9', 'a', 'b', 'c', 'd', 'e', 'f'];
100+
dbg.write_str(tag);
101+
102+
static uint_nibbles: uint = ::uint::bytes << 1;
103+
let mut buffer = [0_u8, ..uint_nibbles+1];
104+
let mut i = p as uint;
105+
let mut c = uint_nibbles;
106+
while c > 0 {
107+
c -= 1;
108+
buffer[c] = letters[i & 0xF] as u8;
109+
i >>= 4;
110+
}
111+
dbg.write(buffer.slice(0, uint_nibbles));
112+
113+
dbg.write_str("\n");
114+
}
78115
}
79116

80117
// NB: Calls to free CANNOT be allowed to fail, as throwing an exception from
@@ -83,13 +120,16 @@ pub unsafe fn exchange_malloc(td: *c_char, size: uintptr_t) -> *c_char {
83120
#[lang="exchange_free"]
84121
#[inline(always)]
85122
pub unsafe fn exchange_free(ptr: *c_char) {
123+
debug_ptr("exchange_free: ", ptr);
86124
exchange_alloc::free(transmute(ptr))
87125
}
88126

89127
#[lang="malloc"]
90128
#[inline(always)]
91129
pub unsafe fn local_malloc(td: *c_char, size: uintptr_t) -> *c_char {
92-
return rustrt::rust_upcall_malloc_noswitch(td, size);
130+
let result = rustrt::rust_upcall_malloc_noswitch(td, size);
131+
debug_ptr("local_malloc: ", result);
132+
return result;
93133
}
94134

95135
// NB: Calls to free CANNOT be allowed to fail, as throwing an exception from
@@ -98,6 +138,7 @@ pub unsafe fn local_malloc(td: *c_char, size: uintptr_t) -> *c_char {
98138
#[lang="free"]
99139
#[inline(always)]
100140
pub unsafe fn local_free(ptr: *c_char) {
141+
debug_ptr("local_free: ", ptr);
101142
rustrt::rust_upcall_free_noswitch(ptr);
102143
}
103144

0 commit comments

Comments
 (0)