OSDN Git Service

* exceptions.cc (INIT_EXCEPTION_HANDLER): Eliminate.
authorcgf <cgf>
Mon, 30 Apr 2001 03:09:18 +0000 (03:09 +0000)
committercgf <cgf>
Mon, 30 Apr 2001 03:09:18 +0000 (03:09 +0000)
(init_exceptions): Just use init_exception_handler.
(open_stackdumpfile): New function.
(stack_info::first_time): Eliminate.
(stack_info::init): Set up fields to avoid "first_time" consideration.
(stack_info::walk): Remove "first_time" consideration.
(stackdump): Change arguments to accept initial frame pointer and open stack
file flag.
(stack): Eliminate.
(cygwin_stackdump): Use stackdump() rather than stack().
(try_to_debug): Remove all synchronization logic.  Just keep looping in
exception handler until debugger notices us.  Return 1 if successfully started
debugger.
(handle_exceptions): Just return if we know that we're debugging.  Reorganize
to avoid creating a stackdump file if we are starting a debugger.  Return from
exception handler if debugger started successfully.
(sig_handle): Create a stackdump only if debugger wasn't started.
* winsup.h (try_to_debug): Add an argument.

winsup/cygwin/ChangeLog
winsup/cygwin/exceptions.cc
winsup/cygwin/winsup.h

index 7578335..d652eba 100644 (file)
@@ -1,3 +1,25 @@
+Sun Apr 29 22:28:06 2001  Christopher Faylor <cgf@cygnus.com>
+
+       * exceptions.cc (INIT_EXCEPTION_HANDLER): Eliminate.
+       (init_exceptions): Just use init_exception_handler.
+       (open_stackdumpfile): New function.
+       (stack_info::first_time): Eliminate.
+       (stack_info::init): Set up fields to avoid "first_time" consideration.
+       (stack_info::walk): Remove "first_time" consideration.
+       (stackdump): Change arguments to accept initial frame pointer and open
+       stack file flag.
+       (stack): Eliminate.
+       (cygwin_stackdump): Use stackdump() rather than stack().
+       (try_to_debug): Remove all synchronization logic.  Just keep looping in
+       exception handler until debugger notices us.  Return 1 if successfully
+       started debugger.
+       (handle_exceptions): Just return if we know that we're debugging.
+       Reorganize to avoid creating a stackdump file if we are starting a
+       debugger.  Return from exception handler if debugger started
+       successfully.
+       (sig_handle): Create a stackdump only if debugger wasn't started.
+       * winsup.h (try_to_debug): Add an argument.
+
 Sun Apr 29 21:41:25 2001  Christopher Faylor <cgf@cygnus.com>
 
        * path.cc (symlink_info::check): Remove extra arguments, move
index 6e80b6b..681ca39 100644 (file)
@@ -109,8 +109,6 @@ init_exception_handler (exception_list *el)
   el->prev = _except_list;
   _except_list = el;
 }
-
-#define INIT_EXCEPTION_HANDLER(el) init_exception_handler (el)
 #endif
 
 void
@@ -134,9 +132,7 @@ set_console_handler ()
 extern "C" void
 init_exceptions (exception_list *el)
 {
-#ifdef INIT_EXCEPTION_HANDLER
-  INIT_EXCEPTION_HANDLER (el);
-#endif
+  init_exception_handler (el);
 }
 
 extern "C" void
@@ -155,6 +151,29 @@ error_start_init (const char *buf)
   __small_sprintf (debugger_command, "%s %s", buf, myself_posix_name);
 }
 
+static void
+open_stackdumpfile ()
+{
+  if (myself->progname[0])
+    {
+      const char *p;
+      /* write to progname.stackdump if possible */
+      if ((p = strrchr (myself->progname, '\\')))
+       p++;
+      else
+       p = myself->progname;
+      char corefile[strlen (p) + sizeof (".stackdump")];
+      __small_sprintf (corefile, "%s.stackdump", p);
+      HANDLE h = CreateFile (corefile, GENERIC_WRITE, 0, &sec_none_nih,
+                            CREATE_ALWAYS, 0, 0);
+      if (h != INVALID_HANDLE_VALUE)
+       {
+         system_printf ("Dumping stack trace to %s", corefile);
+         SetStdHandle (STD_ERROR_HANDLE, h);
+       }
+    }
+}
+
 /* Utilities for dumping the stack, etc.  */
 
 static void
@@ -201,13 +220,11 @@ exception (EXCEPTION_RECORD *e,  CONTEXT *in)
 /* A class for manipulating the stack. */
 class stack_info
 {
-  int first_time;              /* True if just starting to iterate. */
   int walk ();                 /* Uses the "old" method */
   char *next_offset () {return *((char **) sf.AddrFrame.Offset);}
 public:
   STACKFRAME sf;               /* For storing the stack information */
   void init (DWORD);           /* Called the first time that stack info is needed */
-  stack_info (): first_time (1) {}
 
   /* Postfix ++ iterates over the stack, returning zero when nothing is left. */
   int operator ++(int) { return this->walk (); }
@@ -224,11 +241,12 @@ static signal_dispatch sigsave;
 void
 stack_info::init (DWORD ebp)
 {
-  first_time = 1;
+# define debp ((DWORD *) ebp)
   memset (&sf, 0, sizeof (sf));
   sf.AddrFrame.Offset = ebp;
-  sf.AddrPC.Offset = ((DWORD *) ebp)[1];
+  sf.AddrReturn.Offset = debp[1];
   sf.AddrFrame.Mode = AddrModeFlat;
+# undef debp
 }
 
 /* Walk the stack by looking at successive stored 'bp' frames.
@@ -237,10 +255,7 @@ int
 stack_info::walk ()
 {
   char **ebp;
-  if (first_time)
-    /* Everything is filled out already */
-    ebp = (char **) sf.AddrFrame.Offset;
-  else if ((ebp = (char **) next_offset ()) != NULL)
+  if ((ebp = (char **) next_offset ()) != NULL)
     {
       sf.AddrFrame.Offset = (DWORD) ebp;
       sf.AddrPC.Offset = sf.AddrReturn.Offset;
@@ -248,7 +263,6 @@ stack_info::walk ()
   else
     return 0;
 
-  first_time = 0;
   if (!sf.AddrPC.Offset)
     return 0;          /* stack frames are exhausted */
 
@@ -261,13 +275,20 @@ stack_info::walk ()
   return 1;
 }
 
-/* Dump the stack */
 static void
-stack (CONTEXT *cx)
+stackdump (DWORD ebp, int open_file)
 {
+  extern unsigned long rlim_core;
+
+  if (rlim_core == 0UL)
+    return;
+
+  if (open_file)
+    open_stackdumpfile ();
+
   int i;
 
-  thestack.init (cx->Ebp);     /* Initialize from the input CONTEXT */
+  thestack.init (ebp);         /* Initialize from the input CONTEXT */
   small_printf ("Stack trace:\r\nFrame     Function  Args\r\n");
   for (i = 0; i < 16 && thestack++; i++)
     {
@@ -288,15 +309,13 @@ cygwin_stackdump ()
   CONTEXT c;
   c.ContextFlags = CONTEXT_FULL;
   GetThreadContext (GetCurrentThread (), &c);
-  stack (&c);
+  stackdump (c.Ebp, 0);
 }
 
-static int NO_COPY keep_looping = 0;
-
 #define TIME_TO_WAIT_FOR_DEBUGGER 10000
 
 extern "C" int
-try_to_debug ()
+try_to_debug (bool waitloop)
 {
   debug_printf ("debugger_command '%s'", debugger_command);
   if (*debugger_command == '\0')
@@ -306,6 +325,7 @@ try_to_debug ()
 
   BOOL dbg;
 
+  SetThreadPriority (hMainThread, THREAD_PRIORITY_HIGHEST);
   PROCESS_INFORMATION pi = {NULL, 0, 0, 0};
 
   STARTUPINFO si = {0, NULL, NULL, NULL, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL, NULL, NULL, NULL};
@@ -348,65 +368,24 @@ try_to_debug ()
                       NULL,
                       &si,
                       &pi);
-  if (!dbg)
-    {
-      system_printf ("Failed to start debugger: %E");
-      /* FIXME: need to know handles of all running threads to
-       resume_all_threads_except (current_thread_id);
-      */
-    }
-  else
+
+  static int NO_COPY keep_looping = 0;
+
+  if (dbg)
     {
-      char event_name [sizeof ("cygwin_error_start_event") + 9];
-      DWORD win32_pid = GetCurrentProcessId ();
-      __small_sprintf (event_name, "cygwin_error_start_event%x", win32_pid);
-      HANDLE sync_with_dbg = CreateEvent (NULL, TRUE, FALSE, event_name);
-      keep_looping = 1;
+      if (!waitloop)
+       return 1;
+      SetThreadPriority (hMainThread, THREAD_PRIORITY_IDLE);
       while (keep_looping)
-       {
-         if (sync_with_dbg == NULL)
-           Sleep (TIME_TO_WAIT_FOR_DEBUGGER);
-         else
-           {
-             if (WaitForSingleObject (sync_with_dbg,
-                                      TIME_TO_WAIT_FOR_DEBUGGER) == WAIT_OBJECT_0)
-               break;
-           }
-        }
+       /* spin */;
     }
 
-  return 0;
-}
-
-static void
-stackdump (EXCEPTION_RECORD *e, CONTEXT *in)
-{
-  extern unsigned long rlim_core;
-  const char *p;
-
-  if (rlim_core == 0UL)
-    return;
 
-  if (myself->progname[0])
-    {
-      /* write to progname.stackdump if possible */
-      if ((p = strrchr (myself->progname, '\\')))
-       p++;
-      else
-       p = myself->progname;
-      char corefile[strlen (p) + sizeof (".stackdump")];
-      __small_sprintf (corefile, "%s.stackdump", p);
-      HANDLE h = CreateFile (corefile, GENERIC_WRITE, 0, &sec_none_nih,
-                            CREATE_ALWAYS, 0, 0);
-      if (h != INVALID_HANDLE_VALUE)
-       {
-         system_printf ("Dumping stack trace to %s", corefile);
-         SetStdHandle (STD_ERROR_HANDLE, h);
-       }
-    }
-  if (e)
-    exception (e, in);
-  stack (in);
+  system_printf ("Failed to start debugger: %E");
+  /* FIXME: need to know handles of all running threads to
+    resume_all_threads_except (current_thread_id);
+  */
+  return 0;
 }
 
 /* Main exception handler. */
@@ -415,6 +394,11 @@ static int
 handle_exceptions (EXCEPTION_RECORD *e, void *, CONTEXT *in, void *)
 {
   int sig;
+  static int NO_COPY debugging = 0;
+  static int NO_COPY recursed = 0;
+
+  if (debugging)
+    return 0;
 
   /* If we've already exited, don't do anything here.  Returning 1
      tells Windows to keep looking for an exception handler.  */
@@ -499,8 +483,6 @@ handle_exceptions (EXCEPTION_RECORD *e, void *, CONTEXT *in, void *)
       || (void *) myself->getsig (sig).sa_handler == (void *) SIG_IGN
       || (void *) myself->getsig (sig).sa_handler == (void *) SIG_ERR)
     {
-      static NO_COPY int traced = 0;
-
       /* Print the exception to the console */
       if (e)
        {
@@ -516,20 +498,22 @@ handle_exceptions (EXCEPTION_RECORD *e, void *, CONTEXT *in, void *)
 
       /* Another exception could happen while tracing or while exiting.
         Only do this once.  */
-      if (traced++)
+      if (recursed++)
        system_printf ("Error while dumping state (probably corrupted stack)");
       else
        {
-         CONTEXT c = *in;
-         DWORD stack[6];
-         stack[0] = in->Ebp;
-         stack[1] = in->Eip;
-         stack[2] = stack[3] = stack[4] = stack[5] = 0;
-         c.Ebp = (DWORD) &stack;
-         stackdump (e, &c);
+         if (try_to_debug (0))
+           {
+             debugging = 1;
+             return 0;
+           }
+
+         open_stackdumpfile ();
+         exception (e, in);
+         stackdump ((DWORD) ebp, 0);
        }
-      try_to_debug ();
-      signal_exit (0x80 | sig);                // Flag signal + core dump
+
+      signal_exit (0x80 | sig);        // Flag signal + core dump
     }
 
   sig_send (NULL, sig, (DWORD) ebp, 1);                // Signal myself
@@ -1017,30 +1001,30 @@ sig_handle (int sig)
 
   goto dosig;
 
-stop:
+ stop:
   /* Eat multiple attempts to STOP */
   if (ISSTATE (myself, PID_STOPPED))
     goto done;
   handler = (void *) sig_handle_tty_stop;
   thissig = myself->getsig (SIGSTOP);
 
-dosig:
+ dosig:
   /* Dispatch to the appropriate function. */
   sigproc_printf ("signal %d, about to call %p", sig, handler);
   rc = setup_handler (sig, handler, thissig);
 
-done:
+ done:
   sigproc_printf ("returning %d", rc);
   return rc;
 
-exit_sig:
+ exit_sig:
   if (sig == SIGQUIT || sig == SIGABRT)
     {
       CONTEXT c;
       c.ContextFlags = CONTEXT_FULL;
       GetThreadContext (hMainThread, &c);
-      stackdump (NULL, &c);
-      try_to_debug ();
+      if (!try_to_debug ())
+       stackdump (c.Ebp, 1);
       sig |= 0x80;
     }
   sigproc_printf ("signal %d, about to call do_exit", sig);
index 85fda80..663e999 100644 (file)
@@ -184,7 +184,7 @@ extern HANDLE netapi32_handle;
 
 /* debug_on_trap support. see exceptions.cc:try_to_debug() */
 extern "C" void error_start_init (const char*);
-extern "C" int try_to_debug ();
+extern "C" int try_to_debug (bool waitloop = 1);
 
 extern int cygwin_finished_initializing;