Cygwin: (mostly) drop NT4 and Samba < 3.0 support
[newlib-cygwin.git] / winsup / cygwin / exceptions.cc
bloba2a6f9d4c5788dfd3a87cdb743e45562ec6b34d6
1 /* exceptions.cc
3 This file is part of Cygwin.
5 This software is a copyrighted work licensed under the terms of the
6 Cygwin license. Please consult the file "CYGWIN_LICENSE" for
7 details. */
9 #define CYGTLS_HANDLE
10 #include "winsup.h"
11 #include "miscfuncs.h"
12 #include <imagehlp.h>
13 #include <stdlib.h>
14 #include <stdarg.h>
15 #include <syslog.h>
16 #include <wchar.h>
18 #include "cygtls.h"
19 #include "pinfo.h"
20 #include "sigproc.h"
21 #include "shared_info.h"
22 #include "perprocess.h"
23 #include "path.h"
24 #include "fhandler.h"
25 #include "dtable.h"
26 #include "cygheap.h"
27 #include "child_info.h"
28 #include "ntdll.h"
29 #include "exception.h"
30 #include "posix_timer.h"
31 #include "gcc_seh.h"
33 /* Define macros for CPU-agnostic register access. The _CX_foo
34 macros are for access into CONTEXT, the _MC_foo ones for access into
35 mcontext. The idea is to access the registers in terms of their job,
36 not in terms of their name on the given target. */
37 #ifdef __x86_64__
38 #define _CX_instPtr Rip
39 #define _CX_stackPtr Rsp
40 #define _CX_framePtr Rbp
41 /* For special register access inside mcontext. */
42 #define _MC_retReg rax
43 #define _MC_instPtr rip
44 #define _MC_stackPtr rsp
45 #define _MC_uclinkReg rbx /* MUST be callee-saved reg */
46 #else
47 #error unimplemented for this target
48 #endif
50 #define CALL_HANDLER_RETRY_OUTER 10
51 #define CALL_HANDLER_RETRY_INNER 10
52 #define DUMPSTACK_FRAME_LIMIT 32
54 PWCHAR debugger_command;
55 PWCHAR dumper_command;
56 extern uint8_t _sigbe;
57 extern uint8_t _sigdelayed_end;
59 static BOOL ctrl_c_handler (DWORD);
61 static const struct
63 NTSTATUS code;
64 const char *name;
65 } status_info[] =
67 #define X(s) s, #s
68 { X (STATUS_ABANDONED_WAIT_0) },
69 { X (STATUS_ACCESS_VIOLATION) },
70 { X (STATUS_ARRAY_BOUNDS_EXCEEDED) },
71 { X (STATUS_BREAKPOINT) },
72 { X (STATUS_CONTROL_C_EXIT) },
73 { X (STATUS_DATATYPE_MISALIGNMENT) },
74 { X (STATUS_FLOAT_DENORMAL_OPERAND) },
75 { X (STATUS_FLOAT_DIVIDE_BY_ZERO) },
76 { X (STATUS_FLOAT_INEXACT_RESULT) },
77 { X (STATUS_FLOAT_INVALID_OPERATION) },
78 { X (STATUS_FLOAT_OVERFLOW) },
79 { X (STATUS_FLOAT_STACK_CHECK) },
80 { X (STATUS_FLOAT_UNDERFLOW) },
81 { X (STATUS_GUARD_PAGE_VIOLATION) },
82 { X (STATUS_ILLEGAL_INSTRUCTION) },
83 { X (STATUS_INTEGER_DIVIDE_BY_ZERO) },
84 { X (STATUS_INTEGER_OVERFLOW) },
85 { X (STATUS_INVALID_DISPOSITION) },
86 { X (STATUS_IN_PAGE_ERROR) },
87 { X (STATUS_NONCONTINUABLE_EXCEPTION) },
88 { X (STATUS_NO_MEMORY) },
89 { X (STATUS_PENDING) },
90 { X (STATUS_PRIVILEGED_INSTRUCTION) },
91 { X (STATUS_SINGLE_STEP) },
92 { X (STATUS_STACK_OVERFLOW) },
93 { X (STATUS_TIMEOUT) },
94 { X (STATUS_USER_APC) },
95 { X (STATUS_WAIT_0) },
96 { 0, 0 }
97 #undef X
100 /* Initialization code. */
102 void
103 init_console_handler (bool install_handler)
105 BOOL res;
107 SetConsoleCtrlHandler (ctrl_c_handler, FALSE);
108 SetConsoleCtrlHandler (NULL, FALSE);
109 if (install_handler)
110 res = SetConsoleCtrlHandler (ctrl_c_handler, TRUE);
111 else
112 res = SetConsoleCtrlHandler (NULL, TRUE);
113 if (!res)
114 system_printf ("SetConsoleCtrlHandler failed, %E");
117 extern "C" void
118 error_start_init (const char *buf)
120 if (!buf || !*buf)
121 return;
122 if (!debugger_command &&
123 !(debugger_command = (PWCHAR) malloc ((2 * NT_MAX_PATH + 20)
124 * sizeof (WCHAR))))
125 return;
127 PWCHAR cp = debugger_command
128 + sys_mbstowcs (debugger_command, NT_MAX_PATH, buf) - 1;
129 cp = wcpcpy (cp, L" \"");
130 wcpcpy (cp, global_progname);
131 for (PWCHAR p = wcschr (cp, L'\\'); p; p = wcschr (p, L'\\'))
132 *p = L'/';
133 wcscat (cp, L"\"");
136 extern "C" void
137 dumper_init (void)
139 WCHAR dll_dir[PATH_MAX];
140 if (!GetModuleFileNameW (cygwin_hmodule, dll_dir, PATH_MAX))
141 return;
143 /* Strip off last path component ("\\cygwin1.dll") */
144 PWCHAR w = wcsrchr (dll_dir, L'\\');
145 if (!w)
146 return;
148 *w = L'\0';
150 /* Calculate the length of the command, allowing for an appended DWORD PID and
151 terminating null */
152 int cmd_len = 1 + wcslen(dll_dir) + 11 + 5 + 1 + wcslen(global_progname) + 1 + 10 + 1;
153 if (cmd_len > 32767)
155 /* If this comes to more than the 32,767 characters CreateProcess() can
156 accept, we can't work, so don't set dumper_command */
157 return;
160 dumper_command = (PWCHAR) malloc(cmd_len * sizeof (WCHAR));
162 PWCHAR cp = dumper_command;
163 cp = wcpcpy (cp, L"\"");
164 cp = wcpcpy (cp, dll_dir);
165 cp = wcpcpy (cp, L"\\dumper.exe");
166 cp = wcpcpy (cp, L"\" -n ");
167 cp = wcpcpy (cp, L"\"");
168 cp = wcpcpy (cp, global_progname);
169 wcscat (cp, L"\"");
172 void
173 cygwin_exception::open_stackdumpfile ()
175 /* If we have no executable name, or if the CWD handle is NULL,
176 which means, the CWD is a virtual path, don't even try to open
177 a stackdump file. */
178 if (myself->progname[0] && cygheap->cwd.get_handle ())
180 const WCHAR *p;
181 /* write to progname.stackdump if possible */
182 if (!myself->progname[0])
183 p = L"unknown";
184 else if ((p = wcsrchr (myself->progname, L'\\')))
185 p++;
186 else
187 p = myself->progname;
189 WCHAR corefile[wcslen (p) + sizeof (".stackdump")];
190 wcpcpy (wcpcpy(corefile, p), L".stackdump");
191 UNICODE_STRING ucore;
192 OBJECT_ATTRIBUTES attr;
193 /* Create the UNICODE variation of <progname>.stackdump. */
194 RtlInitUnicodeString (&ucore, corefile);
195 /* Create an object attribute which refers to <progname>.stackdump
196 in Cygwin's cwd. Stick to caseinsensitivity. */
197 InitializeObjectAttributes (&attr, &ucore, OBJ_CASE_INSENSITIVE,
198 cygheap->cwd.get_handle (), NULL);
199 IO_STATUS_BLOCK io;
200 NTSTATUS status;
201 /* Try to open it to dump the stack in it. */
202 status = NtCreateFile (&h, GENERIC_WRITE | SYNCHRONIZE, &attr, &io,
203 NULL, FILE_ATTRIBUTE_NORMAL, 0, FILE_OVERWRITE_IF,
204 FILE_SYNCHRONOUS_IO_NONALERT
205 | FILE_OPEN_FOR_BACKUP_INTENT, NULL, 0);
206 if (NT_SUCCESS (status))
208 if (!myself->cygstarted)
209 system_printf ("Dumping stack trace to %S", &ucore);
210 else
211 debug_printf ("Dumping stack trace to %S", &ucore);
212 SetStdHandle (STD_ERROR_HANDLE, h);
217 /* Utilities for dumping the stack, etc. */
219 void
220 cygwin_exception::dump_exception ()
222 const char *exception_name = NULL;
224 for (int i = 0; status_info[i].name; i++)
226 if (status_info[i].code == (NTSTATUS) e->ExceptionCode)
228 exception_name = status_info[i].name;
229 break;
233 #ifdef __x86_64__
234 if (exception_name)
235 small_printf ("Exception: %s at rip=%012X\r\n", exception_name, ctx->Rip);
236 else
237 small_printf ("Signal %d at rip=%012X\r\n", e->ExceptionCode, ctx->Rip);
238 small_printf ("rax=%016X rbx=%016X rcx=%016X\r\n",
239 ctx->Rax, ctx->Rbx, ctx->Rcx);
240 small_printf ("rdx=%016X rsi=%016X rdi=%016X\r\n",
241 ctx->Rdx, ctx->Rsi, ctx->Rdi);
242 small_printf ("r8 =%016X r9 =%016X r10=%016X\r\n",
243 ctx->R8, ctx->R9, ctx->R10);
244 small_printf ("r11=%016X r12=%016X r13=%016X\r\n",
245 ctx->R11, ctx->R12, ctx->R13);
246 small_printf ("r14=%016X r15=%016X\r\n", ctx->R14, ctx->R15);
247 small_printf ("rbp=%016X rsp=%016X\r\n", ctx->Rbp, ctx->Rsp);
248 small_printf ("program=%W, pid %u, thread %s\r\n",
249 myself->progname, myself->pid, mythreadname ());
250 small_printf ("cs=%04x ds=%04x es=%04x fs=%04x gs=%04x ss=%04x\r\n",
251 ctx->SegCs, ctx->SegDs, ctx->SegEs, ctx->SegFs,
252 ctx->SegGs, ctx->SegSs);
253 #else
254 #error unimplemented for this target
255 #endif
258 /* A class for manipulating the stack. */
259 class stack_info
261 int walk (); /* Uses the "old" method */
262 char *next_offset () {return *((char **) sf.AddrFrame.Offset);}
263 bool needargs;
264 PUINT_PTR dummy_frame;
265 CONTEXT c;
266 UNWIND_HISTORY_TABLE hist;
267 __tlsstack_t *sigstackptr;
268 public:
269 STACKFRAME sf; /* For storing the stack information */
270 void init (PUINT_PTR, bool, PCONTEXT); /* Called the first time that stack info is needed */
272 /* Postfix ++ iterates over the stack, returning zero when nothing is left. */
273 int operator ++(int) { return walk (); }
276 /* The number of parameters used in STACKFRAME */
277 #define NPARAMS (sizeof (thestack.sf.Params) / sizeof (thestack.sf.Params[0]))
279 /* This is the main stack frame info for this process. */
280 static NO_COPY stack_info thestack;
282 /* Initialize everything needed to start iterating. */
283 void
284 stack_info::init (PUINT_PTR framep, bool wantargs, PCONTEXT ctx)
286 memset (&hist, 0, sizeof hist);
287 if (ctx)
288 memcpy (&c, ctx, sizeof c);
289 else
291 memset (&c, 0, sizeof c);
292 c.ContextFlags = CONTEXT_ALL;
294 sigstackptr = _my_tls.stackptr;
295 memset (&sf, 0, sizeof (sf));
296 if (ctx)
297 sf.AddrFrame.Offset = (UINT_PTR) framep;
298 else
300 dummy_frame = framep;
301 sf.AddrFrame.Offset = (UINT_PTR) &dummy_frame;
303 if (framep)
304 sf.AddrReturn.Offset = framep[1];
305 sf.AddrFrame.Mode = AddrModeFlat;
306 needargs = wantargs;
309 extern "C" void _cygwin_exit_return ();
311 static inline void
312 __unwind_single_frame (PCONTEXT ctx)
314 PRUNTIME_FUNCTION f;
315 ULONG64 imagebase;
316 UNWIND_HISTORY_TABLE hist = {0};
317 DWORD64 establisher;
318 PVOID hdl;
320 f = RtlLookupFunctionEntry (ctx->_CX_instPtr, &imagebase, &hist);
321 if (f)
322 RtlVirtualUnwind (0, imagebase, ctx->_CX_instPtr, f, ctx, &hdl,
323 &establisher, NULL);
324 else
326 ctx->_CX_instPtr = *(ULONG_PTR *) ctx->_CX_stackPtr;
327 ctx->_CX_stackPtr += 8;
331 /* Walk the stack.
333 On 32 bit we're doing this by looking at successive stored 'ebp' frames.
334 This is not foolproof. */
336 stack_info::walk ()
338 if (!c._CX_instPtr)
339 return 0;
341 sf.AddrPC.Offset = c._CX_instPtr;
342 sf.AddrStack.Offset = c._CX_stackPtr;
343 sf.AddrFrame.Offset = c._CX_framePtr;
345 if ((c._CX_instPtr >= (DWORD64)&_sigbe)
346 && (c._CX_instPtr < (DWORD64)&_sigdelayed_end))
348 /* _sigbe and sigdelayed don't have SEH unwinding data, so virtually
349 unwind the tls sigstack */
350 c._CX_instPtr = sigstackptr[-1];
351 sigstackptr--;
352 return 1;
354 __unwind_single_frame (&c);
355 if (needargs && c._CX_instPtr)
357 PULONG_PTR p = (PULONG_PTR) c._CX_stackPtr;
358 for (unsigned i = 0; i < NPARAMS; ++i)
359 sf.Params[i] = p[i + 1];
361 return 1;
365 Walk the list of modules in the current process to find the one containing
366 'func_va'.
368 This implementation requires no allocation of memory and minimal system
369 calls, so it should be safe in the context of an exception handler.
371 static char *
372 prettyprint_va (PVOID func_va)
374 static char buf[256];
375 buf[0] = '\0';
377 PLIST_ENTRY head = &NtCurrentTeb()->Peb->Ldr->InMemoryOrderModuleList;
378 for (PLIST_ENTRY x = head->Flink; x != head; x = x->Flink)
380 PLDR_DATA_TABLE_ENTRY mod = CONTAINING_RECORD (x, LDR_DATA_TABLE_ENTRY,
381 InMemoryOrderLinks);
382 if ((func_va < mod->DllBase) ||
383 (func_va > (PVOID)((DWORD_PTR)mod->DllBase + mod->SizeOfImage)))
384 continue;
386 __small_sprintf (buf, "%S+0x%x", &mod->BaseDllName,
387 (DWORD_PTR)func_va - (DWORD_PTR)mod->DllBase);
388 break;
391 return buf;
394 void
395 cygwin_exception::dumpstack ()
397 static bool already_dumped;
399 __try
401 if (already_dumped || cygheap->rlim_core == 0Ul)
402 return;
403 already_dumped = true;
404 open_stackdumpfile ();
406 if (e)
407 dump_exception ();
409 int i;
411 thestack.init (framep, 1, ctx); /* Initialize from the input CONTEXT */
412 small_printf ("Stack trace:\r\nFrame Function Args\r\n");
413 for (i = 0; i < DUMPSTACK_FRAME_LIMIT && thestack++; i++)
415 small_printf ("%012X %012X", thestack.sf.AddrFrame.Offset,
416 thestack.sf.AddrPC.Offset);
417 for (unsigned j = 0; j < NPARAMS; j++)
418 small_printf ("%s%012X", j == 0 ? " (" : ", ",
419 thestack.sf.Params[j]);
420 small_printf (") %s\r\n", prettyprint_va((PVOID)thestack.sf.AddrPC.Offset));
422 small_printf ("End of stack trace%s\r\n",
423 i == DUMPSTACK_FRAME_LIMIT ?
424 " (more stack frames may be present)" : "");
426 small_printf ("Loaded modules:\r\n");
427 PLIST_ENTRY head = &NtCurrentTeb()->Peb->Ldr->InMemoryOrderModuleList;
428 for (PLIST_ENTRY x = head->Flink; x != head; x = x->Flink)
430 PLDR_DATA_TABLE_ENTRY mod = CONTAINING_RECORD (x, LDR_DATA_TABLE_ENTRY,
431 InMemoryOrderLinks);
432 small_printf ("%012X %S\r\n", mod->DllBase, &mod->BaseDllName);
435 if (h)
436 NtClose (h);
438 __except (NO_ERROR) {}
439 __endtry
442 bool
443 _cygtls::inside_kernel (CONTEXT *cx)
445 int res;
446 MEMORY_BASIC_INFORMATION m;
448 if (!isinitialized ())
449 return true;
451 memset (&m, 0, sizeof m);
452 if (!VirtualQuery ((LPCVOID) cx->_CX_instPtr, &m, sizeof m))
453 sigproc_printf ("couldn't get memory info, pc %p, %E", cx->_CX_instPtr);
455 size_t size = (windows_system_directory_length + 6) * sizeof (WCHAR);
456 PWCHAR checkdir = (PWCHAR) alloca (size);
457 memset (checkdir, 0, size);
459 # define h ((HMODULE) m.AllocationBase)
460 if (!h || m.State != MEM_COMMIT) /* Be defensive */
461 res = true;
462 else if (h == hntdll)
463 res = true; /* Calling GetModuleFilename on ntdll.dll
464 can hang */
465 else if (h == user_data->hmodule)
466 res = false;
467 else if (!GetModuleFileNameW (h, checkdir,
468 windows_system_directory_length + 6))
469 res = false;
470 else
472 /* Skip potential long path prefix. */
473 if (!wcsncmp (checkdir, L"\\\\?\\", 4))
474 checkdir += 4;
475 res = wcsncasecmp (windows_system_directory, checkdir,
476 windows_system_directory_length) == 0;
478 sigproc_printf ("pc %p, h %p, inside_kernel %d", cx->_CX_instPtr, h, res);
479 # undef h
480 return res;
483 /* Temporary (?) function for external callers to get a stack dump */
484 extern "C" void
485 cygwin_stackdump ()
487 CONTEXT c;
488 c.ContextFlags = CONTEXT_FULL;
489 RtlCaptureContext (&c);
490 cygwin_exception exc ((PUINT_PTR) c._CX_framePtr, &c);
491 exc.dumpstack ();
494 static
495 int exec_prepared_command (PWCHAR command)
497 if (!command)
498 return 0;
499 debug_printf ("executing prepared command '%W'", command);
501 PWCHAR dbg_end = wcschr (command, L'\0');
502 __small_swprintf (dbg_end, L" %u", GetCurrentProcessId ());
504 LONG prio = GetThreadPriority (GetCurrentThread ());
505 SetThreadPriority (GetCurrentThread (), THREAD_PRIORITY_HIGHEST);
506 PROCESS_INFORMATION pi = {NULL, 0, 0, 0};
508 STARTUPINFOW si = {0, NULL, NULL, NULL, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
509 NULL, NULL, NULL, NULL};
510 si.lpReserved = NULL;
511 si.lpDesktop = NULL;
512 si.dwFlags = 0;
513 si.cb = sizeof (si);
515 /* FIXME: need to know handles of all running threads to
516 suspend_all_threads_except (current_thread_id);
519 /* If the tty mutex is owned, we will fail to start any cygwin app
520 until the trapped app exits. However, this will only release any
521 the mutex if it is owned by this thread so that may be problematic. */
523 lock_ttys::release ();
525 /* prevent recursive exception handling */
526 PWCHAR rawenv = GetEnvironmentStringsW () ;
527 for (PWCHAR p = rawenv; *p != L'\0'; p = wcschr (p, L'\0') + 1)
529 if (wcsncmp (p, L"CYGWIN=", wcslen (L"CYGWIN=")) == 0)
531 PWCHAR q = wcsstr (p, L"error_start") ;
532 /* replace 'error_start=...' with '_rror_start=...' */
533 if (q)
535 *q = L'_' ;
536 SetEnvironmentVariableW (L"CYGWIN", p + wcslen (L"CYGWIN=")) ;
538 break;
541 FreeEnvironmentStringsW (rawenv);
543 /* timeout from waiting for debugger to attach after 10 seconds */
544 ULONGLONG timeout = GetTickCount64() + 10*1000;
546 console_printf ("*** starting '%W' for pid %u, tid %u\r\n",
547 command,
548 cygwin_pid (GetCurrentProcessId ()), GetCurrentThreadId ());
549 BOOL dbg;
550 dbg = CreateProcessW (NULL,
551 command,
552 NULL,
553 NULL,
554 FALSE,
555 CREATE_NEW_CONSOLE | CREATE_NEW_PROCESS_GROUP,
556 NULL,
557 NULL,
558 &si,
559 &pi);
561 /* We want to stop here and wait until the error_start process attaches. But
562 we can't wait here for the error_start process to exit, as if it's a
563 debugger, it might want to continue this thread. So we busy wait until a
564 debugger attaches, which stops this process, after which it can decide if
565 we continue or not.
567 Note that this is still racy: if the error_start process does it's work too
568 fast, we don't notice that it attached and get stuck here. So we also
569 apply a timeout to ensure we exit eventually.
572 *dbg_end = L'\0';
573 if (!dbg)
574 system_printf ("Failed to start, %E");
575 else
577 while (!being_debugged () && GetTickCount64() < timeout)
578 Sleep (0);
579 Sleep (2000);
582 console_printf ("*** continuing pid %u\r\n",
583 cygwin_pid (GetCurrentProcessId ()));
585 SetThreadPriority (GetCurrentThread (), prio);
586 return dbg;
589 extern "C" int
590 try_to_debug ()
592 /* If already being debugged, break into the debugger (Note that this function
593 can be called from places other than an exception) */
594 if (being_debugged ())
596 extern void break_here ();
597 break_here ();
598 return 1;
601 /* Otherwise, invoke the JIT debugger, if set */
602 return exec_prepared_command (debugger_command);
605 /* myfault exception handler. */
606 EXCEPTION_DISPOSITION
607 exception::myfault (EXCEPTION_RECORD *e, exception_list *frame, CONTEXT *in,
608 PDISPATCHER_CONTEXT dispatch)
610 PSCOPE_TABLE table = (PSCOPE_TABLE) dispatch->HandlerData;
611 RtlUnwindEx (frame,
612 (char *) dispatch->ImageBase + table->ScopeRecord[0].JumpTarget,
613 e, 0, in, dispatch->HistoryTable);
614 /* NOTREACHED, make gcc happy. */
615 return ExceptionContinueSearch;
618 /* If another exception occurs while running a signal handler on an alternate
619 signal stack, the normal SEH handlers are skipped, because the OS exception
620 handling considers the current (alternate) stack "broken". However, it
621 still calls vectored exception handlers.
623 TODO: What we do here is to handle only __try/__except blocks in Cygwin.
624 "Normal" exceptions will simply exit the process. Still, better
625 than nothing... */
626 LONG
627 myfault_altstack_handler (EXCEPTION_POINTERS *exc)
629 _cygtls& me = _my_tls;
631 if (me.andreas)
633 CONTEXT *c = exc->ContextRecord;
635 /* Unwind the stack manually and call RtlRestoreContext. This
636 is necessary because RtlUnwindEx checks the stack for validity,
637 which, as outlined above, fails for the alternate stack. */
638 while (c->_CX_stackPtr < me.andreas->frame)
639 __unwind_single_frame (c);
640 c->_CX_instPtr = me.andreas->ret;
641 RtlRestoreContext (c, NULL);
643 return EXCEPTION_CONTINUE_SEARCH;
646 /* Main exception handler. */
647 EXCEPTION_DISPOSITION
648 exception::handle (EXCEPTION_RECORD *e, exception_list *frame, CONTEXT *in,
649 PDISPATCHER_CONTEXT dispatch)
651 static int NO_COPY debugging = 0;
652 _cygtls& me = _my_tls;
654 if (debugging && ++debugging < 500000)
656 SetThreadPriority (hMainThread, THREAD_PRIORITY_NORMAL);
657 return ExceptionContinueExecution;
660 /* If we're exiting, tell Windows to keep looking for an
661 exception handler. */
662 if (exit_state || e->ExceptionFlags)
663 return ExceptionContinueSearch;
665 siginfo_t si = {};
666 si.si_code = SI_KERNEL;
667 /* Coerce win32 value to posix value. */
668 switch (e->ExceptionCode)
670 case STATUS_FLOAT_DIVIDE_BY_ZERO:
671 si.si_signo = SIGFPE;
672 si.si_code = FPE_FLTDIV;
673 break;
674 case STATUS_FLOAT_DENORMAL_OPERAND:
675 case STATUS_FLOAT_INVALID_OPERATION:
676 si.si_signo = SIGFPE;
677 si.si_code = FPE_FLTINV;
678 break;
679 case STATUS_FLOAT_STACK_CHECK:
680 si.si_signo = SIGFPE;
681 si.si_code = FPE_FLTSUB;
682 break;
683 case STATUS_FLOAT_INEXACT_RESULT:
684 si.si_signo = SIGFPE;
685 si.si_code = FPE_FLTRES;
686 break;
687 case STATUS_FLOAT_OVERFLOW:
688 si.si_signo = SIGFPE;
689 si.si_code = FPE_FLTOVF;
690 break;
691 case STATUS_FLOAT_UNDERFLOW:
692 si.si_signo = SIGFPE;
693 si.si_code = FPE_FLTUND;
694 break;
695 case STATUS_INTEGER_DIVIDE_BY_ZERO:
696 si.si_signo = SIGFPE;
697 si.si_code = FPE_INTDIV;
698 break;
699 case STATUS_INTEGER_OVERFLOW:
700 si.si_signo = SIGFPE;
701 si.si_code = FPE_INTOVF;
702 break;
704 case STATUS_ILLEGAL_INSTRUCTION:
705 si.si_signo = SIGILL;
706 si.si_code = ILL_ILLOPC;
707 break;
709 case STATUS_PRIVILEGED_INSTRUCTION:
710 si.si_signo = SIGILL;
711 si.si_code = ILL_PRVOPC;
712 break;
714 case STATUS_NONCONTINUABLE_EXCEPTION:
715 si.si_signo = SIGILL;
716 si.si_code = ILL_ILLADR;
717 break;
719 case STATUS_TIMEOUT:
720 si.si_signo = SIGALRM;
721 break;
723 case STATUS_GUARD_PAGE_VIOLATION:
724 si.si_signo = SIGBUS;
725 si.si_code = BUS_OBJERR;
726 break;
728 case STATUS_DATATYPE_MISALIGNMENT:
729 si.si_signo = SIGBUS;
730 si.si_code = BUS_ADRALN;
731 break;
733 case STATUS_ACCESS_VIOLATION:
734 switch (mmap_is_attached_or_noreserve ((void *)e->ExceptionInformation[1],
737 case MMAP_NORESERVE_COMMITED:
738 return ExceptionContinueExecution;
739 case MMAP_RAISE_SIGBUS: /* MAP_NORESERVE page, commit failed, or
740 access to mmap page beyond EOF. */
741 si.si_signo = SIGBUS;
742 si.si_code = BUS_OBJERR;
743 break;
744 default:
745 MEMORY_BASIC_INFORMATION m;
746 VirtualQuery ((PVOID) e->ExceptionInformation[1], &m, sizeof m);
747 si.si_signo = SIGSEGV;
748 si.si_code = m.State == MEM_FREE ? SEGV_MAPERR : SEGV_ACCERR;
749 break;
751 break;
753 case STATUS_STACK_OVERFLOW:
754 /* If we encounter a stack overflow, and if the thread has no alternate
755 stack, don't even try to call a signal handler. This is in line with
756 Linux behaviour and also makes a lot of sense on Windows. */
757 if (me.altstack.ss_flags)
758 global_sigs[SIGSEGV].sa_handler = SIG_DFL;
759 fallthrough;
760 case STATUS_ARRAY_BOUNDS_EXCEEDED:
761 case STATUS_IN_PAGE_ERROR:
762 case STATUS_NO_MEMORY:
763 case STATUS_INVALID_DISPOSITION:
764 si.si_signo = SIGSEGV;
765 si.si_code = SEGV_MAPERR;
766 break;
768 case STATUS_CONTROL_C_EXIT:
769 si.si_signo = SIGINT;
770 break;
772 case STATUS_INVALID_HANDLE:
773 /* CloseHandle will throw this exception if it is given an
774 invalid handle. We don't care about the exception; we just
775 want CloseHandle to return an error. This can be revisited
776 if gcc ever supports Windows style structured exception
777 handling. */
778 return ExceptionContinueExecution;
780 case STATUS_GCC_THROW:
781 case STATUS_GCC_UNWIND:
782 case STATUS_GCC_FORCED:
783 /* According to a comment in the GCC function
784 _Unwind_RaiseException(), GCC expects us to continue all the
785 (continuable) GCC exceptions that reach us. */
786 return ExceptionContinueExecution;
788 default:
789 /* If we don't recognize the exception, we have to assume that
790 we are doing structured exception handling, and we let
791 something else handle it. */
792 return ExceptionContinueSearch;
795 debug_printf ("In cygwin_except_handler exception %y at %p sp %p",
796 e->ExceptionCode, in->_CX_instPtr, in->_CX_stackPtr);
797 debug_printf ("In cygwin_except_handler signal %d at %p",
798 si.si_signo, in->_CX_instPtr);
800 PUINT_PTR framep = (PUINT_PTR) in->_CX_framePtr;
801 /* Sometimes, when a stack is screwed up, the frame pointer tends to be NULL.
802 In that case, base the stacktrace on the stack pointer. In most cases,
803 it allows to generate useful stack trace. */
804 if (!framep)
805 framep = (PUINT_PTR) in->_CX_stackPtr;
807 if (exit_state >= ES_SIGNAL_EXIT
808 && (NTSTATUS) e->ExceptionCode != STATUS_CONTROL_C_EXIT)
809 api_fatal ("Exception during process exit");
810 else if (try_to_debug ())
812 debugging = 1;
813 return ExceptionContinueExecution;
816 cygwin_exception exc (framep, in, e);
817 si.si_cyg = (void *) &exc;
818 /* POSIX requires that for SIGSEGV and SIGBUS, si_addr should be set to the
819 address of faulting memory reference. For SIGILL and SIGFPE these should
820 be the address of the faulting instruction. Other signals are apparently
821 undefined so we just set those to the faulting instruction too. */
822 si.si_addr = (si.si_signo == SIGSEGV || si.si_signo == SIGBUS)
823 ? (void *) e->ExceptionInformation[1] : (void *) in->_CX_instPtr;
824 me.incyg++;
825 sig_send (NULL, si, &me); /* Signal myself */
826 if ((NTSTATUS) e->ExceptionCode == STATUS_STACK_OVERFLOW)
828 /* If we catched a stack overflow, and if the signal handler didn't exit
829 or longjmp, we're back here and about to continue, supposed to run the
830 offending instruction again. That works on Linux, but not on Windows.
831 In case of a stack overflow we're not immediately returning to the
832 system exception handler, but to NTDLL::__stkchk. __stkchk will then
833 terminate the applicaton. So what we do here is to signal our current
834 process again, but this time with SIG_DFL action. This creates a
835 stackdump and then exits through our own means. */
836 global_sigs[SIGSEGV].sa_handler = SIG_DFL;
837 sig_send (NULL, si, &me);
839 me.incyg--;
840 e->ExceptionFlags = 0;
841 return ExceptionContinueExecution;
844 /* Utilities to call a user supplied exception handler. */
846 #define SIG_NONMASKABLE (SIGTOMASK (SIGKILL) | SIGTOMASK (SIGSTOP))
848 /* Non-raceable sigsuspend
849 Note: This implementation is based on the Single UNIX Specification
850 man page. This indicates that sigsuspend always returns -1 and that
851 attempts to block unblockable signals will be silently ignored.
852 This is counter to what appears to be documented in some UNIX
853 man pages, e.g. Linux. */
855 handle_sigsuspend (sigset_t tempmask)
857 sigset_t oldmask = _my_tls.sigmask; // Remember for restoration
859 set_signal_mask (_my_tls.sigmask, tempmask);
860 sigproc_printf ("oldmask %ly, newmask %ly", oldmask, tempmask);
862 pthread_testcancel ();
863 cygwait (NULL, cw_infinite, cw_cancel | cw_cancel_self | cw_sig_eintr);
865 set_sig_errno (EINTR); // Per POSIX
867 /* A signal dispatch function will have been added to our stack and will
868 be hit eventually. Set the old mask to be restored when the signal
869 handler returns and indicate its presence by modifying deltamask. */
871 _my_tls.deltamask |= SIG_NONMASKABLE;
872 _my_tls.oldmask = oldmask; // Will be restored by signal handler
873 return -1;
876 extern DWORD exec_exit; // Possible exit value for exec
878 extern "C" {
879 static void
880 sig_handle_tty_stop (int sig, siginfo_t *, void *)
882 /* Silently ignore attempts to suspend if there is no accommodating
883 cygwin parent to deal with this behavior. */
884 if (!myself->cygstarted)
885 myself->process_state &= ~PID_STOPPED;
886 else
888 _my_tls.incyg = 1;
889 myself->stopsig = sig;
890 myself->alert_parent (sig);
891 sigproc_printf ("process %d stopped by signal %d", myself->pid, sig);
892 /* FIXME! This does nothing to suspend anything other than the main
893 thread. */
894 /* Use special cygwait parameter to handle SIGCONT. _main_tls.sig will
895 be cleared under lock when SIGCONT is detected. */
896 pthread::suspend_all_except_self ();
897 DWORD res = cygwait (NULL, cw_infinite, cw_sig_cont);
898 pthread::resume_all ();
899 switch (res)
901 case WAIT_SIGNALED:
902 myself->stopsig = SIGCONT;
903 myself->alert_parent (SIGCONT);
904 break;
905 default:
906 api_fatal ("WaitSingleObject returned %d", res);
907 break;
909 _my_tls.incyg = 0;
912 } /* end extern "C" */
914 bool
915 _cygtls::interrupt_now (CONTEXT *cx, siginfo_t& si, void *handler,
916 struct sigaction& siga)
918 bool interrupted;
920 /* Delay the interrupt if we are
921 1) somehow inside the DLL
922 2) in _sigfe (spinning is true) and about to enter cygwin DLL
923 3) in a Windows DLL. */
924 if (incyg || spinning || inside_kernel (cx))
925 interrupted = false;
926 else
928 DWORD64 &ip = cx->_CX_instPtr;
929 push (ip);
930 interrupt_setup (si, handler, siga);
931 ip = pop ();
932 SetThreadContext (*this, cx); /* Restart the thread in a new location */
933 interrupted = true;
935 return interrupted;
938 void
939 _cygtls::interrupt_setup (siginfo_t& si, void *handler, struct sigaction& siga)
941 push ((__tlsstack_t) sigdelayed);
942 deltamask = siga.sa_mask & ~SIG_NONMASKABLE;
943 sa_flags = siga.sa_flags;
944 func = (void (*) (int, siginfo_t *, void *)) handler;
945 if (siga.sa_flags & SA_RESETHAND)
946 siga.sa_handler = SIG_DFL;
947 saved_errno = -1; // Flag: no errno to save
948 if (handler == sig_handle_tty_stop)
950 myself->stopsig = 0;
951 myself->process_state |= PID_STOPPED;
954 infodata = si;
955 this->sig = si.si_signo; /* Should always be last thing set to avoid race */
957 if (incyg)
958 set_signal_arrived ();
960 if (!have_execed && !(myself->exec_sendsig && !ch_spawn.iscygwin ()))
961 proc_subproc (PROC_CLEARWAIT, 1);
962 sigproc_printf ("armed signal_arrived %p, signal %d",
963 signal_arrived, si.si_signo);
966 extern "C" void
967 set_sig_errno (int e)
969 *_my_tls.errno_addr = e;
970 _my_tls.saved_errno = e;
974 sigpacket::setup_handler (void *handler, struct sigaction& siga, _cygtls *tls)
976 CONTEXT cx;
977 bool interrupted = false;
979 if (tls->sig)
981 sigproc_printf ("trying to send signal %d but signal %d already armed",
982 si.si_signo, tls->sig);
983 goto out;
986 for (int n = 0; n < CALL_HANDLER_RETRY_OUTER; n++)
988 for (int i = 0; i < CALL_HANDLER_RETRY_INNER; i++)
990 tls->lock ();
991 if (tls->incyg)
993 sigproc_printf ("controlled interrupt. stackptr %p, stack %p, "
994 "stackptr[-1] %p",
995 tls->stackptr, tls->stack, tls->stackptr[-1]);
996 tls->interrupt_setup (si, handler, siga);
997 interrupted = true;
998 tls->unlock ();
999 goto out;
1002 DWORD res;
1003 HANDLE hth = (HANDLE) *tls;
1004 if (!hth)
1006 tls->unlock ();
1007 sigproc_printf ("thread handle NULL, not set up yet?");
1009 else
1011 /* Suspend the thread which will receive the signal.
1012 If one of these conditions is not true we loop.
1013 If the thread is already suspended (which can occur when a
1014 program has called SuspendThread on itself) then just queue
1015 the signal. */
1016 sigproc_printf ("suspending thread, tls %p, _main_tls %p",
1017 tls, _main_tls);
1018 res = SuspendThread (hth);
1019 /* Just set pending if thread is already suspended */
1020 if (res)
1022 tls->unlock ();
1023 ResumeThread (hth);
1024 goto out;
1026 cx.ContextFlags = CONTEXT_CONTROL | CONTEXT_INTEGER;
1027 if (!GetThreadContext (hth, &cx))
1028 sigproc_printf ("couldn't get context of thread, %E");
1029 else
1030 interrupted = tls->interrupt_now (&cx, si, handler, siga);
1032 tls->unlock ();
1033 ResumeThread (hth);
1034 if (interrupted)
1035 goto out;
1038 sigproc_printf ("couldn't interrupt. trying again.");
1039 yield ();
1041 /* Hit here if we couldn't deliver the signal. Take a more drastic
1042 action before trying again. */
1043 Sleep (1);
1046 out:
1047 sigproc_printf ("signal %d %sdelivered", si.si_signo,
1048 interrupted ? "" : "not ");
1049 return interrupted;
1052 static inline bool
1053 has_visible_window_station ()
1055 HWINSTA station_hdl;
1056 USEROBJECTFLAGS uof;
1057 DWORD len;
1059 /* Check if the process is associated with a visible window station.
1060 These are processes running on the local desktop as well as processes
1061 running in terminal server sessions.
1062 Processes running in a service session not explicitely associated
1063 with the desktop (using the "Allow service to interact with desktop"
1064 property) are running in an invisible window station. */
1065 if ((station_hdl = GetProcessWindowStation ())
1066 && GetUserObjectInformationW (station_hdl, UOI_FLAGS, &uof,
1067 sizeof uof, &len)
1068 && (uof.dwFlags & WSF_VISIBLE))
1069 return true;
1070 return false;
1073 /* Keyboard interrupt handler. */
1074 static BOOL
1075 ctrl_c_handler (DWORD type)
1077 static bool saw_close;
1079 /* Remove early or we could overthrow the threadlist in cygheap.
1080 Deleting this line causes ash to SEGV if CTRL-C is hit repeatedly.
1081 I am not exactly sure why that is. Maybe it's just because this
1082 adds some early serialization to ctrl_c_handler which prevents
1083 multiple simultaneous calls? */
1084 _my_tls.remove (INFINITE);
1086 #if 0
1087 if (type == CTRL_C_EVENT || type == CTRL_BREAK_EVENT)
1088 proc_subproc (PROC_KILLFORKED, 0);
1089 #endif
1091 /* Return FALSE to prevent an "End task" dialog box from appearing
1092 for each Cygwin process window that's open when the computer
1093 is shut down or console window is closed. */
1095 if (type == CTRL_SHUTDOWN_EVENT)
1097 #if 0
1098 /* Don't send a signal. Only NT service applications and their child
1099 processes will receive this event and the services typically already
1100 handle the shutdown action when getting the SERVICE_CONTROL_SHUTDOWN
1101 control message. */
1102 sig_send (NULL, SIGTERM);
1103 #endif
1104 return FALSE;
1107 if (myself->ctty != CTTY_UNINITIALIZED)
1109 if (type == CTRL_CLOSE_EVENT)
1111 sig_send (NULL, SIGHUP);
1112 saw_close = true;
1113 return FALSE;
1115 if (!saw_close && type == CTRL_LOGOFF_EVENT)
1117 /* The CTRL_LOGOFF_EVENT is sent when *any* user logs off.
1118 The below code sends a SIGHUP only if it is not performing the
1119 default activity for SIGHUP. Note that it is possible for two
1120 SIGHUP signals to arrive if a process group leader is exiting
1121 too. Getting this 100% right is saved for a future cygwin mailing
1122 list goad. */
1123 if (global_sigs[SIGHUP].sa_handler != SIG_DFL)
1125 sig_send (myself, SIGHUP);
1126 return TRUE;
1128 return FALSE;
1132 if (ch_spawn.set_saw_ctrl_c ())
1134 if (myself->process_state & PID_NOTCYGWIN)
1135 sigExeced = SIGINT;
1136 return TRUE;
1139 /* We're only the process group leader when we have a valid pinfo structure.
1140 If we don't have one, then the parent "stub" will handle the signal. */
1141 if (!pinfo (cygwin_pid (GetCurrentProcessId ())))
1142 return TRUE;
1144 if (type == CTRL_C_EVENT && ::cygheap->ctty
1145 && !cygheap->ctty->need_console_handler ())
1146 /* Ctrl-C is handled in fhandler_console::cons_master_thread(). */
1147 return TRUE;
1149 tty_min *t = cygwin_shared->tty.get_cttyp ();
1151 if (!t)
1152 return TRUE;
1154 /* If process group leader is non-cygwin process or not exist,
1155 send signal to myself. */
1156 pinfo pi (t->getpgid ());
1157 if ((!pi || (pi->process_state & PID_NOTCYGWIN))
1158 && (!have_execed || have_execed_cygwin)
1159 && t->getpgid () == myself->pgid
1160 && type == CTRL_C_EVENT)
1162 t->output_stopped = false;
1163 sig_send(myself, SIGINT);
1166 /* Ignore this if we're not the process group leader since it should be
1167 handled *by* the process group leader. */
1168 if (t && (!have_execed || have_execed_cygwin)
1169 && t->getpgid () == myself->pid &&
1170 (GetTickCount64 () - t->last_ctrl_c) >= MIN_CTRL_C_SLOP)
1171 /* Otherwise we just send a SIGINT to the process group and return TRUE
1172 (to indicate that we have handled the signal). At this point, type
1173 should be a CTRL_C_EVENT or CTRL_BREAK_EVENT. */
1175 int sig = SIGINT;
1176 /* If intr and quit are both mapped to ^C, send SIGQUIT on ^BREAK */
1177 if (type == CTRL_BREAK_EVENT
1178 && t->ti.c_cc[VINTR] == 3 && t->ti.c_cc[VQUIT] == 3)
1179 sig = SIGQUIT;
1180 t->last_ctrl_c = GetTickCount64 ();
1181 t->kill_pgrp (sig);
1182 t->output_stopped = false;
1183 t->last_ctrl_c = GetTickCount64 ();
1184 return TRUE;
1187 return TRUE;
1190 /* Function used by low level sig wrappers. */
1191 extern "C" void
1192 set_process_mask (sigset_t newmask)
1194 set_signal_mask (_my_tls.sigmask, newmask);
1197 extern "C" int
1198 sighold (int sig)
1200 /* check that sig is in right range */
1201 if (sig < 0 || sig >= _NSIG)
1203 set_errno (EINVAL);
1204 syscall_printf ("signal %d out of range", sig);
1205 return -1;
1207 sigset_t mask = _my_tls.sigmask;
1208 sigaddset (&mask, sig);
1209 set_signal_mask (_my_tls.sigmask, mask);
1210 return 0;
1213 extern "C" int
1214 sigrelse (int sig)
1216 /* check that sig is in right range */
1217 if (sig < 0 || sig >= _NSIG)
1219 set_errno (EINVAL);
1220 syscall_printf ("signal %d out of range", sig);
1221 return -1;
1223 sigset_t mask = _my_tls.sigmask;
1224 sigdelset (&mask, sig);
1225 set_signal_mask (_my_tls.sigmask, mask);
1226 return 0;
1229 extern "C" _sig_func_ptr
1230 sigset (int sig, _sig_func_ptr func)
1232 sig_dispatch_pending ();
1233 _sig_func_ptr prev;
1235 /* check that sig is in right range */
1236 if (sig < 0 || sig >= _NSIG || sig == SIGKILL || sig == SIGSTOP)
1238 set_errno (EINVAL);
1239 syscall_printf ("SIG_ERR = sigset (%d, %p)", sig, func);
1240 return (_sig_func_ptr) SIG_ERR;
1243 sigset_t mask = _my_tls.sigmask;
1244 /* If sig was in the signal mask return SIG_HOLD, otherwise return the
1245 previous disposition. */
1246 if (sigismember (&mask, sig))
1247 prev = SIG_HOLD;
1248 else
1249 prev = global_sigs[sig].sa_handler;
1250 /* If func is SIG_HOLD, add sig to the signal mask, otherwise set the
1251 disposition to func and remove sig from the signal mask. */
1252 if (func == SIG_HOLD)
1253 sigaddset (&mask, sig);
1254 else
1256 /* No error checking. The test which could return SIG_ERR has already
1257 been made above. */
1258 signal (sig, func);
1259 sigdelset (&mask, sig);
1261 set_signal_mask (_my_tls.sigmask, mask);
1262 return prev;
1265 extern "C" int
1266 sigignore (int sig)
1268 return sigset (sig, SIG_IGN) == SIG_ERR ? -1 : 0;
1271 /* Update the signal mask for this process and return the old mask.
1272 Called from call_signal_handler */
1273 extern "C" sigset_t
1274 set_process_mask_delta ()
1276 sigset_t newmask, oldmask;
1278 if (_my_tls.deltamask & SIG_NONMASKABLE)
1279 oldmask = _my_tls.oldmask; /* from handle_sigsuspend */
1280 else
1281 oldmask = _my_tls.sigmask;
1282 newmask = (oldmask | _my_tls.deltamask) & ~SIG_NONMASKABLE;
1283 sigproc_printf ("oldmask %lx, newmask %lx, deltamask %lx", oldmask, newmask,
1284 _my_tls.deltamask);
1285 _my_tls.sigmask = newmask;
1286 return oldmask;
1289 /* Set the signal mask for this process.
1290 Note that some signals are unmaskable, as in UNIX. */
1292 void
1293 set_signal_mask (sigset_t& setmask, sigset_t newmask)
1295 newmask &= ~SIG_NONMASKABLE;
1296 sigset_t mask_bits = setmask & ~newmask;
1297 sigproc_printf ("setmask %lx, newmask %lx, mask_bits %lx", setmask, newmask,
1298 mask_bits);
1299 setmask = newmask;
1300 if (mask_bits)
1301 sig_dispatch_pending (true);
1305 DWORD
1306 dumpstack_overflow_wrapper (PVOID arg)
1308 cygwin_exception *exc = (cygwin_exception *) arg;
1309 SetThreadName (GetCurrentThreadId (), "__dumpstack_overflow");
1310 exc->dumpstack ();
1311 return 0;
1314 /* Exit due to a signal. Should only be called from the signal thread. */
1315 extern "C" {
1316 static void
1317 signal_exit (int sig, siginfo_t *si, void *)
1319 debug_printf ("exiting due to signal %d", sig);
1320 exit_state = ES_SIGNAL_EXIT;
1322 switch (sig)
1324 case SIGABRT:
1325 case SIGBUS:
1326 case SIGFPE:
1327 case SIGILL:
1328 case SIGQUIT:
1329 case SIGSEGV:
1330 case SIGSYS:
1331 case SIGTRAP:
1332 case SIGXCPU:
1333 case SIGXFSZ:
1334 if (try_to_debug ())
1335 break;
1337 if (cygheap->rlim_core == 0Ul)
1338 break;
1340 sig |= __WCOREFLAG; /* Set flag in exit status to show that we've "dumped core" */
1342 /* If core dump size is >1MB, try to invoke dumper to write a
1343 .core file */
1344 if (cygheap->rlim_core > 1024*1024)
1346 if (exec_prepared_command (dumper_command))
1347 break;
1348 /* If that failed, fall-through to... */
1351 /* Otherwise write a .stackdump */
1352 if (si->si_code != SI_USER && si->si_cyg)
1354 cygwin_exception *exc = (cygwin_exception *) si->si_cyg;
1355 if ((NTSTATUS) exc->exception_record ()->ExceptionCode
1356 == STATUS_STACK_OVERFLOW)
1358 /* We're handling a stack overflow so we're running low
1359 on stack (surprise!) The dumpstack method needs lots
1360 of stack for buffers. So what we do here is to run
1361 dumpstack in another thread with its own stack. */
1362 HANDLE thread = CreateThread (&sec_none_nih, 0,
1363 dumpstack_overflow_wrapper,
1364 exc, 0, NULL);
1365 if (thread)
1367 WaitForSingleObject (thread, INFINITE);
1368 CloseHandle (thread);
1371 else
1372 ((cygwin_exception *) si->si_cyg)->dumpstack ();
1374 else
1376 CONTEXT c;
1377 c.ContextFlags = CONTEXT_FULL;
1378 RtlCaptureContext (&c);
1379 cygwin_exception exc ((PUINT_PTR) __builtin_frame_address (0), &c);
1380 exc.dumpstack ();
1382 break;
1385 lock_process until_exit (true);
1387 if (have_execed || exit_state > ES_PROCESS_LOCKED)
1389 debug_printf ("recursive exit?");
1390 myself.exit (sig);
1393 /* Starve other threads in a vain attempt to stop them from doing something
1394 stupid. */
1395 SetThreadPriority (GetCurrentThread (), THREAD_PRIORITY_TIME_CRITICAL);
1397 sigproc_printf ("about to call do_exit (%x)", sig);
1398 do_exit (sig);
1400 } /* extern "C" */
1402 /* As above, but before exiting due to api_fatal */
1403 extern "C"
1404 void
1405 api_fatal_debug ()
1407 if (try_to_debug ())
1408 return;
1410 if (cygheap->rlim_core == 0Ul)
1411 return;
1413 if (cygheap->rlim_core > 1024*1024)
1414 if (exec_prepared_command (dumper_command))
1415 return;
1417 cygwin_stackdump();
1420 /* Attempt to carefully handle SIGCONT when we are stopped. */
1421 void
1422 _cygtls::handle_SIGCONT ()
1424 if (NOTSTATE (myself, PID_STOPPED))
1425 return;
1427 myself->stopsig = 0;
1428 myself->process_state &= ~PID_STOPPED;
1429 /* Carefully tell sig_handle_tty_stop to wake up.
1430 Make sure that any pending signal is handled before trying to
1431 send a new one. Then make sure that SIGCONT has been recognized
1432 before exiting the loop. */
1433 bool sigsent = false;
1434 while (1)
1435 if (sig) /* Assume that it's ok to just test sig outside of a
1436 lock since setup_handler does it this way. */
1437 yield (); /* Attempt to schedule another thread. */
1438 else if (sigsent)
1439 break; /* SIGCONT has been recognized by other thread */
1440 else
1442 sig = SIGCONT;
1443 set_signal_arrived (); /* alert sig_handle_tty_stop */
1444 sigsent = true;
1446 /* Clear pending stop signals */
1447 sig_clear (SIGSTOP);
1448 sig_clear (SIGTSTP);
1449 sig_clear (SIGTTIN);
1450 sig_clear (SIGTTOU);
1454 sigpacket::process ()
1456 int rc = 1;
1457 bool issig_wait = false;
1458 struct sigaction& thissig = global_sigs[si.si_signo];
1459 void *handler = have_execed ? NULL : (void *) thissig.sa_handler;
1461 threadlist_t *tl_entry = NULL;
1462 _cygtls *tls = NULL;
1464 /* Don't try to send signals if we're just starting up since signal masks
1465 may not be available. */
1466 if (!cygwin_finished_initializing)
1468 rc = -1;
1469 goto done;
1472 sigproc_printf ("signal %d processing", si.si_signo);
1474 myself->rusage_self.ru_nsignals++;
1476 if (si.si_signo == SIGCONT)
1478 tl_entry = cygheap->find_tls (_main_tls);
1479 _main_tls->handle_SIGCONT ();
1480 cygheap->unlock_tls (tl_entry);
1483 /* SIGKILL is special. It always goes through. */
1484 if (si.si_signo == SIGKILL)
1486 tl_entry = cygheap->find_tls (_main_tls);
1487 tls = _main_tls;
1489 else if (ISSTATE (myself, PID_STOPPED))
1491 rc = -1; /* Don't send signals when stopped */
1492 goto done;
1494 else if (!sigtls)
1496 tl_entry = cygheap->find_tls (si.si_signo, issig_wait);
1497 if (tl_entry)
1499 tls = tl_entry->thread;
1500 sigproc_printf ("using tls %p", tls);
1503 else
1505 tl_entry = cygheap->find_tls (sigtls);
1506 if (tl_entry)
1508 tls = tl_entry->thread;
1509 if (sigismember (&tls->sigwait_mask, si.si_signo))
1510 issig_wait = true;
1511 else if (!sigismember (&tls->sigmask, si.si_signo))
1512 issig_wait = false;
1513 else
1514 tls = NULL;
1518 /* !tls means no threads available to catch a signal. */
1519 if (!tls)
1521 sigproc_printf ("signal %d blocked", si.si_signo);
1522 rc = -1;
1523 goto done;
1526 /* Do stuff for gdb */
1527 if ((HANDLE) *tls)
1528 tls->signal_debugger (si);
1530 if (issig_wait)
1532 tls->sigwait_mask = 0;
1533 goto dosig;
1536 if (handler == SIG_IGN)
1538 if (si.si_code == SI_TIMER)
1539 ((timer_tracker *) si.si_tid)->disarm_overrun_event ();
1540 sigproc_printf ("signal %d ignored", si.si_signo);
1541 goto done;
1544 if (si.si_signo == SIGKILL)
1545 goto exit_sig;
1546 if (si.si_signo == SIGSTOP)
1548 sig_clear (SIGCONT);
1549 goto stop;
1552 /* Clear pending SIGCONT on stop signals */
1553 if (si.si_signo == SIGTSTP || si.si_signo == SIGTTIN
1554 || si.si_signo == SIGTTOU)
1555 sig_clear (SIGCONT);
1557 if (handler == (void *) SIG_DFL)
1559 if (si.si_signo == SIGCHLD || si.si_signo == SIGIO
1560 || si.si_signo == SIGCONT || si.si_signo == SIGWINCH
1561 || si.si_signo == SIGURG)
1563 if (si.si_code == SI_TIMER)
1564 ((timer_tracker *) si.si_tid)->disarm_overrun_event ();
1565 sigproc_printf ("signal %d default is currently ignore", si.si_signo);
1566 goto done;
1569 if (si.si_signo == SIGTSTP || si.si_signo == SIGTTIN
1570 || si.si_signo == SIGTTOU)
1571 goto stop;
1573 goto exit_sig;
1576 if (handler == (void *) SIG_ERR)
1577 goto exit_sig;
1579 goto dosig;
1581 stop:
1582 if (tls != _main_tls)
1584 cygheap->unlock_tls (tl_entry);
1585 tl_entry = cygheap->find_tls (_main_tls);
1586 tls = _main_tls;
1588 handler = (void *) sig_handle_tty_stop;
1589 thissig = global_sigs[SIGSTOP];
1590 goto dosig;
1592 exit_sig:
1593 handler = (void *) signal_exit;
1594 thissig.sa_flags |= SA_SIGINFO;
1595 /* Don't run signal_exit on alternate stack. */
1596 thissig.sa_flags &= ~SA_ONSTACK;
1598 dosig:
1599 if (have_execed)
1601 sigproc_printf ("terminating captive process");
1602 if (::cygheap->ctty)
1603 ::cygheap->ctty->cleanup_before_exit ();
1604 TerminateProcess (ch_spawn, sigExeced = si.si_signo);
1606 /* Dispatch to the appropriate function. */
1607 sigproc_printf ("signal %d, signal handler %p", si.si_signo, handler);
1608 rc = setup_handler (handler, thissig, tls);
1610 done:
1611 cygheap->unlock_tls (tl_entry);
1612 sigproc_printf ("returning %d", rc);
1613 return rc;
1617 static void
1618 altstack_wrapper (int sig, siginfo_t *siginfo, ucontext_t *sigctx,
1619 void (*handler) (int, siginfo_t *, void *))
1621 siginfo_t si = *siginfo;
1622 ULONG guard_size = 0;
1623 DWORD old_prot = (DWORD) -1;
1624 PTEB teb = NtCurrentTeb ();
1625 PVOID old_limit = NULL;
1627 /* Check if we're just handling a stack overflow. If so... */
1628 if (sig == SIGSEGV && si.si_cyg
1629 && ((cygwin_exception *) si.si_cyg)->exception_record ()->ExceptionCode
1630 == (DWORD) STATUS_STACK_OVERFLOW)
1632 /* ...restore guard pages in original stack as if MSVCRT::_resetstkovlw
1633 has been called.
1635 Compute size of guard pages. If SetThreadStackGuarantee returns 0,
1636 use the default guard page size. */
1637 SetThreadStackGuarantee (&guard_size);
1638 if (!guard_size)
1639 guard_size = wincap.def_guard_page_size ();
1640 else
1641 guard_size += wincap.page_size ();
1642 old_limit = teb->Tib.StackLimit;
1643 /* Amazing but true: This VirtualProtect call automatically fixes the
1644 value of teb->Tib.StackLimit on some systems.*/
1645 if (VirtualProtect (teb->Tib.StackLimit, guard_size,
1646 PAGE_READWRITE | PAGE_GUARD, &old_prot)
1647 && old_limit == teb->Tib.StackLimit)
1648 teb->Tib.StackLimit = (caddr_t) old_limit + guard_size;
1650 handler (sig, &si, sigctx);
1651 if (old_prot != (DWORD) -1)
1653 /* Typically the handler would exit or at least perform a siglongjmp
1654 trying to overcome a SEGV condition. However, if we return from a
1655 segv handler after a stack overflow, we're dead. While on Linux the
1656 process returns to the offending code and thus the handler is called
1657 ad infinitum, on Windows the NTDLL::__stkchk function will simply kill
1658 the process. So what we do here is to remove the guard pages again so
1659 we can return to exception::handle. exception::handle will then call
1660 sig_send again, this time with SIG_DFL action, so at least we get a
1661 stackdump. */
1662 if (VirtualProtect ((caddr_t) teb->Tib.StackLimit - guard_size,
1663 guard_size, old_prot, &old_prot))
1664 teb->Tib.StackLimit = old_limit;
1669 _cygtls::call_signal_handler ()
1671 int this_sa_flags = SA_RESTART;
1672 while (1)
1674 lock ();
1675 if (!sig)
1677 unlock ();
1678 break;
1681 /* Pop the stack if the next "return address" is sigdelayed, since
1682 this function is doing what sigdelayed would have done anyway. */
1683 if (retaddr () == (__tlsstack_t) sigdelayed)
1684 pop ();
1686 debug_only_printf ("dealing with signal %d", sig);
1687 this_sa_flags = sa_flags;
1689 sigset_t this_oldmask = set_process_mask_delta ();
1691 if (infodata.si_code == SI_TIMER)
1693 timer_tracker *tt = (timer_tracker *)
1694 infodata.si_tid;
1695 infodata.si_overrun = tt->disarm_overrun_event ();
1698 /* Save information locally on stack to pass to handler. */
1699 int thissig = sig;
1700 siginfo_t thissi = infodata;
1701 void (*thisfunc) (int, siginfo_t *, void *) = func;
1703 ucontext_t *thiscontext = NULL, context_copy;
1705 /* Only make a context for SA_SIGINFO handlers */
1706 if (this_sa_flags & SA_SIGINFO)
1708 context.uc_link = 0;
1709 context.uc_flags = 0;
1710 if (thissi.si_cyg)
1711 memcpy (&context.uc_mcontext,
1712 ((cygwin_exception *) thissi.si_cyg)->context (),
1713 sizeof (CONTEXT));
1714 else
1716 /* Software-generated signal. We're fetching the current
1717 context, unwind to the caller and in case we're called
1718 from sigdelayed, fix the instruction pointer accordingly. */
1719 context.uc_mcontext.ctxflags = CONTEXT_FULL;
1720 RtlCaptureContext ((PCONTEXT) &context.uc_mcontext);
1721 __unwind_single_frame ((PCONTEXT) &context.uc_mcontext);
1722 if (stackptr > stack)
1724 #ifdef __x86_64__
1725 context.uc_mcontext.rip = retaddr ();
1726 #else
1727 #error unimplemented for this target
1728 #endif
1732 if (this_sa_flags & SA_ONSTACK
1733 && !_my_tls.altstack.ss_flags
1734 && _my_tls.altstack.ss_sp)
1736 context.uc_stack = _my_tls.altstack;
1737 context.uc_stack.ss_flags = SS_ONSTACK;
1739 else
1741 context.uc_stack.ss_sp = NtCurrentTeb ()->Tib.StackBase;
1742 context.uc_stack.ss_flags = 0;
1743 if (!NtCurrentTeb ()->DeallocationStack)
1744 context.uc_stack.ss_size
1745 = (uintptr_t) NtCurrentTeb ()->Tib.StackLimit
1746 - (uintptr_t) NtCurrentTeb ()->Tib.StackBase;
1747 else
1748 context.uc_stack.ss_size
1749 = (uintptr_t) NtCurrentTeb ()->DeallocationStack
1750 - (uintptr_t) NtCurrentTeb ()->Tib.StackBase;
1752 context.uc_sigmask = context.uc_mcontext.oldmask = this_oldmask;
1754 context.uc_mcontext.cr2 = (thissi.si_signo == SIGSEGV
1755 || thissi.si_signo == SIGBUS)
1756 ? (uintptr_t) thissi.si_addr : 0;
1758 thiscontext = &context;
1759 context_copy = context;
1762 int this_errno = saved_errno;
1763 reset_signal_arrived ();
1764 incyg = false;
1765 sig = 0; /* Flag that we can accept another signal */
1766 unlock (); /* unlock signal stack */
1768 /* Alternate signal stack requested for this signal and alternate signal
1769 stack set up for this thread? */
1770 if (this_sa_flags & SA_ONSTACK
1771 && !_my_tls.altstack.ss_flags
1772 && _my_tls.altstack.ss_sp)
1774 /* Yes, use alternate signal stack.
1776 NOTE:
1778 We DO NOT change the TEB's stack addresses and we DO NOT move the
1779 _cygtls area to the alternate stack. This seems to work fine,
1780 but there may be Windows functions not working correctly under
1781 these circumstances.
1783 On the other hand, if a Windows function crashed and we're handling
1784 this here, moving the TEB stack addresses may be fatal.
1786 If the current code does not work as expected in the "usual"
1787 POSIX circumstances, this problem must be revisited. */
1789 /* Compute new stackbase. We start from the high address, aligned
1790 to 16 byte. */
1791 uintptr_t new_sp = ((uintptr_t) _my_tls.altstack.ss_sp
1792 + _my_tls.altstack.ss_size) & ~0xf;
1793 /* In assembler: Save regs on new stack, move to alternate stack,
1794 call thisfunc, revert stack regs. */
1795 #ifdef __x86_64__
1796 /* Clobbered regs: rcx, rdx, r8, r9, r10, r11, rbp, rsp */
1797 __asm__ ("\n\
1798 movq %[NEW_SP], %%rax # Load alt stack into rax \n\
1799 subq $0x60, %%rax # Make room on alt stack \n\
1800 # for clobbered regs and \n\
1801 # required shadow space \n\
1802 movq %%rcx, 0x20(%%rax)# Save clobbered regs \n\
1803 movq %%rdx, 0x28(%%rax) \n\
1804 movq %%r8, 0x30(%%rax) \n\
1805 movq %%r9, 0x38(%%rax) \n\
1806 movq %%r10, 0x40(%%rax) \n\
1807 movq %%r11, 0x48(%%rax) \n\
1808 movq %%rbp, 0x50(%%rax) \n\
1809 movq %%rsp, 0x58(%%rax) \n\
1810 movl %[SIG], %%ecx # thissig to 1st arg reg \n\
1811 leaq %[SI], %%rdx # &thissi to 2nd arg reg \n\
1812 movq %[CTX], %%r8 # thiscontext to 3rd arg reg \n\
1813 movq %[FUNC], %%r9 # thisfunc to r9 \n\
1814 leaq %[WRAPPER], %%r10 # wrapper address to r10 \n\
1815 movq %%rax, %%rsp # Move alt stack into rsp \n\
1816 call *%%r10 # Call wrapper \n\
1817 movq %%rsp, %%rax # Restore clobbered regs \n\
1818 movq 0x58(%%rax), %%rsp \n\
1819 movq 0x50(%%rax), %%rbp \n\
1820 movq 0x48(%%rax), %%r11 \n\
1821 movq 0x40(%%rax), %%r10 \n\
1822 movq 0x38(%%rax), %%r9 \n\
1823 movq 0x30(%%rax), %%r8 \n\
1824 movq 0x28(%%rax), %%rdx \n\
1825 movq 0x20(%%rax), %%rcx \n"
1826 : : [NEW_SP] "o" (new_sp),
1827 [SIG] "o" (thissig),
1828 [SI] "o" (thissi),
1829 [CTX] "o" (thiscontext),
1830 [FUNC] "o" (thisfunc),
1831 [WRAPPER] "o" (altstack_wrapper)
1832 : "memory");
1833 #else
1834 #error unimplemented for this target
1835 #endif
1837 else
1838 /* No alternate signal stack requested or available, just call
1839 signal handler. */
1840 thisfunc (thissig, &thissi, thiscontext);
1842 incyg = true;
1844 set_signal_mask (_my_tls.sigmask, (this_sa_flags & SA_SIGINFO)
1845 ? context.uc_sigmask : this_oldmask);
1846 if (this_errno >= 0)
1847 set_errno (this_errno);
1848 if (this_sa_flags & SA_SIGINFO)
1850 /* If more than just the sigmask in the context has been changed by
1851 the signal handler, call setcontext. */
1852 context_copy.uc_sigmask = context.uc_sigmask;
1853 if (memcmp (&context, &context_copy, sizeof context) != 0)
1854 setcontext (&context);
1858 /* FIXME: Since 2011 this return statement always returned 1 (meaning
1859 SA_RESTART is effective) if the thread we're running in is not the
1860 main thread. We're disabling this check to enable EINTR behaviour
1861 on system calls not running in the main thread. It's not quite clear
1862 if that has undesired side-effects, therefore this comment. */
1863 return this_sa_flags & SA_RESTART;
1866 void
1867 _cygtls::signal_debugger (siginfo_t& si)
1869 HANDLE th;
1870 /* If si.si_cyg is set then the signal was already sent to the debugger. */
1871 if (isinitialized () && !si.si_cyg && (th = (HANDLE) *this)
1872 && being_debugged () && SuspendThread (th) >= 0)
1874 CONTEXT c;
1875 c.ContextFlags = CONTEXT_FULL;
1876 if (GetThreadContext (th, &c))
1878 if (incyg)
1879 c._CX_instPtr = retaddr ();
1880 memcpy (&context.uc_mcontext, &c, sizeof (CONTEXT));
1881 /* Enough space for 64 bit addresses */
1882 char sigmsg[2 * sizeof (_CYGWIN_SIGNAL_STRING
1883 " ffffffff ffffffffffffffff")];
1884 __small_sprintf (sigmsg, _CYGWIN_SIGNAL_STRING " %d %y %p",
1885 si.si_signo, thread_id, &context.uc_mcontext);
1886 OutputDebugString (sigmsg);
1888 ResumeThread (th);
1892 extern "C" int
1893 setcontext (const ucontext_t *ucp)
1895 PCONTEXT ctx = (PCONTEXT) &ucp->uc_mcontext;
1896 set_signal_mask (_my_tls.sigmask, ucp->uc_sigmask);
1897 _my_tls.incyg = true;
1898 RtlRestoreContext (ctx, NULL);
1899 /* If we got here, something was wrong. */
1900 set_errno (EINVAL);
1901 return -1;
1904 extern "C" int
1905 getcontext (ucontext_t *ucp)
1907 PCONTEXT ctx = (PCONTEXT) &ucp->uc_mcontext;
1908 ctx->ContextFlags = CONTEXT_FULL;
1909 RtlCaptureContext (ctx);
1910 __unwind_single_frame (ctx);
1911 /* Successful getcontext is supposed to return 0. If we don't set the
1912 return register to 0 here, there's a chance that code like this:
1914 if (getcontext (&ctx) != 0)
1916 assumes that getcontext failed after calling setcontext (&ctx). */
1917 ucp->uc_mcontext._MC_retReg = 0;
1918 ucp->uc_sigmask = ucp->uc_mcontext.oldmask = _my_tls.sigmask;
1919 /* Do not touch any other member of ucontext_t. */
1920 return 0;
1923 extern "C" int
1924 swapcontext (ucontext_t *oucp, const ucontext_t *ucp)
1926 PCONTEXT ctx = (PCONTEXT) &oucp->uc_mcontext;
1927 ctx->ContextFlags = CONTEXT_FULL;
1928 RtlCaptureContext (ctx);
1929 __unwind_single_frame (ctx);
1930 /* See comment in getcontext. */
1931 oucp->uc_mcontext._MC_retReg = 0;
1932 oucp->uc_sigmask = oucp->uc_mcontext.oldmask = _my_tls.sigmask;
1933 return setcontext (ucp);
1936 /* Trampoline function to set the context to uc_link. The pointer to the
1937 address of uc_link is stored in a callee-saved register, referenced by
1938 _MC_uclinkReg from the C code. If uc_link is NULL, call exit. */
1939 #ifdef __x86_64__
1940 /* _MC_uclinkReg == %rbx */
1941 __asm__ (" \n\
1942 .global __cont_link_context \n\
1943 .seh_proc __cont_link_context \n\
1944 __cont_link_context: \n\
1945 .seh_endprologue \n\
1946 movq %rbx, %rsp \n\
1947 movq (%rsp), %rcx \n\
1948 # align stack and subtract shadow space \n\
1949 andq $~0xf, %rsp \n\
1950 subq $0x20, %rsp \n\
1951 testq %rcx, %rcx \n\
1952 je 1f \n\
1953 call setcontext \n\
1954 movq $0xff, %rcx \n\
1955 1: \n\
1956 call cygwin_exit \n\
1957 nop \n\
1958 .seh_endproc \n\
1961 #else
1962 #error unimplemented for this target
1963 #endif
1965 /* makecontext is modelled after GLibc's makecontext. The stack from uc_stack
1966 is prepared so that it starts with a pointer to the linked context uc_link,
1967 followed by the arguments to func, and finally at the bottom the "return"
1968 address set to __cont_link_context. In the ucp context, rbx/ebx is set to
1969 point to the stack address where the pointer to uc_link is stored. The
1970 requirement to make this work is that rbx/ebx are callee-saved registers
1971 per the ABI. If any function is called which doesn't follow the ABI
1972 conventions, e.g. assembler code, this method will break. But that's ok. */
1973 extern "C" void
1974 makecontext (ucontext_t *ucp, void (*func) (void), int argc, ...)
1976 extern void __cont_link_context (void);
1977 uintptr_t *sp;
1978 va_list ap;
1980 /* Initialize sp to the top of the stack. */
1981 sp = (uintptr_t *) ((uintptr_t) ucp->uc_stack.ss_sp + ucp->uc_stack.ss_size);
1982 /* Subtract slots required for arguments and the pointer to uc_link. */
1983 sp -= (argc + 1);
1984 /* Align. */
1985 sp = (uintptr_t *) ((uintptr_t) sp & ~0xf);
1986 /* Subtract one slot for setting the return address. */
1987 --sp;
1988 /* Set return address to the trampolin function __cont_link_context. */
1989 sp[0] = (uintptr_t) __cont_link_context;
1990 /* Fetch arguments and store them on the stack.
1992 x86_64:
1994 - Store first four args in the AMD64 ABI arg registers.
1996 - Note that the stack is not short by these four register args. The
1997 reason is the shadow space for these regs required by the AMD64 ABI.
1999 - The definition of makecontext only allows for "int" sized arguments to
2000 func, 32 bit, likely for historical reasons. However, the argument
2001 slots on x86_64 are 64 bit anyway, so we can fetch and store the args
2002 as 64 bit values, and func can request 64 bit args without violating
2003 the definition. This potentially allows porting 32 bit applications
2004 providing pointer values to func without additional porting effort. */
2005 va_start (ap, argc);
2006 for (int i = 0; i < argc; ++i)
2007 #ifdef __x86_64__
2008 switch (i)
2010 case 0:
2011 ucp->uc_mcontext.rcx = va_arg (ap, uintptr_t);
2012 break;
2013 case 1:
2014 ucp->uc_mcontext.rdx = va_arg (ap, uintptr_t);
2015 break;
2016 case 2:
2017 ucp->uc_mcontext.r8 = va_arg (ap, uintptr_t);
2018 break;
2019 case 3:
2020 ucp->uc_mcontext.r9 = va_arg (ap, uintptr_t);
2021 break;
2022 default:
2023 sp[i + 1] = va_arg (ap, uintptr_t);
2024 break;
2026 #else
2027 #error unimplemented for this target
2028 #endif
2029 va_end (ap);
2030 /* Store pointer to uc_link at the top of the stack. */
2031 sp[argc + 1] = (uintptr_t) ucp->uc_link;
2032 /* Last but not least set the register in the context at ucp so that a
2033 subsequent setcontext or swapcontext picks up the right values:
2034 - Set instruction pointer to the target function.
2035 - Set stack pointer to the just computed stack pointer value.
2036 - Set Cygwin-specific uclink register to the address of the pointer
2037 to uc_link. */
2038 ucp->uc_mcontext._MC_instPtr = (uint64_t) func;
2039 ucp->uc_mcontext._MC_stackPtr = (uint64_t) sp;
2040 ucp->uc_mcontext._MC_uclinkReg = (uint64_t) (sp + argc + 1);