3 Copyright 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004,
4 2005, 2006, 2007, 2008, 2009, 2010 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"
33 #include "exception.h"
35 #define CALL_HANDLER_RETRY 20
37 char debugger_command
[2 * NT_MAX_PATH
+ 20];
40 extern void sigdelayed ();
43 extern child_info_spawn
*chExeced
;
45 static BOOL WINAPI
ctrl_c_handler (DWORD
);
47 /* This is set to indicate that we have already exited. */
49 static NO_COPY
int exit_already
= 0;
50 static muto NO_COPY mask_sync
;
59 { X (STATUS_ABANDONED_WAIT_0
) },
60 { X (STATUS_ACCESS_VIOLATION
) },
61 { X (STATUS_ARRAY_BOUNDS_EXCEEDED
) },
62 { X (STATUS_BREAKPOINT
) },
63 { X (STATUS_CONTROL_C_EXIT
) },
64 { X (STATUS_DATATYPE_MISALIGNMENT
) },
65 { X (STATUS_FLOAT_DENORMAL_OPERAND
) },
66 { X (STATUS_FLOAT_DIVIDE_BY_ZERO
) },
67 { X (STATUS_FLOAT_INEXACT_RESULT
) },
68 { X (STATUS_FLOAT_INVALID_OPERATION
) },
69 { X (STATUS_FLOAT_OVERFLOW
) },
70 { X (STATUS_FLOAT_STACK_CHECK
) },
71 { X (STATUS_FLOAT_UNDERFLOW
) },
72 { X (STATUS_GUARD_PAGE_VIOLATION
) },
73 { X (STATUS_ILLEGAL_INSTRUCTION
) },
74 { X (STATUS_INTEGER_DIVIDE_BY_ZERO
) },
75 { X (STATUS_INTEGER_OVERFLOW
) },
76 { X (STATUS_INVALID_DISPOSITION
) },
77 { X (STATUS_IN_PAGE_ERROR
) },
78 { X (STATUS_NONCONTINUABLE_EXCEPTION
) },
79 { X (STATUS_NO_MEMORY
) },
80 { X (STATUS_PENDING
) },
81 { X (STATUS_PRIVILEGED_INSTRUCTION
) },
82 { X (STATUS_SINGLE_STEP
) },
83 { X (STATUS_STACK_OVERFLOW
) },
84 { X (STATUS_TIMEOUT
) },
85 { X (STATUS_USER_APC
) },
86 { X (STATUS_WAIT_0
) },
91 /* Initialization code. */
94 init_console_handler (bool install_handler
)
98 SetConsoleCtrlHandler (ctrl_c_handler
, FALSE
);
99 SetConsoleCtrlHandler (NULL
, FALSE
);
101 res
= SetConsoleCtrlHandler (ctrl_c_handler
, TRUE
);
103 res
= SetConsoleCtrlHandler (NULL
, TRUE
);
105 system_printf ("SetConsoleCtrlHandler failed, %E");
109 error_start_init (const char *buf
)
113 debugger_command
[0] = '\0';
117 char pgm
[NT_MAX_PATH
];
118 if (!GetModuleFileName (NULL
, pgm
, NT_MAX_PATH
))
119 strcpy (pgm
, "cygwin1.dll");
120 for (char *p
= strchr (pgm
, '\\'); p
; p
= strchr (p
, '\\'))
123 __small_sprintf (debugger_command
, "%s \"%s\"", buf
, pgm
);
127 open_stackdumpfile ()
129 /* If we have no executable name, or if the CWD handle is NULL,
130 which means, the CWD is a virtual path, don't even try to open
132 if (myself
->progname
[0] && cygheap
->cwd
.get_handle ())
135 /* write to progname.stackdump if possible */
136 if (!myself
->progname
[0])
138 else if ((p
= wcsrchr (myself
->progname
, L
'\\')))
141 p
= myself
->progname
;
143 WCHAR corefile
[wcslen (p
) + sizeof (".stackdump")];
144 wcpcpy (wcpcpy(corefile
, p
), L
".stackdump");
145 UNICODE_STRING ucore
;
146 OBJECT_ATTRIBUTES attr
;
147 /* Create the UNICODE variation of <progname>.stackdump. */
148 RtlInitUnicodeString (&ucore
, corefile
);
149 /* Create an object attribute which refers to <progname>.stackdump
150 in Cygwin's cwd. Stick to caseinsensitivity. */
151 InitializeObjectAttributes (&attr
, &ucore
, OBJ_CASE_INSENSITIVE
,
152 cygheap
->cwd
.get_handle (), NULL
);
156 /* Try to open it to dump the stack in it. */
157 status
= NtCreateFile (&h
, GENERIC_WRITE
| SYNCHRONIZE
, &attr
, &io
,
158 NULL
, FILE_ATTRIBUTE_NORMAL
, 0, FILE_OVERWRITE_IF
,
159 FILE_SYNCHRONOUS_IO_NONALERT
160 | FILE_OPEN_FOR_BACKUP_INTENT
, NULL
, 0);
161 if (NT_SUCCESS (status
))
163 if (!myself
->cygstarted
)
164 system_printf ("Dumping stack trace to %S", &ucore
);
166 debug_printf ("Dumping stack trace to %S", &ucore
);
167 SetStdHandle (STD_ERROR_HANDLE
, h
);
172 /* Utilities for dumping the stack, etc. */
175 dump_exception (EXCEPTION_RECORD
*e
, CONTEXT
*in
)
177 const char *exception_name
= NULL
;
181 for (int i
= 0; status_info
[i
].name
; i
++)
183 if (status_info
[i
].code
== e
->ExceptionCode
)
185 exception_name
= status_info
[i
].name
;
192 small_printf ("Exception: %s at eip=%08x\r\n", exception_name
, in
->Eip
);
194 small_printf ("Signal %d at eip=%08x\r\n", e
->ExceptionCode
, in
->Eip
);
195 small_printf ("eax=%08x ebx=%08x ecx=%08x edx=%08x esi=%08x edi=%08x\r\n",
196 in
->Eax
, in
->Ebx
, in
->Ecx
, in
->Edx
, in
->Esi
, in
->Edi
);
197 small_printf ("ebp=%08x esp=%08x program=%W, pid %u, thread %s\r\n",
198 in
->Ebp
, in
->Esp
, myself
->progname
, myself
->pid
, cygthread::name ());
199 small_printf ("cs=%04x ds=%04x es=%04x fs=%04x gs=%04x ss=%04x\r\n",
200 in
->SegCs
, in
->SegDs
, in
->SegEs
, in
->SegFs
, in
->SegGs
, in
->SegSs
);
203 /* A class for manipulating the stack. */
206 int walk (); /* Uses the "old" method */
207 char *next_offset () {return *((char **) sf
.AddrFrame
.Offset
);}
211 STACKFRAME sf
; /* For storing the stack information */
212 void init (DWORD
, bool, bool); /* Called the first time that stack info is needed */
214 /* Postfix ++ iterates over the stack, returning zero when nothing is left. */
215 int operator ++(int) { return walk (); }
218 /* The number of parameters used in STACKFRAME */
219 #define NPARAMS (sizeof (thestack.sf.Params) / sizeof (thestack.sf.Params[0]))
221 /* This is the main stack frame info for this process. */
222 static NO_COPY stack_info thestack
;
224 /* Initialize everything needed to start iterating. */
226 stack_info::init (DWORD ebp
, bool wantargs
, bool goodframe
)
228 # define debp ((DWORD *) ebp)
229 memset (&sf
, 0, sizeof (sf
));
231 sf
.AddrFrame
.Offset
= ebp
;
235 sf
.AddrFrame
.Offset
= (DWORD
) &dummy_frame
;
237 sf
.AddrReturn
.Offset
= debp
[1];
238 sf
.AddrFrame
.Mode
= AddrModeFlat
;
243 extern "C" void _cygwin_exit_return ();
245 /* Walk the stack by looking at successive stored 'bp' frames.
246 This is not foolproof. */
252 if ((void (*) ()) sf
.AddrPC
.Offset
== _cygwin_exit_return
)
253 return 0; /* stack frames are exhausted */
255 if (((ebp
= (char **) next_offset ()) == NULL
) || (ebp
>= (char **) cygwin_hmodule
))
258 sf
.AddrFrame
.Offset
= (DWORD
) ebp
;
259 sf
.AddrPC
.Offset
= sf
.AddrReturn
.Offset
;
261 /* The return address always follows the stack pointer */
262 sf
.AddrReturn
.Offset
= (DWORD
) *++ebp
;
266 unsigned nparams
= NPARAMS
;
268 /* The arguments follow the return address */
269 sf
.Params
[0] = (DWORD
) *++ebp
;
270 /* Hack for XP/2K3 WOW64. If the first stack param points to the
271 application entry point, we can only fetch one additional
272 parameter. Accessing anything beyond this address results in
273 a SEGV. This is fixed in Vista/2K8 WOW64. */
274 if (wincap
.has_restricted_stack_args () && sf
.Params
[0] == 0x401000)
276 for (unsigned i
= 1; i
< nparams
; i
++)
277 sf
.Params
[i
] = (DWORD
) *++ebp
;
284 stackdump (DWORD ebp
, int open_file
, bool isexception
)
286 static bool already_dumped
;
288 if (cygheap
->rlim_core
== 0UL || (open_file
&& already_dumped
))
292 open_stackdumpfile ();
294 already_dumped
= true;
298 thestack
.init (ebp
, 1, !isexception
); /* Initialize from the input CONTEXT */
299 small_printf ("Stack trace:\r\nFrame Function Args\r\n");
300 for (i
= 0; i
< 16 && thestack
++; i
++)
302 small_printf ("%08x %08x ", thestack
.sf
.AddrFrame
.Offset
,
303 thestack
.sf
.AddrPC
.Offset
);
304 for (unsigned j
= 0; j
< NPARAMS
; j
++)
305 small_printf ("%s%08x", j
== 0 ? " (" : ", ", thestack
.sf
.Params
[j
]);
306 small_printf (")\r\n");
308 small_printf ("End of stack trace%s\n",
309 i
== 16 ? " (more stack frames may be present)" : "");
313 _cygtls::inside_kernel (CONTEXT
*cx
)
316 MEMORY_BASIC_INFORMATION m
;
318 if (!isinitialized ())
321 memset (&m
, 0, sizeof m
);
322 if (!VirtualQuery ((LPCVOID
) cx
->Eip
, &m
, sizeof m
))
323 sigproc_printf ("couldn't get memory info, pc %p, %E", cx
->Eip
);
325 size_t size
= (windows_system_directory_length
+ 6) * sizeof (WCHAR
);
326 PWCHAR checkdir
= (PWCHAR
) alloca (size
);
327 memset (checkdir
, 0, size
);
329 # define h ((HMODULE) m.AllocationBase)
330 /* Apparently Windows 95 can sometimes return bogus addresses from
331 GetThreadContext. These resolve to a strange allocation base.
332 These should *never* be treated as interruptible. */
333 if (!h
|| m
.State
!= MEM_COMMIT
)
335 else if (h
== user_data
->hmodule
)
337 else if (!GetModuleFileNameW (h
, checkdir
, windows_system_directory_length
+ 6))
341 /* Skip potential long path prefix. */
342 if (!wcsncmp (checkdir
, L
"\\\\?\\", 4))
344 res
= !wcsncasecmp (windows_system_directory
, checkdir
,
345 windows_system_directory_length
);
347 sigproc_printf ("pc %p, h %p, inside_kernel %d", cx
->Eip
, h
, res
);
352 /* Temporary (?) function for external callers to get a stack dump */
357 c
.ContextFlags
= CONTEXT_FULL
;
358 GetThreadContext (GetCurrentThread (), &c
);
359 stackdump (c
.Ebp
, 0, 0);
362 #define TIME_TO_WAIT_FOR_DEBUGGER 10000
365 try_to_debug (bool waitloop
)
367 debug_printf ("debugger_command '%s'", debugger_command
);
368 if (*debugger_command
== '\0')
370 if (being_debugged ())
372 extern void break_here ();
377 __small_sprintf (strchr (debugger_command
, '\0'), " %u", GetCurrentProcessId ());
379 LONG prio
= GetThreadPriority (GetCurrentThread ());
380 SetThreadPriority (GetCurrentThread (), THREAD_PRIORITY_HIGHEST
);
381 PROCESS_INFORMATION pi
= {NULL
, 0, 0, 0};
383 STARTUPINFOW si
= {0, NULL
, NULL
, NULL
, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL
, NULL
, NULL
, NULL
};
384 si
.lpReserved
= NULL
;
389 /* FIXME: need to know handles of all running threads to
390 suspend_all_threads_except (current_thread_id);
393 /* if any of these mutexes is owned, we will fail to start any cygwin app
394 until trapped app exits */
396 lock_ttys::release ();
398 /* prevent recursive exception handling */
399 PWCHAR rawenv
= GetEnvironmentStringsW () ;
400 for (PWCHAR p
= rawenv
; *p
!= L
'\0'; p
= wcschr (p
, L
'\0') + 1)
402 if (wcsncmp (p
, L
"CYGWIN=", wcslen (L
"CYGWIN=")) == 0)
404 PWCHAR q
= wcsstr (p
, L
"error_start") ;
405 /* replace 'error_start=...' with '_rror_start=...' */
409 SetEnvironmentVariableW (L
"CYGWIN", p
+ wcslen (L
"CYGWIN=")) ;
415 console_printf ("*** starting debugger for pid %u, tid %u\n",
416 cygwin_pid (GetCurrentProcessId ()), GetCurrentThreadId ());
418 WCHAR dbg_cmd
[strlen(debugger_command
)];
419 sys_mbstowcs (dbg_cmd
, strlen(debugger_command
) + 1, 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 ())
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 exception_list
*_except_list
asm ("%fs:0");
476 exception::handle (EXCEPTION_RECORD
*e
, exception_list
*frame
, CONTEXT
*in
, void *)
478 static bool NO_COPY debugging
;
479 static int NO_COPY recursed
;
480 _cygtls
& me
= _my_tls
;
482 if (debugging
&& ++debugging
< 500000)
484 SetThreadPriority (hMainThread
, THREAD_PRIORITY_NORMAL
);
488 /* If we've already exited, don't do anything here. Returning 1
489 tells Windows to keep looking for an exception handler. */
490 if (exit_already
|| e
->ExceptionFlags
)
494 si
.si_code
= SI_KERNEL
;
495 /* Coerce win32 value to posix value. */
496 switch (e
->ExceptionCode
)
498 case STATUS_FLOAT_DENORMAL_OPERAND
:
499 case STATUS_FLOAT_DIVIDE_BY_ZERO
:
500 case STATUS_FLOAT_INVALID_OPERATION
:
501 case STATUS_FLOAT_STACK_CHECK
:
502 si
.si_signo
= SIGFPE
;
503 si
.si_code
= FPE_FLTSUB
;
505 case STATUS_FLOAT_INEXACT_RESULT
:
506 si
.si_signo
= SIGFPE
;
507 si
.si_code
= FPE_FLTRES
;
509 case STATUS_FLOAT_OVERFLOW
:
510 si
.si_signo
= SIGFPE
;
511 si
.si_code
= FPE_FLTOVF
;
513 case STATUS_FLOAT_UNDERFLOW
:
514 si
.si_signo
= SIGFPE
;
515 si
.si_code
= FPE_FLTUND
;
517 case STATUS_INTEGER_DIVIDE_BY_ZERO
:
518 si
.si_signo
= SIGFPE
;
519 si
.si_code
= FPE_INTDIV
;
521 case STATUS_INTEGER_OVERFLOW
:
522 si
.si_signo
= SIGFPE
;
523 si
.si_code
= FPE_INTOVF
;
526 case STATUS_ILLEGAL_INSTRUCTION
:
527 si
.si_signo
= SIGILL
;
528 si
.si_code
= ILL_ILLOPC
;
531 case STATUS_PRIVILEGED_INSTRUCTION
:
532 si
.si_signo
= SIGILL
;
533 si
.si_code
= ILL_PRVOPC
;
536 case STATUS_NONCONTINUABLE_EXCEPTION
:
537 si
.si_signo
= SIGILL
;
538 si
.si_code
= ILL_ILLADR
;
542 si
.si_signo
= SIGALRM
;
545 case STATUS_GUARD_PAGE_VIOLATION
:
546 si
.si_signo
= SIGBUS
;
547 si
.si_code
= BUS_OBJERR
;
550 case STATUS_DATATYPE_MISALIGNMENT
:
551 si
.si_signo
= SIGBUS
;
552 si
.si_code
= BUS_ADRALN
;
555 case STATUS_ACCESS_VIOLATION
:
556 switch (mmap_is_attached_or_noreserve ((void *)e
->ExceptionInformation
[1],
559 case MMAP_NORESERVE_COMMITED
:
561 case MMAP_RAISE_SIGBUS
: /* MAP_NORESERVE page, commit failed, or
562 access to mmap page beyond EOF. */
563 si
.si_signo
= SIGBUS
;
564 si
.si_code
= BUS_OBJERR
;
567 MEMORY_BASIC_INFORMATION m
;
568 VirtualQuery ((PVOID
) e
->ExceptionInformation
[1], &m
, sizeof m
);
569 si
.si_signo
= SIGSEGV
;
570 si
.si_code
= m
.State
== MEM_FREE
? SEGV_MAPERR
: SEGV_ACCERR
;
575 case STATUS_ARRAY_BOUNDS_EXCEEDED
:
576 case STATUS_IN_PAGE_ERROR
:
577 case STATUS_NO_MEMORY
:
578 case STATUS_INVALID_DISPOSITION
:
579 case STATUS_STACK_OVERFLOW
:
580 si
.si_signo
= SIGSEGV
;
581 si
.si_code
= SEGV_MAPERR
;
584 case STATUS_CONTROL_C_EXIT
:
585 si
.si_signo
= SIGINT
;
588 case STATUS_INVALID_HANDLE
:
589 /* CloseHandle will throw this exception if it is given an
590 invalid handle. We don't care about the exception; we just
591 want CloseHandle to return an error. This can be revisited
592 if gcc ever supports Windows style structured exception
597 /* If we don't recognize the exception, we have to assume that
598 we are doing structured exception handling, and we let
599 something else handle it. */
603 debug_printf ("In cygwin_except_handler exc %p at %p sp %p", e
->ExceptionCode
, in
->Eip
, in
->Esp
);
604 debug_printf ("In cygwin_except_handler sig %d at %p", si
.si_signo
, in
->Eip
);
606 bool masked
= !!(me
.sigmask
& 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
)
623 me
.andreas
->leave (); /* Return from a "san" caught fault */
625 me
.copy_context (in
);
627 /* Temporarily replace windows top level SEH with our own handler.
628 We don't want any Windows magic kicking in. This top level frame
629 will be removed automatically after our exception handler returns. */
630 _except_list
->handler
= handle
;
634 || !cygwin_finished_initializing
635 || (void *) global_sigs
[si
.si_signo
].sa_handler
== (void *) SIG_DFL
636 || (void *) global_sigs
[si
.si_signo
].sa_handler
== (void *) SIG_IGN
637 || (void *) global_sigs
[si
.si_signo
].sa_handler
== (void *) SIG_ERR
)
639 /* Print the exception to the console */
640 if (!myself
->cygstarted
)
641 for (int i
= 0; status_info
[i
].name
; i
++)
642 if (status_info
[i
].code
== e
->ExceptionCode
)
644 system_printf ("Exception: %s", status_info
[i
].name
);
648 /* Another exception could happen while tracing or while exiting.
649 Only do this once. */
651 system_printf ("Error while dumping state (probably corrupted stack)");
654 if (try_to_debug (0))
660 rtl_unwind (frame
, e
);
661 if (cygheap
->rlim_core
> 0UL)
663 open_stackdumpfile ();
664 dump_exception (e
, in
);
665 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 /* Flag signal + core dump */
686 me
.signal_exit ((cygheap
->rlim_core
> 0UL ? 0x80 : 0) | si
.si_signo
);
689 si
.si_addr
= (si
.si_signo
== SIGSEGV
|| si
.si_signo
== SIGBUS
690 ? (void *) e
->ExceptionInformation
[1]
692 si
.si_errno
= si
.si_pid
= si
.si_uid
= 0;
694 sig_send (NULL
, si
, &me
); // Signal myself
696 e
->ExceptionFlags
= 0;
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
->stopsig
= SIGCONT
;
766 myself
->alert_parent (SIGCONT
);
769 api_fatal ("WaitSingleObject failed, %E");
777 _cygtls::interrupt_now (CONTEXT
*cx
, int sig
, void *handler
,
778 struct sigaction
& siga
)
782 /* Delay the interrupt if we are
783 1) somehow inside the DLL
784 2) in _sigfe (spinning is true) and about to enter cygwin DLL
785 3) in a Windows DLL. */
786 if (incyg
|| spinning
|| inside_kernel (cx
))
790 push ((__stack_t
) cx
->Eip
);
791 interrupt_setup (sig
, handler
, siga
);
793 SetThreadContext (*this, cx
); /* Restart the thread in a new location */
800 _cygtls::interrupt_setup (int sig
, void *handler
, struct sigaction
& siga
)
802 push ((__stack_t
) sigdelayed
);
803 deltamask
= siga
.sa_mask
& ~SIG_NONMASKABLE
;
804 sa_flags
= siga
.sa_flags
;
805 func
= (void (*) (int)) handler
;
806 if (siga
.sa_flags
& SA_RESETHAND
)
807 siga
.sa_handler
= SIG_DFL
;
808 saved_errno
= -1; // Flag: no errno to save
809 if (handler
== sig_handle_tty_stop
)
812 myself
->process_state
|= PID_STOPPED
;
815 this->sig
= sig
; // Should always be last thing set to avoid a race
826 /* Clear any waiting threads prior to dispatching to handler function */
827 int res
= SetEvent (signal_arrived
); // For an EINTR case
828 proc_subproc (PROC_CLEARWAIT
, 1);
829 sigproc_printf ("armed signal_arrived %p, sig %d, res %d", signal_arrived
,
833 extern "C" void __stdcall
834 set_sig_errno (int e
)
836 *_my_tls
.errno_addr
= e
;
837 _my_tls
.saved_errno
= e
;
838 // sigproc_printf ("errno %d", e);
841 static int setup_handler (int, void *, struct sigaction
&, _cygtls
*tls
)
842 __attribute__((regparm(3)));
844 setup_handler (int sig
, void *handler
, struct sigaction
& siga
, _cygtls
*tls
)
847 bool interrupted
= false;
851 sigproc_printf ("trying to send sig %d but signal %d already armed",
856 for (int i
= 0; i
< CALL_HANDLER_RETRY
; i
++)
861 sigproc_printf ("controlled interrupt. stackptr %p, stack %p, stackptr[-1] %p",
862 tls
->stackptr
, tls
->stack
, tls
->stackptr
[-1]);
863 tls
->interrupt_setup (sig
, handler
, siga
);
870 HANDLE hth
= (HANDLE
) *tls
;
872 /* Suspend the thread which will receive the signal.
873 For Windows 95, we also have to ensure that the addresses returned by
874 GetThreadContext are valid.
875 If one of these conditions is not true we loop for a fixed number of times
876 since we don't want to stall the signal handler. FIXME: Will this result in
878 If the thread is already suspended (which can occur when a program has called
879 SuspendThread on itself) then just queue the signal. */
881 sigproc_printf ("suspending thread");
882 res
= SuspendThread (hth
);
883 /* Just set pending if thread is already suspended */
889 cx
.ContextFlags
= CONTEXT_CONTROL
| CONTEXT_INTEGER
;
890 if (!GetThreadContext (hth
, &cx
))
891 system_printf ("couldn't get context of thread, %E");
893 interrupted
= tls
->interrupt_now (&cx
, sig
, handler
, siga
);
896 res
= ResumeThread (hth
);
900 sigproc_printf ("couldn't interrupt. trying again.");
905 sigproc_printf ("signal %d %sdelivered", sig
, interrupted
? "" : "not ");
910 has_visible_window_station ()
916 /* Check if the process is associated with a visible window station.
917 These are processes running on the local desktop as well as processes
918 running in terminal server sessions.
919 Processes running in a service session not explicitely associated
920 with the desktop (using the "Allow service to interact with desktop"
921 property) are running in an invisible window station. */
922 if ((station_hdl
= GetProcessWindowStation ())
923 && GetUserObjectInformationW (station_hdl
, UOI_FLAGS
, &uof
,
925 && (uof
.dwFlags
& WSF_VISIBLE
))
930 /* Keyboard interrupt handler. */
932 ctrl_c_handler (DWORD type
)
934 static bool saw_close
;
937 if (!cygwin_finished_initializing
)
939 if (myself
->cygstarted
) /* Was this process created by a cygwin process? */
940 return TRUE
; /* Yes. Let the parent eventually handle CTRL-C issues. */
941 debug_printf ("exiting with status %p", STATUS_CONTROL_C_EXIT
);
942 ExitProcess (STATUS_CONTROL_C_EXIT
);
945 _my_tls
.remove (INFINITE
);
948 if (type
== CTRL_C_EVENT
|| type
== CTRL_BREAK_EVENT
)
949 proc_subproc (PROC_KILLFORKED
, 0);
952 /* Return FALSE to prevent an "End task" dialog box from appearing
953 for each Cygwin process window that's open when the computer
954 is shut down or console window is closed. */
956 if (type
== CTRL_SHUTDOWN_EVENT
)
959 /* Don't send a signal. Only NT service applications and their child
960 processes will receive this event and the services typically already
961 handle the shutdown action when getting the SERVICE_CONTROL_SHUTDOWN
963 sig_send (NULL
, SIGTERM
);
968 if (myself
->ctty
!= -1)
970 if (type
== CTRL_CLOSE_EVENT
)
972 sig_send (NULL
, SIGHUP
);
976 if (!saw_close
&& type
== CTRL_LOGOFF_EVENT
)
978 /* The CTRL_LOGOFF_EVENT is sent when *any* user logs off.
979 The below code sends a SIGHUP only if it is not performing the
980 default activity for SIGHUP. Note that it is possible for two
981 SIGHUP signals to arrive if a process group leader is exiting
982 too. Getting this 100% right is saved for a future cygwin mailing
984 if (global_sigs
[SIGHUP
].sa_handler
!= SIG_DFL
)
986 sig_send (myself_nowait
, SIGHUP
);
995 chExeced
->set_saw_ctrl_c ();
999 /* We're only the process group leader when we have a valid pinfo structure.
1000 If we don't have one, then the parent "stub" will handle the signal. */
1001 if (!pinfo (cygwin_pid (GetCurrentProcessId ())))
1004 tty_min
*t
= cygwin_shared
->tty
.get_tty (myself
->ctty
);
1005 /* Ignore this if we're not the process group leader since it should be handled
1006 *by* the process group leader. */
1007 if (myself
->ctty
!= -1 && t
->getpgid () == myself
->pid
&&
1008 (GetTickCount () - t
->last_ctrl_c
) >= MIN_CTRL_C_SLOP
)
1009 /* Otherwise we just send a SIGINT to the process group and return TRUE (to indicate
1010 that we have handled the signal). At this point, type should be
1011 a CTRL_C_EVENT or CTRL_BREAK_EVENT. */
1014 /* If intr and quit are both mapped to ^C, send SIGQUIT on ^BREAK */
1015 if (type
== CTRL_BREAK_EVENT
1016 && t
->ti
.c_cc
[VINTR
] == 3 && t
->ti
.c_cc
[VQUIT
] == 3)
1018 t
->last_ctrl_c
= GetTickCount ();
1019 killsys (-myself
->pid
, sig
);
1020 t
->last_ctrl_c
= GetTickCount ();
1027 /* Function used by low level sig wrappers. */
1028 extern "C" void __stdcall
1029 set_process_mask (sigset_t newmask
)
1031 set_signal_mask (newmask
, _my_tls
.sigmask
);
1037 /* check that sig is in right range */
1038 if (sig
< 0 || sig
>= NSIG
)
1041 syscall_printf ("signal %d out of range", sig
);
1044 mask_sync
.acquire (INFINITE
);
1045 sigset_t mask
= _my_tls
.sigmask
;
1046 sigaddset (&mask
, sig
);
1047 set_signal_mask (mask
, _my_tls
.sigmask
);
1048 mask_sync
.release ();
1055 /* check that sig is in right range */
1056 if (sig
< 0 || sig
>= NSIG
)
1059 syscall_printf ("signal %d out of range", sig
);
1062 mask_sync
.acquire (INFINITE
);
1063 sigset_t mask
= _my_tls
.sigmask
;
1064 sigdelset (&mask
, sig
);
1065 set_signal_mask (mask
, _my_tls
.sigmask
);
1066 mask_sync
.release ();
1070 extern "C" _sig_func_ptr
1071 sigset (int sig
, _sig_func_ptr func
)
1073 sig_dispatch_pending ();
1076 /* check that sig is in right range */
1077 if (sig
< 0 || sig
>= NSIG
|| sig
== SIGKILL
|| sig
== SIGSTOP
)
1080 syscall_printf ("SIG_ERR = sigset (%d, %p)", sig
, func
);
1081 return (_sig_func_ptr
) SIG_ERR
;
1084 mask_sync
.acquire (INFINITE
);
1085 sigset_t mask
= _my_tls
.sigmask
;
1086 /* If sig was in the signal mask return SIG_HOLD, otherwise return the
1087 previous disposition. */
1088 if (sigismember (&mask
, sig
))
1091 prev
= global_sigs
[sig
].sa_handler
;
1092 /* If func is SIG_HOLD, add sig to the signal mask, otherwise set the
1093 disposition to func and remove sig from the signal mask. */
1094 if (func
== SIG_HOLD
)
1095 sigaddset (&mask
, sig
);
1098 /* No error checking. The test which could return SIG_ERR has already
1101 sigdelset (&mask
, sig
);
1103 set_signal_mask (mask
, _my_tls
.sigmask
);
1104 mask_sync
.release ();
1111 return sigset (sig
, SIG_IGN
) == SIG_ERR
? -1 : 0;
1114 /* Update the signal mask for this process and return the old mask.
1115 Called from sigdelayed */
1117 set_process_mask_delta ()
1119 mask_sync
.acquire (INFINITE
);
1120 sigset_t newmask
, oldmask
;
1122 if (_my_tls
.deltamask
& SIG_NONMASKABLE
)
1123 oldmask
= _my_tls
.oldmask
; /* from handle_sigsuspend */
1125 oldmask
= _my_tls
.sigmask
;
1126 newmask
= (oldmask
| _my_tls
.deltamask
) & ~SIG_NONMASKABLE
;
1127 sigproc_printf ("oldmask %p, newmask %p, deltamask %p", oldmask
, newmask
,
1129 _my_tls
.sigmask
= newmask
;
1130 mask_sync
.release ();
1134 /* Set the signal mask for this process.
1135 Note that some signals are unmaskable, as in UNIX. */
1136 extern "C" void __stdcall
1137 set_signal_mask (sigset_t newmask
, sigset_t
& oldmask
)
1140 if (&_my_tls
== _sig_tls
)
1141 small_printf ("********* waiting in signal thread\n");
1143 mask_sync
.acquire (INFINITE
);
1144 newmask
&= ~SIG_NONMASKABLE
;
1145 sigset_t mask_bits
= oldmask
& ~newmask
;
1146 sigproc_printf ("oldmask %p, newmask %p, mask_bits %p", oldmask
, newmask
,
1150 sig_dispatch_pending (true);
1152 sigproc_printf ("not calling sig_dispatch_pending");
1153 mask_sync
.release ();
1157 sigpacket::process ()
1160 struct sigaction dummy
= global_sigs
[SIGSTOP
];
1162 if (si
.si_signo
!= SIGCONT
)
1163 continue_now
= false;
1166 continue_now
= myself
->process_state
& PID_STOPPED
;
1167 myself
->stopsig
= 0;
1168 myself
->process_state
&= ~PID_STOPPED
;
1169 /* Clear pending stop signals */
1170 sig_clear (SIGSTOP
);
1171 sig_clear (SIGTSTP
);
1172 sig_clear (SIGTTIN
);
1173 sig_clear (SIGTTOU
);
1178 sigproc_printf ("signal %d processing", si
.si_signo
);
1179 struct sigaction
& thissig
= global_sigs
[si
.si_signo
];
1181 myself
->rusage_self
.ru_nsignals
++;
1185 if (!hExeced
|| (void *) thissig
.sa_handler
== (void *) SIG_IGN
)
1186 handler
= (void *) thissig
.sa_handler
;
1192 _cygtls
*use_tls
= tls
?: _main_tls
;
1194 if (si
.si_signo
== SIGKILL
)
1196 if (si
.si_signo
== SIGSTOP
)
1198 sig_clear (SIGCONT
);
1202 bool insigwait_mask
;
1203 if ((masked
= ISSTATE (myself
, PID_STOPPED
)))
1204 insigwait_mask
= false;
1206 insigwait_mask
= sigismember (&tls
->sigwait_mask
, si
.si_signo
);
1207 else if (!(tls
= _cygtls::find_tls (si
.si_signo
)))
1208 insigwait_mask
= false;
1212 insigwait_mask
= true;
1216 goto thread_specific
;
1219 /* nothing to do */;
1220 else if (sigismember (mask
, si
.si_signo
))
1223 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 use_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
, use_tls
);
1292 sigproc_printf ("returning %d", rc
);
1296 use_tls
->sig
= si
.si_signo
;
1297 use_tls
->set_siginfo (this);
1298 use_tls
->func
= NULL
;
1299 sigproc_printf ("releasing sigwait for thread");
1300 SetEvent (use_tls
->event
);
1304 if (si
.si_signo
== SIGQUIT
|| si
.si_signo
== SIGABRT
)
1307 c
.ContextFlags
= CONTEXT_FULL
;
1308 GetThreadContext (hMainThread
, &c
);
1309 use_tls
->copy_context (&c
);
1310 if (cygheap
->rlim_core
> 0UL)
1311 si
.si_signo
|= 0x80;
1313 sigproc_printf ("signal %d, about to call do_exit", si
.si_signo
);
1314 use_tls
->signal_exit (si
.si_signo
); /* never returns */
1317 /* Cover function to `do_exit' to handle exiting even in presence of more
1318 exceptions. We used to call exit, but a SIGSEGV shouldn't cause atexit
1321 _cygtls::signal_exit (int rc
)
1325 sigproc_printf ("terminating captive process");
1326 TerminateProcess (hExeced
, sigExeced
= rc
);
1329 signal_debugger (rc
& 0x7f);
1330 if ((rc
& 0x80) && !try_to_debug ())
1331 stackdump (thread_context
.ebp
, 1, 1);
1333 lock_process
until_exit (true);
1334 if (hExeced
|| exit_state
> ES_PROCESS_LOCKED
)
1337 /* Starve other threads in a vain attempt to stop them from doing something
1339 SetThreadPriority (GetCurrentThread (), THREAD_PRIORITY_TIME_CRITICAL
);
1341 sigproc_printf ("about to call do_exit (%x)", rc
);
1348 mask_sync
.init ("mask_sync");
1358 _cygtls::call_signal_handler ()
1360 int this_sa_flags
= 0;
1361 /* Call signal handler. */
1365 this_sa_flags
= sa_flags
;
1367 void (*thisfunc
) (int) = func
;
1370 reset_signal_arrived ();
1371 sigset_t this_oldmask
= set_process_mask_delta ();
1372 int this_errno
= saved_errno
;
1374 unlock (); // make sure synchronized
1376 if (!(this_sa_flags
& SA_SIGINFO
))
1378 void (*sigfunc
) (int) = thisfunc
;
1383 siginfo_t thissi
= infodata
;
1384 void (*sigact
) (int, siginfo_t
*, void *) = (void (*) (int, siginfo_t
*, void *)) thisfunc
;
1385 /* no ucontext_t information provided yet */
1386 sigact (thissig
, &thissi
, NULL
);
1389 set_signal_mask (this_oldmask
, _my_tls
.sigmask
);
1390 if (this_errno
>= 0)
1391 set_errno (this_errno
);
1394 return this_sa_flags
& SA_RESTART
;
1397 extern "C" void __stdcall
1398 reset_signal_arrived ()
1400 // NEEDED? WaitForSingleObject (signal_arrived, 10);
1401 ResetEvent (signal_arrived
);
1402 sigproc_printf ("reset signal_arrived");
1403 if (_my_tls
.stackptr
> _my_tls
.stack
)
1404 debug_printf ("stackptr[-1] %p", _my_tls
.stackptr
[-1]);
1408 _cygtls::copy_context (CONTEXT
*c
)
1410 memcpy (&thread_context
, c
, (&thread_context
._internal
- (unsigned char *) &thread_context
));
1414 _cygtls::signal_debugger (int sig
)
1416 if (isinitialized () && being_debugged ())
1418 char sigmsg
[2 * sizeof (_CYGWIN_SIGNAL_STRING
" ffffffff ffffffff")];
1419 __small_sprintf (sigmsg
, _CYGWIN_SIGNAL_STRING
" %d %p %p", sig
, thread_id
, &thread_context
);
1420 OutputDebugString (sigmsg
);