1
Fork 0

Add a huge hack to allow the test runner to continue if a single task leaks

This is just until unwinding works. Adds a flag to the runtime to turn
the memory leak checks on task destruction into warnings instead of fatal
errors. I am so sorry.

Issue #428
This commit is contained in:
Brian Anderson 2011-07-19 23:33:37 -07:00
parent 3fb33008ce
commit a467e8e4e6
5 changed files with 39 additions and 1 deletions

View file

@ -227,12 +227,26 @@ fn run_test(&test_desc test) -> test_result {
} }
} }
native "rust" mod rustrt {
fn hack_allow_leaks();
}
// We need to run our tests in another task in order to trap test failures. // We need to run our tests in another task in order to trap test failures.
// But, at least currently, functions can't be used as spawn arguments so // But, at least currently, functions can't be used as spawn arguments so
// we've got to treat our test functions as unsafe pointers. // we've got to treat our test functions as unsafe pointers.
fn run_test_fn_in_task(&fn() f) -> bool { fn run_test_fn_in_task(&fn() f) -> bool {
fn run_task(*mutable fn() fptr) { fn run_task(*mutable fn() fptr) {
// If this task fails we don't want that failure to propagate to the
// test runner or else we couldn't keep running tests
task::unsupervise(); task::unsupervise();
// FIXME (236): Hack supreme - unwinding doesn't work yet so if this
// task fails memory will not be freed correctly. This turns off the
// sanity checks in the runtime's memory region for the task, so that
// the test runner can continue.
rustrt::hack_allow_leaks();
// Run the test
(*fptr)() (*fptr)()
} }
auto fptr = ptr::addr_of(f); auto fptr = ptr::addr_of(f);

View file

@ -152,10 +152,21 @@ memory_region::~memory_region() {
} }
} }
#endif #endif
_srv->fatal(msg, __FILE__, __LINE__, "%d objects", _live_allocations); if (!_hack_allow_leaks) {
_srv->fatal(msg, __FILE__, __LINE__,
"%d objects", _live_allocations);
} else {
_srv->warning(msg, __FILE__, __LINE__,
"%d objects", _live_allocations);
}
if (_synchronized) { _lock.unlock(); } if (_synchronized) { _lock.unlock(); }
} }
void
memory_region::hack_allow_leaks() {
_hack_allow_leaks = true;
}
// //
// Local Variables: // Local Variables:
// mode: C++ // mode: C++

View file

@ -22,6 +22,7 @@ private:
const bool _detailed_leaks; const bool _detailed_leaks;
const bool _synchronized; const bool _synchronized;
lock_and_signal _lock; lock_and_signal _lock;
bool _hack_allow_leaks;
void add_alloc(); void add_alloc();
void dec_alloc(); void dec_alloc();
@ -33,6 +34,10 @@ public:
void *realloc(void *mem, size_t size); void *realloc(void *mem, size_t size);
void free(void *mem); void free(void *mem);
virtual ~memory_region(); virtual ~memory_region();
// FIXME (236: This is a temporary hack to allow failing tasks that leak
// to not kill the entire process, which the test runner needs. Please
// kill with prejudice once unwinding works.
void hack_allow_leaks();
}; };
inline void *operator new(size_t size, memory_region &region) { inline void *operator new(size_t size, memory_region &region) {

View file

@ -459,6 +459,13 @@ debug_opaque(rust_task *task, type_desc *t, uint8_t *front)
} }
} }
extern "C" CDECL void
hack_allow_leaks(rust_task *task)
{
LOG(task, stdlib, "hack_allow_leaks");
task->local_region.hack_allow_leaks();
}
struct rust_box { struct rust_box {
RUST_REFCOUNTED(rust_box) RUST_REFCOUNTED(rust_box)

View file

@ -10,6 +10,7 @@ debug_trap
debug_tydesc debug_tydesc
do_gc do_gc
get_time get_time
hack_allow_leaks
ivec_copy_from_buf ivec_copy_from_buf
ivec_copy_from_buf_shared ivec_copy_from_buf_shared
ivec_on_heap ivec_on_heap