OSDN Git Service

e9975171438fec4748fd91af20d8f763ad118853
[pf3gnuchains/sourceware.git] / winsup / cygwin / exceptions.cc
1 /* exceptions.cc
2
3    Copyright 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003 Red Hat, Inc.
4
5 This file is part of Cygwin.
6
7 This software is a copyrighted work licensed under the terms of the
8 Cygwin license.  Please consult the file "CYGWIN_LICENSE" for
9 details. */
10
11 #include "winsup.h"
12 #include <imagehlp.h>
13 #include <stdlib.h>
14
15 #include "exceptions.h"
16 #include "sync.h"
17 #include "sigproc.h"
18 #include "pinfo.h"
19 #include "cygerrno.h"
20 #include "perthread.h"
21 #include "shared_info.h"
22 #include "perprocess.h"
23 #include "security.h"
24
25 #define CALL_HANDLER_RETRY 20
26
27 char debugger_command[2 * MAX_PATH + 20];
28
29 extern "C" {
30 static int handle_exceptions (EXCEPTION_RECORD *, void *, CONTEXT *, void *);
31 extern void sigreturn ();
32 extern void sigdelayed ();
33 extern void sigdelayed0 ();
34 extern void siglast ();
35 extern DWORD __no_sig_start, __no_sig_end;
36 };
37
38 extern DWORD sigtid;
39
40 extern HANDLE hExeced;
41 extern DWORD dwExeced;
42
43 static BOOL WINAPI ctrl_c_handler (DWORD);
44 static void signal_exit (int) __attribute__ ((noreturn));
45 static char windows_system_directory[1024];
46 static size_t windows_system_directory_length;
47
48 /* This is set to indicate that we have already exited.  */
49
50 static NO_COPY int exit_already = 0;
51 static NO_COPY muto *mask_sync = NULL;
52
53 HMODULE NO_COPY cygwin_hmodule;
54
55 NO_COPY static struct
56 {
57   unsigned int code;
58   const char *name;
59 } status_info[] =
60 {
61 #define X(s) s, #s
62   { X (STATUS_ABANDONED_WAIT_0) },
63   { X (STATUS_ACCESS_VIOLATION) },
64   { X (STATUS_ARRAY_BOUNDS_EXCEEDED) },
65   { X (STATUS_BREAKPOINT) },
66   { X (STATUS_CONTROL_C_EXIT) },
67   { X (STATUS_DATATYPE_MISALIGNMENT) },
68   { X (STATUS_FLOAT_DENORMAL_OPERAND) },
69   { X (STATUS_FLOAT_DIVIDE_BY_ZERO) },
70   { X (STATUS_FLOAT_INEXACT_RESULT) },
71   { X (STATUS_FLOAT_INVALID_OPERATION) },
72   { X (STATUS_FLOAT_OVERFLOW) },
73   { X (STATUS_FLOAT_STACK_CHECK) },
74   { X (STATUS_FLOAT_UNDERFLOW) },
75   { X (STATUS_GUARD_PAGE_VIOLATION) },
76   { X (STATUS_ILLEGAL_INSTRUCTION) },
77   { X (STATUS_INTEGER_DIVIDE_BY_ZERO) },
78   { X (STATUS_INTEGER_OVERFLOW) },
79   { X (STATUS_INVALID_DISPOSITION) },
80   { X (STATUS_IN_PAGE_ERROR) },
81   { X (STATUS_NONCONTINUABLE_EXCEPTION) },
82   { X (STATUS_NO_MEMORY) },
83   { X (STATUS_PENDING) },
84   { X (STATUS_PRIVILEGED_INSTRUCTION) },
85   { X (STATUS_SINGLE_STEP) },
86   { X (STATUS_STACK_OVERFLOW) },
87   { X (STATUS_TIMEOUT) },
88   { X (STATUS_USER_APC) },
89   { X (STATUS_WAIT_0) },
90   { 0, 0 }
91 #undef X
92 };
93
94 /* Initialization code.  */
95
96 #ifdef __i386__
97
98 // Set up the exception handler for the current thread.  The PowerPC & Mips
99 // use compiler generated tables to set up the exception handlers for each
100 // region of code, and the kernel walks the call list until it finds a region
101 // of code that handles exceptions.  The x86 on the other hand uses segment
102 // register fs, offset 0 to point to the current exception handler.
103
104 asm (".equ __except_list,0");
105
106 extern exception_list *_except_list asm ("%fs:__except_list");
107
108 static void
109 init_exception_handler (exception_list *el)
110 {
111   el->handler = handle_exceptions;
112   el->prev = _except_list;
113   _except_list = el;
114 }
115 #endif
116
117 void
118 early_stuff_init ()
119 {
120   (void) SetConsoleCtrlHandler (ctrl_c_handler, FALSE);
121   if (!SetConsoleCtrlHandler (ctrl_c_handler, TRUE))
122     system_printf ("SetConsoleCtrlHandler failed, %E");
123
124   /* Initialize global security attribute stuff */
125
126   sec_none.nLength = sec_none_nih.nLength =
127   sec_all.nLength = sec_all_nih.nLength = sizeof (SECURITY_ATTRIBUTES);
128   sec_none.bInheritHandle = sec_all.bInheritHandle = TRUE;
129   sec_none_nih.bInheritHandle = sec_all_nih.bInheritHandle = FALSE;
130   sec_none.lpSecurityDescriptor = sec_none_nih.lpSecurityDescriptor = NULL;
131   sec_all.lpSecurityDescriptor = sec_all_nih.lpSecurityDescriptor =
132     get_null_sd ();
133 }
134
135 extern "C" void
136 init_exceptions (exception_list *el)
137 {
138   init_exception_handler (el);
139 }
140
141 extern "C" void
142 error_start_init (const char *buf)
143 {
144   if (!buf || !*buf)
145     {
146       debugger_command[0] = '\0';
147       return;
148     }
149
150   char pgm[MAX_PATH + 1];
151   if (!GetModuleFileName (NULL, pgm, MAX_PATH))
152     strcpy (pgm, "cygwin1.dll");
153   for (char *p = strchr (pgm, '\\'); p; p = strchr (p, '\\'))
154     *p = '/';
155
156   __small_sprintf (debugger_command, "%s \"%s\"", buf, pgm);
157 }
158
159 static void
160 open_stackdumpfile ()
161 {
162   if (myself->progname[0])
163     {
164       const char *p;
165       /* write to progname.stackdump if possible */
166       if (!myself->progname[0])
167         p = "unknown";
168       else if ((p = strrchr (myself->progname, '\\')))
169         p++;
170       else
171         p = myself->progname;
172       char corefile[strlen (p) + sizeof (".stackdump")];
173       __small_sprintf (corefile, "%s.stackdump", p);
174       HANDLE h = CreateFile (corefile, GENERIC_WRITE, 0, &sec_none_nih,
175                              CREATE_ALWAYS, 0, 0);
176       if (h != INVALID_HANDLE_VALUE)
177         {
178           if (!myself->ppid_handle)
179             system_printf ("Dumping stack trace to %s", corefile);
180           else
181             debug_printf ("Dumping stack trace to %s", corefile);
182           SetStdHandle (STD_ERROR_HANDLE, h);
183         }
184     }
185 }
186
187 /* Utilities for dumping the stack, etc.  */
188
189 static void
190 exception (EXCEPTION_RECORD *e,  CONTEXT *in)
191 {
192   const char *exception_name = NULL;
193
194   if (e)
195     {
196       for (int i = 0; status_info[i].name; i++)
197         {
198           if (status_info[i].code == e->ExceptionCode)
199             {
200               exception_name = status_info[i].name;
201               break;
202             }
203         }
204     }
205
206 #ifdef __i386__
207 #define HAVE_STATUS
208   if (exception_name)
209     small_printf ("Exception: %s at eip=%08x\r\n", exception_name, in->Eip);
210   else
211     small_printf ("Exception %d at eip=%08x\r\n", e->ExceptionCode, in->Eip);
212   small_printf ("eax=%08x ebx=%08x ecx=%08x edx=%08x esi=%08x edi=%08x\r\n",
213               in->Eax, in->Ebx, in->Ecx, in->Edx, in->Esi, in->Edi);
214   small_printf ("ebp=%08x esp=%08x program=%s\r\n",
215               in->Ebp, in->Esp, myself->progname);
216   small_printf ("cs=%04x ds=%04x es=%04x fs=%04x gs=%04x ss=%04x\r\n",
217               in->SegCs, in->SegDs, in->SegEs, in->SegFs, in->SegGs, in->SegSs);
218 #endif
219
220 #ifndef HAVE_STATUS
221   system_printf ("Had an exception");
222 #endif
223 }
224
225 #ifdef __i386__
226 /* Print a stack backtrace. */
227
228 #define HAVE_STACK_TRACE
229
230 /* A class for manipulating the stack. */
231 class stack_info
232 {
233   int walk ();                  /* Uses the "old" method */
234   char *next_offset () {return *((char **) sf.AddrFrame.Offset);}
235   bool needargs;
236   DWORD dummy_frame;
237 public:
238   STACKFRAME sf;                 /* For storing the stack information */
239   void init (DWORD, bool, bool); /* Called the first time that stack info is needed */
240
241   /* Postfix ++ iterates over the stack, returning zero when nothing is left. */
242   int operator ++(int) { return walk (); }
243 };
244
245 /* The number of parameters used in STACKFRAME */
246 #define NPARAMS (sizeof (thestack.sf.Params) / sizeof (thestack.sf.Params[0]))
247
248 /* This is the main stack frame info for this process. */
249 static NO_COPY stack_info thestack;
250 static signal_dispatch sigsave;
251
252 /* Initialize everything needed to start iterating. */
253 void
254 stack_info::init (DWORD ebp, bool wantargs, bool goodframe)
255 {
256 # define debp ((DWORD *) ebp)
257   memset (&sf, 0, sizeof (sf));
258   if (!goodframe)
259     sf.AddrFrame.Offset = ebp;
260   else
261     {
262       dummy_frame = ebp;
263       sf.AddrFrame.Offset = (DWORD) &dummy_frame;
264     }
265   sf.AddrReturn.Offset = debp[1];
266   sf.AddrFrame.Mode = AddrModeFlat;
267   needargs = wantargs;
268 # undef debp
269 }
270
271 /* Walk the stack by looking at successive stored 'bp' frames.
272    This is not foolproof. */
273 int
274 stack_info::walk ()
275 {
276   char **ebp;
277   if ((ebp = (char **) next_offset ()) == NULL)
278     return 0;
279
280   sf.AddrFrame.Offset = (DWORD) ebp;
281   sf.AddrPC.Offset = sf.AddrReturn.Offset;
282
283   if (!sf.AddrPC.Offset)
284     return 0;           /* stack frames are exhausted */
285
286   /* The return address always follows the stack pointer */
287   sf.AddrReturn.Offset = (DWORD) *++ebp;
288
289   if (needargs)
290     /* The arguments follow the return address */
291     for (unsigned i = 0; i < NPARAMS; i++)
292       sf.Params[i] = (DWORD) *++ebp;
293
294   return 1;
295 }
296
297 static void
298 stackdump (DWORD ebp, int open_file, bool isexception)
299 {
300   extern unsigned long rlim_core;
301
302   if (rlim_core == 0UL)
303     return;
304
305   if (open_file)
306     open_stackdumpfile ();
307
308   int i;
309
310   thestack.init (ebp, 1, !isexception); /* Initialize from the input CONTEXT */
311   small_printf ("Stack trace:\r\nFrame     Function  Args\r\n");
312   for (i = 0; i < 16 && thestack++; i++)
313     {
314       small_printf ("%08x  %08x ", thestack.sf.AddrFrame.Offset,
315                     thestack.sf.AddrPC.Offset);
316       for (unsigned j = 0; j < NPARAMS; j++)
317         small_printf ("%s%08x", j == 0 ? " (" : ", ", thestack.sf.Params[j]);
318       small_printf (")\r\n");
319     }
320   small_printf ("End of stack trace%s",
321               i == 16 ? " (more stack frames may be present)" : "");
322 }
323
324 /* Temporary (?) function for external callers to get a stack dump */
325 extern "C" void
326 cygwin_stackdump ()
327 {
328   CONTEXT c;
329   c.ContextFlags = CONTEXT_FULL;
330   GetThreadContext (GetCurrentThread (), &c);
331   stackdump (c.Ebp, 0, 0);
332 }
333
334 #define TIME_TO_WAIT_FOR_DEBUGGER 10000
335
336 extern "C" int
337 try_to_debug (bool waitloop)
338 {
339   debug_printf ("debugger_command '%s'", debugger_command);
340   if (*debugger_command == '\0' || being_debugged ())
341     return 0;
342
343   __small_sprintf (strchr (debugger_command, '\0'), " %u", GetCurrentProcessId ());
344
345   LONG prio = GetThreadPriority (GetCurrentThread ());
346   SetThreadPriority (GetCurrentThread (), THREAD_PRIORITY_HIGHEST);
347   PROCESS_INFORMATION pi = {NULL, 0, 0, 0};
348
349   STARTUPINFO si = {0, NULL, NULL, NULL, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL, NULL, NULL, NULL};
350   si.lpReserved = NULL;
351   si.lpDesktop = NULL;
352   si.dwFlags = 0;
353   si.cb = sizeof (si);
354
355   /* FIXME: need to know handles of all running threads to
356      suspend_all_threads_except (current_thread_id);
357   */
358
359   /* if any of these mutexes is owned, we will fail to start any cygwin app
360      until trapped app exits */
361
362   ReleaseMutex (title_mutex);
363
364   /* prevent recursive exception handling */
365   char* rawenv = GetEnvironmentStrings () ;
366   for (char* p = rawenv; *p != '\0'; p = strchr (p, '\0') + 1)
367     {
368       if (strncmp (p, "CYGWIN=", sizeof ("CYGWIN=") - 1) == 0)
369         {
370           char* q = strstr (p, "error_start") ;
371           /* replace 'error_start=...' with '_rror_start=...' */
372           if (q) *q = '_' ;
373           SetEnvironmentVariable ("CYGWIN", p + sizeof ("CYGWIN=")) ;
374           break ;
375         }
376     }
377
378   BOOL dbg;
379   dbg = CreateProcess (NULL,
380                        debugger_command,
381                        NULL,
382                        NULL,
383                        FALSE,
384                        CREATE_NEW_CONSOLE | CREATE_NEW_PROCESS_GROUP,
385                        NULL,
386                        NULL,
387                        &si,
388                        &pi);
389
390   if (!dbg)
391     system_printf ("Failed to start debugger: %E");
392   else
393     {
394       if (!waitloop)
395         return 1;
396       SetThreadPriority (GetCurrentThread (), THREAD_PRIORITY_IDLE);
397       while (!being_debugged ())
398         Sleep (0);
399       Sleep (2000);
400       small_printf ("*** continuing from debugger call\n");
401       SetThreadPriority (GetCurrentThread (), prio);
402     }
403
404   /* FIXME: need to know handles of all running threads to
405     resume_all_threads_except (current_thread_id);
406   */
407   return 0;
408 }
409
410 /* Main exception handler. */
411
412 static int
413 handle_exceptions (EXCEPTION_RECORD *e, void *, CONTEXT *in, void *)
414 {
415   int sig;
416   static int NO_COPY debugging = 0;
417   static int NO_COPY recursed = 0;
418
419   if (debugging && ++debugging < 500000)
420     {
421       SetThreadPriority (hMainThread, THREAD_PRIORITY_NORMAL);
422       return 0;
423     }
424
425   /* If we've already exited, don't do anything here.  Returning 1
426      tells Windows to keep looking for an exception handler.  */
427   if (exit_already)
428     return 1;
429
430   /* Coerce win32 value to posix value.  */
431   switch (e->ExceptionCode)
432     {
433     case STATUS_FLOAT_DENORMAL_OPERAND:
434     case STATUS_FLOAT_DIVIDE_BY_ZERO:
435     case STATUS_FLOAT_INEXACT_RESULT:
436     case STATUS_FLOAT_INVALID_OPERATION:
437     case STATUS_FLOAT_OVERFLOW:
438     case STATUS_FLOAT_STACK_CHECK:
439     case STATUS_FLOAT_UNDERFLOW:
440     case STATUS_INTEGER_DIVIDE_BY_ZERO:
441     case STATUS_INTEGER_OVERFLOW:
442       sig = SIGFPE;
443       break;
444
445     case STATUS_ILLEGAL_INSTRUCTION:
446     case STATUS_PRIVILEGED_INSTRUCTION:
447     case STATUS_NONCONTINUABLE_EXCEPTION:
448       sig = SIGILL;
449       break;
450
451     case STATUS_TIMEOUT:
452       sig = SIGALRM;
453       break;
454
455     case STATUS_ACCESS_VIOLATION:
456     case STATUS_DATATYPE_MISALIGNMENT:
457     case STATUS_ARRAY_BOUNDS_EXCEEDED:
458     case STATUS_GUARD_PAGE_VIOLATION:
459     case STATUS_IN_PAGE_ERROR:
460     case STATUS_NO_MEMORY:
461     case STATUS_INVALID_DISPOSITION:
462     case STATUS_STACK_OVERFLOW:
463       sig = SIGSEGV;
464       break;
465
466     case STATUS_CONTROL_C_EXIT:
467       sig = SIGINT;
468       break;
469
470     case STATUS_INVALID_HANDLE:
471       /* CloseHandle will throw this exception if it is given an
472          invalid handle.  We don't care about the exception; we just
473          want CloseHandle to return an error.  This can be revisited
474          if gcc ever supports Windows style structured exception
475          handling.  */
476       return 0;
477
478     default:
479       /* If we don't recognize the exception, we have to assume that
480          we are doing structured exception handling, and we let
481          something else handle it.  */
482       return 1;
483     }
484
485   debug_printf ("In cygwin_except_handler exc %p at %p sp %p", e->ExceptionCode, in->Eip, in->Esp);
486   debug_printf ("In cygwin_except_handler sig = %d at %p", sig, in->Eip);
487
488   if (myself->getsig (sig).sa_mask & SIGTOMASK (sig))
489     syscall_printf ("signal %d, masked %p", sig, myself->getsig (sig).sa_mask);
490
491   debug_printf ("In cygwin_except_handler calling %p",
492                  myself->getsig (sig).sa_handler);
493
494   DWORD *ebp = (DWORD *)in->Esp;
495   for (DWORD *bpend = (DWORD *) __builtin_frame_address (0); ebp > bpend; ebp--)
496     if (*ebp == in->SegCs && ebp[-1] == in->Eip)
497       {
498         ebp -= 2;
499         break;
500       }
501
502   if (!myself->progname[0]
503       || GetCurrentThreadId () == sigtid
504       || (void *) myself->getsig (sig).sa_handler == (void *) SIG_DFL
505       || (void *) myself->getsig (sig).sa_handler == (void *) SIG_IGN
506       || (void *) myself->getsig (sig).sa_handler == (void *) SIG_ERR)
507     {
508       /* Print the exception to the console */
509       if (e)
510         {
511           for (int i = 0; status_info[i].name; i++)
512             {
513               if (status_info[i].code == e->ExceptionCode)
514                 {
515                   if (!myself->ppid_handle)
516                     system_printf ("Exception: %s", status_info[i].name);
517                   break;
518                 }
519             }
520         }
521
522       /* Another exception could happen while tracing or while exiting.
523          Only do this once.  */
524       if (recursed++)
525         system_printf ("Error while dumping state (probably corrupted stack)");
526       else
527         {
528           if (try_to_debug (0))
529             {
530               debugging = 1;
531               return 0;
532             }
533
534           open_stackdumpfile ();
535           exception (e, in);
536           stackdump ((DWORD) ebp, 0, 1);
537         }
538
539       signal_exit (0x80 | sig); // Flag signal + core dump
540     }
541
542   sig_send (NULL, sig, (DWORD) ebp, 1);         // Signal myself
543   return 0;
544 }
545 #endif /* __i386__ */
546
547 #ifndef HAVE_STACK_TRACE
548 void
549 stack (void)
550 {
551   system_printf ("Stack trace not yet supported on this machine.");
552 }
553 #endif
554
555 /* Utilities to call a user supplied exception handler.  */
556
557 #define SIG_NONMASKABLE (SIGTOMASK (SIGKILL) | SIGTOMASK (SIGSTOP))
558
559 #ifdef __i386__
560 #define HAVE_CALL_HANDLER
561
562 /* Non-raceable sigsuspend
563  * Note: This implementation is based on the Single UNIX Specification
564  * man page.  This indicates that sigsuspend always returns -1 and that
565  * attempts to block unblockable signals will be silently ignored.
566  * This is counter to what appears to be documented in some UNIX
567  * man pages, e.g. Linux.
568  */
569 int __stdcall
570 handle_sigsuspend (sigset_t tempmask)
571 {
572   sig_dispatch_pending ();
573   sigframe thisframe (mainthread);
574   sigset_t oldmask = myself->getsigmask ();     // Remember for restoration
575
576   set_process_mask (tempmask & ~SIG_NONMASKABLE);// Let signals we're
577                                 //  interested in through.
578   sigproc_printf ("old mask %x, new mask %x", oldmask, tempmask);
579
580   pthread_testcancel ();
581   pthread::cancelable_wait (signal_arrived, INFINITE);
582
583   set_sig_errno (EINTR);        // Per POSIX
584
585   /* A signal dispatch function will have been added to our stack and will
586      be hit eventually.  Set the old mask to be restored when the signal
587      handler returns. */
588
589   sigsave.oldmask = oldmask;    // Will be restored by signal handler
590   return -1;
591 }
592
593 extern DWORD exec_exit;         // Possible exit value for exec
594
595 extern "C" {
596 static void
597 sig_handle_tty_stop (int sig)
598 {
599   /* Silently ignore attempts to suspend if there is no accomodating
600      cygwin parent to deal with this behavior. */
601   if (!myself->ppid_handle)
602     {
603       myself->process_state &= ~PID_STOPPED;
604       return;
605     }
606
607   myself->stopsig = sig;
608   /* See if we have a living parent.  If so, send it a special signal.
609      It will figure out exactly which pid has stopped by scanning
610      its list of subprocesses.  */
611   if (my_parent_is_alive ())
612     {
613       pinfo parent (myself->ppid);
614       if (!(parent->getsig (SIGCHLD).sa_flags & SA_NOCLDSTOP))
615         sig_send (parent, SIGCHLD);
616     }
617   sigproc_printf ("process %d stopped by signal %d, myself->ppid_handle %p",
618                   myself->pid, sig, myself->ppid_handle);
619   if (WaitForSingleObject (sigCONT, INFINITE) != WAIT_OBJECT_0)
620     api_fatal ("WaitSingleObject failed, %E");
621   (void) ResetEvent (sigCONT);
622   return;
623 }
624 }
625
626 int
627 interruptible (DWORD pc, int testvalid = 0)
628 {
629   int res;
630   MEMORY_BASIC_INFORMATION m;
631
632   memset (&m, 0, sizeof m);
633   if (!VirtualQuery ((LPCVOID) pc, &m, sizeof m))
634     sigproc_printf ("couldn't get memory info, pc %p, %E", pc);
635
636   char *checkdir = (char *) alloca (windows_system_directory_length + 4);
637   memset (checkdir, 0, sizeof (checkdir));
638
639 # define h ((HMODULE) m.AllocationBase)
640   /* Apparently Windows 95 can sometimes return bogus addresses from
641      GetThreadContext.  These resolve to a strange allocation base.
642      These should *never* be treated as interruptible. */
643   if (!h || m.State != MEM_COMMIT)
644     res = 0;
645   else if (testvalid)
646     res = 1;    /* All we wanted to know was if this was a valid module. */
647   else if (h == user_data->hmodule)
648     res = 1;
649   else if (h == cygwin_hmodule)
650     res = 0;
651   else if (!GetModuleFileName (h, checkdir, windows_system_directory_length + 2))
652     res = 0;
653   else
654     res = !strncasematch (windows_system_directory, checkdir,
655                           windows_system_directory_length);
656   sigproc_printf ("pc %p, h %p, interruptible %d, testvalid %d", pc, h, res, testvalid);
657 # undef h
658   return res;
659 }
660
661 bool
662 sigthread::get_winapi_lock (int test)
663 {
664   if (test)
665     return !InterlockedExchange (&winapi_lock, 1);
666
667   /* Need to do a busy loop because we can't block or a potential SuspendThread
668      will hang. */
669   while (InterlockedExchange (&winapi_lock, 1))
670     low_priority_sleep (0);
671   return 1;
672 }
673
674 void
675 sigthread::release_winapi_lock ()
676 {
677   /* Assumes that we have the lock. */
678   InterlockedExchange (&winapi_lock, 0);
679 }
680
681 static void __stdcall interrupt_setup (int sig, void *handler, DWORD retaddr,
682                                        DWORD *retaddr_on_stack,
683                                        struct sigaction& siga)
684                       __attribute__((regparm(3)));
685 static void __stdcall
686 interrupt_setup (int sig, void *handler, DWORD retaddr, DWORD *retaddr_on_stack,
687                  struct sigaction& siga)
688 {
689   sigsave.retaddr = retaddr;
690   sigsave.retaddr_on_stack = retaddr_on_stack;
691   /* FIXME: Not multi-thread aware */
692   sigsave.oldmask = myself->getsigmask ();
693   sigsave.newmask = sigsave.oldmask | siga.sa_mask | SIGTOMASK (sig);
694   sigsave.sa_flags = siga.sa_flags;
695   sigsave.func = (void (*)(int)) handler;
696   sigsave.saved_errno = -1;             // Flag: no errno to save
697   if (handler == sig_handle_tty_stop)
698     {
699       myself->stopsig = 0;
700       myself->process_state |= PID_STOPPED;
701     }
702   /* Clear any waiting threads prior to dispatching to handler function */
703   proc_subproc (PROC_CLEARWAIT, 1);
704   int res = SetEvent (signal_arrived);  // For an EINTR case
705   sigsave.sig = sig;                    // Should ALWAYS be last thing set to avoid a race
706   sigproc_printf ("armed signal_arrived %p, res %d", signal_arrived, res);
707 }
708
709 static bool interrupt_now (CONTEXT *, int, void *, struct sigaction&) __attribute__((regparm(3)));
710 static bool
711 interrupt_now (CONTEXT *ctx, int sig, void *handler, struct sigaction& siga)
712 {
713   interrupt_setup (sig, handler, ctx->Eip, 0, siga);
714   ctx->Eip = (DWORD) sigdelayed;
715   SetThreadContext (myself->getthread2signal (), ctx); /* Restart the thread in a new location */
716   return 1;
717 }
718
719 void __stdcall
720 signal_fixup_after_fork ()
721 {
722   if (sigsave.sig)
723     {
724       sigsave.sig = 0;
725       if (sigsave.retaddr_on_stack)
726         {
727           *sigsave.retaddr_on_stack = sigsave.retaddr;
728           set_process_mask (sigsave.oldmask);
729         }
730     }
731   sigproc_init ();
732 }
733
734 void __stdcall
735 signal_fixup_after_exec ()
736 {
737   /* Set up child's signal handlers */
738   for (int i = 0; i < NSIG; i++)
739     {
740       myself->getsig (i).sa_mask = 0;
741       if (myself->getsig (i).sa_handler != SIG_IGN)
742         myself->getsig (i).sa_handler = SIG_DFL;
743     }
744 }
745
746 static int interrupt_on_return (sigthread *, int, void *, struct sigaction&) __attribute__((regparm(3)));
747 static int
748 interrupt_on_return (sigthread *th, int sig, void *handler, struct sigaction& siga)
749 {
750   int i;
751   DWORD ebp = th->frame;
752
753   if (!ebp)
754     return 0;
755
756   thestack.init (ebp, 0, 1);  /* Initialize from the input CONTEXT */
757   for (i = 0; i < 32 && thestack++ ; i++)
758     if (th->exception || interruptible (thestack.sf.AddrReturn.Offset))
759       {
760         DWORD *addr_retaddr = ((DWORD *)thestack.sf.AddrFrame.Offset) + 1;
761         if (*addr_retaddr  == thestack.sf.AddrReturn.Offset)
762           {
763             interrupt_setup (sig, handler, *addr_retaddr, addr_retaddr, siga);
764             *addr_retaddr = (DWORD) sigdelayed;
765           }
766         return 1;
767       }
768
769   sigproc_printf ("couldn't find a stack frame, i %d", i);
770   return 0;
771 }
772
773 extern "C" void __stdcall
774 set_sig_errno (int e)
775 {
776   set_errno (e);
777   sigsave.saved_errno = e;
778   // sigproc_printf ("errno %d", e);
779 }
780
781 static int setup_handler (int, void *, struct sigaction&) __attribute__((regparm(3)));
782 static int
783 setup_handler (int sig, void *handler, struct sigaction& siga)
784 {
785   CONTEXT cx;
786   bool interrupted = false;
787   sigthread *th = NULL;         // Initialization needed to shut up gcc
788   int prio = INFINITE;
789
790   if (sigsave.sig)
791     goto set_pending;
792
793   for (int i = 0; i < CALL_HANDLER_RETRY; i++)
794     {
795       DWORD res;
796       HANDLE hth;
797
798       EnterCriticalSection (&mainthread.lock);
799       if (mainthread.frame)
800         {
801           hth = NULL;
802           th = &mainthread;
803         }
804       else
805         {
806           LeaveCriticalSection (&mainthread.lock);
807
808           if (!mainthread.get_winapi_lock (1))
809             continue;
810
811           hth = myself->getthread2signal ();
812           th = NULL;
813
814           /* Suspend the thread which will receive the signal.  But first ensure that
815              this thread doesn't have any mutos.  (FIXME: Someday we should just grab
816              all of the mutos rather than checking for them)
817              For Windows 95, we also have to ensure that the addresses returned by GetThreadContext
818              are valid.
819              If one of these conditions is not true we loop for a fixed number of times
820              since we don't want to stall the signal handler.  FIXME: Will this result in
821              noticeable delays?
822              If the thread is already suspended (which can occur when a program has called
823              SuspendThread on itself then just queue the signal. */
824
825           EnterCriticalSection (&mainthread.lock);
826           sigproc_printf ("suspending mainthread");
827           res = SuspendThread (hth);
828           /* Just release the lock now since we hav suspended the main thread and it
829              definitely can't be grabbing it now.  This will have to change, of course,
830              if/when we can send signals to other than the main thread. */
831           LeaveCriticalSection (&mainthread.lock);
832
833           /* Just set pending if thread is already suspended */
834           if (res)
835             {
836               mainthread.release_winapi_lock ();
837               (void) ResumeThread (hth);
838               break;
839             }
840
841           mainthread.release_winapi_lock ();
842           if (mainthread.frame)
843             goto resume_thread; /* We just got the frame.  What are the odds?
844                                    Just loop and we'll hopefully pick it up on
845                                    the next pass through. */
846
847           muto *m;
848           /* FIXME: Make multi-thread aware */
849           for (m = muto_start.next;  m != NULL; m = m->next)
850             if (m->unstable () || m->owner () == mainthread.id)
851               {
852                 sigproc_printf ("suspended thread owns a muto (%s)", m->name);
853                 goto resume_thread;
854               }
855
856           if (mainthread.frame)
857             th = &mainthread;
858           else
859             {
860               cx.ContextFlags = CONTEXT_CONTROL | CONTEXT_INTEGER;
861               if (!GetThreadContext (hth, &cx))
862                 {
863                   system_printf ("couldn't get context of main thread, %E");
864                   goto resume_thread;
865                 }
866             }
867         }
868
869       if ((DWORD) prio != INFINITE)
870         {
871           /* Reset the priority so we can finish this off quickly. */
872           SetThreadPriority (GetCurrentThread (), WAIT_SIG_PRIORITY);
873           prio = INFINITE;
874         }
875
876       if (th)
877         {
878           interrupted = interrupt_on_return (th, sig, handler, siga);
879           LeaveCriticalSection (&th->lock);
880         }
881       else if (interruptible (cx.Eip))
882         interrupted = interrupt_now (&cx, sig, handler, siga);
883
884     resume_thread:
885       if (hth)
886         res = ResumeThread (hth);
887
888       if (interrupted)
889         break;
890
891       if ((DWORD) prio != INFINITE && !mainthread.frame)
892         prio = low_priority_sleep (SLEEP_0_STAY_LOW);
893       sigproc_printf ("couldn't interrupt.  trying again.");
894     }
895
896  set_pending:
897   if (interrupted)
898     {
899       if ((DWORD) prio != INFINITE)
900         SetThreadPriority (GetCurrentThread (), WAIT_SIG_PRIORITY);
901       sigproc_printf ("signal successfully delivered");
902     }
903
904   sigproc_printf ("returning %d", interrupted);
905   return interrupted;
906 }
907 #endif /* i386 */
908
909 #ifndef HAVE_CALL_HANDLER
910 #error "Need to supply machine dependent setup_handler"
911 #endif
912
913 /* Keyboard interrupt handler.  */
914 static BOOL WINAPI
915 ctrl_c_handler (DWORD type)
916 {
917   static bool saw_close;
918
919   /* Return FALSE to prevent an "End task" dialog box from appearing
920      for each Cygwin process window that's open when the computer
921      is shut down or console window is closed. */
922
923   if (type == CTRL_SHUTDOWN_EVENT)
924     {
925 #if 0
926       /* Don't send a signal.  Only NT service applications and their child
927          processes will receive this event and the services typically already
928          handle the shutdown action when getting the SERVICE_CONTROL_SHUTDOWN
929          control message. */
930       sig_send (NULL, SIGTERM);
931 #endif
932       return FALSE;
933     }
934
935   if (myself->ctty != -1
936       && (type == CTRL_CLOSE_EVENT || (!saw_close && type == CTRL_LOGOFF_EVENT)))
937     {
938       if (type == CTRL_CLOSE_EVENT)
939         saw_close = true;
940       sig_send (NULL, SIGHUP);
941       return FALSE;
942     }
943
944   /* If we are a stub and the new process has a pinfo structure, let it
945      handle this signal. */
946   if (dwExeced && pinfo (dwExeced))
947     return TRUE;
948
949   /* We're only the process group leader when we have a valid pinfo structure.
950      If we don't have one, then the parent "stub" will handle the signal. */
951   if (!pinfo (cygwin_pid (GetCurrentProcessId ())))
952     return TRUE;
953
954   tty_min *t = cygwin_shared->tty.get_tty (myself->ctty);
955   /* Ignore this if we're not the process group leader since it should be handled
956      *by* the process group leader. */
957   if (myself->ctty != -1 && t->getpgid () == myself->pid &&
958        (GetTickCount () - t->last_ctrl_c) >= MIN_CTRL_C_SLOP)
959     /* Otherwise we just send a SIGINT to the process group and return TRUE (to indicate
960        that we have handled the signal).  At this point, type should be
961        a CTRL_C_EVENT or CTRL_BREAK_EVENT. */
962     {
963       t->last_ctrl_c = GetTickCount ();
964       kill (-myself->pid, SIGINT);
965       t->last_ctrl_c = GetTickCount ();
966       return TRUE;
967     }
968
969   return TRUE;
970 }
971
972 /* Set the signal mask for this process.
973    Note that some signals are unmaskable, as in UNIX.  */
974 extern "C" void __stdcall
975 set_process_mask (sigset_t newmask)
976 {
977   sigframe thisframe (mainthread);
978   mask_sync->acquire (INFINITE);
979   sigset_t oldmask = myself->getsigmask ();
980   newmask &= ~SIG_NONMASKABLE;
981   sigproc_printf ("old mask = %x, new mask = %x", myself->getsigmask (), newmask);
982   myself->setsigmask (newmask); // Set a new mask
983   mask_sync->release ();
984   if (oldmask != newmask)
985     sig_dispatch_pending ();
986   else
987     sigproc_printf ("not calling sig_dispatch_pending.  sigtid %p current %p",
988                     sigtid, GetCurrentThreadId ());
989   return;
990 }
991
992 int __stdcall
993 sig_handle (int sig)
994 {
995   int rc = 1;
996
997   sigproc_printf ("signal %d", sig);
998
999   struct sigaction thissig = myself->getsig (sig);
1000   void *handler = (void *) thissig.sa_handler;
1001
1002   myself->rusage_self.ru_nsignals++;
1003
1004   /* Clear pending SIGCONT on stop signals */
1005   if (sig == SIGSTOP || sig == SIGTSTP || sig == SIGTTIN || sig == SIGTTOU)
1006     sig_clear (SIGCONT);
1007
1008   if (sig == SIGKILL)
1009     goto exit_sig;
1010
1011   if (sig == SIGSTOP)
1012     goto stop;
1013
1014   /* FIXME: Should we still do this if SIGCONT has a handler? */
1015   if (sig == SIGCONT)
1016     {
1017       DWORD stopped = myself->process_state & PID_STOPPED;
1018       myself->stopsig = 0;
1019       myself->process_state &= ~PID_STOPPED;
1020       /* Clear pending stop signals */
1021       sig_clear (SIGSTOP);
1022       sig_clear (SIGTSTP);
1023       sig_clear (SIGTTIN);
1024       sig_clear (SIGTTOU);
1025       if (stopped)
1026         SetEvent (sigCONT);
1027       /* process pending signals */
1028 #if 0 // FIXME?
1029       sig_dispatch_pending ();
1030 #endif
1031     }
1032
1033 #if 0
1034   char sigmsg[24];
1035   __small_sprintf (sigmsg, "cygwin: signal %d\n", sig);
1036   OutputDebugString (sigmsg);
1037 #endif
1038
1039   if (handler == (void *) SIG_DFL)
1040     {
1041       if (sig == SIGCHLD || sig == SIGIO || sig == SIGCONT || sig == SIGWINCH
1042           || sig == SIGURG || (hExeced && sig == SIGINT))
1043         {
1044           sigproc_printf ("default signal %d ignored", sig);
1045           goto done;
1046         }
1047
1048       if (sig == SIGTSTP || sig == SIGTTIN || sig == SIGTTOU)
1049         goto stop;
1050
1051       goto exit_sig;
1052     }
1053
1054   if (handler == (void *) SIG_IGN)
1055     {
1056       sigproc_printf ("signal %d ignored", sig);
1057       goto done;
1058     }
1059
1060   if (handler == (void *) SIG_ERR)
1061     goto exit_sig;
1062
1063   goto dosig;
1064
1065  stop:
1066   /* Eat multiple attempts to STOP */
1067   if (ISSTATE (myself, PID_STOPPED))
1068     goto done;
1069   handler = (void *) sig_handle_tty_stop;
1070   thissig = myself->getsig (SIGSTOP);
1071
1072  dosig:
1073   /* Dispatch to the appropriate function. */
1074   sigproc_printf ("signal %d, about to call %p", sig, handler);
1075   rc = setup_handler (sig, handler, thissig);
1076
1077  done:
1078   sigproc_printf ("returning %d", rc);
1079   return rc;
1080
1081  exit_sig:
1082   if (sig == SIGQUIT || sig == SIGABRT)
1083     {
1084       CONTEXT c;
1085       c.ContextFlags = CONTEXT_FULL;
1086       GetThreadContext (hMainThread, &c);
1087       if (!try_to_debug ())
1088         stackdump (c.Ebp, 1, 1);
1089       sig |= 0x80;
1090     }
1091   sigproc_printf ("signal %d, about to call do_exit", sig);
1092   signal_exit (sig);
1093   /* Never returns */
1094 }
1095
1096 CRITICAL_SECTION NO_COPY exit_lock;
1097
1098 /* Cover function to `do_exit' to handle exiting even in presence of more
1099    exceptions.  We used to call exit, but a SIGSEGV shouldn't cause atexit
1100    routines to run.  */
1101 static void
1102 signal_exit (int rc)
1103 {
1104   EnterCriticalSection (&exit_lock);
1105   rc = EXIT_SIGNAL | (rc << 8);
1106   if (exit_already++)
1107     myself->exit (rc);
1108
1109   /* We'd like to stop the main thread from executing but when we do that it
1110      causes random, inexplicable hangs.  So, instead, we set up the priority
1111      of this thread really high so that it should do its thing and then exit. */
1112   (void) SetThreadPriority (hMainThread, THREAD_PRIORITY_IDLE);
1113   (void) SetThreadPriority (GetCurrentThread (), THREAD_PRIORITY_TIME_CRITICAL);
1114
1115   /* Unlock any main thread mutos since we're executing with prejudice. */
1116   muto *m;
1117   for (m = muto_start.next;  m != NULL; m = m->next)
1118     if (m->unstable () || m->owner () == mainthread.id)
1119       m->reset ();
1120
1121   user_data->resourcelocks->Delete ();
1122   user_data->resourcelocks->Init ();
1123
1124   if (hExeced)
1125     TerminateProcess (hExeced, rc);
1126
1127   sigproc_printf ("about to call do_exit (%x)", rc);
1128   (void) SetEvent (signal_arrived);
1129   do_exit (rc);
1130 }
1131
1132 HANDLE NO_COPY title_mutex = NULL;
1133
1134 void
1135 events_init (void)
1136 {
1137   char *name;
1138   char mutex_name[MAX_PATH];
1139   /* title_mutex protects modification of console title. It's necessary
1140      while finding console window handle */
1141
1142   if (!(title_mutex = CreateMutex (&sec_all_nih, FALSE,
1143                                    name = shared_name (mutex_name,
1144                                                        "title_mutex", 0))))
1145     api_fatal ("can't create title mutex '%s', %E", name);
1146
1147   ProtectHandle (title_mutex);
1148   new_muto (mask_sync);
1149   windows_system_directory[0] = '\0';
1150   (void) GetSystemDirectory (windows_system_directory, sizeof (windows_system_directory) - 2);
1151   char *end = strchr (windows_system_directory, '\0');
1152   if (end == windows_system_directory)
1153     api_fatal ("can't find windows system directory");
1154   if (end[-1] != '\\')
1155     {
1156       *end++ = '\\';
1157       *end = '\0';
1158     }
1159   windows_system_directory_length = end - windows_system_directory;
1160   debug_printf ("windows_system_directory '%s', windows_system_directory_length %d",
1161                 windows_system_directory, windows_system_directory_length);
1162   debug_printf ("cygwin_hmodule %p", cygwin_hmodule);
1163   InitializeCriticalSection (&exit_lock);
1164 }
1165
1166 void
1167 events_terminate (void)
1168 {
1169   exit_already = 1;
1170 }
1171
1172 extern "C" {
1173 static int __stdcall
1174 call_signal_handler_now ()
1175 {
1176   if (!sigsave.sig)
1177     {
1178       sigproc_printf ("call_signal_handler_now called when no signal active");
1179       return 0;
1180     }
1181
1182   int sa_flags = sigsave.sa_flags;
1183   sigproc_printf ("sa_flags %p", sa_flags);
1184   *sigsave.retaddr_on_stack = sigsave.retaddr;
1185   sigdelayed0 ();
1186   return sa_flags & SA_RESTART;
1187 }
1188 /* This kludge seems to keep a copy of call_signal_handler_now around
1189    even when compiling with -finline-functions. */
1190 static int __stdcall call_signal_handler_now_dummy ()
1191   __attribute__((alias ("call_signal_handler_now")));
1192 };
1193
1194 int
1195 sigframe::call_signal_handler ()
1196 {
1197   return unregister () ? call_signal_handler_now () : 0;
1198 }
1199
1200 #define pid_offset (unsigned)(((_pinfo *)NULL)->pid)
1201 extern "C" {
1202 void __stdcall
1203 reset_signal_arrived ()
1204 {
1205   (void) ResetEvent (signal_arrived);
1206   sigproc_printf ("reset signal_arrived");
1207 }
1208
1209 #undef errno
1210 #define errno ((DWORD volatile) _impure_ptr) + (((char *) &_impure_ptr->_errno) - ((char *) _impure_ptr))
1211
1212 __attribute__((const, used, noinline)) static void
1213 unused_sig_wrapper ()
1214 {
1215 /* Signal cleanup stuff.  Cleans up stack (too bad that we didn't
1216    prototype signal handlers as __stdcall), calls _set_process_mask
1217    to restore any mask, restores any potentially clobbered registers
1218    and returns to original caller. */
1219 __asm__ volatile ("\n\
1220         .text                                                           \n\
1221 _sigreturn:                                                             \n\
1222         addl    $4,%%esp        # Remove argument                       \n\
1223         call    _set_process_mask@4                                     \n\
1224                                                                         \n\
1225         cmpl    $0,%4           # Did a signal come in?                 \n\
1226         jz      1f              # No, if zero                           \n\
1227         movl    %2,%%eax                                                \n\
1228         movl    %%esp,%%ebp                                             \n\
1229         movl    %%eax,36(%%ebp) # Restore return address                \n\
1230         jmp     3f                                                      \n\
1231                                                                         \n\
1232 1:      popl    %%eax           # saved errno                           \n\
1233         testl   %%eax,%%eax     # Is it < 0                             \n\
1234         jl      2f              # yup.  ignore it                       \n\
1235         movl    %1,%%ebx                                                \n\
1236         movl    %%eax,(%%ebx)                                           \n\
1237 2:      popl    %%eax                                                   \n\
1238         popl    %%ebx                                                   \n\
1239         popl    %%ecx                                                   \n\
1240         popl    %%edx                                                   \n\
1241         popl    %%edi                                                   \n\
1242         popl    %%esi                                                   \n\
1243         popf                                                            \n\
1244         popl    %%ebp                                                   \n\
1245         ret                                                             \n\
1246                                                                         \n\
1247 __no_sig_start:                                                         \n\
1248 _sigdelayed:                                                            \n\
1249         pushl   %2                      # original return address       \n\
1250 _sigdelayed0:                                                           \n\
1251         pushl   %%ebp                                                   \n\
1252         movl    %%esp,%%ebp                                             \n\
1253         pushf                                                           \n\
1254         pushl   %%esi                                                   \n\
1255         pushl   %%edi                                                   \n\
1256         pushl   %%edx                                                   \n\
1257         pushl   %%ecx                                                   \n\
1258         pushl   %%ebx                                                   \n\
1259         pushl   %%eax                                                   \n\
1260         pushl   %6                      # saved errno                   \n\
1261 3:      pushl   %3                      # oldmask                       \n\
1262         pushl   %4                      # signal argument               \n\
1263         pushl   $_sigreturn                                             \n\
1264                                                                         \n\
1265         call    _reset_signal_arrived@0                                 \n\
1266         pushl   %5                      # signal number                 \n\
1267         pushl   %7                      # newmask                       \n\
1268                                                                         \n\
1269         call    _set_process_mask@4                                     \n\
1270         movl    $0,%0                   # zero the signal number as a   \n\
1271                                         # flag to the signal handler thread\n\
1272                                         # that it is ok to set up sigsave\n\
1273         popl    %%eax                                                   \n\
1274         jmp     *%%eax                                                  \n\
1275 __no_sig_end:                                                           \n\
1276 " : "=m" (sigsave.sig):  "X" ((char *) &_impure_ptr->_errno),
1277   "g" (sigsave.retaddr), "g" (sigsave.oldmask), "g" (sigsave.sig),
1278     "g" (sigsave.func), "g" (sigsave.saved_errno), "g" (sigsave.newmask)
1279 );
1280 }
1281 }