diff --git a/run_time_python/explain_error.py b/run_time_python/explain_error.py index 68f9bb9..1d2976b 100644 --- a/run_time_python/explain_error.py +++ b/run_time_python/explain_error.py @@ -11,6 +11,22 @@ def explain_error(output_stream, color): # file descriptor 3 is a dup of stderr (see below) # stdout & stderr have been diverted to /dev/null print(file=output_stream) + + dprint(2, os.environ.get("DCC_ASAN_THREAD")) + if "DCC_ASAN_THREAD" in os.environ: + # gdb's thread numbers start counting at 1 + # asan's thread numbers start counting at 0 + thread_id = int(os.environ.get("DCC_ASAN_THREAD")) + 1 + gdb_interface.gdb_execute(f"thread {thread_id}") + elif "DCC_SIGNAL_THREAD" in os.environ: + # signal gives us the Linux TID, gdb calls this the LWP + threads = gdb_interface.gdb_execute("info threads").split('\n') + lwp = int(os.environ.get("DCC_SIGNAL_THREAD")) + # should only be one thread + thread_entry = [line for line in threads if f"(LWP {lwp})" in line][0] + thread_id = int(thread_entry[2:].split(' ')[0]) + gdb_interface.gdb_execute(f"thread {thread_id}") + stack = parse_stack() location = stack[0] if stack else None signal_number = int(os.environ.get("DCC_SIGNAL", signal.SIGABRT)) diff --git a/wrapper_c/dcc_util.c b/wrapper_c/dcc_util.c index 85f3830..8c4dd8d 100644 --- a/wrapper_c/dcc_util.c +++ b/wrapper_c/dcc_util.c @@ -119,8 +119,17 @@ void __asan_on_error(void) { #if __SANITIZER__ == ADDRESS && __CLANG_VERSION_MAJOR__ >= 6 extern char *__asan_get_report_description(); extern int __asan_report_present(); + extern void *__asan_get_report_address(); + extern size_t __asan_get_alloc_stack(void *, void **, size_t, int *); + // putenv does not copy strings, we need to alloc it outside the if block scope + char thread_env[64]; if (__asan_report_present()) { report = __asan_get_report_description(); + + int thread_id; + __asan_get_alloc_stack(__asan_get_report_address(), NULL, 0, &thread_id); + snprintf(thread_env, sizeof thread_env, "DCC_ASAN_THREAD=%d", thread_id); + putenvd(thread_env); } #endif char report_description[8192]; @@ -238,6 +247,10 @@ static void __dcc_signal_handler(int signum) { putenvd( signum_buffer); // less likely? to trigger another error than direct setenv + char threadid_buffer[64]; + snprintf(threadid_buffer, sizeof threadid_buffer, "DCC_SIGNAL_THREAD=%ld", (long)gettid()); + putenvd(threadid_buffer); + _explain_error(); // not reached }