1 /* Page fault handling library.
2 Copyright (C) 1993-2021 Bruno Haible <bruno@clisp.org>
3 Copyright (C) 2018 Nylon Chen <nylon7@andestech.com>
5 This program is free software: you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation; either version 3 of the License, or
8 (at your option) any later version.
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
15 You should have received a copy of the GNU General Public License
16 along with this program. If not, see <https://www.gnu.org/licenses/>. */
24 #include <stdio.h> /* declares perror */
25 #include <stdint.h> /* defines uintptr_t */
29 # include <sys/resource.h> /* declares struct rlimit */
33 # include <sys/param.h> /* defines macro OpenBSD */
38 int libsigsegv_version = LIBSIGSEGV_VERSION;
41 /* ======================= Fault handler information ======================= */
45 SIGSEGV_FAULT_HANDLER_ARGLIST
46 is the argument list for the actual fault handler.
48 and if available (optional):
51 is a macro for fetching the fault address.
54 is a macro giving a pointer to the entire fault context (i.e.
55 the register set etc.).
57 SIGSEGV_FAULT_STACKPOINTER
58 is a macro for fetching the stackpointer at the moment the fault
62 #if defined __linux__ || defined __ANDROID__ /* Linux */
64 # define SIGSEGV_FAULT_HANDLER_ARGLIST int sig, siginfo_t *sip, void *ucp
65 # define SIGSEGV_FAULT_ADDRESS sip->si_addr
66 # define SIGSEGV_FAULT_CONTEXT ((ucontext_t *) ucp)
67 # define SIGSEGV_FAULT_ADDRESS_FROM_SIGINFO
69 # if defined __alpha__
71 /* See glibc/sysdeps/unix/sysv/linux/alpha/sys/ucontext.h
72 and the definition of GET_STACK in
73 glibc/sysdeps/unix/sysv/linux/alpha/sigcontextinfo.h.
74 Note that the 'mcontext_t' defined in
75 glibc/sysdeps/unix/sysv/linux/alpha/sys/ucontext.h
76 and the 'struct sigcontext' defined in <asm/sigcontext.h>
77 are actually the same. */
79 # define SIGSEGV_FAULT_STACKPOINTER ((ucontext_t *) ucp)->uc_mcontext.sc_regs[30]
81 # elif defined __arm64__ /* 64-bit */
83 /* See glibc/sysdeps/unix/sysv/linux/aarch64/sys/ucontext.h.
84 Note that the 'mcontext_t' defined in
85 glibc/sysdeps/unix/sysv/linux/aarch64/sys/ucontext.h
86 and the 'struct sigcontext' defined in <asm/sigcontext.h>
87 are actually the same. */
89 # define SIGSEGV_FAULT_STACKPOINTER ((ucontext_t *) ucp)->uc_mcontext.sp
91 # elif defined __arm__ || defined __armhf__ /* 32-bit */
93 /* See glibc/sysdeps/unix/sysv/linux/arm/sys/ucontext.h
94 and the definition of GET_STACK in
95 glibc/sysdeps/unix/sysv/linux/arm/sigcontextinfo.h.
96 Note that the 'mcontext_t' defined in
97 glibc/sysdeps/unix/sysv/linux/arm/sys/ucontext.h
98 and the 'struct sigcontext' defined in <asm/sigcontext.h>
99 are actually the same. */
101 # define SIGSEGV_FAULT_STACKPOINTER ((ucontext_t *) ucp)->uc_mcontext.arm_sp
103 # elif defined __cris__
105 /* See glibc-ports/sysdeps/unix/sysv/linux/cris/sys/ucontext.h.
106 Note that the 'mcontext_t' defined in
107 glibc-ports/sysdeps/unix/sysv/linux/cris/sys/ucontext.h
108 and the 'struct sigcontext' defined in <asm/sigcontext.h>
109 are actually the same. */
111 # define SIGSEGV_FAULT_STACKPOINTER ((ucontext_t *) ucp)->uc_mcontext.usp
113 # elif defined __hppa__
115 /* See glibc/sysdeps/unix/sysv/linux/hppa/sys/ucontext.h.
116 Note that the 'mcontext_t' defined in
117 glibc/sysdeps/unix/sysv/linux/hppa/sys/ucontext.h
118 and the 'struct sigcontext' defined in <asm/sigcontext.h>
119 are actually the same. */
121 # define SIGSEGV_FAULT_STACKPOINTER ((ucontext_t *) ucp)->uc_mcontext.sc_gr[30]
123 # elif defined __x86_64__ /* 64 bit registers */
125 /* See glibc/sysdeps/unix/sysv/linux/x86/sys/ucontext.h
126 and the definition of GET_STACK in
127 glibc/sysdeps/unix/sysv/linux/x86_64/sigcontextinfo.h.
128 Note that the 'mcontext_t' defined in
129 glibc/sysdeps/unix/sysv/linux/x86/sys/ucontext.h
130 and the 'struct sigcontext' defined in
131 glibc/sysdeps/unix/sysv/linux/x86/bits/sigcontext.h
132 (see also <asm/sigcontext.h>)
133 are effectively the same. */
135 # define SIGSEGV_FAULT_STACKPOINTER ((ucontext_t *) ucp)->uc_mcontext.gregs[REG_RSP]
137 # elif defined __i386__ /* 32 bit registers */
139 /* See glibc/sysdeps/unix/sysv/linux/x86/sys/ucontext.h
140 and the definition of GET_STACK in
141 glibc/sysdeps/unix/sysv/linux/i386/sigcontextinfo.h.
142 Note that the 'mcontext_t' defined in
143 glibc/sysdeps/unix/sysv/linux/x86/sys/ucontext.h
144 and the 'struct sigcontext_ia32' defined in <asm/sigcontext32.h>
145 are effectively the same. */
147 # define SIGSEGV_FAULT_STACKPOINTER ((ucontext_t *) ucp)->uc_mcontext.gregs[REG_ESP]
148 /* same value as ((ucontext_t *) ucp)->uc_mcontext.gregs[REG_UESP] */
150 # elif defined __ia64__
152 /* See glibc/sysdeps/unix/sysv/linux/ia64/sys/ucontext.h.
153 Note that the 'mcontext_t' defined in
154 glibc/sysdeps/unix/sysv/linux/ia64/sys/ucontext.h
155 and the 'struct sigcontext' defined in
156 glibc/sysdeps/unix/sysv/linux/ia64/bits/sigcontext.h
157 (see also <asm/sigcontext.h>)
158 are actually the same. */
160 /* IA-64 has two stack pointers, one that grows down, called $r12, and one
161 that grows up, called $bsp/$bspstore. */
162 # define SIGSEGV_FAULT_STACKPOINTER ((ucontext_t *) ucp)->uc_mcontext.sc_gr[12]
164 /* It would be better to access $bspstore instead of $bsp but I don't know
165 where to find it in 'struct sigcontext'. Anyway, it doesn't matter
166 because $bsp and $bspstore never differ by more than ca. 1 KB. */
167 # define SIGSEGV_FAULT_BSP_POINTER ((ucontext_t *) ucp)->uc_mcontext.sc_ar_bsp
169 # elif defined __m68k__
171 /* See glibc/sysdeps/unix/sysv/linux/m68k/sys/ucontext.h
172 and the definition of GET_STACK in
173 glibc/sysdeps/unix/sysv/linux/m68k/sigcontextinfo.h.
174 Note that the 'mcontext_t' defined in
175 glibc/sysdeps/unix/sysv/linux/m68k/sys/ucontext.h
176 and the 'struct sigcontext' defined in <asm/sigcontext.h>
177 are quite different types. */
179 # define SIGSEGV_FAULT_STACKPOINTER ((ucontext_t *) ucp)->uc_mcontext.gregs[R_SP]
181 # elif defined __mips__ || defined __mipsn32__ || defined __mips64__
183 /* See glibc/sysdeps/unix/sysv/linux/mips/sys/ucontext.h
184 and the definition of GET_STACK in
185 glibc/sysdeps/unix/sysv/linux/mips/sigcontextinfo.h.
186 Note that the 'mcontext_t' defined in
187 glibc/sysdeps/unix/sysv/linux/mips/sys/ucontext.h
188 and the 'struct sigcontext' defined in
189 glibc/sysdeps/unix/sysv/linux/mips/bits/sigcontext.h
190 (see also <asm/sigcontext.h>)
191 are effectively the same. */
193 # define SIGSEGV_FAULT_STACKPOINTER ((ucontext_t *) ucp)->uc_mcontext.gregs[29]
195 # elif defined __nds32__
197 /* See glibc/sysdeps/unix/sysv/linux/nds32/sys/ucontext.h
198 and the definition of GET_STACK in
199 glibc/sysdeps/unix/sysv/linux/nds32/sigcontextinfo.h.
200 Both are found in <https://patches-gcc.linaro.org/cover/4409/> part 08/11
201 <https://sourceware.org/ml/libc-alpha/2018-05/msg00125.html>. */
203 # define SIGSEGV_FAULT_STACKPOINTER ((ucontext_t *) ucp)->uc_mcontext.nds32_sp
205 # elif defined __powerpc__ || defined __powerpc64__ || defined __powerpc64_elfv2__
207 /* See glibc/sysdeps/unix/sysv/linux/powerpc/sys/ucontext.h
208 and the definition of GET_STACK in
209 glibc/sysdeps/unix/sysv/linux/powerpc/sigcontextinfo.h.
210 Note that the 'mcontext_t' defined in
211 glibc/sysdeps/unix/sysv/linux/powerpc/sys/ucontext.h,
212 the 'struct sigcontext' defined in <asm/sigcontext.h>,
213 and the 'struct pt_regs' defined in <asm/ptrace.h>
214 are quite different types. */
216 # if defined __powerpc64__ || defined __powerpc64_elfv2__ /* 64-bit */
217 # define SIGSEGV_FAULT_STACKPOINTER ((ucontext_t *) ucp)->uc_mcontext.gp_regs[1]
219 /* both should be equivalent */
221 # define SIGSEGV_FAULT_STACKPOINTER ((ucontext_t *) ucp)->uc_mcontext.regs->gpr[1]
223 # define SIGSEGV_FAULT_STACKPOINTER ((ucontext_t *) ucp)->uc_mcontext.uc_regs->gregs[1]
227 # elif defined __riscv32__ || __riscv64__
229 /* See glibc/sysdeps/unix/sysv/linux/riscv/sys/ucontext.h
230 and the definition of GET_STACK in
231 glibc/sysdeps/unix/sysv/linux/riscv/sigcontextinfo.h.
232 Note that the 'mcontext_t' defined in
233 glibc/sysdeps/unix/sysv/linux/riscv/sys/ucontext.h
234 and the 'struct sigcontext' defined in
235 glibc/sysdeps/unix/sysv/linux/riscv/bits/sigcontext.h
236 start with the same block of 32 general-purpose registers. */
238 # define SIGSEGV_FAULT_STACKPOINTER ((ucontext_t *) ucp)->uc_mcontext.__gregs[REG_SP]
240 # elif defined __s390__ || defined __s390x__
242 /* See glibc/sysdeps/unix/sysv/linux/s390/sys/ucontext.h
243 and the definition of GET_STACK in
244 glibc/sysdeps/unix/sysv/linux/s390/sigcontextinfo.h.
245 Note that the 'mcontext_t' defined in
246 glibc/sysdeps/unix/sysv/linux/s390/sys/ucontext.h
247 and the '_sigregs' type, indirect part of 'struct sigcontext', defined
248 in <asm/sigcontext.h>, are effectively the same. */
250 # define SIGSEGV_FAULT_STACKPOINTER ((ucontext_t *) ucp)->uc_mcontext.gregs[15]
252 # elif defined __sh__
254 /* See glibc/sysdeps/unix/sysv/linux/sh/sys/ucontext.h
255 and the definition of GET_STACK in
256 glibc/sysdeps/unix/sysv/linux/sh/sigcontextinfo.h.
257 Note that the 'mcontext_t' defined in
258 glibc/sysdeps/unix/sysv/linux/sh/sys/ucontext.h
259 and the 'struct sigcontext' defined in <asm/sigcontext.h>
260 are effectively the same. */
262 # define SIGSEGV_FAULT_STACKPOINTER ((ucontext_t *) ucp)->uc_mcontext.gregs[15]
264 # elif defined __sparc__ || defined __sparc64__
266 /* See glibc/sysdeps/unix/sysv/linux/sparc/sys/ucontext.h
267 and the definition of GET_STACK in
268 glibc/sysdeps/unix/sysv/linux/sparc/{sparc32,sparc64}/sigcontextinfo.h.
269 Note that the 'mcontext_t' defined in
270 glibc/sysdeps/unix/sysv/linux/sparc/sys/ucontext.h
271 and the 'struct sigcontext' defined in
272 glibc/sysdeps/unix/sysv/linux/sparc/bits/sigcontext.h
273 (see also <asm/sigcontext.h>)
274 are quite different types. */
276 # if defined __sparc64__/* 64-bit */
277 /* From linux-4.8.1/arch/sparc/kernel/signal_64.c, function setup_rt_frame, we
278 see that ucp is not an 'ucontext_t *' but rather a 'struct sigcontext *'
279 that happens to have the same value as sip (which is possible because a
280 'struct sigcontext' starts with 128 bytes room for the siginfo_t). */
281 # define SIGSEGV_FAULT_STACKPOINTER (((struct sigcontext *) ucp)->sigc_regs.u_regs[14] + 2047)
283 /* From linux-4.8.1/arch/sparc/kernel/signal_32.c, function setup_rt_frame,
284 and linux-4.8.1/arch/sparc/kernel/signal32.c, function setup_rt_frame32, we
285 see that ucp is a 'struct pt_regs *' or 'struct pt_regs32 *', respectively.
286 In userland, this is a 'struct sigcontext *'. */
287 # define SIGSEGV_FAULT_STACKPOINTER ((struct sigcontext *) ucp)->si_regs.u_regs[14]
290 /* The sip->si_addr field is correct for a normal fault, but unusable in case
291 of a stack overflow. What I observe (when running
292 tests/test-sigsegv-catch-stackoverflow1, with a printf right at the beginning
293 of sigsegv_handler) is that sip->si_addr is near 0:
294 - in 64-bit mode: sip->si_addr = 0x000000000000030F, and gdb shows me that
295 the fault occurs in an instruction 'stx %o3,[%fp+0x30f]' and %fp is 0.
296 In fact, all registers %l0..%l7 and %i0..%i7 are 0.
297 - in 32-bit mode: sip->si_addr = 0xFFFFFA64, and gdb shows me that
298 the fault occurs in an instruction 'st %g2,[%fp-1436]' and %fp is 0.
299 In fact, all registers %l0..%l7 and %i0..%i7 are 0.
300 Apparently when the stack overflow occurred, some trap has tried to move the
301 contents of the registers %l0..%l7 and %i0..%i7 (a "window" in SPARC
302 terminology) to the stack, did not succeed in doing this, replaced all these
303 register values with 0, and resumed execution at the fault location. This
304 time, due to %fp = 0, a different fault was triggered. Now it is impossible
305 to determine the real (previous) fault address because, even if know the
306 faulting instruction, the previous register values have been lost. */
307 # define BOGUS_FAULT_ADDRESS_UPON_STACK_OVERFLOW
311 /* When adding support for other CPUs here: */
313 /* For SIGSEGV_FAULT_HANDLER_ARGLIST, see the definition of SIGCONTEXT in
314 glibc/sysdeps/unix/sysv/linux/<cpu>/sigcontextinfo.h. */
316 /* For SIGSEGV_FAULT_STACKPOINTER, see the definition of GET_STACK in
317 glibc/sysdeps/unix/sysv/linux/<cpu>/sigcontextinfo.h. */
323 #if defined __GNU__ /* Hurd */
325 # define SIGSEGV_FAULT_HANDLER_ARGLIST int sig, int code, struct sigcontext *scp
326 # define SIGSEGV_FAULT_ADDRESS (unsigned long) code
327 # define SIGSEGV_FAULT_CONTEXT scp
329 # if defined __i386__
331 /* scp points to a 'struct sigcontext' (defined in
332 glibc/sysdeps/mach/hurd/i386/bits/sigcontext.h).
333 The registers of this struct get pushed on the stack through
334 gnumach/i386/i386/locore.S:trapall. */
335 /* Both sc_esp and sc_uesp appear to have the same value.
336 It appears more reliable to use sc_uesp because it is labelled as
337 "old esp, if trapped from user". */
338 # define SIGSEGV_FAULT_STACKPOINTER scp->sc_uesp
344 #if defined __FreeBSD_kernel__ || defined __FreeBSD__ || defined __DragonFly__ /* GNU/kFreeBSD, FreeBSD */
346 # if defined __arm__ || defined __armhf__ || defined __arm64__
348 # define SIGSEGV_FAULT_HANDLER_ARGLIST int sig, siginfo_t *sip, void *ucp
349 # define SIGSEGV_FAULT_ADDRESS sip->si_addr
350 # define SIGSEGV_FAULT_CONTEXT ((ucontext_t *) ucp)
352 # if defined __arm64__ /* 64-bit */
354 /* See sys/arm64/include/ucontext.h. */
356 # define SIGSEGV_FAULT_STACKPOINTER ((ucontext_t *) ucp)->uc_mcontext.mc_gpregs.gp_sp
358 # elif defined __arm__ || defined __armhf__ /* 32-bit */
360 /* See sys/arm/include/ucontext.h. */
362 # define SIGSEGV_FAULT_STACKPOINTER ((ucontext_t *) ucp)->uc_mcontext.__gregs[_REG_SP]
368 /* On FreeBSD 12, both of these approaches work. On FreeBSD derivatives, the
369 first one has more chances to work. */
371 /* Use signal handlers without SA_SIGINFO. */
373 # define SIGSEGV_FAULT_HANDLER_ARGLIST int sig, int code, struct sigcontext *scp, void *addr
374 # define SIGSEGV_FAULT_ADDRESS addr
375 # define SIGSEGV_FAULT_CONTEXT scp
377 /* See sys/x86/include/signal.h. */
379 # if defined __x86_64__
380 /* 64 bit registers */
382 # define SIGSEGV_FAULT_STACKPOINTER scp->sc_rsp
384 # elif defined __i386__
385 /* 32 bit registers */
387 # define SIGSEGV_FAULT_STACKPOINTER scp->sc_esp
392 /* Use signal handlers with SA_SIGINFO. */
394 # define SIGSEGV_FAULT_HANDLER_ARGLIST int sig, siginfo_t *sip, void *scp
395 # define SIGSEGV_FAULT_ADDRESS sip->si_addr
396 # define SIGSEGV_FAULT_CONTEXT ((struct sigcontext *) scp)
397 # define SIGSEGV_FAULT_ADDRESS_FROM_SIGINFO
399 /* See sys/x86/include/signal.h. */
401 # if defined __x86_64__
402 /* 64 bit registers */
404 # define SIGSEGV_FAULT_STACKPOINTER ((struct sigcontext *) scp)->sc_rsp
406 # elif defined __i386__
407 /* 32 bit registers */
409 # define SIGSEGV_FAULT_STACKPOINTER ((struct sigcontext *) scp)->sc_esp
419 #if defined __NetBSD__ /* NetBSD */
421 # define SIGSEGV_FAULT_HANDLER_ARGLIST int sig, siginfo_t *sip, void *ucp
422 # define SIGSEGV_FAULT_ADDRESS sip->si_addr
423 # define SIGSEGV_FAULT_CONTEXT ((ucontext_t *) ucp)
424 # define SIGSEGV_FAULT_ADDRESS_FROM_SIGINFO
426 /* _UC_MACHINE_SP is a platform independent macro.
427 Defined in <machine/mcontext.h>, see
428 http://cvsweb.netbsd.org/bsdweb.cgi/src/sys/arch/$arch/include/mcontext.h
429 Supported on alpha, amd64, i386, ia64, m68k, mips, powerpc, sparc since
431 On i386, _UC_MACHINE_SP is the same as ->uc_mcontext.__gregs[_REG_UESP],
432 and apparently the same value as ->uc_mcontext.__gregs[_REG_ESP]. */
433 # ifdef _UC_MACHINE_SP
434 # define SIGSEGV_FAULT_STACKPOINTER _UC_MACHINE_SP ((ucontext_t *) ucp)
439 #if defined __OpenBSD__ /* OpenBSD */
441 # define SIGSEGV_FAULT_HANDLER_ARGLIST int sig, siginfo_t *sip, struct sigcontext *scp
442 # define SIGSEGV_FAULT_ADDRESS sip->si_addr
443 # define SIGSEGV_FAULT_CONTEXT scp
444 # define SIGSEGV_FAULT_ADDRESS_FROM_SIGINFO
446 # if defined __alpha__
448 /* See the definition of 'struct sigcontext' in
449 openbsd-src/sys/arch/alpha/include/signal.h. */
451 # define SIGSEGV_FAULT_STACKPOINTER scp->sc_regs[30]
453 # elif defined __arm__ || defined __armhf__
455 /* See the definition of 'struct sigcontext' in
456 openbsd-src/sys/arch/arm/include/signal.h. */
458 # define SIGSEGV_FAULT_STACKPOINTER scp->sc_usr_sp
460 # elif defined __hppa__ || defined __hppa64__
462 /* See the definition of 'struct sigcontext' in
463 openbsd-src/sys/arch/hppa/include/signal.h
465 openbsd-src/sys/arch/hppa64/include/signal.h. */
467 # define SIGSEGV_FAULT_STACKPOINTER scp->sc_regs[30]
469 # elif defined __x86_64__
470 /* 64 bit registers */
472 /* See the definition of 'struct sigcontext' in
473 openbsd-src/sys/arch/amd64/include/signal.h. */
475 # define SIGSEGV_FAULT_STACKPOINTER scp->sc_rsp
477 # elif defined __i386__
478 /* 32 bit registers */
480 /* See the definition of 'struct sigcontext' in
481 openbsd-src/sys/arch/i386/include/signal.h. */
483 # define SIGSEGV_FAULT_STACKPOINTER scp->sc_esp
485 # elif defined __m68k__
487 /* See the definition of 'struct sigcontext' in
488 openbsd-src/sys/arch/m68k/include/signal.h. */
490 # define SIGSEGV_FAULT_STACKPOINTER scp->sc_sp
492 # elif defined __m88k__
494 /* See the definition of 'struct sigcontext' in
495 openbsd-src/sys/arch/m88k/include/signal.h
496 and the definition of 'struct reg' in
497 openbsd-src/sys/arch/m88k/include/reg.h. */
499 # if OpenBSD >= 201211 /* OpenBSD version >= 5.2 */
500 # define SIGSEGV_FAULT_STACKPOINTER scp->sc_regs[31]
502 # define SIGSEGV_FAULT_STACKPOINTER scp->sc_regs.r[31]
505 # elif defined __mips__ || defined __mipsn32__ || defined __mips64__
507 /* See the definition of 'struct sigcontext' in
508 openbsd-src/sys/arch/mips64/include/signal.h. */
510 # define SIGSEGV_FAULT_STACKPOINTER scp->sc_regs[29]
512 # elif defined __powerpc__ || defined __powerpc64__
514 /* See the definition of 'struct sigcontext' and 'struct trapframe' in
515 openbsd-src/sys/arch/powerpc/include/signal.h. */
517 # define SIGSEGV_FAULT_STACKPOINTER scp->sc_frame.fixreg[1]
519 # elif defined __sh__
521 /* See the definition of 'struct sigcontext' in
522 openbsd-src/sys/arch/sh/include/signal.h
523 and the definition of 'struct reg' in
524 openbsd-src/sys/arch/sh/include/reg.h. */
526 # if OpenBSD >= 201211 /* OpenBSD version >= 5.2 */
527 # define SIGSEGV_FAULT_STACKPOINTER scp->sc_reg[20-15]
529 # define SIGSEGV_FAULT_STACKPOINTER scp->sc_reg.r_r15
532 # elif defined __sparc__ || defined __sparc64__
534 /* See the definition of 'struct sigcontext' in
535 openbsd-src/sys/arch/sparc/include/signal.h
537 openbsd-src/sys/arch/sparc64/include/signal.h. */
539 # define SIGSEGV_FAULT_STACKPOINTER scp->sc_sp
541 # elif defined __vax__
543 /* See the definition of 'struct sigcontext' in
544 openbsd-src/sys/arch/vax/include/signal.h. */
546 # define SIGSEGV_FAULT_STACKPOINTER scp->sc_sp
552 #if (defined __APPLE__ && defined __MACH__) /* macOS */
554 # define SIGSEGV_FAULT_HANDLER_ARGLIST int sig, siginfo_t *sip, void *ucp
555 # define SIGSEGV_FAULT_ADDRESS sip->si_addr
556 # define SIGSEGV_FAULT_CONTEXT ((ucontext_t *) ucp)
557 # define SIGSEGV_FAULT_ADDRESS_FROM_SIGINFO
559 # if defined __x86_64__
561 /* See the definitions of
562 - 'ucontext_t' and 'struct __darwin_ucontext' in <sys/_types/_ucontext.h>,
563 - 'struct __darwin_mcontext64' in <i386/_mcontext.h>, and
564 - 'struct __darwin_x86_thread_state64' in <mach/i386/_structs.h>. */
565 # define SIGSEGV_FAULT_STACKPOINTER ((ucontext_t *) ucp)->uc_mcontext->__ss.__rsp
567 # elif defined __i386__
569 /* See the definitions of
570 - 'ucontext_t' and 'struct __darwin_ucontext' in <sys/_types/_ucontext.h>,
571 - 'struct __darwin_mcontext32' in <i386/_mcontext.h>, and
572 - 'struct __darwin_i386_thread_state' in <mach/i386/_structs.h>. */
573 # define SIGSEGV_FAULT_STACKPOINTER ((ucontext_t *) ucp)->uc_mcontext->__ss.__esp
575 # elif defined __arm64__
577 /* See the definitions of
578 - 'ucontext_t' and 'struct __darwin_ucontext' in <sys/_types/_ucontext.h>,
579 - 'struct __darwin_mcontext64' in <arm/_mcontext.h>, and
580 - 'struct __darwin_arm_thread_state64' in <mach/arm/_structs.h>. */
581 # define SIGSEGV_FAULT_STACKPOINTER ((ucontext_t *) ucp)->uc_mcontext->__ss.__sp
583 # elif defined __powerpc__
585 /* See the definitions of
586 - 'ucontext_t' and 'struct __darwin_ucontext' in <sys/_structs.h>,
587 - 'struct __darwin_mcontext' in <ppc/_structs.h>, and
588 - 'struct __darwin_ppc_thread_state' in <mach/ppc/_structs.h>. */
589 # define SIGSEGV_FAULT_STACKPOINTER ((ucontext_t *) ucp)->uc_mcontext->__ss.__r1
595 #if defined _AIX /* AIX */
597 # define SIGSEGV_FAULT_HANDLER_ARGLIST int sig, siginfo_t *sip, void *ucp
598 # define SIGSEGV_FAULT_ADDRESS sip->si_addr
599 # define SIGSEGV_FAULT_CONTEXT ((ucontext_t *) ucp)
600 # define SIGSEGV_FAULT_ADDRESS_FROM_SIGINFO
602 # if defined __powerpc__ || defined __powerpc64__
603 # define SIGSEGV_FAULT_STACKPOINTER ((ucontext_t *) ucp)->uc_mcontext.jmp_context.gpr[1]
608 #if defined __sgi /* IRIX */
610 # define SIGSEGV_FAULT_HANDLER_ARGLIST int sig, int code, struct sigcontext *scp
611 # define SIGSEGV_FAULT_ADDRESS (unsigned long) scp->sc_badvaddr
612 # define SIGSEGV_FAULT_CONTEXT scp
614 # if defined __mips__ || defined __mipsn32__ || defined __mips64__
615 # define SIGSEGV_FAULT_STACKPOINTER scp->sc_regs[29]
620 #if defined __sun /* Solaris */
622 # define SIGSEGV_FAULT_HANDLER_ARGLIST int sig, siginfo_t *sip, void *ucp
623 # define SIGSEGV_FAULT_ADDRESS sip->si_addr
624 # define SIGSEGV_FAULT_CONTEXT ((ucontext_t *) ucp)
625 # define SIGSEGV_FAULT_ADDRESS_FROM_SIGINFO
627 # if defined __x86_64__
628 /* 64 bit registers */
630 # define SIGSEGV_FAULT_STACKPOINTER ((ucontext_t *) ucp)->uc_mcontext.gregs[REG_RSP]
632 # elif defined __i386__
633 /* 32 bit registers */
635 # define SIGSEGV_FAULT_STACKPOINTER ((ucontext_t *) ucp)->uc_mcontext.gregs[ESP]
637 # elif defined __sparc__ || defined __sparc64__
639 # define SIGSEGV_FAULT_STACKPOINTER ((ucontext_t *) ucp)->uc_mcontext.gregs[REG_O6]
643 /* On Solaris 11.3/SPARC, both in 32-bit and 64-bit mode, when catching
644 stack overflow, the fault address is correct the first time, but is zero
645 or near zero the second time.
646 'truss tests/test-sigsegv-catch-stackoverflow1' shows it:
650 Incurred fault #6, FLTBOUNDS %pc = 0x000116E8
651 siginfo: SIGSEGV SEGV_MAPERR addr=0xFFB00000
652 Received signal #11, SIGSEGV [caught]
653 siginfo: SIGSEGV SEGV_MAPERR addr=0xFFB00000
655 Incurred fault #6, FLTBOUNDS %pc = 0x000116E8
656 siginfo: SIGSEGV SEGV_MAPERR addr=0x00000008
657 Received signal #11, SIGSEGV [caught]
658 siginfo: SIGSEGV SEGV_MAPERR addr=0x00000008
662 Incurred fault #6, FLTBOUNDS %pc = 0x100001C58
663 siginfo: SIGSEGV SEGV_MAPERR addr=0xFFFFFFFF7FF00000
664 Received signal #11, SIGSEGV [caught]
665 siginfo: SIGSEGV SEGV_MAPERR addr=0xFFFFFFFF7FF00000
667 Incurred fault #6, FLTBOUNDS %pc = 0x100001C58
668 siginfo: SIGSEGV SEGV_MAPERR addr=0x00000000
669 Received signal #11, SIGSEGV [caught]
670 siginfo: SIGSEGV SEGV_MAPERR addr=0x00000000
672 # define BOGUS_FAULT_ADDRESS_UPON_STACK_OVERFLOW
680 #if defined __CYGWIN__ /* Cygwin */
682 # define SIGSEGV_FAULT_HANDLER_ARGLIST int sig, siginfo_t *sip, void *ucp
683 # define SIGSEGV_FAULT_ADDRESS sip->si_addr
684 # define SIGSEGV_FAULT_CONTEXT ((ucontext_t *) ucp)
685 # define SIGSEGV_FAULT_ADDRESS_FROM_SIGINFO
687 /* See the definition of 'ucontext_t' in <sys/ucontext.h> and
688 of 'struct __mcontext' in <cygwin/signal.h>. */
689 # if defined __x86_64__
690 /* 64 bit registers */
691 # define SIGSEGV_FAULT_STACKPOINTER ((ucontext_t *) ucp)->uc_mcontext.rsp
692 # elif defined __i386__
693 /* 32 bit registers */
694 # define SIGSEGV_FAULT_STACKPOINTER ((ucontext_t *) ucp)->uc_mcontext.esp
699 #if defined __HAIKU__ /* Haiku */
701 # define SIGSEGV_FAULT_HANDLER_ARGLIST int sig, siginfo_t *sip, void *ucp
702 # define SIGSEGV_FAULT_ADDRESS sip->si_addr
703 # define SIGSEGV_FAULT_CONTEXT ((ucontext_t *) ucp)
704 # define SIGSEGV_FAULT_ADDRESS_FROM_SIGINFO
706 # if defined __x86_64__
707 /* 64 bit registers */
709 /* See the definition of 'ucontext_t' in <signal.h> and
710 of 'struct vregs' in <arch/x86_64/signal.h>. */
712 # define SIGSEGV_FAULT_STACKPOINTER ((ucontext_t *) ucp)->uc_mcontext.rsp
714 # elif defined __i386__
715 /* 32 bit registers */
717 /* See the definition of 'ucontext_t' in <signal.h> and
718 of 'struct vregs' in <arch/x86/signal.h>. */
720 # define SIGSEGV_FAULT_STACKPOINTER ((ucontext_t *) ucp)->uc_mcontext.esp
726 /* ========================================================================== */
728 /* List of signals that are sent when an invalid virtual memory address
729 is accessed, or when the stack overflows. */
730 #if defined __GNU__ \
731 || defined __FreeBSD_kernel__ || defined __FreeBSD__ || defined __DragonFly__ \
732 || defined __NetBSD__ || defined __OpenBSD__ \
733 || (defined __APPLE__ && defined __MACH__)
734 # define SIGSEGV_FOR_ALL_SIGNALS(var,body) \
735 { int var; var = SIGSEGV; { body } var = SIGBUS; { body } }
737 # define SIGSEGV_FOR_ALL_SIGNALS(var,body) \
738 { int var; var = SIGSEGV; { body } }
741 /* ========================================================================== */
743 /* Determine the virtual memory area of a given address. */
744 #include "stackvma.h"
746 /* ========================================================================== */
748 /* On the average Unix platform, we define
750 HAVE_SIGSEGV_RECOVERY
751 if there is a fault-*.h include file which defines
752 SIGSEGV_FAULT_HANDLER_ARGLIST and SIGSEGV_FAULT_ADDRESS.
754 HAVE_STACK_OVERFLOW_RECOVERY
755 if HAVE_SIGALTSTACK is set and
756 at least two of the following are true:
757 A) There is a fault-*.h include file which defines
758 SIGSEGV_FAULT_HANDLER_ARGLIST and SIGSEGV_FAULT_ADDRESS.
759 B) There is a fault-*.h include file which defines
760 SIGSEGV_FAULT_HANDLER_ARGLIST and SIGSEGV_FAULT_STACKPOINTER.
761 C) There is a stackvma-*.c, other than stackvma-none.c, which
762 defines sigsegv_get_vma.
764 Why? Obviously, to catch stack overflow, we need an alternate signal
765 stack; this requires kernel support. But we also need to distinguish
766 (with a reasonable confidence) a stack overflow from a regular SIGSEGV.
767 If we have A) and B), we use the
768 Heuristic AB: If the fault address is near the stack pointer, it's a
770 If we have A) and C), we use the
771 Heuristic AC: If the fault address is near and beyond the bottom of
772 the stack's virtual memory area, it's a stack overflow.
773 If we have B) and C), we use the
774 Heuristic BC: If the stack pointer is near the bottom of the stack's
775 virtual memory area, it's a stack overflow.
776 This heuristic comes in two flavours: On OSes which let the stack's
777 VMA grow continuously, we determine the bottom by use of getrlimit().
778 On OSes which preallocate the stack's VMA with its maximum size
779 (like BeOS), we use the stack's VMA directly.
782 #if HAVE_SIGSEGV_RECOVERY \
783 && !(defined SIGSEGV_FAULT_HANDLER_ARGLIST && defined SIGSEGV_FAULT_ADDRESS)
784 # error "You need to define SIGSEGV_FAULT_HANDLER_ARGLIST and SIGSEGV_FAULT_ADDRESS before you can define HAVE_SIGSEGV_RECOVERY."
786 #if !HAVE_SIGSEGV_RECOVERY \
787 && (defined SIGSEGV_FAULT_HANDLER_ARGLIST && defined SIGSEGV_FAULT_ADDRESS) \
788 && !(defined __FreeBSD__ && (defined __sparc__ || defined __sparc64__))
789 # if __GNUC__ || (__clang_major__ >= 4)
790 # warning "You can define HAVE_SIGSEGV_RECOVERY on this platform."
792 # error "You can define HAVE_SIGSEGV_RECOVERY on this platform."
796 #if HAVE_STACK_OVERFLOW_RECOVERY \
797 && !(defined SIGSEGV_FAULT_ADDRESS + defined SIGSEGV_FAULT_STACKPOINTER + HAVE_STACKVMA >= 2)
798 # error "You need to define two of SIGSEGV_FAULT_ADDRESS, SIGSEGV_FAULT_STACKPOINTER, HAVE_STACKVMA, before you can define HAVE_STACK_OVERFLOW_RECOVERY."
800 #if !HAVE_STACK_OVERFLOW_RECOVERY \
801 && (defined SIGSEGV_FAULT_ADDRESS + defined SIGSEGV_FAULT_STACKPOINTER + HAVE_STACKVMA >= 2) \
802 && !(defined __FreeBSD__ && (defined __sparc__ || defined __sparc64__)) \
803 && !(defined __NetBSD__ && (defined __sparc__ || defined __sparc64__))
804 # if __GNUC__ || (__clang_major__ >= 4)
805 # warning "You can define HAVE_STACK_OVERFLOW_RECOVERY on this platform."
807 # error "You can define HAVE_STACK_OVERFLOW_RECOVERY on this platform."
811 /* ========================================================================== */
813 #if HAVE_STACK_OVERFLOW_RECOVERY
815 /* ======= Leaving a signal handler executing on the alternate stack ======= */
817 /* Platform dependent:
818 Leaving a signal handler executing on the alternate stack. */
819 static void sigsegv_reset_onstack_flag (void);
821 /* -------------------------- leave-sigaltstack.c -------------------------- */
823 # if defined __GNU__ \
824 || defined __FreeBSD_kernel__ || defined __FreeBSD__ || defined __DragonFly__ \
825 || defined __NetBSD__ || defined __OpenBSD__
828 sigsegv_reset_onstack_flag (void)
832 if (sigaltstack (NULL, &ss) >= 0)
834 ss.ss_flags &= ~SS_ONSTACK;
835 sigaltstack (&ss, NULL);
839 /* --------------------------- leave-setcontext.c --------------------------- */
841 # elif defined __sgi || defined __sun /* IRIX, Solaris */
843 # include <ucontext.h>
846 sigsegv_reset_onstack_flag (void)
850 if (getcontext (&uc) >= 0)
851 /* getcontext returns twice. We are interested in the returned context
852 only the first time, i.e. when the SS_ONSTACK bit is set. */
853 if (uc.uc_stack.ss_flags & SS_ONSTACK)
855 uc.uc_stack.ss_flags &= ~SS_ONSTACK;
856 /* Note that setcontext() does not refill uc. Therefore if
857 setcontext() keeps SS_ONSTACK set in the kernel, either
858 setcontext() will return -1 or getcontext() will return a
859 second time, with the SS_ONSTACK bit being cleared. */
864 /* ------------------------------ leave-nop.c ------------------------------ */
869 sigsegv_reset_onstack_flag (void)
871 /* Nothing to do. sigaltstack() simply looks at the stack pointer,
872 therefore SS_ONSTACK is not sticky. */
877 /* ========================================================================== */
881 /* Address of the last byte belonging to the stack vma. */
882 static uintptr_t stack_top = 0;
884 /* Needs to be called once only. */
886 remember_stack_top (void *some_variable_on_stack)
888 struct vma_struct vma;
890 if (sigsegv_get_vma ((uintptr_t) some_variable_on_stack, &vma) >= 0)
891 stack_top = vma.end - 1;
894 # endif /* HAVE_STACKVMA */
896 static stackoverflow_handler_t stk_user_handler = (stackoverflow_handler_t)NULL;
897 static uintptr_t stk_extra_stack;
898 static size_t stk_extra_stack_size;
900 #endif /* HAVE_STACK_OVERFLOW_RECOVERY */
902 #if HAVE_SIGSEGV_RECOVERY
904 /* User's SIGSEGV handler. */
905 static sigsegv_handler_t user_handler = (sigsegv_handler_t)NULL;
907 #endif /* HAVE_SIGSEGV_RECOVERY */
910 /* Our SIGSEGV handler, with OS dependent argument list. */
912 #if HAVE_SIGSEGV_RECOVERY
915 sigsegv_handler (SIGSEGV_FAULT_HANDLER_ARGLIST)
917 void *address = (void *) (SIGSEGV_FAULT_ADDRESS);
919 # if HAVE_STACK_OVERFLOW_RECOVERY
920 # if !(HAVE_STACKVMA || defined SIGSEGV_FAULT_STACKPOINTER)
921 #error "Insufficient heuristics for detecting a stack overflow. Either define CFG_STACKVMA and HAVE_STACKVMA correctly, or define SIGSEGV_FAULT_STACKPOINTER correctly, or undefine HAVE_STACK_OVERFLOW_RECOVERY!"
924 /* Call user's handler. */
925 if (user_handler && (*user_handler) (address, 0))
927 /* Handler successful. */
931 /* Handler declined responsibility. */
933 /* Did the user install a stack overflow handler? */
934 if (stk_user_handler)
936 /* See whether it was a stack overflow. If so, longjump away. */
937 # ifdef SIGSEGV_FAULT_STACKPOINTER
938 uintptr_t old_sp = (uintptr_t) (SIGSEGV_FAULT_STACKPOINTER);
940 uintptr_t old_bsp = (uintptr_t) (SIGSEGV_FAULT_BSP_POINTER);
945 /* Were we able to determine the stack top? */
948 /* Determine stack bounds. */
950 struct vma_struct vma;
954 ret = sigsegv_get_vma (stack_top, &vma);
958 # ifndef BOGUS_FAULT_ADDRESS_UPON_STACK_OVERFLOW
959 /* Heuristic AC: If the fault_address is nearer to the stack
960 segment's [start,end] than to the previous segment, we
961 consider it a stack overflow.
962 In the case of IA-64, we know that the previous segment
963 is the up-growing bsp segment, and either of the two
964 stacks can overflow. */
965 uintptr_t addr = (uintptr_t) address;
968 if (addr >= vma.prev_end && addr <= vma.end - 1)
970 # if STACK_DIRECTION < 0
971 if (addr >= vma.start
972 ? (addr <= vma.end - 1)
973 : vma.is_near_this (addr, &vma))
975 if (addr <= vma.end - 1
976 ? (addr >= vma.start)
977 : vma.is_near_this (addr, &vma))
981 # else /* BOGUS_FAULT_ADDRESS_UPON_STACK_OVERFLOW */
982 # if HAVE_GETRLIMIT && defined RLIMIT_STACK
983 /* Heuristic BC: If the stack size has reached its maximal size,
984 and old_sp is near the low end, we consider it a stack
989 ret = getrlimit (RLIMIT_STACK, &rl);
993 uintptr_t current_stack_size = vma.end - vma.start;
994 uintptr_t max_stack_size = rl.rlim_cur;
995 if (current_stack_size <= max_stack_size + 4096
996 && max_stack_size <= current_stack_size + 4096
1001 # ifdef SIGSEGV_FAULT_STACKPOINTER
1002 /* Heuristic BC: If we know old_sp, and it is neither
1003 near the low end, nor in the alternate stack, then
1004 it's probably not a stack overflow. */
1005 && ((old_sp >= stk_extra_stack
1006 && old_sp <= stk_extra_stack + stk_extra_stack_size)
1007 # if STACK_DIRECTION < 0
1008 || (old_sp <= vma.start + 4096
1009 && vma.start <= old_sp + 4096))
1011 || (old_sp <= vma.end + 4096
1012 && vma.end <= old_sp + 4096))
1016 # endif /* BOGUS_FAULT_ADDRESS_UPON_STACK_OVERFLOW */
1017 # else /* !HAVE_STACKVMA */
1018 /* Heuristic AB: If the fault address is near the stack pointer,
1019 it's a stack overflow. */
1020 uintptr_t addr = (uintptr_t) address;
1022 if ((addr <= old_sp + 4096 && old_sp <= addr + 4096)
1024 || (addr <= old_bsp + 4096 && old_bsp <= addr + 4096)
1030 # endif /* !HAVE_STACKVMA */
1032 # ifdef SIGSEGV_FAULT_STACKPOINTER
1034 (old_sp >= stk_extra_stack
1035 && old_sp <= stk_extra_stack + stk_extra_stack_size);
1036 stackoverflow_context_t context = (SIGSEGV_FAULT_CONTEXT);
1039 stackoverflow_context_t context = (void *) 0;
1041 /* Call user's handler. */
1042 (*stk_user_handler) (emergency, context);
1048 # endif /* HAVE_STACK_OVERFLOW_RECOVERY */
1050 if (user_handler && (*user_handler) (address, 1))
1052 /* Handler successful. */
1056 /* Handler declined responsibility for real. */
1058 /* Remove ourselves and dump core. */
1059 SIGSEGV_FOR_ALL_SIGNALS (sig, signal (sig, SIG_DFL);)
1062 # if HAVE_STACK_OVERFLOW_RECOVERY
1064 # endif /* HAVE_STACK_OVERFLOW_RECOVERY */
1067 #elif HAVE_STACK_OVERFLOW_RECOVERY
1070 # ifdef SIGSEGV_FAULT_STACKPOINTER
1071 sigsegv_handler (SIGSEGV_FAULT_HANDLER_ARGLIST)
1073 sigsegv_handler (int sig)
1076 # if !((HAVE_GETRLIMIT && defined RLIMIT_STACK) || defined SIGSEGV_FAULT_STACKPOINTER)
1077 # error "Insufficient heuristics for detecting a stack overflow. Either define SIGSEGV_FAULT_STACKPOINTER correctly, or undefine HAVE_STACK_OVERFLOW_RECOVERY!"
1080 /* Did the user install a handler? */
1081 if (stk_user_handler)
1083 /* See whether it was a stack overflow. If so, longjump away. */
1084 # ifdef SIGSEGV_FAULT_STACKPOINTER
1085 uintptr_t old_sp = (uintptr_t) (SIGSEGV_FAULT_STACKPOINTER);
1088 /* Were we able to determine the stack top? */
1091 /* Determine stack bounds. */
1093 struct vma_struct vma;
1096 saved_errno = errno;
1097 ret = sigsegv_get_vma (stack_top, &vma);
1098 errno = saved_errno;
1101 # if HAVE_GETRLIMIT && defined RLIMIT_STACK
1102 /* Heuristic BC: If the stack size has reached its maximal size,
1103 and old_sp is near the low end, we consider it a stack
1107 saved_errno = errno;
1108 ret = getrlimit (RLIMIT_STACK, &rl);
1109 errno = saved_errno;
1112 uintptr_t current_stack_size = vma.end - vma.start;
1113 uintptr_t max_stack_size = rl.rlim_cur;
1114 if (current_stack_size <= max_stack_size + 4096
1115 && max_stack_size <= current_stack_size + 4096
1120 # ifdef SIGSEGV_FAULT_STACKPOINTER
1121 /* Heuristic BC: If we know old_sp, and it is neither
1122 near the low end, nor in the alternate stack, then
1123 it's probably not a stack overflow. */
1124 && ((old_sp >= stk_extra_stack
1125 && old_sp <= stk_extra_stack + stk_extra_stack_size)
1126 # if STACK_DIRECTION < 0
1127 || (old_sp <= vma.start + 4096
1128 && vma.start <= old_sp + 4096))
1130 || (old_sp <= vma.end + 4096
1131 && vma.end <= old_sp + 4096))
1136 # ifdef SIGSEGV_FAULT_STACKPOINTER
1138 (old_sp >= stk_extra_stack
1139 && old_sp <= stk_extra_stack + stk_extra_stack_size);
1140 stackoverflow_context_t context = (SIGSEGV_FAULT_CONTEXT);
1143 stackoverflow_context_t context = (void *) 0;
1145 /* Call user's handler. */
1146 (*stk_user_handler)(emergency,context);
1153 /* Remove ourselves and dump core. */
1154 SIGSEGV_FOR_ALL_SIGNALS (sig, signal (sig, SIG_DFL);)
1160 #if HAVE_SIGSEGV_RECOVERY || HAVE_STACK_OVERFLOW_RECOVERY
1163 install_for (int sig)
1165 struct sigaction action;
1167 # ifdef SIGSEGV_FAULT_ADDRESS_FROM_SIGINFO
1168 action.sa_sigaction = &sigsegv_handler;
1170 action.sa_handler = (void (*) (int)) &sigsegv_handler;
1172 /* Block most signals while SIGSEGV is being handled. */
1173 /* Signals SIGKILL, SIGSTOP cannot be blocked. */
1174 /* Signals SIGCONT, SIGTSTP, SIGTTIN, SIGTTOU are not blocked because
1175 dealing with these signals seems dangerous. */
1176 /* Signals SIGILL, SIGABRT, SIGFPE, SIGSEGV, SIGTRAP, SIGIOT, SIGEMT, SIGBUS,
1177 SIGSYS, SIGSTKFLT are not blocked because these are synchronous signals,
1178 which may require immediate intervention, otherwise the process may
1180 sigemptyset (&action.sa_mask);
1182 sigaddset (&action.sa_mask,SIGHUP);
1185 sigaddset (&action.sa_mask,SIGINT);
1188 sigaddset (&action.sa_mask,SIGQUIT);
1191 sigaddset (&action.sa_mask,SIGPIPE);
1194 sigaddset (&action.sa_mask,SIGALRM);
1197 sigaddset (&action.sa_mask,SIGTERM);
1200 sigaddset (&action.sa_mask,SIGUSR1);
1203 sigaddset (&action.sa_mask,SIGUSR2);
1206 sigaddset (&action.sa_mask,SIGCHLD);
1209 sigaddset (&action.sa_mask,SIGCLD);
1212 sigaddset (&action.sa_mask,SIGURG);
1215 sigaddset (&action.sa_mask,SIGIO);
1218 sigaddset (&action.sa_mask,SIGPOLL);
1221 sigaddset (&action.sa_mask,SIGXCPU);
1224 sigaddset (&action.sa_mask,SIGXFSZ);
1227 sigaddset (&action.sa_mask,SIGVTALRM);
1230 sigaddset (&action.sa_mask,SIGPROF);
1233 sigaddset (&action.sa_mask,SIGPWR);
1236 sigaddset (&action.sa_mask,SIGLOST);
1239 sigaddset (&action.sa_mask,SIGWINCH);
1241 /* Note that sigaction() implicitly adds sig itself to action.sa_mask. */
1242 /* Ask the OS to provide a structure siginfo_t to the handler. */
1243 # ifdef SIGSEGV_FAULT_ADDRESS_FROM_SIGINFO
1244 action.sa_flags = SA_SIGINFO;
1246 action.sa_flags = 0;
1248 # if HAVE_STACK_OVERFLOW_RECOVERY && HAVE_SIGALTSTACK /* not BeOS */
1249 /* Work around Linux 2.2.5 bug: If SA_ONSTACK is specified but sigaltstack()
1250 has not been called, the kernel will busy loop, eating CPU time. So
1251 avoid setting SA_ONSTACK until the user has requested stack overflow
1253 if (stk_user_handler)
1254 action.sa_flags |= SA_ONSTACK;
1256 sigaction (sig, &action, (struct sigaction *) NULL);
1259 #endif /* HAVE_SIGSEGV_RECOVERY || HAVE_STACK_OVERFLOW_RECOVERY */
1262 sigsegv_install_handler (sigsegv_handler_t handler)
1264 #if HAVE_SIGSEGV_RECOVERY
1265 user_handler = handler;
1267 SIGSEGV_FOR_ALL_SIGNALS (sig, install_for (sig);)
1276 sigsegv_deinstall_handler (void)
1278 #if HAVE_SIGSEGV_RECOVERY
1279 user_handler = (sigsegv_handler_t)NULL;
1281 # if HAVE_STACK_OVERFLOW_RECOVERY
1282 if (!stk_user_handler)
1285 SIGSEGV_FOR_ALL_SIGNALS (sig, signal (sig, SIG_DFL);)
1291 sigsegv_leave_handler (void (*continuation) (void*, void*, void*),
1292 void* cont_arg1, void* cont_arg2, void* cont_arg3)
1294 #if HAVE_STACK_OVERFLOW_RECOVERY
1296 * Reset the system's knowledge that we are executing on the alternate
1297 * stack. If we didn't do that, siglongjmp would be needed instead of
1298 * longjmp to leave the signal handler.
1300 sigsegv_reset_onstack_flag ();
1302 (*continuation) (cont_arg1, cont_arg2, cont_arg3);
1307 stackoverflow_install_handler (stackoverflow_handler_t handler,
1308 void *extra_stack, size_t extra_stack_size)
1310 #if HAVE_STACK_OVERFLOW_RECOVERY
1315 remember_stack_top (&dummy);
1321 stk_user_handler = handler;
1322 stk_extra_stack = (uintptr_t) extra_stack;
1323 stk_extra_stack_size = extra_stack_size;
1326 # if SIGALTSTACK_SS_REVERSED
1327 ss.ss_sp = (char *) extra_stack + extra_stack_size - sizeof (void *);
1328 ss.ss_size = extra_stack_size - sizeof (void *);
1330 ss.ss_sp = extra_stack;
1331 ss.ss_size = extra_stack_size;
1333 ss.ss_flags = 0; /* no SS_DISABLE */
1334 if (sigaltstack (&ss, (stack_t*)0) < 0)
1338 /* Install the signal handlers with SA_ONSTACK. */
1339 SIGSEGV_FOR_ALL_SIGNALS (sig, install_for (sig);)
1347 stackoverflow_deinstall_handler (void)
1349 #if HAVE_STACK_OVERFLOW_RECOVERY
1350 stk_user_handler = (stackoverflow_handler_t) NULL;
1352 # if HAVE_SIGSEGV_RECOVERY
1355 /* Reinstall the signal handlers without SA_ONSTACK, to avoid Linux
1357 SIGSEGV_FOR_ALL_SIGNALS (sig, install_for (sig);)
1362 SIGSEGV_FOR_ALL_SIGNALS (sig, signal (sig, SIG_DFL);)
1367 ss.ss_flags = SS_DISABLE;
1368 if (sigaltstack (&ss, (stack_t *) 0) < 0)
1369 perror ("gnulib sigsegv (stackoverflow_deinstall_handler)");