3 Copyright 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004,
4 2005, 2006, 2007, 2008, 2009 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
14 #include "miscfuncs.h"
25 #include "shared_info.h"
26 #include "perprocess.h"
31 #include "child_info.h"
34 #define CALL_HANDLER_RETRY 20
36 char debugger_command[2 * NT_MAX_PATH + 20];
39 extern void sigdelayed ();
42 extern child_info_spawn *chExeced;
44 static BOOL WINAPI ctrl_c_handler (DWORD);
45 static WCHAR windows_system_directory[1024];
46 static size_t windows_system_directory_length;
48 /* This is set to indicate that we have already exited. */
50 static NO_COPY int exit_already = 0;
51 static muto NO_COPY mask_sync;
60 { X (STATUS_ABANDONED_WAIT_0) },
61 { X (STATUS_ACCESS_VIOLATION) },
62 { X (STATUS_ARRAY_BOUNDS_EXCEEDED) },
63 { X (STATUS_BREAKPOINT) },
64 { X (STATUS_CONTROL_C_EXIT) },
65 { X (STATUS_DATATYPE_MISALIGNMENT) },
66 { X (STATUS_FLOAT_DENORMAL_OPERAND) },
67 { X (STATUS_FLOAT_DIVIDE_BY_ZERO) },
68 { X (STATUS_FLOAT_INEXACT_RESULT) },
69 { X (STATUS_FLOAT_INVALID_OPERATION) },
70 { X (STATUS_FLOAT_OVERFLOW) },
71 { X (STATUS_FLOAT_STACK_CHECK) },
72 { X (STATUS_FLOAT_UNDERFLOW) },
73 { X (STATUS_GUARD_PAGE_VIOLATION) },
74 { X (STATUS_ILLEGAL_INSTRUCTION) },
75 { X (STATUS_INTEGER_DIVIDE_BY_ZERO) },
76 { X (STATUS_INTEGER_OVERFLOW) },
77 { X (STATUS_INVALID_DISPOSITION) },
78 { X (STATUS_IN_PAGE_ERROR) },
79 { X (STATUS_NONCONTINUABLE_EXCEPTION) },
80 { X (STATUS_NO_MEMORY) },
81 { X (STATUS_PENDING) },
82 { X (STATUS_PRIVILEGED_INSTRUCTION) },
83 { X (STATUS_SINGLE_STEP) },
84 { X (STATUS_STACK_OVERFLOW) },
85 { X (STATUS_TIMEOUT) },
86 { X (STATUS_USER_APC) },
87 { X (STATUS_WAIT_0) },
92 /* Initialization code. */
95 init_console_handler (bool install_handler)
99 SetConsoleCtrlHandler (ctrl_c_handler, FALSE);
100 SetConsoleCtrlHandler (NULL, FALSE);
102 res = SetConsoleCtrlHandler (ctrl_c_handler, TRUE);
104 res = SetConsoleCtrlHandler (NULL, TRUE);
106 system_printf ("SetConsoleCtrlHandler failed, %E");
110 error_start_init (const char *buf)
114 debugger_command[0] = '\0';
118 char pgm[NT_MAX_PATH];
119 if (!GetModuleFileName (NULL, pgm, NT_MAX_PATH))
120 strcpy (pgm, "cygwin1.dll");
121 for (char *p = strchr (pgm, '\\'); p; p = strchr (p, '\\'))
124 __small_sprintf (debugger_command, "%s \"%s\"", buf, pgm);
128 open_stackdumpfile ()
130 if (myself->progname[0])
133 /* write to progname.stackdump if possible */
134 if (!myself->progname[0])
136 else if ((p = strrchr (myself->progname, '\\')))
139 p = myself->progname;
141 WCHAR corefile[strlen (p) + sizeof (".stackdump")];
142 UNICODE_STRING ucore;
143 OBJECT_ATTRIBUTES attr;
144 /* Create the UNICODE variation of <progname>.stackdump. */
145 RtlInitEmptyUnicodeString (&ucore, corefile,
146 sizeof corefile - sizeof (WCHAR));
147 ucore.Length = sys_mbstowcs (ucore.Buffer,
148 ucore.MaximumLength / sizeof (WCHAR),
149 p, strlen (p)) * sizeof (WCHAR);
150 RtlAppendUnicodeToString (&ucore, L".stackdump");
151 /* Create an object attribute which refers to <progname>.stackdump
152 in Cygwin's cwd. Stick to caseinsensitivity. */
153 InitializeObjectAttributes (&attr, &ucore, OBJ_CASE_INSENSITIVE,
154 cygheap->cwd.get_handle (), NULL);
158 /* Try to open it to dump the stack in it. */
159 status = NtCreateFile (&h, GENERIC_WRITE | SYNCHRONIZE, &attr, &io,
160 NULL, FILE_ATTRIBUTE_NORMAL, 0, FILE_OVERWRITE_IF,
161 FILE_SYNCHRONOUS_IO_NONALERT
162 | FILE_OPEN_FOR_BACKUP_INTENT, NULL, 0);
163 if (NT_SUCCESS (status))
165 if (!myself->cygstarted)
166 system_printf ("Dumping stack trace to %S", &ucore);
168 debug_printf ("Dumping stack trace to %S", &ucore);
169 SetStdHandle (STD_ERROR_HANDLE, h);
174 /* Utilities for dumping the stack, etc. */
177 exception (EXCEPTION_RECORD *e, CONTEXT *in)
179 const char *exception_name = NULL;
183 for (int i = 0; status_info[i].name; i++)
185 if (status_info[i].code == e->ExceptionCode)
187 exception_name = status_info[i].name;
194 small_printf ("Exception: %s at eip=%08x\r\n", exception_name, in->Eip);
196 small_printf ("Signal %d at eip=%08x\r\n", e->ExceptionCode, in->Eip);
197 small_printf ("eax=%08x ebx=%08x ecx=%08x edx=%08x esi=%08x edi=%08x\r\n",
198 in->Eax, in->Ebx, in->Ecx, in->Edx, in->Esi, in->Edi);
199 small_printf ("ebp=%08x esp=%08x program=%s, pid %u, thread %s\r\n",
200 in->Ebp, in->Esp, myself->progname, myself->pid, cygthread::name ());
201 small_printf ("cs=%04x ds=%04x es=%04x fs=%04x gs=%04x ss=%04x\r\n",
202 in->SegCs, in->SegDs, in->SegEs, in->SegFs, in->SegGs, in->SegSs);
205 /* A class for manipulating the stack. */
208 int walk (); /* Uses the "old" method */
209 char *next_offset () {return *((char **) sf.AddrFrame.Offset);}
213 STACKFRAME sf; /* For storing the stack information */
214 void init (DWORD, bool, bool); /* Called the first time that stack info is needed */
216 /* Postfix ++ iterates over the stack, returning zero when nothing is left. */
217 int operator ++(int) { return walk (); }
220 /* The number of parameters used in STACKFRAME */
221 #define NPARAMS (sizeof (thestack.sf.Params) / sizeof (thestack.sf.Params[0]))
223 /* This is the main stack frame info for this process. */
224 static NO_COPY stack_info thestack;
226 /* Initialize everything needed to start iterating. */
228 stack_info::init (DWORD ebp, bool wantargs, bool goodframe)
230 # define debp ((DWORD *) ebp)
231 memset (&sf, 0, sizeof (sf));
233 sf.AddrFrame.Offset = ebp;
237 sf.AddrFrame.Offset = (DWORD) &dummy_frame;
239 sf.AddrReturn.Offset = debp[1];
240 sf.AddrFrame.Mode = AddrModeFlat;
245 extern "C" void _cygwin_exit_return ();
247 /* Walk the stack by looking at successive stored 'bp' frames.
248 This is not foolproof. */
254 if ((void (*) ()) sf.AddrPC.Offset == _cygwin_exit_return)
255 return 0; /* stack frames are exhausted */
257 if (((ebp = (char **) next_offset ()) == NULL) || (ebp >= (char **) cygwin_hmodule))
260 sf.AddrFrame.Offset = (DWORD) ebp;
261 sf.AddrPC.Offset = sf.AddrReturn.Offset;
263 /* The return address always follows the stack pointer */
264 sf.AddrReturn.Offset = (DWORD) *++ebp;
268 unsigned nparams = NPARAMS;
270 /* The arguments follow the return address */
271 sf.Params[0] = (DWORD) *++ebp;
272 /* Hack for XP/2K3 WOW64. If the first stack param points to the
273 application entry point, we can only fetch one additional
274 parameter. Accessing anything beyond this address results in
275 a SEGV. This is fixed in Vista/2K8 WOW64. */
276 if (wincap.has_restricted_stack_args () && sf.Params[0] == 0x401000)
278 for (unsigned i = 1; i < nparams; i++)
279 sf.Params[i] = (DWORD) *++ebp;
286 stackdump (DWORD ebp, int open_file, bool isexception)
288 extern unsigned long rlim_core;
289 static bool already_dumped;
291 if (rlim_core == 0UL || (open_file && already_dumped))
295 open_stackdumpfile ();
297 already_dumped = true;
301 thestack.init (ebp, 1, !isexception); /* Initialize from the input CONTEXT */
302 small_printf ("Stack trace:\r\nFrame Function Args\r\n");
303 for (i = 0; i < 16 && thestack++; i++)
305 small_printf ("%08x %08x ", thestack.sf.AddrFrame.Offset,
306 thestack.sf.AddrPC.Offset);
307 for (unsigned j = 0; j < NPARAMS; j++)
308 small_printf ("%s%08x", j == 0 ? " (" : ", ", thestack.sf.Params[j]);
309 small_printf (")\r\n");
311 small_printf ("End of stack trace%s\n",
312 i == 16 ? " (more stack frames may be present)" : "");
316 _cygtls::inside_kernel (CONTEXT *cx)
319 MEMORY_BASIC_INFORMATION m;
321 if (!isinitialized ())
324 memset (&m, 0, sizeof m);
325 if (!VirtualQuery ((LPCVOID) cx->Eip, &m, sizeof m))
326 sigproc_printf ("couldn't get memory info, pc %p, %E", cx->Eip);
328 size_t size = (windows_system_directory_length + 6) * sizeof (WCHAR);
329 PWCHAR checkdir = (PWCHAR) alloca (size);
330 memset (checkdir, 0, size);
332 # define h ((HMODULE) m.AllocationBase)
333 /* Apparently Windows 95 can sometimes return bogus addresses from
334 GetThreadContext. These resolve to a strange allocation base.
335 These should *never* be treated as interruptible. */
336 if (!h || m.State != MEM_COMMIT)
338 else if (h == user_data->hmodule)
340 else if (!GetModuleFileNameW (h, checkdir, windows_system_directory_length + 6))
344 /* Skip potential long path prefix. */
345 if (!wcsncmp (checkdir, L"\\\\?\\", 4))
347 res = !wcsncasecmp (windows_system_directory, checkdir,
348 windows_system_directory_length);
350 sigproc_printf ("pc %p, h %p, inside_kernel %d", cx->Eip, h, res);
355 /* Temporary (?) function for external callers to get a stack dump */
360 c.ContextFlags = CONTEXT_FULL;
361 GetThreadContext (GetCurrentThread (), &c);
362 stackdump (c.Ebp, 0, 0);
365 #define TIME_TO_WAIT_FOR_DEBUGGER 10000
368 try_to_debug (bool waitloop)
370 debug_printf ("debugger_command '%s'", debugger_command);
371 if (*debugger_command == '\0')
373 if (being_debugged ())
375 extern void break_here ();
380 __small_sprintf (strchr (debugger_command, '\0'), " %u", GetCurrentProcessId ());
382 LONG prio = GetThreadPriority (GetCurrentThread ());
383 SetThreadPriority (GetCurrentThread (), THREAD_PRIORITY_HIGHEST);
384 PROCESS_INFORMATION pi = {NULL, 0, 0, 0};
386 STARTUPINFOW si = {0, NULL, NULL, NULL, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL, NULL, NULL, NULL};
387 si.lpReserved = NULL;
392 /* FIXME: need to know handles of all running threads to
393 suspend_all_threads_except (current_thread_id);
396 /* if any of these mutexes is owned, we will fail to start any cygwin app
397 until trapped app exits */
399 lock_ttys::release ();
401 /* prevent recursive exception handling */
402 PWCHAR rawenv = GetEnvironmentStringsW () ;
403 for (PWCHAR p = rawenv; *p != L'\0'; p = wcschr (p, L'\0') + 1)
405 if (wcsncmp (p, L"CYGWIN=", wcslen (L"CYGWIN=")) == 0)
407 PWCHAR q = wcsstr (p, L"error_start") ;
408 /* replace 'error_start=...' with '_rror_start=...' */
412 SetEnvironmentVariableW (L"CYGWIN", p + wcslen (L"CYGWIN=")) ;
418 console_printf ("*** starting debugger for pid %u, tid %u\n",
419 cygwin_pid (GetCurrentProcessId ()), GetCurrentThreadId ());
421 WCHAR dbg_cmd[strlen(debugger_command)];
422 sys_mbstowcs (dbg_cmd, strlen(debugger_command) + 1, debugger_command);
423 dbg = CreateProcessW (NULL,
428 CREATE_NEW_CONSOLE | CREATE_NEW_PROCESS_GROUP,
435 system_printf ("Failed to start debugger, %E");
440 SetThreadPriority (GetCurrentThread (), THREAD_PRIORITY_IDLE);
441 while (!being_debugged ())
442 low_priority_sleep (0);
446 console_printf ("*** continuing pid %u from debugger call (%d)\n",
447 cygwin_pid (GetCurrentProcessId ()), dbg);
449 SetThreadPriority (GetCurrentThread (), prio);
453 extern "C" DWORD __stdcall RtlUnwind (void *, void *, void *, DWORD);
454 static void __stdcall rtl_unwind (exception_list *, PEXCEPTION_RECORD) __attribute__ ((noinline, regparm (3)));
456 rtl_unwind (exception_list *frame, PEXCEPTION_RECORD e)
466 call _RtlUnwind@16 \n\
471 ": : "r" (frame), "r" (e));
474 /* Main exception handler. */
476 extern exception_list *_except_list asm ("%fs:0");
479 _cygtls::handle_exceptions (EXCEPTION_RECORD *e, exception_list *frame, CONTEXT *in, void *)
481 static bool NO_COPY debugging;
482 static int NO_COPY recursed;
483 _cygtls& me = _my_tls;
485 if (debugging && ++debugging < 500000)
487 SetThreadPriority (GetCurrentThread (), THREAD_PRIORITY_NORMAL);
491 /* If we've already exited, don't do anything here. Returning 1
492 tells Windows to keep looking for an exception handler. */
493 if (exit_already || e->ExceptionFlags)
497 si.si_code = SI_KERNEL;
498 /* Coerce win32 value to posix value. */
499 switch (e->ExceptionCode)
501 case STATUS_FLOAT_DENORMAL_OPERAND:
502 case STATUS_FLOAT_DIVIDE_BY_ZERO:
503 case STATUS_FLOAT_INVALID_OPERATION:
504 case STATUS_FLOAT_STACK_CHECK:
505 si.si_signo = SIGFPE;
506 si.si_code = FPE_FLTSUB;
508 case STATUS_FLOAT_INEXACT_RESULT:
509 si.si_signo = SIGFPE;
510 si.si_code = FPE_FLTRES;
512 case STATUS_FLOAT_OVERFLOW:
513 si.si_signo = SIGFPE;
514 si.si_code = FPE_FLTOVF;
516 case STATUS_FLOAT_UNDERFLOW:
517 si.si_signo = SIGFPE;
518 si.si_code = FPE_FLTUND;
520 case STATUS_INTEGER_DIVIDE_BY_ZERO:
521 si.si_signo = SIGFPE;
522 si.si_code = FPE_INTDIV;
524 case STATUS_INTEGER_OVERFLOW:
525 si.si_signo = SIGFPE;
526 si.si_code = FPE_INTOVF;
529 case STATUS_ILLEGAL_INSTRUCTION:
530 si.si_signo = SIGILL;
531 si.si_code = ILL_ILLOPC;
534 case STATUS_PRIVILEGED_INSTRUCTION:
535 si.si_signo = SIGILL;
536 si.si_code = ILL_PRVOPC;
539 case STATUS_NONCONTINUABLE_EXCEPTION:
540 si.si_signo = SIGILL;
541 si.si_code = ILL_ILLADR;
545 si.si_signo = SIGALRM;
548 case STATUS_GUARD_PAGE_VIOLATION:
549 si.si_signo = SIGBUS;
550 si.si_code = BUS_OBJERR;
553 case STATUS_DATATYPE_MISALIGNMENT:
554 si.si_signo = SIGBUS;
555 si.si_code = BUS_ADRALN;
558 case STATUS_ACCESS_VIOLATION:
559 switch (mmap_is_attached_or_noreserve ((void *)e->ExceptionInformation[1],
562 case MMAP_NORESERVE_COMMITED:
564 case MMAP_RAISE_SIGBUS: /* MAP_NORESERVE page, commit failed, or
565 access to mmap page beyond EOF. */
566 si.si_signo = SIGBUS;
567 si.si_code = BUS_OBJERR;
570 MEMORY_BASIC_INFORMATION m;
571 VirtualQuery ((PVOID) e->ExceptionInformation[1], &m, sizeof m);
572 si.si_signo = SIGSEGV;
573 si.si_code = m.State == MEM_FREE ? SEGV_MAPERR : SEGV_ACCERR;
578 case STATUS_ARRAY_BOUNDS_EXCEEDED:
579 case STATUS_IN_PAGE_ERROR:
580 case STATUS_NO_MEMORY:
581 case STATUS_INVALID_DISPOSITION:
582 case STATUS_STACK_OVERFLOW:
583 si.si_signo = SIGSEGV;
584 si.si_code = SEGV_MAPERR;
587 case STATUS_CONTROL_C_EXIT:
588 si.si_signo = SIGINT;
591 case STATUS_INVALID_HANDLE:
592 /* CloseHandle will throw this exception if it is given an
593 invalid handle. We don't care about the exception; we just
594 want CloseHandle to return an error. This can be revisited
595 if gcc ever supports Windows style structured exception
600 /* If we don't recognize the exception, we have to assume that
601 we are doing structured exception handling, and we let
602 something else handle it. */
606 debug_printf ("In cygwin_except_handler exc %p at %p sp %p", e->ExceptionCode, in->Eip, in->Esp);
607 debug_printf ("In cygwin_except_handler sig %d at %p", si.si_signo, in->Eip);
609 bool masked = !!(me.sigmask & SIGTOMASK (si.si_signo));
611 syscall_printf ("signal %d, masked %p", si.si_signo,
612 global_sigs[si.si_signo].sa_mask);
614 debug_printf ("In cygwin_except_handler calling %p",
615 global_sigs[si.si_signo].sa_handler);
617 DWORD *ebp = (DWORD *) in->Esp;
618 for (DWORD *bpend = (DWORD *) __builtin_frame_address (0); ebp > bpend; ebp--)
619 if (*ebp == in->SegCs && ebp[-1] == in->Eip)
625 if (me.fault_guarded ())
626 me.return_from_fault ();
628 me.copy_context (in);
630 /* Temporarily replace windows top level SEH with our own handler.
631 We don't want any Windows magic kicking in. This top level frame
632 will be removed automatically after our exception handler returns. */
633 _except_list->handler = _cygtls::handle_exceptions;
637 || !cygwin_finished_initializing
638 || (void *) global_sigs[si.si_signo].sa_handler == (void *) SIG_DFL
639 || (void *) global_sigs[si.si_signo].sa_handler == (void *) SIG_IGN
640 || (void *) global_sigs[si.si_signo].sa_handler == (void *) SIG_ERR)
642 /* Print the exception to the console */
643 if (!myself->cygstarted)
644 for (int i = 0; status_info[i].name; i++)
645 if (status_info[i].code == e->ExceptionCode)
647 system_printf ("Exception: %s", status_info[i].name);
651 /* Another exception could happen while tracing or while exiting.
652 Only do this once. */
654 system_printf ("Error while dumping state (probably corrupted stack)");
657 if (try_to_debug (0))
663 rtl_unwind (frame, e);
664 open_stackdumpfile ();
666 stackdump ((DWORD) ebp, 0, 1);
669 if (e->ExceptionCode == STATUS_ACCESS_VIOLATION)
672 if (si.si_code == SEGV_ACCERR) /* Address present */
674 if (e->ExceptionInformation[0]) /* Write access */
676 if (!me.inside_kernel (in)) /* User space */
678 klog (LOG_INFO, "%s[%d]: segfault at %08x rip %08x rsp %08x error %d",
679 __progname, myself->pid,
680 e->ExceptionInformation[1], in->Eip, in->Esp,
681 ((in->Eip >= 0x61000000 && in->Eip < 0x61200000)
682 ? 0 : 4) | (e->ExceptionInformation[0] << 1));
685 me.signal_exit (0x80 | si.si_signo); // Flag signal + core dump
688 si.si_addr = (si.si_signo == SIGSEGV || si.si_signo == SIGBUS
689 ? (void *) e->ExceptionInformation[1]
691 si.si_errno = si.si_pid = si.si_uid = 0;
693 sig_send (NULL, si, &me); // Signal myself
695 e->ExceptionFlags = 0;
699 /* Utilities to call a user supplied exception handler. */
701 #define SIG_NONMASKABLE (SIGTOMASK (SIGKILL) | SIGTOMASK (SIGSTOP))
703 /* Non-raceable sigsuspend
704 * Note: This implementation is based on the Single UNIX Specification
705 * man page. This indicates that sigsuspend always returns -1 and that
706 * attempts to block unblockable signals will be silently ignored.
707 * This is counter to what appears to be documented in some UNIX
708 * man pages, e.g. Linux.
711 handle_sigsuspend (sigset_t tempmask)
713 if (&_my_tls != _main_tls)
715 cancelable_wait (signal_arrived, INFINITE, cw_cancel_self);
719 sigset_t oldmask = _my_tls.sigmask; // Remember for restoration
721 set_signal_mask (tempmask, _my_tls.sigmask);
722 sigproc_printf ("oldmask %p, newmask %p", oldmask, tempmask);
724 pthread_testcancel ();
725 cancelable_wait (signal_arrived, INFINITE);
727 set_sig_errno (EINTR); // Per POSIX
729 /* A signal dispatch function will have been added to our stack and will
730 be hit eventually. Set the old mask to be restored when the signal
731 handler returns and indicate its presence by modifying deltamask. */
733 _my_tls.deltamask |= SIG_NONMASKABLE;
734 _my_tls.oldmask = oldmask; // Will be restored by signal handler
738 extern DWORD exec_exit; // Possible exit value for exec
742 sig_handle_tty_stop (int sig)
745 /* Silently ignore attempts to suspend if there is no accommodating
746 cygwin parent to deal with this behavior. */
747 if (!myself->cygstarted)
749 myself->process_state &= ~PID_STOPPED;
753 myself->stopsig = sig;
754 myself->alert_parent (sig);
755 sigproc_printf ("process %d stopped by signal %d", myself->pid, sig);
758 w4[1] = signal_arrived;
759 switch (WaitForMultipleObjects (2, w4, TRUE, INFINITE))
762 case WAIT_OBJECT_0 + 1:
763 reset_signal_arrived ();
764 myself->stopsig = SIGCONT;
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 && GetUserObjectInformationW (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 _cygtls *use_tls = tls ?: _main_tls;
1196 if (si.si_signo == SIGKILL)
1198 if (si.si_signo == SIGSTOP)
1200 sig_clear (SIGCONT);
1204 bool insigwait_mask;
1205 if ((masked = ISSTATE (myself, PID_STOPPED)))
1206 insigwait_mask = false;
1208 insigwait_mask = sigismember (&tls->sigwait_mask, si.si_signo);
1209 else if (!(tls = _cygtls::find_tls (si.si_signo)))
1210 insigwait_mask = false;
1214 insigwait_mask = true;
1218 goto thread_specific;
1221 /* nothing to do */;
1222 else if (sigismember (mask, si.si_signo))
1225 masked = sigismember (&tls->sigmask, si.si_signo);
1229 sigproc_printf ("signal %d blocked", si.si_signo);
1234 /* Clear pending SIGCONT on stop signals */
1235 if (si.si_signo == SIGTSTP || si.si_signo == SIGTTIN || si.si_signo == SIGTTOU)
1236 sig_clear (SIGCONT);
1239 if (being_debugged ())
1241 char sigmsg[sizeof (_CYGWIN_SIGNAL_STRING " 0xffffffff")];
1242 __small_sprintf (sigmsg, _CYGWIN_SIGNAL_STRING " %p", si.si_signo);
1243 OutputDebugString (sigmsg);
1247 if (handler == (void *) SIG_DFL)
1250 goto thread_specific;
1251 if (si.si_signo == SIGCHLD || si.si_signo == SIGIO || si.si_signo == SIGCONT || si.si_signo == SIGWINCH
1252 || si.si_signo == SIGURG)
1254 sigproc_printf ("default signal %d ignored", si.si_signo);
1256 SetEvent (signal_arrived);
1260 if (si.si_signo == SIGTSTP || si.si_signo == SIGTTIN || si.si_signo == SIGTTOU)
1266 if (handler == (void *) SIG_IGN)
1268 sigproc_printf ("signal %d ignored", si.si_signo);
1272 if (handler == (void *) SIG_ERR)
1275 use_tls->set_siginfo (this);
1279 /* Eat multiple attempts to STOP */
1280 if (ISSTATE (myself, PID_STOPPED))
1282 handler = (void *) sig_handle_tty_stop;
1286 /* Dispatch to the appropriate function. */
1287 sigproc_printf ("signal %d, about to call %p", si.si_signo, handler);
1288 rc = setup_handler (si.si_signo, handler, thissig, use_tls);
1294 sigproc_printf ("returning %d", rc);
1298 use_tls->sig = si.si_signo;
1299 use_tls->set_siginfo (this);
1300 use_tls->func = NULL;
1301 sigproc_printf ("releasing sigwait for thread");
1302 SetEvent (use_tls->event);
1306 if (si.si_signo == SIGQUIT || si.si_signo == SIGABRT)
1309 c.ContextFlags = CONTEXT_FULL;
1310 GetThreadContext (GetCurrentThread (), &c);
1311 use_tls->copy_context (&c);
1312 si.si_signo |= 0x80;
1314 sigproc_printf ("signal %d, about to call do_exit", si.si_signo);
1315 use_tls->signal_exit (si.si_signo); /* never returns */
1318 /* Cover function to `do_exit' to handle exiting even in presence of more
1319 exceptions. We used to call exit, but a SIGSEGV shouldn't cause atexit
1322 _cygtls::signal_exit (int rc)
1326 sigproc_printf ("terminating captive process");
1327 TerminateProcess (hExeced, sigExeced = rc);
1330 signal_debugger (rc & 0x7f);
1331 if ((rc & 0x80) && !try_to_debug ())
1332 stackdump (thread_context.ebp, 1, 1);
1334 lock_process until_exit (true);
1335 if (hExeced || exit_state > ES_PROCESS_LOCKED)
1338 /* Starve other threads in a vain attempt to stop them from doing something
1340 SetThreadPriority (GetCurrentThread (), THREAD_PRIORITY_TIME_CRITICAL);
1342 sigproc_printf ("about to call do_exit (%x)", rc);
1349 mask_sync.init ("mask_sync");
1350 windows_system_directory[0] = L'\0';
1351 GetSystemDirectoryW (windows_system_directory, sizeof (windows_system_directory) / sizeof (WCHAR) - 2);
1352 PWCHAR end = wcschr (windows_system_directory, L'\0');
1353 if (end == windows_system_directory)
1354 api_fatal ("can't find windows system directory");
1355 if (end[-1] != L'\\')
1360 windows_system_directory_length = end - windows_system_directory;
1361 debug_printf ("windows_system_directory '%W', windows_system_directory_length %d",
1362 windows_system_directory, windows_system_directory_length);
1372 _cygtls::call_signal_handler ()
1374 int this_sa_flags = 0;
1375 /* Call signal handler. */
1379 this_sa_flags = sa_flags;
1383 reset_signal_arrived ();
1384 sigset_t this_oldmask = set_process_mask_delta ();
1385 int this_errno = saved_errno;
1387 unlock (); // make sure synchronized
1389 if (!(this_sa_flags & SA_SIGINFO))
1391 void (*sigfunc) (int) = func;
1396 siginfo_t thissi = infodata;
1397 void (*sigact) (int, siginfo_t *, void *) = (void (*) (int, siginfo_t *, void *)) func;
1398 /* no ucontext_t information provided yet */
1399 sigact (thissig, &thissi, NULL);
1402 set_signal_mask (this_oldmask, _my_tls.sigmask);
1403 if (this_errno >= 0)
1404 set_errno (this_errno);
1407 return this_sa_flags & SA_RESTART;
1410 extern "C" void __stdcall
1411 reset_signal_arrived ()
1413 // NEEDED? WaitForSingleObject (signal_arrived, 10);
1414 ResetEvent (signal_arrived);
1415 sigproc_printf ("reset signal_arrived");
1416 if (_my_tls.stackptr > _my_tls.stack)
1417 debug_printf ("stackptr[-1] %p", _my_tls.stackptr[-1]);
1421 _cygtls::copy_context (CONTEXT *c)
1423 memcpy (&thread_context, c, (&thread_context._internal - (unsigned char *) &thread_context));
1427 _cygtls::signal_debugger (int sig)
1429 if (isinitialized () && being_debugged ())
1431 char sigmsg[2 * sizeof (_CYGWIN_SIGNAL_STRING " ffffffff ffffffff")];
1432 __small_sprintf (sigmsg, _CYGWIN_SIGNAL_STRING " %d %p %p", sig, thread_id, &thread_context);
1433 OutputDebugString (sigmsg);