Implement a --backtrace-all option for winedbg (take 3)

Mike Hearn mh at codeweavers.com
Fri Jun 11 14:46:49 CDT 2004


OK, I suck. I should not forget to check *all* the error paths when
fixing a leak. Sorry :(

Mike Hearn <mh at codeweavers.com>
Implement a --backtrace-all mode for winedbg which backtraces 
every thread in every process (except winedbg itself).

Index: programs/winedbg/stack.c
===================================================================
RCS file: /home/wine/wine/programs/winedbg/stack.c,v
retrieving revision 1.3
diff -u -p -r1.3 stack.c
--- programs/winedbg/stack.c	4 Jun 2004 00:59:16 -0000	1.3
+++ programs/winedbg/stack.c	11 Jun 2004 19:46:02 -0000
@@ -135,7 +135,7 @@ void stack_backtrace(DWORD tid, BOOL noi
     memory_get_current_frame(&sf.AddrFrame);
     memory_get_current_pc(&sf.AddrPC);
 
-    if (noisy) dbg_printf("Backtrace:\n");
+    if (noisy) dbg_printf("Backtrace for thread 0x%lx in process 0x%lx (%s):\n", tid, dbg_curr_pid, dbg_curr_process->imageName);
     while (StackWalk(IMAGE_FILE_MACHINE_I386, dbg_curr_process->handle, 
                      thread->handle, &sf, &ctx, NULL, SymFunctionTableAccess,
                      SymGetModuleBase, NULL))
Index: programs/winedbg/winedbg.c
===================================================================
RCS file: /home/wine/wine/programs/winedbg/winedbg.c,v
retrieving revision 1.20
diff -u -p -r1.20 winedbg.c
--- programs/winedbg/winedbg.c	4 Jun 2004 00:59:16 -0000	1.20
+++ programs/winedbg/winedbg.c	11 Jun 2004 19:46:02 -0000
@@ -26,9 +26,9 @@
 #include "debugger.h"
 
 #include "winternl.h"
+#include "tlhelp32.h"
 #include "wine/exception.h"
 #include "wine/library.h"
-
 #include "wine/debug.h"
 
 /* TODO list:
@@ -82,7 +82,7 @@ static unsigned         dbg_in_exception
 static char*	        dbg_last_cmd_line = NULL;
 
 static struct dbg_process*      dbg_process_list = NULL;
-static enum {none_mode = 0, winedbg_mode, automatic_mode, gdb_mode} dbg_action_mode;
+static enum {none_mode = 0, winedbg_mode, automatic_mode, gdb_mode, backtrace_all_mode} dbg_action_mode;
 
 struct dbg_internal_var         dbg_internal_vars[DBG_IV_LAST];
 const struct dbg_internal_var*  dbg_context_vars;
@@ -433,6 +433,7 @@ BOOL dbg_detach_debuggee(void)
         ContinueDebugEvent(dbg_curr_pid, dbg_curr_tid, DBG_CONTINUE);
     if (!DebugActiveProcessStop(dbg_curr_pid)) return FALSE;
     dbg_del_process(dbg_curr_process);
+    dbg_curr_process = NULL;
 
     return TRUE;
 }
@@ -965,6 +966,47 @@ void dbg_wait_next_exception(DWORD cont,
                dbg_curr_thread->exec_count);
 }
 
+static void dbg_backtrace_all()
+{
+    /* attach to all processes, and backtrace every thread in each process */
+    HANDLE snapshot;
+    THREADENTRY32 entry;
+    BOOL ok;
+    
+    snapshot = CreateToolhelp32Snapshot(TH32CS_SNAPTHREAD, 0);
+    if (snapshot == INVALID_HANDLE_VALUE) {
+        dbg_printf("dbg_backtrace_all: unable to create snapshot\n");
+        return;
+    }
+
+    dbg_printf("Generating system-wide backtrace\n");
+    
+    entry.dwSize = sizeof(entry);
+    ok = Thread32First(snapshot, &entry);
+    while (ok) {
+        /* don't try and backtrace the debugger */
+        if (entry.th32OwnerProcessID == GetCurrentProcessId()) {
+            ok = Thread32Next(snapshot, &entry);
+            continue;
+        }
+        
+        /* detach from current process, if any */
+        if (dbg_curr_process) dbg_detach_debuggee();
+        if ((dbg_curr_pid != entry.th32OwnerProcessID) && !dbg_attach_debuggee(entry.th32OwnerProcessID, FALSE, TRUE)) {
+            dbg_printf("could not attach to 0x%lx, aborting\n", entry.th32OwnerProcessID);
+            goto end;
+        }
+        stack_backtrace(entry.th32ThreadID, TRUE);
+        dbg_printf("\n");
+        ok = Thread32Next(snapshot, &entry);        
+    }
+
+    if (dbg_curr_process) dbg_detach_debuggee();  /* don't terminate the app as we quit */
+    dbg_printf("\nGenerated system-wide backtrace.\n");
+ end:
+    CloseHandle(snapshot);
+}
+
 static	DWORD	dbg_main_loop(void)
 {
     DEBUG_EVENT		de;
@@ -979,6 +1021,9 @@ static	DWORD	dbg_main_loop(void)
     }
     switch (dbg_action_mode)
     {
+    case backtrace_all_mode:
+        dbg_backtrace_all();
+        break;
     case automatic_mode:
         /* print some extra information */
         dbg_printf("Modules:\n");
@@ -1116,6 +1161,13 @@ int main(int argc, char** argv)
         {
             if (dbg_action_mode != none_mode) return dbg_winedbg_usage();
             dbg_action_mode = gdb_mode;
+            argc--; argv++;
+            continue;
+        }
+        if (!strcmp(argv[1], "--backtrace-all"))
+        {
+            if (dbg_action_mode != none_mode) return dbg_winedbg_usage();
+            dbg_action_mode = backtrace_all_mode;
             argc--; argv++;
             continue;
         }



More information about the wine-patches mailing list