diff options
| author | Patrick Walton <pcwalton@mimiga.net> | 2011-09-23 11:42:20 -0700 |
|---|---|---|
| committer | Patrick Walton <pcwalton@mimiga.net> | 2011-09-23 11:42:20 -0700 |
| commit | 61afef29a186513570bcbe4f6dfa635e31d8a610 (patch) | |
| tree | 7fc02dfa6a72410392a04717098186455c72eb9f /src/rt/rust_debug.cpp | |
| parent | dbdeff659fb30fd845490cf215b5733e1e064d46 (diff) | |
| download | rust-61afef29a186513570bcbe4f6dfa635e31d8a610.tar.gz rust-61afef29a186513570bcbe4f6dfa635e31d8a610.zip | |
rt: Add a RUST_TRACK_ORIGINS debug flag to help track down memory corruption
Diffstat (limited to 'src/rt/rust_debug.cpp')
| -rw-r--r-- | src/rt/rust_debug.cpp | 70 |
1 files changed, 70 insertions, 0 deletions
diff --git a/src/rt/rust_debug.cpp b/src/rt/rust_debug.cpp new file mode 100644 index 00000000000..697f9f13bbc --- /dev/null +++ b/src/rt/rust_debug.cpp @@ -0,0 +1,70 @@ +// Routines useful when debugging the Rust runtime. + +#include "rust_debug.h" +#include "rust_internal.h" + +#include <iostream> +#include <string> +#include <sstream> +#include <stdint.h> + +#if defined(__APPLE__) || defined(__linux__) +#define HAVE_BACKTRACE +#include <execinfo.h> +#elif defined(_WIN32) +#include <windows.h> +#endif + +namespace { + +debug::flag track_origins("RUST_TRACK_ORIGINS"); + +} // end anonymous namespace + +namespace debug { + +std::string +backtrace() { + void *call_stack[256]; + int n_frames = ::backtrace(call_stack, 256); + char **syms = backtrace_symbols(call_stack, n_frames); + + std::stringstream ss; + for (int i = 0; i < n_frames; i++) + ss << syms[i] << std::endl; + + free(syms); + + return ss.str(); +} + +void +maybe_track_origin(rust_task *task, void *ptr) { + if (!*track_origins) + return; + task->debug.origins[ptr] = backtrace(); +} + +void +maybe_untrack_origin(rust_task *task, void *ptr) { + if (!*track_origins) + return; + task->debug.origins.erase(ptr); +} + +// This function is intended to be called by the debugger. +void +dump_origin(rust_task *task, void *ptr) { + if (!*track_origins) { + std::cerr << "Try again with RUST_TRACK_ORIGINS=1." << std::endl; + } else if (task->debug.origins.find(ptr) == task->debug.origins.end()) { + std::cerr << "Pointer " << std::hex << (uintptr_t)ptr << + " does not have a tracked origin."; + } else { + std::cerr << "Origin of pointer " << std::hex << ":" << std::endl << + task->debug.origins[ptr]; + } +} + +} // end namespace debug + |
