diff options
| author | Patrick Walton <pcwalton@mimiga.net> | 2011-09-23 15:05:24 -0700 |
|---|---|---|
| committer | Patrick Walton <pcwalton@mimiga.net> | 2011-09-23 15:06:28 -0700 |
| commit | 557d641175c505d34bf3eac194597d1d2fc3a494 (patch) | |
| tree | 3682443763943603f4afc8c52e166d313475ce19 /src/rt | |
| parent | 7b1a3bb8e6296541f0200e42d54a77363709a9bd (diff) | |
rt: Get RUST_TRACK_ORIGINS working. You can now call 'debug::dump_origin' in gdb and get a backtrace saying where a box came from.
Diffstat (limited to 'src/rt')
| -rw-r--r-- | src/rt/rust_abi.cpp | 44 | ||||
| -rw-r--r-- | src/rt/rust_abi.h | 4 | ||||
| -rw-r--r-- | src/rt/rust_debug.cpp | 38 |
3 files changed, 51 insertions, 35 deletions
diff --git a/src/rt/rust_abi.cpp b/src/rt/rust_abi.cpp index 2a08a25a9fa..3fba1ada3f3 100644 --- a/src/rt/rust_abi.cpp +++ b/src/rt/rust_abi.cpp @@ -1,10 +1,19 @@ // ABI-specific routines. +#include <sstream> +#include <string> #include <vector> #include <cstdlib> #include <stdint.h> #include "rust_abi.h" +#if defined(__APPLE__) || defined(__linux__) +#define HAVE_DLFCN_H +#include <dlfcn.h> +#elif defined(_WIN32) +// TODO +#endif + #define END_OF_STACK_RA (void (*)())0xdeadbeef weak_symbol<uint32_t> abi_version("rust_abi_version"); @@ -15,6 +24,29 @@ uint32_t get_abi_version() { namespace stack_walk { +#ifdef HAVE_DLFCN_H +std::string +frame::symbol() const { + std::stringstream ss; + + Dl_info info; + if (!dladdr((void *)ra, &info)) + ss << "??"; + else + ss << info.dli_sname; + + ss << " @ " << std::hex << (uintptr_t)ra; + return ss.str(); +} +#else +std::string +frame::symbol() { + std::stringstream ss; + ss << std::hex << (uintptr_t)ra; + return ss.str(); +} +#endif + std::vector<frame> backtrace() { std::vector<frame> frames; @@ -31,5 +63,17 @@ backtrace() { return frames; } +std::string +symbolicate(const std::vector<frame> &frames) { + std::stringstream ss; + std::vector<frame>::const_iterator begin(frames.begin()), + end(frames.end()); + while (begin != end) { + ss << begin->symbol() << std::endl; + ++begin; + } + return ss.str(); +} + } // end namespace stack_walk diff --git a/src/rt/rust_abi.h b/src/rt/rust_abi.h index 884eed4b717..c533d372b72 100644 --- a/src/rt/rust_abi.h +++ b/src/rt/rust_abi.h @@ -4,6 +4,7 @@ #define RUST_ABI_H #include <cstdlib> +#include <string> #include <vector> #ifdef __WIN32__ @@ -51,9 +52,12 @@ struct frame { ra = *(void (**)())(bp + sizeof(void *)); bp = *(uint8_t **)bp; } + + std::string symbol() const; }; std::vector<frame> backtrace(); +std::string symbolicate(const std::vector<frame> &frames); } // end namespace stack_walk diff --git a/src/rt/rust_debug.cpp b/src/rt/rust_debug.cpp index 7bb80a4f36e..9591d9ade07 100644 --- a/src/rt/rust_debug.cpp +++ b/src/rt/rust_debug.cpp @@ -1,5 +1,6 @@ // Routines useful when debugging the Rust runtime. +#include "rust_abi.h" #include "rust_debug.h" #include "rust_internal.h" @@ -8,13 +9,6 @@ #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"); @@ -23,38 +17,12 @@ debug::flag track_origins("RUST_TRACK_ORIGINS"); namespace debug { -#ifdef HAVE_BACKTRACE -std::string -backtrace() { - void *call_stack[128]; - int n_frames = ::backtrace(call_stack, 128); - char **syms = backtrace_symbols(call_stack, n_frames); - - std::cerr << "n_frames: " << n_frames << std::endl; - - std::stringstream ss; - for (int i = 0; i < n_frames; i++) { - std::cerr << syms[i] << std::endl; - ss << syms[i] << std::endl; - } - - free(syms); - - return ss.str(); -} -#else -std::string -backtrace() { - std::string s; - return s; -} -#endif - void maybe_track_origin(rust_task *task, void *ptr) { if (!*track_origins) return; - task->debug.origins[ptr] = backtrace(); + task->debug.origins[ptr] = + stack_walk::symbolicate(stack_walk::backtrace()); } void |
