|
From: | Eric Youngdale |
Subject: | Bug in gdb on Win32. |
Date: | Fri, 12 Dec 2003 18:11:32 -0500 |
I ran across a bug in gdb on Win32 platforms. The problem comes up when a Microsoft-compiled C++ program throws a C++ exception - this manifests itself as a normal exception that is reported as an EXCEPTION_DEBUG_EVENT exception with an exception type of 0xE06D7363. The existing gdb code doesn't know what to do with this exception - I believe it calls
ContinueDebugEvent(..., ..., DBG_CONTINUE);
the problem is that the debugged application crashes at this point. If instead the application is continued with:
ContinueDebugEvent(..., ..., DBG_EXCEPTION_NOT_HANDLED);
then life is good and the application proceeds.
The enclosed diffs are certainly not perfect - in particular, gdb has this inbuilt assumption that a program will only stop because of a signal that is raised in the application, and this C++ exception doesn't map well to a signal.
With my diff this exception is ignored (in the sense that the application proceeds) - in theory one might want to have the debugger stop at this point so that one can see why a C++ exception was being raised in the first place. Thus in the long run I suppose there should be something that the user can configure to turn this on and off, as desired. Then again, debugging Microsoft-compiled C++ code with gdb isn't likely to be very fruitful as the debug symbols that Microsoft generates don't seem to be of much use to gdb.
-Eric
diff -cr orig/gdb-5.1.1/gdb/win32-nat.c gdb-5.1.1/gdb/win32-nat.c
*** orig/gdb-5.1.1/gdb/win32-nat.c Mon Feb 11 16:09:01 2002
--- gdb-5.1.1/gdb/win32-nat.c Sun Dec 7 23:10:22 2003
***************
*** 798,804 ****
}
static int
! handle_exception (struct target_waitstatus *ourstatus)
{
thread_info *th;
DWORD code = current_event.u.Exception.ExceptionRecord.ExceptionCode;
--- 798,804 ----
}
static int
! handle_exception (struct target_waitstatus *ourstatus, DWORD * continue_status)
{
thread_info *th;
DWORD code = current_event.u.Exception.ExceptionRecord.ExceptionCode;
***************
*** 852,857 ****
--- 852,869 ----
ourstatus->value.sig = TARGET_SIGNAL_ILL;
last_sig = SIGILL;
break;
+ case 0xE06D7363:
+ /*
+ * I am not aware of a place where this value is defined in any Microsoft headers,
+ * but this 'magic' number implies a C++ runtime exception (throw()). If you were to
+ * stuff this number in a buffer, 3 characters would be 'msc'.
+ */
+ DEBUG_EXCEPT (("Microsoft C++ exception"));
+ ourstatus->value.sig = TARGET_SIGNAL_UNKNOWN;
+ *continue_status = DBG_EXCEPTION_NOT_HANDLED;
+ last_sig = 0;
+ return 0;
+
default:
if (current_event.u.Exception.dwFirstChance)
return 0;
***************
*** 996,1002 ****
(unsigned) current_event.dwProcessId,
(unsigned) current_event.dwThreadId,
"EXCEPTION_DEBUG_EVENT"));
! if (handle_exception (ourstatus))
retval = current_event.dwThreadId;
break;
--- 1008,1014 ----
(unsigned) current_event.dwProcessId,
(unsigned) current_event.dwThreadId,
"EXCEPTION_DEBUG_EVENT"));
! if (handle_exception (ourstatus, &continue_status))
retval = current_event.dwThreadId;
break;
[Prev in Thread] | Current Thread | [Next in Thread] |