OSDN Git Service

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