* config/mips/tm-mips64.h (TARGET_LONG_BIT): Allow final target to
[deliverable/binutils-gdb.git] / gdb / win32-nat.c
index 580b13b179f0fdcb5258f111bf3cff06eb8dffe4..be83b7af3e5c0f906bcb1721d4c9055c7a7a1219 100644 (file)
@@ -1,5 +1,5 @@
 /* Target-vector operations for controlling win32 child processes, for GDB.
-   Copyright 1995, 1996 Free Software Foundation, Inc.
+   Copyright 1995, 1996, 1997, 1998 Free Software Foundation, Inc.
    Contributed by Cygnus Support.
 
    This file is part of GDB.
@@ -16,7 +16,8 @@
 
    You should have received a copy of the GNU General Public License
    along with this program; if not, write to the Free Software
-   Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
+   Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+*/
 
 /* by Steve Chamberlain, sac@cygnus.com */
 
 #include <signal.h>
 #include <sys/types.h>
 #include <fcntl.h>
+#include <stdlib.h>
+
+#ifdef _MSC_VER
 #include "windefs.h"
+#else /* other WIN32 compiler */
+#include <windows.h>
+#endif
+
 #include "buildsym.h"
 #include "symfile.h"
 #include "objfiles.h"
@@ -96,7 +104,6 @@ struct regmappings
     int mask;
   };
 
-
 static const struct regmappings  mappings[] =
 {
 #ifdef __PPC__
@@ -172,7 +179,6 @@ static const struct regmappings  mappings[] =
   {(char *) &context.Fpr30, CONTEXT_FLOATING_POINT},
   {(char *) &context.Fpr31, CONTEXT_FLOATING_POINT},
 
-
   {(char *) &context.Iar, CONTEXT_CONTROL},
   {(char *) &context.Msr, CONTEXT_CONTROL},
   {(char *) &context.Cr,  CONTEXT_INTEGER},
@@ -209,7 +215,6 @@ static const struct regmappings  mappings[] =
 #endif
 };
 
-
 /* This vector maps the target's idea of an exception (extracted
    from the DEBUG_EVENT structure) to GDB's idea. */
 
@@ -219,7 +224,6 @@ struct xlate_exception
     enum target_signal us;
   };
 
-
 static const struct xlate_exception
   xlate[] =
 {
@@ -230,7 +234,6 @@ static const struct xlate_exception
   {EXCEPTION_SINGLE_STEP, TARGET_SIGNAL_TRAP},
   {-1, -1}};
 
-
 static void 
 check (BOOL ok, const char *file, int line)
 {
@@ -270,7 +273,6 @@ child_store_inferior_registers (int r)
 /* Wait for child to do something.  Return pid of child, or -1 in case
    of error; store status through argument pointer OURSTATUS.  */
 
-
 static int
 handle_load_dll (char *eventp)
 {
@@ -352,7 +354,6 @@ handle_load_dll (char *eventp)
              return 1;
            }
        }
 
       context.ContextFlags = CONTEXT_FULL | CONTEXT_FLOATING_POINT;
       GetThreadContext (current_thread, &context);
@@ -374,7 +375,7 @@ handle_load_dll (char *eventp)
 }
 
 
-static void
+static int
 handle_exception (DEBUG_EVENT * event, struct target_waitstatus *ourstatus)
 {
   int i;
@@ -410,6 +411,12 @@ handle_exception (DEBUG_EVENT * event, struct target_waitstatus *ourstatus)
       ourstatus->value.sig = TARGET_SIGNAL_TRAP;
       break;
     default:
+      /* This may be a structured exception handling exception.  In
+         that case, we want to let the program try to handle it, and
+         only break if we see the exception a second time.  */
+      if (event->u.Exception.dwFirstChance)
+       return 0;
+
       printf_unfiltered ("gdb: unknown target exception 0x%08x at 0x%08x\n",
                         event->u.Exception.ExceptionRecord.ExceptionCode,
                         event->u.Exception.ExceptionRecord.ExceptionAddress);
@@ -419,6 +426,7 @@ handle_exception (DEBUG_EVENT * event, struct target_waitstatus *ourstatus)
   context.ContextFlags = CONTEXT_FULL | CONTEXT_FLOATING_POINT;
   GetThreadContext (current_thread, &context);
   exception_count++;
+  return 1;
 }
 
 static int
@@ -435,12 +443,15 @@ child_wait (int pid, struct target_waitstatus *ourstatus)
       DEBUG_EVENT event;
       BOOL t = WaitForDebugEvent (&event, INFINITE);
       char *p;
+      DWORD continue_status;
 
       event_count++;
 
       current_thread_id = event.dwThreadId;
       current_process_id = event.dwProcessId;
 
+      continue_status = DBG_CONTINUE;
+
       switch (event.dwDebugEventCode)
        {
        case CREATE_THREAD_DEBUG_EVENT:
@@ -489,8 +500,10 @@ child_wait (int pid, struct target_waitstatus *ourstatus)
          DEBUG_EVENTS (("gdb: kernel event for pid=%d tid=%d code=%s)\n",
                        event.dwProcessId, event.dwThreadId,
                        "EXCEPTION_DEBUG_EVENT"));
-         handle_exception (&event, ourstatus);
-         return current_process_id;
+         if (handle_exception (&event, ourstatus))
+           return current_process_id;
+         continue_status = DBG_EXCEPTION_NOT_HANDLED;
+         break;
 
        case OUTPUT_DEBUG_STRING_EVENT: /* message from the kernel */
          DEBUG_EVENTS (("gdb: kernel event for pid=%d tid=%d code=%s)\n",
@@ -515,11 +528,10 @@ child_wait (int pid, struct target_waitstatus *ourstatus)
                     current_process_id, current_thread_id));
       CHECK (ContinueDebugEvent (current_process_id,
                                 current_thread_id,
-                                DBG_CONTINUE));
+                                continue_status));
     }
 }
 
-
 /* Attach to process PID, then initialize for debugging it.  */
 
 static void
@@ -539,7 +551,6 @@ child_attach (args, from_tty)
   if (!ok)
     error ("Can't attach to process.");
 
-
   exception_count = 0;
   event_count = 0;
 
@@ -561,7 +572,6 @@ child_attach (args, from_tty)
   push_target (&child_ops);
 }
 
-
 static void
 child_detach (args, from_tty)
      char *args;
@@ -580,7 +590,6 @@ child_detach (args, from_tty)
   unpush_target (&child_ops);
 }
 
-
 /* Print status information about what we're accessing.  */
 
 static void
@@ -759,11 +768,13 @@ child_create_inferior (exec_file, allargs, env)
 static void
 child_mourn_inferior ()
 {
+  (void) ContinueDebugEvent (current_process_id,
+                            current_thread_id,
+                            DBG_CONTINUE);
   unpush_target (&child_ops);
   generic_mourn_inferior ();
 }
 
-
 /* Send a SIGINT to the process group.  This acts just like the user typed a
    ^C on the controlling terminal. */
 
@@ -800,6 +811,22 @@ void
 child_kill_inferior (void)
 {
   CHECK (TerminateProcess (current_process, 0));
+  
+  for (;;)
+    {
+      DEBUG_EVENT event;
+      if (!ContinueDebugEvent (current_process_id,
+                              current_thread_id,
+                              DBG_CONTINUE))
+       break;
+      if (!WaitForDebugEvent (&event, INFINITE))
+       break;
+      current_thread_id = event.dwThreadId;
+      current_process_id = event.dwProcessId;
+      if (event.dwDebugEventCode == EXIT_PROCESS_DEBUG_EVENT)
+       break;
+    }
+
   CHECK (CloseHandle (current_process));
   CHECK (CloseHandle (current_thread));
   target_mourn_inferior();     /* or just child_mourn_inferior? */
This page took 0.026571 seconds and 4 git commands to generate.