3 Copyright 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004,
4 2005, 2006, 2007 Red Hat, Inc.
6 This file is part of Cygwin.
8 This software is a copyrighted work licensed under the terms of the
9 Cygwin license. Please consult the file "CYGWIN_LICENSE" for
21 #include "exceptions.h"
27 #include "shared_info.h"
28 #include "perprocess.h"
34 #include "child_info.h"
37 #define CALL_HANDLER_RETRY 20
39 char debugger_command[2 * NT_MAX_PATH + 20];
42 extern void sigdelayed ();
45 extern child_info_spawn *chExeced;
46 int NO_COPY sigExeced;
48 static BOOL WINAPI ctrl_c_handler (DWORD);
49 char windows_system_directory[1024];
50 static size_t windows_system_directory_length;
52 /* This is set to indicate that we have already exited. */
54 static NO_COPY int exit_already = 0;
55 static muto NO_COPY mask_sync;
64 { X (STATUS_ABANDONED_WAIT_0) },
65 { X (STATUS_ACCESS_VIOLATION) },
66 { X (STATUS_ARRAY_BOUNDS_EXCEEDED) },
67 { X (STATUS_BREAKPOINT) },
68 { X (STATUS_CONTROL_C_EXIT) },
69 { X (STATUS_DATATYPE_MISALIGNMENT) },
70 { X (STATUS_FLOAT_DENORMAL_OPERAND) },
71 { X (STATUS_FLOAT_DIVIDE_BY_ZERO) },
72 { X (STATUS_FLOAT_INEXACT_RESULT) },
73 { X (STATUS_FLOAT_INVALID_OPERATION) },
74 { X (STATUS_FLOAT_OVERFLOW) },
75 { X (STATUS_FLOAT_STACK_CHECK) },
76 { X (STATUS_FLOAT_UNDERFLOW) },
77 { X (STATUS_GUARD_PAGE_VIOLATION) },
78 { X (STATUS_ILLEGAL_INSTRUCTION) },
79 { X (STATUS_INTEGER_DIVIDE_BY_ZERO) },
80 { X (STATUS_INTEGER_OVERFLOW) },
81 { X (STATUS_INVALID_DISPOSITION) },
82 { X (STATUS_IN_PAGE_ERROR) },
83 { X (STATUS_NONCONTINUABLE_EXCEPTION) },
84 { X (STATUS_NO_MEMORY) },
85 { X (STATUS_PENDING) },
86 { X (STATUS_PRIVILEGED_INSTRUCTION) },
87 { X (STATUS_SINGLE_STEP) },
88 { X (STATUS_STACK_OVERFLOW) },
89 { X (STATUS_TIMEOUT) },
90 { X (STATUS_USER_APC) },
91 { X (STATUS_WAIT_0) },
96 /* Initialization code. */
99 init_console_handler (bool install_handler)
103 SetConsoleCtrlHandler (ctrl_c_handler, FALSE);
104 SetConsoleCtrlHandler (NULL, FALSE);
106 res = SetConsoleCtrlHandler (ctrl_c_handler, TRUE);
108 res = SetConsoleCtrlHandler (NULL, TRUE);
110 system_printf ("SetConsoleCtrlHandler failed, %E");
114 error_start_init (const char *buf)
118 debugger_command[0] = '\0';
122 char pgm[NT_MAX_PATH];
123 if (!GetModuleFileName (NULL, pgm, NT_MAX_PATH))
124 strcpy (pgm, "cygwin1.dll");
125 for (char *p = strchr (pgm, '\\'); p; p = strchr (p, '\\'))
128 __small_sprintf (debugger_command, "%s \"%s\"", buf, pgm);
132 open_stackdumpfile ()
134 if (myself->progname[0])
137 /* write to progname.stackdump if possible */
138 if (!myself->progname[0])
140 else if ((p = strrchr (myself->progname, '\\')))
143 p = myself->progname;
145 WCHAR corefile[strlen (p) + sizeof (".stackdump")];
146 UNICODE_STRING ucore;
147 OBJECT_ATTRIBUTES attr;
148 /* Create the UNICODE variation of <progname>.stackdump. */
149 RtlInitEmptyUnicodeString (&ucore, corefile,
150 sizeof corefile - sizeof (WCHAR));
151 ucore.Length = sys_mbstowcs (ucore.Buffer,
152 ucore.MaximumLength / sizeof (WCHAR),
153 p, strlen (p)) * sizeof (WCHAR);
154 RtlAppendUnicodeToString (&ucore, L".stackdump");
155 /* Create an object attribute which refers to <progname>.stackdump
157 InitializeObjectAttributes (&attr, &ucore, OBJ_CASE_INSENSITIVE,
158 cygheap->cwd.get_handle (), NULL);
162 /* Try to open it to dump the stack in it. */
163 status = NtCreateFile (&h, GENERIC_WRITE | SYNCHRONIZE, &attr, &io,
164 NULL, FILE_ATTRIBUTE_NORMAL, 0, FILE_OVERWRITE_IF,
165 FILE_SYNCHRONOUS_IO_NONALERT
166 | FILE_OPEN_FOR_BACKUP_INTENT
167 | FILE_OPEN_FOR_RECOVERY, NULL, 0);
168 if (NT_SUCCESS (status))
170 if (!myself->cygstarted)
171 system_printf ("Dumping stack trace to %s", corefile);
173 debug_printf ("Dumping stack trace to %s", corefile);
174 SetStdHandle (STD_ERROR_HANDLE, h);
179 /* Utilities for dumping the stack, etc. */
182 exception (EXCEPTION_RECORD *e, CONTEXT *in)
184 const char *exception_name = NULL;
188 for (int i = 0; status_info[i].name; i++)
190 if (status_info[i].code == e->ExceptionCode)
192 exception_name = status_info[i].name;
199 small_printf ("Exception: %s at eip=%08x\r\n", exception_name, in->Eip);
201 small_printf ("Signal %d at eip=%08x\r\n", e->ExceptionCode, in->Eip);
202 small_printf ("eax=%08x ebx=%08x ecx=%08x edx=%08x esi=%08x edi=%08x\r\n",
203 in->Eax, in->Ebx, in->Ecx, in->Edx, in->Esi, in->Edi);
204 small_printf ("ebp=%08x esp=%08x program=%s, pid %u, thread %s\r\n",
205 in->Ebp, in->Esp, myself->progname, myself->pid, cygthread::name ());
206 small_printf ("cs=%04x ds=%04x es=%04x fs=%04x gs=%04x ss=%04x\r\n",
207 in->SegCs, in->SegDs, in->SegEs, in->SegFs, in->SegGs, in->SegSs);
210 /* A class for manipulating the stack. */
213 int walk (); /* Uses the "old" method */
214 char *next_offset () {return *((char **) sf.AddrFrame.Offset);}
218 STACKFRAME sf; /* For storing the stack information */
219 void init (DWORD, bool, bool); /* Called the first time that stack info is needed */
221 /* Postfix ++ iterates over the stack, returning zero when nothing is left. */
222 int operator ++(int) { return walk (); }
225 /* The number of parameters used in STACKFRAME */
226 #define NPARAMS (sizeof (thestack.sf.Params) / sizeof (thestack.sf.Params[0]))
228 /* This is the main stack frame info for this process. */
229 static NO_COPY stack_info thestack;
231 /* Initialize everything needed to start iterating. */
233 stack_info::init (DWORD ebp, bool wantargs, bool goodframe)
235 # define debp ((DWORD *) ebp)
236 memset (&sf, 0, sizeof (sf));
238 sf.AddrFrame.Offset = ebp;
242 sf.AddrFrame.Offset = (DWORD) &dummy_frame;
244 sf.AddrReturn.Offset = debp[1];
245 sf.AddrFrame.Mode = AddrModeFlat;
250 /* Walk the stack by looking at successive stored 'bp' frames.
251 This is not foolproof. */
256 if ((ebp = (char **) next_offset ()) == NULL)
259 sf.AddrFrame.Offset = (DWORD) ebp;
260 sf.AddrPC.Offset = sf.AddrReturn.Offset;
262 if (!sf.AddrPC.Offset)
263 return 0; /* stack frames are exhausted */
265 /* The return address always follows the stack pointer */
266 sf.AddrReturn.Offset = (DWORD) *++ebp;
270 unsigned nparams = NPARAMS;
272 /* The arguments follow the return address */
273 sf.Params[0] = (DWORD) *++ebp;
274 /* Hack for XP/2K3 WOW64. If the first stack param points to the
275 application entry point, we can only fetch one additional
276 parameter. Accessing anything beyond this address results in
277 a SEGV. This is fixed in Vista/2K8 WOW64. */
278 if (wincap.has_restricted_stack_args () && sf.Params[0] == 0x401000)
280 for (unsigned i = 1; i < nparams; i++)
281 sf.Params[i] = (DWORD) *++ebp;
288 stackdump (DWORD ebp, int open_file, bool isexception)
290 extern unsigned long rlim_core;
291 static bool already_dumped;
293 if (rlim_core == 0UL || (open_file && already_dumped))
297 open_stackdumpfile ();
299 already_dumped = true;
303 thestack.init (ebp, 1, !isexception); /* Initialize from the input CONTEXT */
304 small_printf ("Stack trace:\r\nFrame Function Args\r\n");
305 for (i = 0; i < 16 && thestack++; i++)
307 small_printf ("%08x %08x ", thestack.sf.AddrFrame.Offset,
308 thestack.sf.AddrPC.Offset);
309 for (unsigned j = 0; j < NPARAMS; j++)
310 small_printf ("%s%08x", j == 0 ? " (" : ", ", thestack.sf.Params[j]);
311 small_printf (")\r\n");
313 small_printf ("End of stack trace%s\n",
314 i == 16 ? " (more stack frames may be present)" : "");
318 _cygtls::inside_kernel (CONTEXT *cx)
321 MEMORY_BASIC_INFORMATION m;
323 if (!isinitialized ())
326 memset (&m, 0, sizeof m);
327 if (!VirtualQuery ((LPCVOID) cx->Eip, &m, sizeof m))
328 sigproc_printf ("couldn't get memory info, pc %p, %E", cx->Eip);
330 char *checkdir = (char *) alloca (windows_system_directory_length + 4);
331 memset (checkdir, 0, sizeof (checkdir));
333 # define h ((HMODULE) m.AllocationBase)
334 /* Apparently Windows 95 can sometimes return bogus addresses from
335 GetThreadContext. These resolve to a strange allocation base.
336 These should *never* be treated as interruptible. */
337 if (!h || m.State != MEM_COMMIT)
339 else if (h == user_data->hmodule)
341 else if (!GetModuleFileName (h, checkdir, windows_system_directory_length + 2))
344 res = strncasematch (windows_system_directory, checkdir,
345 windows_system_directory_length);
346 sigproc_printf ("pc %p, h %p, inside_kernel %d", cx->Eip, h, res);
351 /* Temporary (?) function for external callers to get a stack dump */
356 c.ContextFlags = CONTEXT_FULL;
357 GetThreadContext (GetCurrentThread (), &c);
358 stackdump (c.Ebp, 0, 0);
361 #define TIME_TO_WAIT_FOR_DEBUGGER 10000
364 try_to_debug (bool waitloop)
366 WCHAR dbg_cmd[sizeof debugger_command];
368 debug_printf ("debugger_command '%s'", debugger_command);
369 if (*debugger_command == '\0')
371 if (being_debugged ())
373 extern void break_here ();
378 __small_sprintf (strchr (debugger_command, '\0'), " %u", GetCurrentProcessId ());
380 LONG prio = GetThreadPriority (GetCurrentThread ());
381 SetThreadPriority (GetCurrentThread (), THREAD_PRIORITY_HIGHEST);
382 PROCESS_INFORMATION pi = {NULL, 0, 0, 0};
384 STARTUPINFOW si = {0, NULL, NULL, NULL, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL, NULL, NULL, NULL};
385 si.lpReserved = NULL;
390 /* FIXME: need to know handles of all running threads to
391 suspend_all_threads_except (current_thread_id);
394 /* if any of these mutexes is owned, we will fail to start any cygwin app
395 until trapped app exits */
397 lock_ttys::release ();
399 /* prevent recursive exception handling */
400 char* rawenv = GetEnvironmentStrings () ;
401 for (char* p = rawenv; *p != '\0'; p = strchr (p, '\0') + 1)
403 if (strncmp (p, "CYGWIN=", strlen ("CYGWIN=")) == 0)
405 char* q = strstr (p, "error_start") ;
406 /* replace 'error_start=...' with '_rror_start=...' */
410 SetEnvironmentVariable ("CYGWIN", p + strlen ("CYGWIN=")) ;
416 console_printf ("*** starting debugger for pid %u, tid %u\n",
417 cygwin_pid (GetCurrentProcessId ()), GetCurrentThreadId ());
419 sys_mbstowcs (dbg_cmd, sizeof debugger_command, debugger_command);
420 dbg = CreateProcessW (NULL,
425 CREATE_NEW_CONSOLE | CREATE_NEW_PROCESS_GROUP,
432 system_printf ("Failed to start debugger, %E");
437 SetThreadPriority (GetCurrentThread (), THREAD_PRIORITY_IDLE);
438 while (!being_debugged ())
439 low_priority_sleep (0);
443 console_printf ("*** continuing pid %u from debugger call (%d)\n",
444 cygwin_pid (GetCurrentProcessId ()), dbg);
446 SetThreadPriority (GetCurrentThread (), prio);
450 extern "C" DWORD __stdcall RtlUnwind (void *, void *, void *, DWORD);
451 static void __stdcall rtl_unwind (exception_list *, PEXCEPTION_RECORD) __attribute__ ((noinline, regparm (3)));
453 rtl_unwind (exception_list *frame, PEXCEPTION_RECORD e)
463 call _RtlUnwind@16 \n\
468 ": : "r" (frame), "r" (e));
471 /* Main exception handler. */
473 extern "C" char *__progname;
475 _cygtls::handle_exceptions (EXCEPTION_RECORD *e, exception_list *frame, CONTEXT *in, void *)
477 static bool NO_COPY debugging;
478 static int NO_COPY recursed;
479 _cygtls& me = _my_tls;
481 if (debugging && ++debugging < 500000)
483 SetThreadPriority (hMainThread, THREAD_PRIORITY_NORMAL);
487 /* If we've already exited, don't do anything here. Returning 1
488 tells Windows to keep looking for an exception handler. */
489 if (exit_already || e->ExceptionFlags)
493 si.si_code = SI_KERNEL;
494 /* Coerce win32 value to posix value. */
495 switch (e->ExceptionCode)
497 case STATUS_FLOAT_DENORMAL_OPERAND:
498 case STATUS_FLOAT_DIVIDE_BY_ZERO:
499 case STATUS_FLOAT_INVALID_OPERATION:
500 case STATUS_FLOAT_STACK_CHECK:
501 si.si_signo = SIGFPE;
502 si.si_code = FPE_FLTSUB;
504 case STATUS_FLOAT_INEXACT_RESULT:
505 si.si_signo = SIGFPE;
506 si.si_code = FPE_FLTRES;
508 case STATUS_FLOAT_OVERFLOW:
509 si.si_signo = SIGFPE;
510 si.si_code = FPE_FLTOVF;
512 case STATUS_FLOAT_UNDERFLOW:
513 si.si_signo = SIGFPE;
514 si.si_code = FPE_FLTUND;
516 case STATUS_INTEGER_DIVIDE_BY_ZERO:
517 si.si_signo = SIGFPE;
518 si.si_code = FPE_INTDIV;
520 case STATUS_INTEGER_OVERFLOW:
521 si.si_signo = SIGFPE;
522 si.si_code = FPE_INTOVF;
525 case STATUS_ILLEGAL_INSTRUCTION:
526 si.si_signo = SIGILL;
527 si.si_code = ILL_ILLOPC;
530 case STATUS_PRIVILEGED_INSTRUCTION:
531 si.si_signo = SIGILL;
532 si.si_code = ILL_PRVOPC;
535 case STATUS_NONCONTINUABLE_EXCEPTION:
536 si.si_signo = SIGILL;
537 si.si_code = ILL_ILLADR;
541 si.si_signo = SIGALRM;
544 case STATUS_GUARD_PAGE_VIOLATION:
545 si.si_signo = SIGBUS;
546 si.si_code = BUS_OBJERR;
549 case STATUS_DATATYPE_MISALIGNMENT:
550 si.si_signo = SIGBUS;
551 si.si_code = BUS_ADRALN;
554 case STATUS_ACCESS_VIOLATION:
555 switch (mmap_is_attached_or_noreserve ((void *)e->ExceptionInformation[1],
558 case MMAP_NORESERVE_COMMITED:
560 case MMAP_RAISE_SIGBUS: /* MAP_NORESERVE page, commit failed, or
561 access to mmap page beyond EOF. */
562 si.si_signo = SIGBUS;
563 si.si_code = BUS_OBJERR;
566 MEMORY_BASIC_INFORMATION m;
567 VirtualQuery ((PVOID) e->ExceptionInformation[1], &m, sizeof m);
568 si.si_signo = SIGSEGV;
569 si.si_code = m.State == MEM_FREE ? SEGV_MAPERR : SEGV_ACCERR;
574 case STATUS_ARRAY_BOUNDS_EXCEEDED:
575 case STATUS_IN_PAGE_ERROR:
576 case STATUS_NO_MEMORY:
577 case STATUS_INVALID_DISPOSITION:
578 case STATUS_STACK_OVERFLOW:
579 si.si_signo = SIGSEGV;
580 si.si_code = SEGV_MAPERR;
583 case STATUS_CONTROL_C_EXIT:
584 si.si_signo = SIGINT;
587 case STATUS_INVALID_HANDLE:
588 /* CloseHandle will throw this exception if it is given an
589 invalid handle. We don't care about the exception; we just
590 want CloseHandle to return an error. This can be revisited
591 if gcc ever supports Windows style structured exception
596 /* If we don't recognize the exception, we have to assume that
597 we are doing structured exception handling, and we let
598 something else handle it. */
602 rtl_unwind (frame, e);
604 debug_printf ("In cygwin_except_handler exc %p at %p sp %p", e->ExceptionCode, in->Eip, in->Esp);
605 debug_printf ("In cygwin_except_handler sig %d at %p", si.si_signo, in->Eip);
607 if (global_sigs[si.si_signo].sa_mask & SIGTOMASK (si.si_signo))
608 syscall_printf ("signal %d, masked %p", si.si_signo,
609 global_sigs[si.si_signo].sa_mask);
611 debug_printf ("In cygwin_except_handler calling %p",
612 global_sigs[si.si_signo].sa_handler);
614 DWORD *ebp = (DWORD *) in->Esp;
615 for (DWORD *bpend = (DWORD *) __builtin_frame_address (0); ebp > bpend; ebp--)
616 if (*ebp == in->SegCs && ebp[-1] == in->Eip)
622 if (me.fault_guarded ())
623 me.return_from_fault ();
625 me.copy_context (in);
626 if (!cygwin_finished_initializing
628 || (void *) global_sigs[si.si_signo].sa_handler == (void *) SIG_DFL
629 || (void *) global_sigs[si.si_signo].sa_handler == (void *) SIG_IGN
630 || (void *) global_sigs[si.si_signo].sa_handler == (void *) SIG_ERR)
632 /* Print the exception to the console */
633 if (!myself->cygstarted)
634 for (int i = 0; status_info[i].name; i++)
635 if (status_info[i].code == e->ExceptionCode)
637 system_printf ("Exception: %s", status_info[i].name);
641 /* Another exception could happen while tracing or while exiting.
642 Only do this once. */
644 system_printf ("Error while dumping state (probably corrupted stack)");
647 if (try_to_debug (0))
653 open_stackdumpfile ();
655 stackdump ((DWORD) ebp, 0, 1);
658 if (e->ExceptionCode == STATUS_ACCESS_VIOLATION)
661 if (si.si_code == SEGV_ACCERR) /* Address present */
663 if (e->ExceptionInformation[0]) /* Write access */
665 if (!me.inside_kernel (in)) /* User space */
667 klog (LOG_INFO, "%s[%d]: segfault at %08x rip %08x rsp %08x error %d",
668 __progname, myself->pid,
669 e->ExceptionInformation[1], in->Eip, in->Esp,
670 ((in->Eip >= 0x61000000 && in->Eip < 0x61200000)
671 ? 0 : 4) | (e->ExceptionInformation[0] << 1));
674 me.signal_exit (0x80 | si.si_signo); // Flag signal + core dump
677 si.si_addr = (void *) in->Eip;
678 si.si_errno = si.si_pid = si.si_uid = 0;
680 sig_send (NULL, si, &me); // Signal myself
682 e->ExceptionFlags = 0;
683 /* The OS adds an exception list frame to the stack. It expects to be
684 able to remove this entry after the exception handler returned.
685 However, when unwinding to our frame, our frame becomes the uppermost
686 frame on the stack (%fs:0 points to frame). This way, our frame
687 is removed from the exception stack and just disappears. So, we can't
688 just return here or things will be screwed up by the helpful function
689 in (presumably) ntdll.dll.
691 So, instead, we will do the equivalent of a longjmp here and return
692 to the caller without visiting any of the helpful code installed prior
693 to this function. This should work ok, since a longjmp() out of here has
694 to work if linux signal semantics are to be maintained. */
696 SetThreadContext (GetCurrentThread (), in);
697 return 0; /* Never actually returns. This is just to keep gcc happy. */
700 /* Utilities to call a user supplied exception handler. */
702 #define SIG_NONMASKABLE (SIGTOMASK (SIGKILL) | SIGTOMASK (SIGSTOP))
704 /* Non-raceable sigsuspend
705 * Note: This implementation is based on the Single UNIX Specification
706 * man page. This indicates that sigsuspend always returns -1 and that
707 * attempts to block unblockable signals will be silently ignored.
708 * This is counter to what appears to be documented in some UNIX
709 * man pages, e.g. Linux.
712 handle_sigsuspend (sigset_t tempmask)
714 if (&_my_tls != _main_tls)
716 cancelable_wait (signal_arrived, INFINITE, cw_cancel_self);
720 sigset_t oldmask = _my_tls.sigmask; // Remember for restoration
722 set_signal_mask (tempmask, _my_tls.sigmask);
723 sigproc_printf ("oldmask %p, newmask %p", oldmask, tempmask);
725 pthread_testcancel ();
726 cancelable_wait (signal_arrived, INFINITE);
728 set_sig_errno (EINTR); // Per POSIX
730 /* A signal dispatch function will have been added to our stack and will
731 be hit eventually. Set the old mask to be restored when the signal
732 handler returns and indicate its presence by modifying deltamask. */
734 _my_tls.deltamask |= SIG_NONMASKABLE;
735 _my_tls.oldmask = oldmask; // Will be restored by signal handler
739 extern DWORD exec_exit; // Possible exit value for exec
743 sig_handle_tty_stop (int sig)
746 /* Silently ignore attempts to suspend if there is no accommodating
747 cygwin parent to deal with this behavior. */
748 if (!myself->cygstarted)
750 myself->process_state &= ~PID_STOPPED;
754 myself->stopsig = sig;
755 myself->alert_parent (sig);
756 sigproc_printf ("process %d stopped by signal %d", myself->pid, sig);
759 w4[1] = signal_arrived;
760 switch (WaitForMultipleObjects (2, w4, TRUE, INFINITE))
763 case WAIT_OBJECT_0 + 1:
764 reset_signal_arrived ();
765 myself->alert_parent (SIGCONT);
768 api_fatal ("WaitSingleObject failed, %E");
776 _cygtls::interrupt_now (CONTEXT *cx, int sig, void *handler,
777 struct sigaction& siga)
781 if (incyg || spinning || locked () || inside_kernel (cx))
785 push ((__stack_t) cx->Eip);
786 interrupt_setup (sig, handler, siga);
788 SetThreadContext (*this, cx); /* Restart the thread in a new location */
795 _cygtls::interrupt_setup (int sig, void *handler, struct sigaction& siga)
797 push ((__stack_t) sigdelayed);
798 deltamask = siga.sa_mask & ~SIG_NONMASKABLE;
799 sa_flags = siga.sa_flags;
800 func = (void (*) (int)) handler;
801 if (siga.sa_flags & SA_RESETHAND)
802 siga.sa_handler = SIG_DFL;
803 saved_errno = -1; // Flag: no errno to save
804 if (handler == sig_handle_tty_stop)
807 myself->process_state |= PID_STOPPED;
810 this->sig = sig; // Should always be last thing set to avoid a race
821 /* Clear any waiting threads prior to dispatching to handler function */
822 int res = SetEvent (signal_arrived); // For an EINTR case
823 proc_subproc (PROC_CLEARWAIT, 1);
824 sigproc_printf ("armed signal_arrived %p, sig %d, res %d", signal_arrived,
828 extern "C" void __stdcall
829 set_sig_errno (int e)
831 *_my_tls.errno_addr = e;
832 _my_tls.saved_errno = e;
833 // sigproc_printf ("errno %d", e);
836 static int setup_handler (int, void *, struct sigaction&, _cygtls *tls)
837 __attribute__((regparm(3)));
839 setup_handler (int sig, void *handler, struct sigaction& siga, _cygtls *tls)
842 bool interrupted = false;
846 sigproc_printf ("trying to send sig %d but signal %d already armed",
851 for (int i = 0; i < CALL_HANDLER_RETRY; i++)
856 sigproc_printf ("controlled interrupt. stackptr %p, stack %p, stackptr[-1] %p",
857 tls->stackptr, tls->stack, tls->stackptr[-1]);
858 tls->interrupt_setup (sig, handler, siga);
866 HANDLE hth = (HANDLE) *tls;
868 /* Suspend the thread which will receive the signal.
869 For Windows 95, we also have to ensure that the addresses returned by
870 GetThreadContext are valid.
871 If one of these conditions is not true we loop for a fixed number of times
872 since we don't want to stall the signal handler. FIXME: Will this result in
874 If the thread is already suspended (which can occur when a program has called
875 SuspendThread on itself) then just queue the signal. */
878 sigproc_printf ("suspending mainthread");
880 cx.ContextFlags = CONTEXT_CONTROL | CONTEXT_INTEGER;
881 if (!GetThreadContext (hth, &cx))
882 memset (&cx, 0, sizeof cx);
883 sigproc_printf ("suspending mainthread PC %p", cx.Eip);
885 res = SuspendThread (hth);
886 /* Just set pending if thread is already suspended */
892 cx.ContextFlags = CONTEXT_CONTROL | CONTEXT_INTEGER;
893 if (!GetThreadContext (hth, &cx))
894 system_printf ("couldn't get context of main thread, %E");
896 interrupted = tls->interrupt_now (&cx, sig, handler, siga);
898 res = ResumeThread (hth);
902 sigproc_printf ("couldn't interrupt. trying again.");
903 low_priority_sleep (0);
907 sigproc_printf ("signal %d %sdelivered", sig, interrupted ? "" : "not ");
912 has_visible_window_station ()
918 /* Check if the process is associated with a visible window station.
919 These are processes running on the local desktop as well as processes
920 running in terminal server sessions.
921 Processes running in a service session not explicitely associated
922 with the desktop (using the "Allow service to interact with desktop"
923 property) are running in an invisible window station. */
924 if ((station_hdl = GetProcessWindowStation ())
925 && GetUserObjectInformationA (station_hdl, UOI_FLAGS, &uof,
927 && (uof.dwFlags & WSF_VISIBLE))
932 /* Keyboard interrupt handler. */
934 ctrl_c_handler (DWORD type)
936 static bool saw_close;
939 if (!cygwin_finished_initializing)
941 if (myself->cygstarted) /* Was this process created by a cygwin process? */
942 return TRUE; /* Yes. Let the parent eventually handle CTRL-C issues. */
943 debug_printf ("exiting with status %p", STATUS_CONTROL_C_EXIT);
944 ExitProcess (STATUS_CONTROL_C_EXIT);
947 _my_tls.remove (INFINITE);
950 if (type == CTRL_C_EVENT || type == CTRL_BREAK_EVENT)
951 proc_subproc (PROC_KILLFORKED, 0);
954 /* Return FALSE to prevent an "End task" dialog box from appearing
955 for each Cygwin process window that's open when the computer
956 is shut down or console window is closed. */
958 if (type == CTRL_SHUTDOWN_EVENT)
961 /* Don't send a signal. Only NT service applications and their child
962 processes will receive this event and the services typically already
963 handle the shutdown action when getting the SERVICE_CONTROL_SHUTDOWN
965 sig_send (NULL, SIGTERM);
970 if (myself->ctty != -1)
972 if (type == CTRL_CLOSE_EVENT)
974 sig_send (NULL, SIGHUP);
978 if (!saw_close && type == CTRL_LOGOFF_EVENT)
980 /* The CTRL_LOGOFF_EVENT is sent when *any* user logs off.
981 The below code sends a SIGHUP only if it is not performing the
982 default activity for SIGHUP. Note that it is possible for two
983 SIGHUP signals to arrive if a process group leader is exiting
984 too. Getting this 100% right is saved for a future cygwin mailing
986 if (global_sigs[SIGHUP].sa_handler != SIG_DFL)
988 sig_send (myself_nowait, SIGHUP);
997 chExeced->set_saw_ctrl_c ();
1001 /* We're only the process group leader when we have a valid pinfo structure.
1002 If we don't have one, then the parent "stub" will handle the signal. */
1003 if (!pinfo (cygwin_pid (GetCurrentProcessId ())))
1006 tty_min *t = cygwin_shared->tty.get_tty (myself->ctty);
1007 /* Ignore this if we're not the process group leader since it should be handled
1008 *by* the process group leader. */
1009 if (myself->ctty != -1 && t->getpgid () == myself->pid &&
1010 (GetTickCount () - t->last_ctrl_c) >= MIN_CTRL_C_SLOP)
1011 /* Otherwise we just send a SIGINT to the process group and return TRUE (to indicate
1012 that we have handled the signal). At this point, type should be
1013 a CTRL_C_EVENT or CTRL_BREAK_EVENT. */
1016 /* If intr and quit are both mapped to ^C, send SIGQUIT on ^BREAK */
1017 if (type == CTRL_BREAK_EVENT
1018 && t->ti.c_cc[VINTR] == 3 && t->ti.c_cc[VQUIT] == 3)
1020 t->last_ctrl_c = GetTickCount ();
1021 killsys (-myself->pid, sig);
1022 t->last_ctrl_c = GetTickCount ();
1029 /* Function used by low level sig wrappers. */
1030 extern "C" void __stdcall
1031 set_process_mask (sigset_t newmask)
1033 set_signal_mask (newmask, _my_tls.sigmask);
1039 /* check that sig is in right range */
1040 if (sig < 0 || sig >= NSIG)
1043 syscall_printf ("signal %d out of range", sig);
1046 mask_sync.acquire (INFINITE);
1047 sigset_t mask = _my_tls.sigmask;
1048 sigaddset (&mask, sig);
1049 set_signal_mask (mask, _my_tls.sigmask);
1050 mask_sync.release ();
1057 /* check that sig is in right range */
1058 if (sig < 0 || sig >= NSIG)
1061 syscall_printf ("signal %d out of range", sig);
1064 mask_sync.acquire (INFINITE);
1065 sigset_t mask = _my_tls.sigmask;
1066 sigdelset (&mask, sig);
1067 set_signal_mask (mask, _my_tls.sigmask);
1068 mask_sync.release ();
1072 extern "C" _sig_func_ptr
1073 sigset (int sig, _sig_func_ptr func)
1075 sig_dispatch_pending ();
1078 /* check that sig is in right range */
1079 if (sig < 0 || sig >= NSIG || sig == SIGKILL || sig == SIGSTOP)
1082 syscall_printf ("SIG_ERR = sigset (%d, %p)", sig, func);
1083 return (_sig_func_ptr) SIG_ERR;
1086 mask_sync.acquire (INFINITE);
1087 sigset_t mask = _my_tls.sigmask;
1088 /* If sig was in the signal mask return SIG_HOLD, otherwise return the
1089 previous disposition. */
1090 if (sigismember (&mask, sig))
1093 prev = global_sigs[sig].sa_handler;
1094 /* If func is SIG_HOLD, add sig to the signal mask, otherwise set the
1095 disposition to func and remove sig from the signal mask. */
1096 if (func == SIG_HOLD)
1097 sigaddset (&mask, sig);
1100 /* No error checking. The test which could return SIG_ERR has already
1103 sigdelset (&mask, sig);
1105 set_signal_mask (mask, _my_tls.sigmask);
1106 mask_sync.release ();
1113 return sigset (sig, SIG_IGN) == SIG_ERR ? -1 : 0;
1116 /* Update the signal mask for this process and return the old mask.
1117 Called from sigdelayed */
1119 set_process_mask_delta ()
1121 mask_sync.acquire (INFINITE);
1122 sigset_t newmask, oldmask;
1124 if (_my_tls.deltamask & SIG_NONMASKABLE)
1125 oldmask = _my_tls.oldmask; /* from handle_sigsuspend */
1127 oldmask = _my_tls.sigmask;
1128 newmask = (oldmask | _my_tls.deltamask) & ~SIG_NONMASKABLE;
1129 sigproc_printf ("oldmask %p, newmask %p, deltamask %p", oldmask, newmask,
1131 _my_tls.sigmask = newmask;
1132 mask_sync.release ();
1136 /* Set the signal mask for this process.
1137 Note that some signals are unmaskable, as in UNIX. */
1138 extern "C" void __stdcall
1139 set_signal_mask (sigset_t newmask, sigset_t& oldmask)
1142 if (&_my_tls == _sig_tls)
1143 small_printf ("********* waiting in signal thread\n");
1145 mask_sync.acquire (INFINITE);
1146 newmask &= ~SIG_NONMASKABLE;
1147 sigset_t mask_bits = oldmask & ~newmask;
1148 sigproc_printf ("oldmask %p, newmask %p, mask_bits %p", oldmask, newmask,
1152 sig_dispatch_pending (true);
1154 sigproc_printf ("not calling sig_dispatch_pending");
1155 mask_sync.release ();
1159 sigpacket::process ()
1162 struct sigaction dummy = global_sigs[SIGSTOP];
1164 if (si.si_signo != SIGCONT)
1165 continue_now = false;
1168 continue_now = myself->process_state & PID_STOPPED;
1169 myself->stopsig = 0;
1170 myself->process_state &= ~PID_STOPPED;
1171 /* Clear pending stop signals */
1172 sig_clear (SIGSTOP);
1173 sig_clear (SIGTSTP);
1174 sig_clear (SIGTTIN);
1175 sig_clear (SIGTTOU);
1180 sigproc_printf ("signal %d processing", si.si_signo);
1181 struct sigaction& thissig = global_sigs[si.si_signo];
1183 myself->rusage_self.ru_nsignals++;
1187 if (!hExeced || (void *) thissig.sa_handler == (void *) SIG_IGN)
1188 handler = (void *) thissig.sa_handler;
1194 if (si.si_signo == SIGKILL)
1196 if (si.si_signo == SIGSTOP)
1198 sig_clear (SIGCONT);
1204 bool insigwait_mask;
1205 if ((masked = ISSTATE (myself, PID_STOPPED)))
1206 insigwait_mask = false;
1208 insigwait_mask = !handler && (tls = _cygtls::find_tls (si.si_signo));
1210 insigwait_mask = sigismember (&tls->sigwait_mask, si.si_signo);
1213 goto thread_specific;
1216 /* nothing to do */;
1217 else if (sigismember (mask, si.si_signo))
1220 masked = sigismember (&tls->sigmask, si.si_signo);
1227 sigproc_printf ("signal %d blocked", si.si_signo);
1232 /* Clear pending SIGCONT on stop signals */
1233 if (si.si_signo == SIGTSTP || si.si_signo == SIGTTIN || si.si_signo == SIGTTOU)
1234 sig_clear (SIGCONT);
1237 if (being_debugged ())
1239 char sigmsg[sizeof (_CYGWIN_SIGNAL_STRING " 0xffffffff")];
1240 __small_sprintf (sigmsg, _CYGWIN_SIGNAL_STRING " %p", si.si_signo);
1241 OutputDebugString (sigmsg);
1245 if (handler == (void *) SIG_DFL)
1248 goto thread_specific;
1249 if (si.si_signo == SIGCHLD || si.si_signo == SIGIO || si.si_signo == SIGCONT || si.si_signo == SIGWINCH
1250 || si.si_signo == SIGURG)
1252 sigproc_printf ("default signal %d ignored", si.si_signo);
1254 SetEvent (signal_arrived);
1258 if (si.si_signo == SIGTSTP || si.si_signo == SIGTTIN || si.si_signo == SIGTTOU)
1264 if (handler == (void *) SIG_IGN)
1266 sigproc_printf ("signal %d ignored", si.si_signo);
1270 if (handler == (void *) SIG_ERR)
1273 tls->set_siginfo (this);
1277 /* Eat multiple attempts to STOP */
1278 if (ISSTATE (myself, PID_STOPPED))
1280 handler = (void *) sig_handle_tty_stop;
1284 /* Dispatch to the appropriate function. */
1285 sigproc_printf ("signal %d, about to call %p", si.si_signo, handler);
1286 rc = setup_handler (si.si_signo, handler, thissig, tls);
1291 sigproc_printf ("returning %d", rc);
1295 tls->sig = si.si_signo;
1296 tls->set_siginfo (this);
1297 sigproc_printf ("releasing sigwait for thread");
1298 SetEvent (tls->event);
1302 if (si.si_signo == SIGQUIT || si.si_signo == SIGABRT)
1305 c.ContextFlags = CONTEXT_FULL;
1306 GetThreadContext (hMainThread, &c);
1307 tls->copy_context (&c);
1308 si.si_signo |= 0x80;
1310 sigproc_printf ("signal %d, about to call do_exit", si.si_signo);
1311 tls->signal_exit (si.si_signo); /* never returns */
1314 /* Cover function to `do_exit' to handle exiting even in presence of more
1315 exceptions. We used to call exit, but a SIGSEGV shouldn't cause atexit
1318 _cygtls::signal_exit (int rc)
1322 sigproc_printf ("terminating captive process");
1323 TerminateProcess (hExeced, sigExeced = rc);
1326 signal_debugger (rc & 0x7f);
1327 if ((rc & 0x80) && !try_to_debug ())
1328 stackdump (thread_context.ebp, 1, 1);
1330 lock_process until_exit (true);
1331 if (hExeced || exit_state > ES_PROCESS_LOCKED)
1334 /* Starve other threads in a vain attempt to stop them from doing something
1336 SetThreadPriority (GetCurrentThread (), THREAD_PRIORITY_TIME_CRITICAL);
1338 sigproc_printf ("about to call do_exit (%x)", rc);
1339 SetEvent (signal_arrived);
1346 mask_sync.init ("mask_sync");
1347 windows_system_directory[0] = '\0';
1348 GetSystemDirectory (windows_system_directory, sizeof (windows_system_directory) - 2);
1349 char *end = strchr (windows_system_directory, '\0');
1350 if (end == windows_system_directory)
1351 api_fatal ("can't find windows system directory");
1352 if (end[-1] != '\\')
1357 windows_system_directory_length = end - windows_system_directory;
1358 debug_printf ("windows_system_directory '%s', windows_system_directory_length %d",
1359 windows_system_directory, windows_system_directory_length);
1369 _cygtls::call_signal_handler ()
1371 int this_sa_flags = 0;
1372 /* Call signal handler. */
1376 this_sa_flags = sa_flags;
1380 reset_signal_arrived ();
1381 sigset_t this_oldmask = set_process_mask_delta ();
1382 int this_errno = saved_errno;
1384 unlock (); // make sure synchronized
1386 if (!(this_sa_flags & SA_SIGINFO))
1388 void (*sigfunc) (int) = func;
1393 siginfo_t thissi = infodata;
1394 void (*sigact) (int, siginfo_t *, void *) = (void (*) (int, siginfo_t *, void *)) func;
1395 /* no ucontext_t information provided yet */
1396 sigact (thissig, &thissi, NULL);
1399 set_signal_mask (this_oldmask, _my_tls.sigmask);
1400 if (this_errno >= 0)
1401 set_errno (this_errno);
1404 return this_sa_flags & SA_RESTART;
1407 extern "C" void __stdcall
1408 reset_signal_arrived ()
1410 // NEEDED? WaitForSingleObject (signal_arrived, 10);
1411 ResetEvent (signal_arrived);
1412 sigproc_printf ("reset signal_arrived");
1413 if (_my_tls.stackptr > _my_tls.stack)
1414 debug_printf ("stackptr[-1] %p", _my_tls.stackptr[-1]);
1418 _cygtls::copy_context (CONTEXT *c)
1420 memcpy (&thread_context, c, (&thread_context._internal - (unsigned char *) &thread_context));
1424 _cygtls::signal_debugger (int sig)
1426 if (isinitialized () && being_debugged ())
1428 char sigmsg[2 * sizeof (_CYGWIN_SIGNAL_STRING " ffffffff ffffffff")];
1429 __small_sprintf (sigmsg, _CYGWIN_SIGNAL_STRING " %d %p %p", sig, thread_id, &thread_context);
1430 OutputDebugString (sigmsg);