about summary refs log tree commit diff
path: root/src/rt/rust_debug.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/rt/rust_debug.cpp')
-rw-r--r--src/rt/rust_debug.cpp70
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
+