blob: 24f816fcddb0ccecb53853214a664e6eccd894a8 [file] [log] [blame]
sewardjde4a1d02002-03-22 01:27:54 +00001
2/*--------------------------------------------------------------------*/
nethercote73b526f2004-10-31 18:48:21 +00003/*--- Implementation of POSIX signals. vg_signals.c ---*/
sewardjde4a1d02002-03-22 01:27:54 +00004/*--------------------------------------------------------------------*/
5
6/*
njnb9c427c2004-12-01 14:14:42 +00007 This file is part of Valgrind, a dynamic binary instrumentation
8 framework.
sewardjde4a1d02002-03-22 01:27:54 +00009
njn53612422005-03-12 16:22:54 +000010 Copyright (C) 2000-2005 Julian Seward
sewardjde4a1d02002-03-22 01:27:54 +000011 jseward@acm.org
sewardjde4a1d02002-03-22 01:27:54 +000012
13 This program is free software; you can redistribute it and/or
14 modify it under the terms of the GNU General Public License as
15 published by the Free Software Foundation; either version 2 of the
16 License, or (at your option) any later version.
17
18 This program is distributed in the hope that it will be useful, but
19 WITHOUT ANY WARRANTY; without even the implied warranty of
20 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
21 General Public License for more details.
22
23 You should have received a copy of the GNU General Public License
24 along with this program; if not, write to the Free Software
25 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
26 02111-1307, USA.
27
njn25e49d8e72002-09-23 09:36:25 +000028 The GNU General Public License is contained in the file COPYING.
sewardjde4a1d02002-03-22 01:27:54 +000029*/
30
jsgf855d93d2003-10-13 22:26:55 +000031/*
sewardjb5f6f512005-03-10 23:59:00 +000032 Signal handling.
jsgf855d93d2003-10-13 22:26:55 +000033
sewardjb5f6f512005-03-10 23:59:00 +000034 There are 4 distinct classes of signal:
jsgf855d93d2003-10-13 22:26:55 +000035
sewardjb5f6f512005-03-10 23:59:00 +000036 1. Synchronous, instruction-generated (SIGILL, FPE, BUS, SEGV and
37 TRAP): these are signals as a result of an instruction fault. If
38 we get one while running client code, then we just do the
39 appropriate thing. If it happens while running Valgrind code, then
40 it indicates a Valgrind bug. Note that we "manually" implement
41 automatic stack growth, such that if a fault happens near the
42 client process stack, it is extended in the same way the kernel
43 would, and the fault is never reported to the client program.
jsgf855d93d2003-10-13 22:26:55 +000044
sewardjb5f6f512005-03-10 23:59:00 +000045 2. Asynchronous varients of the above signals: If the kernel tries
46 to deliver a sync signal while it is blocked, it just kills the
47 process. Therefore, we can't block those signals if we want to be
48 able to report on bugs in Valgrind. This means that we're also
49 open to receiving those signals from other processes, sent with
50 kill. We could get away with just dropping them, since they aren't
51 really signals that processes send to each other.
jsgf855d93d2003-10-13 22:26:55 +000052
sewardjb5f6f512005-03-10 23:59:00 +000053 3. Synchronous, general signals. If a thread/process sends itself
54 a signal with kill, its expected to be synchronous: ie, the signal
55 will have been delivered by the time the syscall finishes.
56
57 4. Asyncronous, general signals. All other signals, sent by
58 another process with kill. These are generally blocked, except for
59 two special cases: we poll for them each time we're about to run a
60 thread for a time quanta, and while running blocking syscalls.
jsgf855d93d2003-10-13 22:26:55 +000061
jsgf855d93d2003-10-13 22:26:55 +000062
sewardjb5f6f512005-03-10 23:59:00 +000063 In addition, we define two signals for internal use: SIGVGCHLD and
64 SIGVGKILL. SIGVGCHLD is used to indicate thread death to any
65 reaping thread (the master thread). It is always blocked and never
66 delivered as a signal; it is always polled with sigtimedwait.
67
68 SIGVGKILL is used to terminate threads. When one thread wants
69 another to exit, it will set its exitreason and send it SIGVGKILL
70 if it appears to be blocked in a syscall.
71
72
73 We use a kernel thread for each application thread. When the
74 thread allows itself to be open to signals, it sets the thread
75 signal mask to what the client application set it to. This means
76 that we get the kernel to do all signal routing: under Valgrind,
77 signals get delivered in the same way as in the non-Valgrind case
78 (the exception being for the sync signal set, since they're almost
79 always unblocked).
jsgf855d93d2003-10-13 22:26:55 +000080 */
sewardjde4a1d02002-03-22 01:27:54 +000081
nethercotef1e5e152004-09-01 23:58:16 +000082#include "core.h"
sewardjde4a1d02002-03-22 01:27:54 +000083
njn2521d322005-05-08 14:45:13 +000084#include "pub_core_aspacemgr.h"
njnd2b17112005-04-19 04:10:25 +000085#include "pub_core_errormgr.h"
njn20242342005-05-16 23:31:24 +000086#include "pub_core_options.h"
sewardj985fabb2005-04-24 14:18:14 +000087#include "pub_core_sigframe.h"
njn2521d322005-05-08 14:45:13 +000088#include "pub_core_syscalls.h"
njn43b9a8a2005-05-10 04:37:01 +000089#include "pub_core_tooliface.h"
sewardj985fabb2005-04-24 14:18:14 +000090
njnd2b17112005-04-19 04:10:25 +000091
sewardj018f7622002-05-15 21:13:39 +000092/* Define to give more sanity checking for signals. */
93#define DEBUG_SIGNALS
94
95
96/* ---------------------------------------------------------------------
97 Forwards decls.
98 ------------------------------------------------------------------ */
99
njn695c16e2005-03-27 03:40:28 +0000100static void sync_signalhandler ( Int sigNo, vki_siginfo_t *info, struct vki_ucontext * );
101static void async_signalhandler ( Int sigNo, vki_siginfo_t *info, struct vki_ucontext * );
sewardjb5f6f512005-03-10 23:59:00 +0000102static void sigvgkill_handler ( Int sigNo, vki_siginfo_t *info, struct vki_ucontext * );
sewardj018f7622002-05-15 21:13:39 +0000103
jsgf855d93d2003-10-13 22:26:55 +0000104static const Char *signame(Int sigNo);
sewardj018f7622002-05-15 21:13:39 +0000105
sewardjb5f6f512005-03-10 23:59:00 +0000106/* Maximum usable signal. */
107Int VG_(max_signal) = _VKI_NSIG;
nethercote759dda32004-08-07 18:16:56 +0000108
sewardjb5f6f512005-03-10 23:59:00 +0000109#define N_QUEUED_SIGNALS 8
nethercote759dda32004-08-07 18:16:56 +0000110
sewardjb5f6f512005-03-10 23:59:00 +0000111typedef struct SigQueue {
112 Int next;
113 vki_siginfo_t sigs[N_QUEUED_SIGNALS];
114} SigQueue;
nethercote759dda32004-08-07 18:16:56 +0000115
njn605f4882005-05-29 17:50:40 +0000116#if defined(VGP_x86_linux)
117# define VGP_UCONTEXT_INSTR_PTR(uc) ((uc)->uc_mcontext.eip)
118# define VGP_UCONTEXT_STACK_PTR(uc) ((uc)->uc_mcontext.esp)
119# define VGP_UCONTEXT_FRAME_PTR(uc) ((uc)->uc_mcontext.ebp)
120# define VGP_UCONTEXT_SYSCALL_NUM(uc) ((uc)->uc_mcontext.eax)
121# define VGP_UCONTEXT_SYSCALL_RET(uc) ((uc)->uc_mcontext.eax)
122#elif defined(VGP_amd64_linux)
123# define VGP_UCONTEXT_INSTR_PTR(uc) ((uc)->uc_mcontext.rip)
124# define VGP_UCONTEXT_STACK_PTR(uc) ((uc)->uc_mcontext.rsp)
125# define VGP_UCONTEXT_FRAME_PTR(uc) ((uc)->uc_mcontext.rbp)
126# define VGP_UCONTEXT_SYSCALL_NUM(uc) ((uc)->uc_mcontext.rax)
127# define VGP_UCONTEXT_SYSCALL_RET(uc) ((uc)->uc_mcontext.rax)
128#elif defined(VGP_arm_linux)
129# define VGP_UCONTEXT_INSTR_PTR(uc) ((uc)->uc_mcontext.arm_pc)
130# define VGP_UCONTEXT_STACK_PTR(uc) ((uc)->uc_mcontext.arm_sp)
131# define VGP_UCONTEXT_FRAME_PTR(uc) ((uc)->uc_mcontext.arm_fp)
132# define VGP_UCONTEXT_SYSCALL_NUM(uc) ((uc)->uc_mcontext.arm_r0)
133# error VGP_UCONTEXT_SYSCALL_RET undefined for ARM/Linux
134#else
135# error Unknown platform
136#endif
137
nethercote759dda32004-08-07 18:16:56 +0000138/* ---------------------------------------------------------------------
sewardj018f7622002-05-15 21:13:39 +0000139 HIGH LEVEL STUFF TO DO WITH SIGNALS: POLICY (MOSTLY)
140 ------------------------------------------------------------------ */
141
sewardjde4a1d02002-03-22 01:27:54 +0000142/* ---------------------------------------------------------------------
sewardjde4a1d02002-03-22 01:27:54 +0000143 Signal state for this process.
144 ------------------------------------------------------------------ */
145
sewardj018f7622002-05-15 21:13:39 +0000146
nethercote73b526f2004-10-31 18:48:21 +0000147/* Base-ment of these arrays[_VKI_NSIG].
sewardjb48e5002002-05-13 00:16:03 +0000148
nethercote73b526f2004-10-31 18:48:21 +0000149 Valid signal numbers are 1 .. _VKI_NSIG inclusive.
sewardjb48e5002002-05-13 00:16:03 +0000150 Rather than subtracting 1 for indexing these arrays, which
151 is tedious and error-prone, they are simply dimensioned 1 larger,
152 and entry [0] is not used.
153 */
154
sewardjb48e5002002-05-13 00:16:03 +0000155
sewardj018f7622002-05-15 21:13:39 +0000156/* -----------------------------------------------------
157 Static client signal state (SCSS). This is the state
158 that the client thinks it has the kernel in.
159 SCSS records verbatim the client's settings. These
160 are mashed around only when SKSS is calculated from it.
161 -------------------------------------------------- */
sewardjb48e5002002-05-13 00:16:03 +0000162
sewardj018f7622002-05-15 21:13:39 +0000163typedef
164 struct {
165 void* scss_handler; /* VKI_SIG_DFL or VKI_SIG_IGN or ptr to
166 client's handler */
167 UInt scss_flags;
nethercote73b526f2004-10-31 18:48:21 +0000168 vki_sigset_t scss_mask;
sewardjb5f6f512005-03-10 23:59:00 +0000169 void* scss_restorer; /* where sigreturn goes */
sewardj018f7622002-05-15 21:13:39 +0000170 }
171 SCSS_Per_Signal;
sewardjb48e5002002-05-13 00:16:03 +0000172
sewardj018f7622002-05-15 21:13:39 +0000173typedef
174 struct {
sewardj2342c972002-05-22 23:34:20 +0000175 /* per-signal info */
nethercote73b526f2004-10-31 18:48:21 +0000176 SCSS_Per_Signal scss_per_sig[1+_VKI_NSIG];
sewardj2342c972002-05-22 23:34:20 +0000177
sewardj018f7622002-05-15 21:13:39 +0000178 /* Additional elements to SCSS not stored here:
179 - for each thread, the thread's blocking mask
180 - for each thread in WaitSIG, the set of waited-on sigs
181 */
182 }
183 SCSS;
sewardjb48e5002002-05-13 00:16:03 +0000184
njn695c16e2005-03-27 03:40:28 +0000185static SCSS scss;
sewardj018f7622002-05-15 21:13:39 +0000186
187
188/* -----------------------------------------------------
189 Static kernel signal state (SKSS). This is the state
190 that we have the kernel in. It is computed from SCSS.
191 -------------------------------------------------- */
192
193/* Let's do:
194 sigprocmask assigns to all thread masks
195 so that at least everything is always consistent
196 Flags:
jsgf855d93d2003-10-13 22:26:55 +0000197 SA_SIGINFO -- we always set it, and honour it for the client
sewardj018f7622002-05-15 21:13:39 +0000198 SA_NOCLDSTOP -- passed to kernel
sewardjb5f6f512005-03-10 23:59:00 +0000199 SA_ONESHOT or SA_RESETHAND -- pass through
jsgf855d93d2003-10-13 22:26:55 +0000200 SA_RESTART -- we observe this but set our handlers to always restart
201 SA_NOMASK or SA_NODEFER -- we observe this, but our handlers block everything
sewardjb5f6f512005-03-10 23:59:00 +0000202 SA_ONSTACK -- pass through
203 SA_NOCLDWAIT -- pass through
sewardjb48e5002002-05-13 00:16:03 +0000204*/
sewardjde4a1d02002-03-22 01:27:54 +0000205
sewardj77e466c2002-04-14 02:29:29 +0000206
sewardj018f7622002-05-15 21:13:39 +0000207typedef
208 struct {
209 void* skss_handler; /* VKI_SIG_DFL or VKI_SIG_IGN
210 or ptr to our handler */
211 UInt skss_flags;
212 /* There is no skss_mask, since we know that we will always ask
jsgf855d93d2003-10-13 22:26:55 +0000213 for all signals to be blocked in our sighandlers. */
sewardj018f7622002-05-15 21:13:39 +0000214 /* Also there is no skss_restorer. */
215 }
216 SKSS_Per_Signal;
sewardjde4a1d02002-03-22 01:27:54 +0000217
sewardj018f7622002-05-15 21:13:39 +0000218typedef
219 struct {
nethercote73b526f2004-10-31 18:48:21 +0000220 SKSS_Per_Signal skss_per_sig[1+_VKI_NSIG];
sewardj018f7622002-05-15 21:13:39 +0000221 }
222 SKSS;
223
njn695c16e2005-03-27 03:40:28 +0000224static SKSS skss;
sewardjde4a1d02002-03-22 01:27:54 +0000225
njn07ef6c02005-05-18 19:43:09 +0000226static Bool is_sig_ign(Int sigNo)
jsgf855d93d2003-10-13 22:26:55 +0000227{
nethercote73b526f2004-10-31 18:48:21 +0000228 vg_assert(sigNo >= 1 && sigNo <= _VKI_NSIG);
sewardj2e93c502002-04-12 11:12:52 +0000229
njn695c16e2005-03-27 03:40:28 +0000230 return scss.scss_per_sig[sigNo].scss_handler == VKI_SIG_IGN;
jsgf855d93d2003-10-13 22:26:55 +0000231}
sewardjb48e5002002-05-13 00:16:03 +0000232
sewardj018f7622002-05-15 21:13:39 +0000233/* ---------------------------------------------------------------------
234 Compute the SKSS required by the current SCSS.
235 ------------------------------------------------------------------ */
236
sewardj4f29ddf2002-05-03 22:29:04 +0000237static
sewardj018f7622002-05-15 21:13:39 +0000238void pp_SKSS ( void )
239{
240 Int sig;
241 VG_(printf)("\n\nSKSS:\n");
nethercote73b526f2004-10-31 18:48:21 +0000242 for (sig = 1; sig <= _VKI_NSIG; sig++) {
sewardj018f7622002-05-15 21:13:39 +0000243 VG_(printf)("sig %d: handler 0x%x, flags 0x%x\n", sig,
njn695c16e2005-03-27 03:40:28 +0000244 skss.skss_per_sig[sig].skss_handler,
245 skss.skss_per_sig[sig].skss_flags );
sewardj77e466c2002-04-14 02:29:29 +0000246
sewardj018f7622002-05-15 21:13:39 +0000247 }
sewardj018f7622002-05-15 21:13:39 +0000248}
249
sewardj018f7622002-05-15 21:13:39 +0000250/* This is the core, clever bit. Computation is as follows:
251
252 For each signal
253 handler = if client has a handler, then our handler
jsgf855d93d2003-10-13 22:26:55 +0000254 else if client is DFL, then our handler as well
255 else (client must be IGN)
sewardjb5f6f512005-03-10 23:59:00 +0000256 then hander is IGN
sewardj018f7622002-05-15 21:13:39 +0000257*/
258static
259void calculate_SKSS_from_SCSS ( SKSS* dst )
260{
261 Int sig;
sewardj018f7622002-05-15 21:13:39 +0000262 UInt scss_flags;
263 UInt skss_flags;
264
nethercote73b526f2004-10-31 18:48:21 +0000265 for (sig = 1; sig <= _VKI_NSIG; sig++) {
jsgf855d93d2003-10-13 22:26:55 +0000266 void *skss_handler;
267 void *scss_handler;
268
njn695c16e2005-03-27 03:40:28 +0000269 scss_handler = scss.scss_per_sig[sig].scss_handler;
270 scss_flags = scss.scss_per_sig[sig].scss_flags;
sewardj018f7622002-05-15 21:13:39 +0000271
jsgf855d93d2003-10-13 22:26:55 +0000272 switch(sig) {
273 case VKI_SIGSEGV:
274 case VKI_SIGBUS:
275 case VKI_SIGFPE:
276 case VKI_SIGILL:
sewardjb5f6f512005-03-10 23:59:00 +0000277 case VKI_SIGTRAP:
jsgf855d93d2003-10-13 22:26:55 +0000278 /* For these, we always want to catch them and report, even
279 if the client code doesn't. */
njn695c16e2005-03-27 03:40:28 +0000280 skss_handler = sync_signalhandler;
jsgf855d93d2003-10-13 22:26:55 +0000281 break;
282
sewardjb5f6f512005-03-10 23:59:00 +0000283 case VKI_SIGCONT:
284 /* Let the kernel handle SIGCONT unless the client is actually
285 catching it. */
njna530fc62005-03-13 04:46:36 +0000286 case VKI_SIGCHLD:
287 case VKI_SIGWINCH:
288 case VKI_SIGURG:
289 /* For signals which are have a default action of Ignore,
290 only set a handler if the client has set a signal handler.
291 Otherwise the kernel will interrupt a syscall which
292 wouldn't have otherwise been interrupted. */
njn695c16e2005-03-27 03:40:28 +0000293 if (scss.scss_per_sig[sig].scss_handler == VKI_SIG_DFL)
sewardjb5f6f512005-03-10 23:59:00 +0000294 skss_handler = VKI_SIG_DFL;
njn695c16e2005-03-27 03:40:28 +0000295 else if (scss.scss_per_sig[sig].scss_handler == VKI_SIG_IGN)
jsgf855d93d2003-10-13 22:26:55 +0000296 skss_handler = VKI_SIG_IGN;
sewardjb5f6f512005-03-10 23:59:00 +0000297 else
njn695c16e2005-03-27 03:40:28 +0000298 skss_handler = async_signalhandler;
jsgf855d93d2003-10-13 22:26:55 +0000299 break;
jsgf855d93d2003-10-13 22:26:55 +0000300
sewardjb5f6f512005-03-10 23:59:00 +0000301 default:
njna530fc62005-03-13 04:46:36 +0000302 // VKI_SIGVG* are runtime variables, so we can't make them
303 // cases in the switch, so we handle them in the 'default' case.
sewardjb5f6f512005-03-10 23:59:00 +0000304 if (sig == VKI_SIGVGKILL)
305 skss_handler = sigvgkill_handler;
306 else if (sig == VKI_SIGVGCHLD)
307 skss_handler = VKI_SIG_IGN; /* we only poll for it */
308 else {
309 if (scss_handler == VKI_SIG_IGN)
310 skss_handler = VKI_SIG_IGN;
311 else
njn695c16e2005-03-27 03:40:28 +0000312 skss_handler = async_signalhandler;
sewardjb5f6f512005-03-10 23:59:00 +0000313 }
314 break;
315 }
sewardj018f7622002-05-15 21:13:39 +0000316
sewardj018f7622002-05-15 21:13:39 +0000317 /* Flags */
318
319 skss_flags = 0;
jsgf855d93d2003-10-13 22:26:55 +0000320
sewardjb5f6f512005-03-10 23:59:00 +0000321 /* SA_NOCLDSTOP, SA_NOCLDWAIT: pass to kernel */
322 skss_flags |= scss_flags & (VKI_SA_NOCLDSTOP | VKI_SA_NOCLDWAIT);
jsgf855d93d2003-10-13 22:26:55 +0000323
sewardj018f7622002-05-15 21:13:39 +0000324 /* SA_ONESHOT: ignore client setting */
sewardjb5f6f512005-03-10 23:59:00 +0000325
jsgf855d93d2003-10-13 22:26:55 +0000326 /* SA_RESTART: ignore client setting and always set it for us
327 (even though we never rely on the kernel to restart a
328 syscall, we observe whether it wanted to restart the syscall
sewardjb5f6f512005-03-10 23:59:00 +0000329 or not, which helps VGA_(interrupted_syscall)()) */
sewardj018f7622002-05-15 21:13:39 +0000330 skss_flags |= VKI_SA_RESTART;
jsgf855d93d2003-10-13 22:26:55 +0000331
332 /* SA_NOMASK: ignore it */
333
sewardj2342c972002-05-22 23:34:20 +0000334 /* SA_ONSTACK: client setting is irrelevant here */
sewardjb5f6f512005-03-10 23:59:00 +0000335 /* We don't set a signal stack, so ignore */
sewardj018f7622002-05-15 21:13:39 +0000336
jsgf855d93d2003-10-13 22:26:55 +0000337 /* always ask for SA_SIGINFO */
338 skss_flags |= VKI_SA_SIGINFO;
sewardj018f7622002-05-15 21:13:39 +0000339
fitzhardinge4f10ada2004-06-03 10:00:42 +0000340 /* use our own restorer */
341 skss_flags |= VKI_SA_RESTORER;
342
jsgf855d93d2003-10-13 22:26:55 +0000343 /* Create SKSS entry for this signal. */
sewardj6a3c26e2002-05-23 17:09:43 +0000344 if (sig != VKI_SIGKILL && sig != VKI_SIGSTOP)
345 dst->skss_per_sig[sig].skss_handler = skss_handler;
346 else
347 dst->skss_per_sig[sig].skss_handler = VKI_SIG_DFL;
348
sewardj018f7622002-05-15 21:13:39 +0000349 dst->skss_per_sig[sig].skss_flags = skss_flags;
350 }
351
352 /* Sanity checks. */
nethercote5fd72bb2004-11-04 19:28:38 +0000353 vg_assert(dst->skss_per_sig[VKI_SIGKILL].skss_handler == VKI_SIG_DFL);
354 vg_assert(dst->skss_per_sig[VKI_SIGSTOP].skss_handler == VKI_SIG_DFL);
sewardj018f7622002-05-15 21:13:39 +0000355
356 if (0)
357 pp_SKSS();
358}
359
360
361/* ---------------------------------------------------------------------
362 After a possible SCSS change, update SKSS and the kernel itself.
363 ------------------------------------------------------------------ */
364
nethercote9dd11512004-08-04 15:31:30 +0000365static void handle_SCSS_change ( Bool force_update )
sewardj018f7622002-05-15 21:13:39 +0000366{
nethercote73b526f2004-10-31 18:48:21 +0000367 Int res, sig;
368 SKSS skss_old;
369 struct vki_sigaction ksa, ksa_old;
sewardj018f7622002-05-15 21:13:39 +0000370
sewardj018f7622002-05-15 21:13:39 +0000371 /* Remember old SKSS and calculate new one. */
njn695c16e2005-03-27 03:40:28 +0000372 skss_old = skss;
373 calculate_SKSS_from_SCSS ( &skss );
sewardj018f7622002-05-15 21:13:39 +0000374
375 /* Compare the new SKSS entries vs the old ones, and update kernel
376 where they differ. */
sewardjb5f6f512005-03-10 23:59:00 +0000377 for (sig = 1; sig <= VG_(max_signal); sig++) {
sewardj018f7622002-05-15 21:13:39 +0000378
379 /* Trying to do anything with SIGKILL is pointless; just ignore
380 it. */
381 if (sig == VKI_SIGKILL || sig == VKI_SIGSTOP)
382 continue;
383
sewardj018f7622002-05-15 21:13:39 +0000384 if (!force_update) {
385 if ((skss_old.skss_per_sig[sig].skss_handler
njn695c16e2005-03-27 03:40:28 +0000386 == skss.skss_per_sig[sig].skss_handler)
sewardj018f7622002-05-15 21:13:39 +0000387 && (skss_old.skss_per_sig[sig].skss_flags
njn695c16e2005-03-27 03:40:28 +0000388 == skss.skss_per_sig[sig].skss_flags))
sewardj018f7622002-05-15 21:13:39 +0000389 /* no difference */
390 continue;
391 }
392
njn695c16e2005-03-27 03:40:28 +0000393 ksa.ksa_handler = skss.skss_per_sig[sig].skss_handler;
394 ksa.sa_flags = skss.skss_per_sig[sig].skss_flags;
nethercote73b526f2004-10-31 18:48:21 +0000395 ksa.sa_restorer = VG_(sigreturn);
fitzhardinge4f10ada2004-06-03 10:00:42 +0000396
sewardjb5f6f512005-03-10 23:59:00 +0000397 /* block all signals in handler */
nethercote73b526f2004-10-31 18:48:21 +0000398 VG_(sigfillset)( &ksa.sa_mask );
399 VG_(sigdelset)( &ksa.sa_mask, VKI_SIGKILL );
400 VG_(sigdelset)( &ksa.sa_mask, VKI_SIGSTOP );
sewardj018f7622002-05-15 21:13:39 +0000401
sewardjb5f6f512005-03-10 23:59:00 +0000402 if (VG_(clo_trace_signals) && VG_(clo_verbosity) > 2)
sewardj018f7622002-05-15 21:13:39 +0000403 VG_(message)(Vg_DebugMsg,
404 "setting ksig %d to: hdlr 0x%x, flags 0x%x, "
405 "mask(63..0) 0x%x 0x%x",
406 sig, ksa.ksa_handler,
nethercote73b526f2004-10-31 18:48:21 +0000407 ksa.sa_flags,
408 ksa.sa_mask.sig[1],
409 ksa.sa_mask.sig[0]
sewardj018f7622002-05-15 21:13:39 +0000410 );
411
nethercote73b526f2004-10-31 18:48:21 +0000412 res = VG_(sigaction)( sig, &ksa, &ksa_old );
sewardj018f7622002-05-15 21:13:39 +0000413 vg_assert(res == 0);
414
415 /* Since we got the old sigaction more or less for free, might
416 as well extract the maximum sanity-check value from it. */
417 if (!force_update) {
418 vg_assert(ksa_old.ksa_handler
419 == skss_old.skss_per_sig[sig].skss_handler);
nethercote73b526f2004-10-31 18:48:21 +0000420 vg_assert(ksa_old.sa_flags
sewardj018f7622002-05-15 21:13:39 +0000421 == skss_old.skss_per_sig[sig].skss_flags);
nethercote73b526f2004-10-31 18:48:21 +0000422 vg_assert(ksa_old.sa_restorer
fitzhardingedc4d4f42004-06-03 17:12:07 +0000423 == VG_(sigreturn));
nethercote73b526f2004-10-31 18:48:21 +0000424 VG_(sigaddset)( &ksa_old.sa_mask, VKI_SIGKILL );
425 VG_(sigaddset)( &ksa_old.sa_mask, VKI_SIGSTOP );
426 vg_assert(VG_(isfullsigset)( &ksa_old.sa_mask ));
sewardj018f7622002-05-15 21:13:39 +0000427 }
428 }
sewardj018f7622002-05-15 21:13:39 +0000429}
430
431
432/* ---------------------------------------------------------------------
433 Update/query SCSS in accordance with client requests.
434 ------------------------------------------------------------------ */
435
sewardj2342c972002-05-22 23:34:20 +0000436/* Logic for this alt-stack stuff copied directly from do_sigaltstack
437 in kernel/signal.[ch] */
438
439/* True if we are on the alternate signal stack. */
sewardjb5f6f512005-03-10 23:59:00 +0000440static Bool on_sig_stack ( ThreadId tid, Addr m_SP )
sewardj2342c972002-05-22 23:34:20 +0000441{
fitzhardinge98c4dc02004-03-16 08:27:29 +0000442 ThreadState *tst = VG_(get_ThreadState)(tid);
443
nethercote511e4062004-09-11 13:34:08 +0000444 return (m_SP - (Addr)tst->altstack.ss_sp < tst->altstack.ss_size);
sewardj2342c972002-05-22 23:34:20 +0000445}
446
nethercote511e4062004-09-11 13:34:08 +0000447static Int sas_ss_flags ( ThreadId tid, Addr m_SP )
sewardj2342c972002-05-22 23:34:20 +0000448{
fitzhardinge98c4dc02004-03-16 08:27:29 +0000449 ThreadState *tst = VG_(get_ThreadState)(tid);
450
451 return (tst->altstack.ss_size == 0
sewardj2342c972002-05-22 23:34:20 +0000452 ? VKI_SS_DISABLE
nethercote511e4062004-09-11 13:34:08 +0000453 : on_sig_stack(tid, m_SP) ? VKI_SS_ONSTACK : 0);
sewardj2342c972002-05-22 23:34:20 +0000454}
455
456
njn502badb2005-05-08 02:04:49 +0000457Int VG_(do_sys_sigaltstack) ( ThreadId tid, vki_stack_t* ss, vki_stack_t* oss )
sewardj2342c972002-05-22 23:34:20 +0000458{
njn502badb2005-05-08 02:04:49 +0000459 Addr m_SP;
sewardj2342c972002-05-22 23:34:20 +0000460
461 vg_assert(VG_(is_valid_tid)(tid));
njncf45fd42004-11-24 16:30:22 +0000462 m_SP = STACK_PTR(VG_(threads)[tid].arch);
sewardj2342c972002-05-22 23:34:20 +0000463
464 if (VG_(clo_trace_signals))
465 VG_(message)(Vg_DebugExtraMsg,
nethercote04d3a802004-11-16 18:26:11 +0000466 "sys_sigaltstack: tid %d, "
nethercote511e4062004-09-11 13:34:08 +0000467 "ss %p, oss %p (current SP %p)",
468 tid, (void*)ss, (void*)oss, (void*)m_SP );
sewardj2342c972002-05-22 23:34:20 +0000469
470 if (oss != NULL) {
fitzhardinge98c4dc02004-03-16 08:27:29 +0000471 oss->ss_sp = VG_(threads)[tid].altstack.ss_sp;
472 oss->ss_size = VG_(threads)[tid].altstack.ss_size;
nethercote511e4062004-09-11 13:34:08 +0000473 oss->ss_flags = VG_(threads)[tid].altstack.ss_flags | sas_ss_flags(tid, m_SP);
sewardj2342c972002-05-22 23:34:20 +0000474 }
475
476 if (ss != NULL) {
njncf45fd42004-11-24 16:30:22 +0000477 if (on_sig_stack(tid, STACK_PTR(VG_(threads)[tid].arch))) {
njn4fbc86c2005-05-08 00:45:11 +0000478 return -VKI_EPERM;
sewardj2342c972002-05-22 23:34:20 +0000479 }
480 if (ss->ss_flags != VKI_SS_DISABLE
481 && ss->ss_flags != VKI_SS_ONSTACK
482 && ss->ss_flags != 0) {
njn4fbc86c2005-05-08 00:45:11 +0000483 return -VKI_EINVAL;
sewardj2342c972002-05-22 23:34:20 +0000484 }
485 if (ss->ss_flags == VKI_SS_DISABLE) {
fitzhardinge98c4dc02004-03-16 08:27:29 +0000486 VG_(threads)[tid].altstack.ss_flags = VKI_SS_DISABLE;
sewardj2342c972002-05-22 23:34:20 +0000487 } else {
488 if (ss->ss_size < VKI_MINSIGSTKSZ) {
njn4fbc86c2005-05-08 00:45:11 +0000489 return -VKI_ENOMEM;
sewardj2342c972002-05-22 23:34:20 +0000490 }
jsgf855d93d2003-10-13 22:26:55 +0000491
nethercote20283c62004-11-04 19:43:22 +0000492 VG_(threads)[tid].altstack.ss_sp = ss->ss_sp;
493 VG_(threads)[tid].altstack.ss_size = ss->ss_size;
fitzhardinge98c4dc02004-03-16 08:27:29 +0000494 VG_(threads)[tid].altstack.ss_flags = 0;
sewardj2342c972002-05-22 23:34:20 +0000495 }
sewardj2342c972002-05-22 23:34:20 +0000496 }
njn4fbc86c2005-05-08 00:45:11 +0000497 return 0;
sewardj2342c972002-05-22 23:34:20 +0000498}
499
500
sewardjb5f6f512005-03-10 23:59:00 +0000501Int VG_(do_sys_sigaction) ( Int signo,
502 const struct vki_sigaction *new_act,
503 struct vki_sigaction *old_act )
sewardj018f7622002-05-15 21:13:39 +0000504{
sewardj018f7622002-05-15 21:13:39 +0000505 if (VG_(clo_trace_signals))
506 VG_(message)(Vg_DebugExtraMsg,
sewardjb5f6f512005-03-10 23:59:00 +0000507 "sys_sigaction: sigNo %d, "
nethercote93246cf2004-11-04 18:56:47 +0000508 "new %p, old %p, new flags 0x%llx",
sewardjb5f6f512005-03-10 23:59:00 +0000509 signo, (UWord)new_act, (UWord)old_act,
nethercote93246cf2004-11-04 18:56:47 +0000510 (ULong)(new_act ? new_act->sa_flags : 0) );
sewardj018f7622002-05-15 21:13:39 +0000511
512 /* Rule out various error conditions. The aim is to ensure that if
513 when the call is passed to the kernel it will definitely
514 succeed. */
515
516 /* Reject out-of-range signal numbers. */
sewardjb5f6f512005-03-10 23:59:00 +0000517 if (signo < 1 || signo > VG_(max_signal)) goto bad_signo;
sewardj018f7622002-05-15 21:13:39 +0000518
jsgf855d93d2003-10-13 22:26:55 +0000519 /* don't let them use our signals */
sewardjb5f6f512005-03-10 23:59:00 +0000520 if ( (signo > VKI_SIGVGRTUSERMAX)
jsgf855d93d2003-10-13 22:26:55 +0000521 && new_act
522 && !(new_act->ksa_handler == VKI_SIG_DFL || new_act->ksa_handler == VKI_SIG_IGN) )
nethercote9c42a0f2003-11-17 10:37:19 +0000523 goto bad_signo_reserved;
jsgf855d93d2003-10-13 22:26:55 +0000524
sewardj018f7622002-05-15 21:13:39 +0000525 /* Reject attempts to set a handler (or set ignore) for SIGKILL. */
526 if ( (signo == VKI_SIGKILL || signo == VKI_SIGSTOP)
527 && new_act
528 && new_act->ksa_handler != VKI_SIG_DFL)
529 goto bad_sigkill_or_sigstop;
530
531 /* If the client supplied non-NULL old_act, copy the relevant SCSS
532 entry into it. */
533 if (old_act) {
njn695c16e2005-03-27 03:40:28 +0000534 old_act->ksa_handler = scss.scss_per_sig[signo].scss_handler;
535 old_act->sa_flags = scss.scss_per_sig[signo].scss_flags;
536 old_act->sa_mask = scss.scss_per_sig[signo].scss_mask;
537 old_act->sa_restorer = scss.scss_per_sig[signo].scss_restorer;
sewardj018f7622002-05-15 21:13:39 +0000538 }
539
540 /* And now copy new SCSS entry from new_act. */
541 if (new_act) {
njn695c16e2005-03-27 03:40:28 +0000542 scss.scss_per_sig[signo].scss_handler = new_act->ksa_handler;
543 scss.scss_per_sig[signo].scss_flags = new_act->sa_flags;
544 scss.scss_per_sig[signo].scss_mask = new_act->sa_mask;
545 scss.scss_per_sig[signo].scss_restorer = new_act->sa_restorer;
sewardjb5f6f512005-03-10 23:59:00 +0000546
njn695c16e2005-03-27 03:40:28 +0000547 VG_(sigdelset)(&scss.scss_per_sig[signo].scss_mask, VKI_SIGKILL);
548 VG_(sigdelset)(&scss.scss_per_sig[signo].scss_mask, VKI_SIGSTOP);
sewardj018f7622002-05-15 21:13:39 +0000549 }
550
551 /* All happy bunnies ... */
552 if (new_act) {
nethercote9dd11512004-08-04 15:31:30 +0000553 handle_SCSS_change( False /* lazy update */ );
sewardj018f7622002-05-15 21:13:39 +0000554 }
sewardjb5f6f512005-03-10 23:59:00 +0000555 return 0;
sewardj018f7622002-05-15 21:13:39 +0000556
557 bad_signo:
sewardj9a3d8bd2005-05-23 14:47:52 +0000558 if (VG_(needs).core_errors && VG_(clo_verbosity) >= 1
559 && !VG_(clo_xml)) {
njn25e49d8e72002-09-23 09:36:25 +0000560 VG_(message)(Vg_UserMsg,
nethercote9c42a0f2003-11-17 10:37:19 +0000561 "Warning: bad signal number %d in sigaction()",
njn25e49d8e72002-09-23 09:36:25 +0000562 signo);
sewardj9a3d8bd2005-05-23 14:47:52 +0000563 }
sewardjb5f6f512005-03-10 23:59:00 +0000564 return -VKI_EINVAL;
sewardj018f7622002-05-15 21:13:39 +0000565
nethercote9c42a0f2003-11-17 10:37:19 +0000566 bad_signo_reserved:
sewardj9a3d8bd2005-05-23 14:47:52 +0000567 if (VG_(needs).core_errors && VG_(clo_verbosity) >= 1
568 && !VG_(clo_xml)) {
nethercote9c42a0f2003-11-17 10:37:19 +0000569 VG_(message)(Vg_UserMsg,
570 "Warning: ignored attempt to set %s handler in sigaction();",
571 signame(signo));
572 VG_(message)(Vg_UserMsg,
573 " the %s signal is used internally by Valgrind",
574 signame(signo));
fitzhardingebf459872003-11-18 16:55:33 +0000575 }
sewardjb5f6f512005-03-10 23:59:00 +0000576 return -VKI_EINVAL;
nethercote9c42a0f2003-11-17 10:37:19 +0000577
sewardj018f7622002-05-15 21:13:39 +0000578 bad_sigkill_or_sigstop:
sewardj9a3d8bd2005-05-23 14:47:52 +0000579 if (VG_(needs).core_errors && VG_(clo_verbosity) >= 1
580 && !VG_(clo_xml)) {
njn25e49d8e72002-09-23 09:36:25 +0000581 VG_(message)(Vg_UserMsg,
nethercote9c42a0f2003-11-17 10:37:19 +0000582 "Warning: ignored attempt to set %s handler in sigaction();",
jsgf855d93d2003-10-13 22:26:55 +0000583 signame(signo));
nethercote9c42a0f2003-11-17 10:37:19 +0000584 VG_(message)(Vg_UserMsg,
585 " the %s signal is uncatchable",
586 signame(signo));
sewardj9a3d8bd2005-05-23 14:47:52 +0000587 }
sewardjb5f6f512005-03-10 23:59:00 +0000588 return -VKI_EINVAL;
sewardj018f7622002-05-15 21:13:39 +0000589}
590
591
592static
593void do_sigprocmask_bitops ( Int vki_how,
nethercote73b526f2004-10-31 18:48:21 +0000594 vki_sigset_t* orig_set,
595 vki_sigset_t* modifier )
sewardj018f7622002-05-15 21:13:39 +0000596{
597 switch (vki_how) {
598 case VKI_SIG_BLOCK:
nethercote73b526f2004-10-31 18:48:21 +0000599 VG_(sigaddset_from_set)( orig_set, modifier );
sewardj018f7622002-05-15 21:13:39 +0000600 break;
601 case VKI_SIG_UNBLOCK:
nethercote73b526f2004-10-31 18:48:21 +0000602 VG_(sigdelset_from_set)( orig_set, modifier );
sewardj018f7622002-05-15 21:13:39 +0000603 break;
604 case VKI_SIG_SETMASK:
605 *orig_set = *modifier;
606 break;
607 default:
njne427a662002-10-02 11:08:25 +0000608 VG_(core_panic)("do_sigprocmask_bitops");
sewardj018f7622002-05-15 21:13:39 +0000609 break;
610 }
611}
612
jsgf855d93d2003-10-13 22:26:55 +0000613/*
614 This updates the thread's signal mask. There's no such thing as a
615 process-wide signal mask.
sewardj018f7622002-05-15 21:13:39 +0000616
617 Note that the thread signal masks are an implicit part of SCSS,
618 which is why this routine is allowed to mess with them.
619*/
620static
621void do_setmask ( ThreadId tid,
622 Int how,
nethercote73b526f2004-10-31 18:48:21 +0000623 vki_sigset_t* newset,
624 vki_sigset_t* oldset )
sewardj018f7622002-05-15 21:13:39 +0000625{
sewardj018f7622002-05-15 21:13:39 +0000626 if (VG_(clo_trace_signals))
sewardja464e5c2002-05-23 17:34:49 +0000627 VG_(message)(Vg_DebugExtraMsg,
jsgf855d93d2003-10-13 22:26:55 +0000628 "do_setmask: tid = %d how = %d (%s), set = %p %08x%08x",
629 tid, how,
630 how==VKI_SIG_BLOCK ? "SIG_BLOCK" : (
631 how==VKI_SIG_UNBLOCK ? "SIG_UNBLOCK" : (
632 how==VKI_SIG_SETMASK ? "SIG_SETMASK" : "???")),
nethercote73b526f2004-10-31 18:48:21 +0000633 newset, newset ? newset->sig[1] : 0, newset ? newset->sig[0] : 0
jsgf855d93d2003-10-13 22:26:55 +0000634 );
sewardj018f7622002-05-15 21:13:39 +0000635
jsgf855d93d2003-10-13 22:26:55 +0000636 /* Just do this thread. */
637 vg_assert(VG_(is_valid_tid)(tid));
638 if (oldset) {
sewardjb5f6f512005-03-10 23:59:00 +0000639 *oldset = VG_(threads)[tid].sig_mask;
jsgf855d93d2003-10-13 22:26:55 +0000640 if (VG_(clo_trace_signals))
641 VG_(message)(Vg_DebugExtraMsg,
642 "\toldset=%p %08x%08x",
nethercote73b526f2004-10-31 18:48:21 +0000643 oldset, oldset->sig[1], oldset->sig[0]);
sewardj018f7622002-05-15 21:13:39 +0000644 }
sewardj018f7622002-05-15 21:13:39 +0000645 if (newset) {
jsgf855d93d2003-10-13 22:26:55 +0000646 do_sigprocmask_bitops (how, &VG_(threads)[tid].sig_mask, newset );
nethercote73b526f2004-10-31 18:48:21 +0000647 VG_(sigdelset)(&VG_(threads)[tid].sig_mask, VKI_SIGKILL);
648 VG_(sigdelset)(&VG_(threads)[tid].sig_mask, VKI_SIGSTOP);
sewardjb5f6f512005-03-10 23:59:00 +0000649 VG_(threads)[tid].tmp_sig_mask = VG_(threads)[tid].sig_mask;
sewardj018f7622002-05-15 21:13:39 +0000650 }
651}
652
653
njn4fbc86c2005-05-08 00:45:11 +0000654int VG_(do_sys_sigprocmask) ( ThreadId tid,
sewardj018f7622002-05-15 21:13:39 +0000655 Int how,
nethercote73b526f2004-10-31 18:48:21 +0000656 vki_sigset_t* set,
657 vki_sigset_t* oldset )
sewardj018f7622002-05-15 21:13:39 +0000658{
jsgf855d93d2003-10-13 22:26:55 +0000659 switch(how) {
660 case VKI_SIG_BLOCK:
661 case VKI_SIG_UNBLOCK:
662 case VKI_SIG_SETMASK:
sewardj018f7622002-05-15 21:13:39 +0000663 vg_assert(VG_(is_valid_tid)(tid));
jsgf855d93d2003-10-13 22:26:55 +0000664 do_setmask ( tid, how, set, oldset );
sewardjb5f6f512005-03-10 23:59:00 +0000665 VG_(poll_signals)(tid); /* look for any newly deliverable signals */
njn4fbc86c2005-05-08 00:45:11 +0000666 return 0;
jsgf855d93d2003-10-13 22:26:55 +0000667
668 default:
sewardj018f7622002-05-15 21:13:39 +0000669 VG_(message)(Vg_DebugMsg,
njn02bc4b82005-05-15 17:28:26 +0000670 "sigprocmask: unknown 'how' field %d", how);
njn4fbc86c2005-05-08 00:45:11 +0000671 return -VKI_EINVAL;
sewardj018f7622002-05-15 21:13:39 +0000672 }
673}
674
675
sewardj018f7622002-05-15 21:13:39 +0000676/* ---------------------------------------------------------------------
677 LOW LEVEL STUFF TO DO WITH SIGNALS: IMPLEMENTATION
678 ------------------------------------------------------------------ */
sewardj77e466c2002-04-14 02:29:29 +0000679
sewardj2e93c502002-04-12 11:12:52 +0000680/* ---------------------------------------------------------------------
681 Handy utilities to block/restore all host signals.
682 ------------------------------------------------------------------ */
683
684/* Block all host signals, dumping the old mask in *saved_mask. */
njn444eba12005-05-12 03:47:31 +0000685static void block_all_host_signals ( /* OUT */ vki_sigset_t* saved_mask )
sewardj2e93c502002-04-12 11:12:52 +0000686{
687 Int ret;
nethercote73b526f2004-10-31 18:48:21 +0000688 vki_sigset_t block_procmask;
689 VG_(sigfillset)(&block_procmask);
690 ret = VG_(sigprocmask)
sewardj2e93c502002-04-12 11:12:52 +0000691 (VKI_SIG_SETMASK, &block_procmask, saved_mask);
692 vg_assert(ret == 0);
693}
694
695/* Restore the blocking mask using the supplied saved one. */
njn444eba12005-05-12 03:47:31 +0000696static void restore_all_host_signals ( /* IN */ vki_sigset_t* saved_mask )
sewardj2e93c502002-04-12 11:12:52 +0000697{
698 Int ret;
nethercote73b526f2004-10-31 18:48:21 +0000699 ret = VG_(sigprocmask)(VKI_SIG_SETMASK, saved_mask, NULL);
sewardj2e93c502002-04-12 11:12:52 +0000700 vg_assert(ret == 0);
701}
sewardjde4a1d02002-03-22 01:27:54 +0000702
njn444eba12005-05-12 03:47:31 +0000703void VG_(clear_out_queued_signals)( ThreadId tid, vki_sigset_t* saved_mask )
704{
705 block_all_host_signals(saved_mask);
706 if (VG_(threads)[tid].sig_queue != NULL) {
707 VG_(arena_free)(VG_AR_CORE, VG_(threads)[tid].sig_queue);
708 VG_(threads)[tid].sig_queue = NULL;
709 }
710 restore_all_host_signals(saved_mask);
711}
712
sewardjb5f6f512005-03-10 23:59:00 +0000713Bool VG_(client_signal_OK)(Int sigNo)
jsgf855d93d2003-10-13 22:26:55 +0000714{
sewardjb5f6f512005-03-10 23:59:00 +0000715 /* signal 0 is OK for kill */
716 Bool ret = sigNo >= 0 && sigNo <= VKI_SIGVGRTUSERMAX;
jsgf855d93d2003-10-13 22:26:55 +0000717
sewardjb5f6f512005-03-10 23:59:00 +0000718 //VG_(printf)("client_signal_OK(%d) -> %d\n", sigNo, ret);
jsgf855d93d2003-10-13 22:26:55 +0000719
720 return ret;
721}
722
sewardjde4a1d02002-03-22 01:27:54 +0000723/* ---------------------------------------------------------------------
724 The signal simulation proper. A simplified version of what the
725 Linux kernel does.
726 ------------------------------------------------------------------ */
727
sewardjde4a1d02002-03-22 01:27:54 +0000728/* Set up a stack frame (VgSigContext) for the client's signal
nethercotefedd8102004-09-13 15:19:34 +0000729 handler. */
sewardj2c5ffbe2005-03-12 13:32:06 +0000730static
njn695c16e2005-03-27 03:40:28 +0000731void push_signal_frame ( ThreadId tid, const vki_siginfo_t *siginfo )
sewardjde4a1d02002-03-22 01:27:54 +0000732{
nethercote6eec4602004-09-13 14:15:36 +0000733 Addr esp_top_of_frame;
sewardj2e93c502002-04-12 11:12:52 +0000734 ThreadState* tst;
jsgf855d93d2003-10-13 22:26:55 +0000735 Int sigNo = siginfo->si_signo;
sewardj2e93c502002-04-12 11:12:52 +0000736
sewardjb5f6f512005-03-10 23:59:00 +0000737 vg_assert(sigNo >= 1 && sigNo <= VG_(max_signal));
sewardj018f7622002-05-15 21:13:39 +0000738 vg_assert(VG_(is_valid_tid)(tid));
739 tst = & VG_(threads)[tid];
sewardj2e93c502002-04-12 11:12:52 +0000740
jsgf855d93d2003-10-13 22:26:55 +0000741 if (VG_(clo_trace_signals))
742 VG_(message)(Vg_DebugMsg,
njn695c16e2005-03-27 03:40:28 +0000743 "push_signal_frame (thread %d): signal %d", tid, sigNo);
jsgf855d93d2003-10-13 22:26:55 +0000744
sewardj2342c972002-05-22 23:34:20 +0000745 if (/* this signal asked to run on an alt stack */
njn695c16e2005-03-27 03:40:28 +0000746 (scss.scss_per_sig[sigNo].scss_flags & VKI_SA_ONSTACK )
sewardj2342c972002-05-22 23:34:20 +0000747 && /* there is a defined and enabled alt stack, which we're not
748 already using. Logic from get_sigframe in
749 arch/i386/kernel/signal.c. */
njncf45fd42004-11-24 16:30:22 +0000750 sas_ss_flags(tid, STACK_PTR(tst->arch)) == 0
sewardj2342c972002-05-22 23:34:20 +0000751 ) {
752 esp_top_of_frame
fitzhardinge98c4dc02004-03-16 08:27:29 +0000753 = (Addr)(tst->altstack.ss_sp) + tst->altstack.ss_size;
sewardj2342c972002-05-22 23:34:20 +0000754 if (VG_(clo_trace_signals))
755 VG_(message)(Vg_DebugMsg,
sewardjb5f6f512005-03-10 23:59:00 +0000756 "delivering signal %d (%s) to thread %d: on ALT STACK (%p-%p; %d bytes)",
757 sigNo, signame(sigNo), tid,
758 tst->altstack.ss_sp,
759 tst->altstack.ss_sp + tst->altstack.ss_size,
760 tst->altstack.ss_size );
njnfdc28af2003-02-24 10:36:48 +0000761
nethercote7cc9c232004-01-21 15:08:04 +0000762 /* Signal delivery to tools */
fitzhardinge98c4dc02004-03-16 08:27:29 +0000763 VG_TRACK( pre_deliver_signal, tid, sigNo, /*alt_stack*/True );
njnfdc28af2003-02-24 10:36:48 +0000764
sewardj2342c972002-05-22 23:34:20 +0000765 } else {
njna60a7c12005-05-08 17:49:37 +0000766 esp_top_of_frame = STACK_PTR(tst->arch) - VGA_STACK_REDZONE_SZB;
njnfdc28af2003-02-24 10:36:48 +0000767
nethercote7cc9c232004-01-21 15:08:04 +0000768 /* Signal delivery to tools */
fitzhardinge98c4dc02004-03-16 08:27:29 +0000769 VG_TRACK( pre_deliver_signal, tid, sigNo, /*alt_stack*/False );
sewardj2342c972002-05-22 23:34:20 +0000770 }
sewardjb5f6f512005-03-10 23:59:00 +0000771
njn695c16e2005-03-27 03:40:28 +0000772 vg_assert(scss.scss_per_sig[sigNo].scss_handler != VKI_SIG_IGN);
773 vg_assert(scss.scss_per_sig[sigNo].scss_handler != VKI_SIG_DFL);
sewardjb5f6f512005-03-10 23:59:00 +0000774
775 /* This may fail if the client stack is busted; if that happens,
776 the whole process will exit rather than simply calling the
777 signal handler. */
sewardj985fabb2005-04-24 14:18:14 +0000778 VG_(sigframe_create) (tid, esp_top_of_frame, siginfo,
779 scss.scss_per_sig[sigNo].scss_handler,
780 scss.scss_per_sig[sigNo].scss_flags,
781 &tst->sig_mask,
782 scss.scss_per_sig[sigNo].scss_restorer);
sewardjde4a1d02002-03-22 01:27:54 +0000783}
784
sewardjde4a1d02002-03-22 01:27:54 +0000785
jsgf855d93d2003-10-13 22:26:55 +0000786static const Char *signame(Int sigNo)
sewardjde4a1d02002-03-22 01:27:54 +0000787{
jsgf855d93d2003-10-13 22:26:55 +0000788 static Char buf[10];
sewardjb48e5002002-05-13 00:16:03 +0000789
jsgf855d93d2003-10-13 22:26:55 +0000790 switch(sigNo) {
791#define S(x) case VKI_##x: return #x
792 S(SIGHUP);
793 S(SIGINT);
794 S(SIGQUIT);
795 S(SIGILL);
796 S(SIGTRAP);
797 S(SIGABRT);
798 S(SIGBUS);
799 S(SIGFPE);
800 S(SIGKILL);
801 S(SIGUSR1);
802 S(SIGUSR2);
803 S(SIGSEGV);
804 S(SIGPIPE);
805 S(SIGALRM);
806 S(SIGTERM);
807 S(SIGSTKFLT);
808 S(SIGCHLD);
809 S(SIGCONT);
810 S(SIGSTOP);
811 S(SIGTSTP);
812 S(SIGTTIN);
813 S(SIGTTOU);
814 S(SIGURG);
815 S(SIGXCPU);
816 S(SIGXFSZ);
817 S(SIGVTALRM);
818 S(SIGPROF);
819 S(SIGWINCH);
820 S(SIGIO);
821 S(SIGPWR);
822 S(SIGUNUSED);
823#undef S
sewardjde4a1d02002-03-22 01:27:54 +0000824
jsgf855d93d2003-10-13 22:26:55 +0000825 case VKI_SIGRTMIN ... VKI_SIGRTMAX:
sewardjb5f6f512005-03-10 23:59:00 +0000826 VG_(sprintf)(buf, "SIGRT%d", sigNo-VKI_SIGRTMIN);
jsgf855d93d2003-10-13 22:26:55 +0000827 return buf;
sewardjde4a1d02002-03-22 01:27:54 +0000828
jsgf855d93d2003-10-13 22:26:55 +0000829 default:
830 VG_(sprintf)(buf, "SIG%d", sigNo);
831 return buf;
832 }
833}
sewardjde4a1d02002-03-22 01:27:54 +0000834
jsgf855d93d2003-10-13 22:26:55 +0000835/* Hit ourselves with a signal using the default handler */
836void VG_(kill_self)(Int sigNo)
837{
nethercote73b526f2004-10-31 18:48:21 +0000838 vki_sigset_t mask, origmask;
839 struct vki_sigaction sa, origsa;
sewardj018f7622002-05-15 21:13:39 +0000840
jsgf855d93d2003-10-13 22:26:55 +0000841 sa.ksa_handler = VKI_SIG_DFL;
nethercote73b526f2004-10-31 18:48:21 +0000842 sa.sa_flags = 0;
843 sa.sa_restorer = 0;
844 VG_(sigemptyset)(&sa.sa_mask);
sewardj2e93c502002-04-12 11:12:52 +0000845
nethercote73b526f2004-10-31 18:48:21 +0000846 VG_(sigaction)(sigNo, &sa, &origsa);
sewardj018f7622002-05-15 21:13:39 +0000847
sewardjb5f6f512005-03-10 23:59:00 +0000848 VG_(sigemptyset)(&mask);
849 VG_(sigaddset)(&mask, sigNo);
850 VG_(sigprocmask)(VKI_SIG_UNBLOCK, &mask, &origmask);
jsgf855d93d2003-10-13 22:26:55 +0000851
nethercote73b526f2004-10-31 18:48:21 +0000852 VG_(tkill)(VG_(getpid)(), sigNo);
jsgf855d93d2003-10-13 22:26:55 +0000853
nethercote73b526f2004-10-31 18:48:21 +0000854 VG_(sigaction)(sigNo, &origsa, NULL);
855 VG_(sigprocmask)(VKI_SIG_SETMASK, &origmask, NULL);
jsgf855d93d2003-10-13 22:26:55 +0000856}
857
njn277a6d62004-11-26 14:07:24 +0000858// Core dumping is disabled until someone can work out how to abstract out
859// the arch-specific and word-size-specific parts neatly.
njnbde30272004-11-29 15:45:31 +0000860//
861// Note that the code below is not 64-bit clean!
862//
njn277a6d62004-11-26 14:07:24 +0000863#if 0
fitzhardinged65dcad2004-03-13 02:06:58 +0000864/*
865 Dump core
866
867 Generate a standard ELF core file corresponding to the client state
868 at the time of a crash.
869 */
870#include <elf.h>
871#ifndef NT_PRXFPREG
872#define NT_PRXFPREG 0x46e62b7f /* copied from gdb5.1/include/elf/common.h */
873#endif /* NT_PRXFPREG */
874
875/* If true, then this Segment may be mentioned in the core */
876static Bool may_dump(const Segment *seg)
877{
sewardjb5f6f512005-03-10 23:59:00 +0000878 return (seg->flags & (SF_DEVICE|SF_VALGRIND)) == 0 && VG_(is_client_addr)(seg->addr);
fitzhardinged65dcad2004-03-13 02:06:58 +0000879}
880
881/* If true, then this Segment's contents will be in the core */
882static Bool should_dump(const Segment *seg)
883{
884 return may_dump(seg); // && (seg->prot & VKI_PROT_WRITE);
885}
886
887static void fill_ehdr(Elf32_Ehdr *ehdr, Int num_phdrs)
888{
njne1d981a2005-03-11 04:47:23 +0000889 VG_(memset)(ehdr, 0, sizeof(*ehdr));
fitzhardinged65dcad2004-03-13 02:06:58 +0000890
891 VG_(memcpy)(ehdr->e_ident, ELFMAG, SELFMAG);
njn35172bc2005-03-26 00:04:03 +0000892 ehdr->e_ident[EI_CLASS] = VGA_ELF_CLASS;
893 ehdr->e_ident[EI_DATA] = VGA_ELF_ENDIANNESS;
fitzhardinged65dcad2004-03-13 02:06:58 +0000894 ehdr->e_ident[EI_VERSION] = EV_CURRENT;
fitzhardinged65dcad2004-03-13 02:06:58 +0000895
896 ehdr->e_type = ET_CORE;
njn35172bc2005-03-26 00:04:03 +0000897 ehdr->e_machine = VGA_ELF_MACHINE;
fitzhardinged65dcad2004-03-13 02:06:58 +0000898 ehdr->e_version = EV_CURRENT;
899 ehdr->e_entry = 0;
900 ehdr->e_phoff = sizeof(Elf32_Ehdr);
901 ehdr->e_shoff = 0;
902 ehdr->e_flags = 0;
903 ehdr->e_ehsize = sizeof(Elf32_Ehdr);
904 ehdr->e_phentsize = sizeof(Elf32_Phdr);
905 ehdr->e_phnum = num_phdrs;
906 ehdr->e_shentsize = 0;
907 ehdr->e_shnum = 0;
908 ehdr->e_shstrndx = 0;
909
910}
911
912static void fill_phdr(Elf32_Phdr *phdr, const Segment *seg, UInt off, Bool write)
913{
914 write = write && should_dump(seg);
915
916 VG_(memset)(phdr, 0, sizeof(*phdr));
917
918 phdr->p_type = PT_LOAD;
919 phdr->p_offset = off;
920 phdr->p_vaddr = seg->addr;
921 phdr->p_paddr = 0;
922 phdr->p_filesz = write ? seg->len : 0;
923 phdr->p_memsz = seg->len;
924 phdr->p_flags = 0;
925
926 if (seg->prot & VKI_PROT_READ)
927 phdr->p_flags |= PF_R;
928 if (seg->prot & VKI_PROT_WRITE)
929 phdr->p_flags |= PF_W;
930 if (seg->prot & VKI_PROT_EXEC)
931 phdr->p_flags |= PF_X;
932
nethercote73b526f2004-10-31 18:48:21 +0000933 phdr->p_align = VKI_PAGE_SIZE;
fitzhardinged65dcad2004-03-13 02:06:58 +0000934}
935
936struct note {
937 struct note *next;
938 Elf32_Nhdr note;
939 Char name[0];
940};
941
942static UInt note_size(const struct note *n)
943{
944 return sizeof(Elf32_Nhdr) + ROUNDUP(VG_(strlen)(n->name)+1, 4) + ROUNDUP(n->note.n_descsz, 4);
945}
946
947static void add_note(struct note **list, const Char *name, UInt type, const void *data, UInt datasz)
948{
949 Int namelen = VG_(strlen)(name)+1;
950 Int notelen = sizeof(struct note) +
951 ROUNDUP(namelen, 4) +
952 ROUNDUP(datasz, 4);
953 struct note *n = VG_(arena_malloc)(VG_AR_CORE, notelen);
954
955 VG_(memset)(n, 0, notelen);
956
957 n->next = *list;
958 *list = n;
959
960 n->note.n_type = type;
961 n->note.n_namesz = namelen;
962 n->note.n_descsz = datasz;
963
964 VG_(memcpy)(n->name, name, namelen);
965 VG_(memcpy)(n->name+ROUNDUP(namelen,4), data, datasz);
966}
967
968static void write_note(Int fd, const struct note *n)
969{
970 VG_(write)(fd, &n->note, note_size(n));
971}
972
nethercote73b526f2004-10-31 18:48:21 +0000973static void fill_prpsinfo(const ThreadState *tst, struct vki_elf_prpsinfo *prpsinfo)
fitzhardinged65dcad2004-03-13 02:06:58 +0000974{
975 Char *name;
976
977 VG_(memset)(prpsinfo, 0, sizeof(*prpsinfo));
978
979 switch(tst->status) {
980 case VgTs_Runnable:
sewardjb5f6f512005-03-10 23:59:00 +0000981 case VgTs_Yielding:
fitzhardinged65dcad2004-03-13 02:06:58 +0000982 prpsinfo->pr_sname = 'R';
983 break;
984
fitzhardinged65dcad2004-03-13 02:06:58 +0000985 case VgTs_WaitSys:
fitzhardinged65dcad2004-03-13 02:06:58 +0000986 prpsinfo->pr_sname = 'S';
987 break;
988
sewardjb5f6f512005-03-10 23:59:00 +0000989 case VgTs_Zombie:
990 prpsinfo->pr_sname = 'Z';
991 break;
992
fitzhardinged65dcad2004-03-13 02:06:58 +0000993 case VgTs_Empty:
sewardjb5f6f512005-03-10 23:59:00 +0000994 case VgTs_Init:
995 prpsinfo->pr_sname = '?';
fitzhardinged65dcad2004-03-13 02:06:58 +0000996 break;
997 }
998
999 prpsinfo->pr_uid = 0;
1000 prpsinfo->pr_gid = 0;
1001
1002 name = VG_(resolve_filename)(VG_(clexecfd));
1003
1004 if (name != NULL) {
1005 Char *n = name+VG_(strlen)(name)-1;
1006
1007 while(n > name && *n != '/')
1008 n--;
1009 if (n != name)
1010 n++;
1011
1012 VG_(strncpy)(prpsinfo->pr_fname, n, sizeof(prpsinfo->pr_fname));
1013 }
1014}
1015
sewardjb5f6f512005-03-10 23:59:00 +00001016static void fill_prstatus(const ThreadState *tst,
1017 struct vki_elf_prstatus *prs,
1018 const vki_siginfo_t *si)
fitzhardinged65dcad2004-03-13 02:06:58 +00001019{
nethercote73b526f2004-10-31 18:48:21 +00001020 struct vki_user_regs_struct *regs;
fitzhardinged65dcad2004-03-13 02:06:58 +00001021
1022 VG_(memset)(prs, 0, sizeof(*prs));
1023
1024 prs->pr_info.si_signo = si->si_signo;
1025 prs->pr_info.si_code = si->si_code;
1026 prs->pr_info.si_errno = 0;
1027
1028 prs->pr_cursig = si->si_signo;
1029
sewardjb5f6f512005-03-10 23:59:00 +00001030 prs->pr_pid = tst->os_state.lwpid;
fitzhardinged65dcad2004-03-13 02:06:58 +00001031 prs->pr_ppid = 0;
sewardjb5f6f512005-03-10 23:59:00 +00001032 prs->pr_pgrp = VG_(getpgrp)();
1033 prs->pr_sid = VG_(getpgrp)();
fitzhardinged65dcad2004-03-13 02:06:58 +00001034
nethercote73b526f2004-10-31 18:48:21 +00001035 regs = (struct vki_user_regs_struct *)prs->pr_reg;
fitzhardinged65dcad2004-03-13 02:06:58 +00001036
1037 vg_assert(sizeof(*regs) == sizeof(prs->pr_reg));
1038
sewardj2a99cf62004-11-24 10:44:19 +00001039 VGA_(fill_elfregs_from_tst)(regs, &tst->arch);
fitzhardinged65dcad2004-03-13 02:06:58 +00001040}
1041
nethercote73b526f2004-10-31 18:48:21 +00001042static void fill_fpu(const ThreadState *tst, vki_elf_fpregset_t *fpu)
fitzhardinged65dcad2004-03-13 02:06:58 +00001043{
sewardj2a99cf62004-11-24 10:44:19 +00001044 VGA_(fill_elffpregs_from_tst)(fpu, &tst->arch);
fitzhardinged65dcad2004-03-13 02:06:58 +00001045}
1046
nethercote73b526f2004-10-31 18:48:21 +00001047static void fill_xfpu(const ThreadState *tst, vki_elf_fpxregset_t *xfpu)
fitzhardinged65dcad2004-03-13 02:06:58 +00001048{
sewardj2a99cf62004-11-24 10:44:19 +00001049 VGA_(fill_elffpxregs_from_tst)(xfpu, &tst->arch);
fitzhardinged65dcad2004-03-13 02:06:58 +00001050}
1051
nethercote73b526f2004-10-31 18:48:21 +00001052static void make_coredump(ThreadId tid, const vki_siginfo_t *si, UInt max_size)
fitzhardinged65dcad2004-03-13 02:06:58 +00001053{
1054 Char buf[1000];
1055 Char *basename = "vgcore";
1056 Char *coreext = "";
1057 Int seq = 0;
1058 Int core_fd;
1059 Segment *seg;
1060 Elf32_Ehdr ehdr;
1061 Elf32_Phdr *phdrs;
1062 Int num_phdrs;
sewardjb5f6f512005-03-10 23:59:00 +00001063 Int i, idx;
fitzhardinged65dcad2004-03-13 02:06:58 +00001064 UInt off;
1065 struct note *notelist, *note;
1066 UInt notesz;
nethercote73b526f2004-10-31 18:48:21 +00001067 struct vki_elf_prpsinfo prpsinfo;
1068 struct vki_elf_prstatus prstatus;
fitzhardinged65dcad2004-03-13 02:06:58 +00001069
nethercotef8548672004-06-21 12:42:35 +00001070 if (VG_(clo_log_name) != NULL) {
fitzhardinged65dcad2004-03-13 02:06:58 +00001071 coreext = ".core";
nethercotef8548672004-06-21 12:42:35 +00001072 basename = VG_(clo_log_name);
fitzhardinged65dcad2004-03-13 02:06:58 +00001073 }
1074
1075 for(;;) {
1076 if (seq == 0)
1077 VG_(sprintf)(buf, "%s%s.pid%d",
sewardjb5f6f512005-03-10 23:59:00 +00001078 basename, coreext, VG_(getpid)());
fitzhardinged65dcad2004-03-13 02:06:58 +00001079 else
1080 VG_(sprintf)(buf, "%s%s.pid%d.%d",
sewardjb5f6f512005-03-10 23:59:00 +00001081 basename, coreext, VG_(getpid)(), seq);
fitzhardinged65dcad2004-03-13 02:06:58 +00001082 seq++;
1083
1084 core_fd = VG_(open)(buf,
1085 VKI_O_CREAT|VKI_O_WRONLY|VKI_O_EXCL|VKI_O_TRUNC,
1086 VKI_S_IRUSR|VKI_S_IWUSR);
1087 if (core_fd >= 0)
1088 break;
1089
1090 if (core_fd != -VKI_EEXIST)
1091 return; /* can't create file */
1092 }
1093
1094 /* First, count how many memory segments to dump */
1095 num_phdrs = 1; /* start with notes */
1096 for(seg = VG_(first_segment)();
1097 seg != NULL;
1098 seg = VG_(next_segment)(seg)) {
1099 if (!may_dump(seg))
1100 continue;
1101
1102 num_phdrs++;
1103 }
1104
1105 fill_ehdr(&ehdr, num_phdrs);
1106
sewardjb5f6f512005-03-10 23:59:00 +00001107 notelist = NULL;
1108
fitzhardinged65dcad2004-03-13 02:06:58 +00001109 /* Second, work out their layout */
1110 phdrs = VG_(arena_malloc)(VG_AR_CORE, sizeof(*phdrs) * num_phdrs);
1111
1112 for(i = 1; i < VG_N_THREADS; i++) {
sewardj51ac0872004-12-21 01:20:49 +00001113 vki_elf_fpregset_t fpu;
1114 vki_elf_fpxregset_t xfpu;
fitzhardinged65dcad2004-03-13 02:06:58 +00001115
1116 if (VG_(threads)[i].status == VgTs_Empty)
1117 continue;
1118
sewardj51ac0872004-12-21 01:20:49 +00001119 fill_xfpu(&VG_(threads)[i], &xfpu);
1120 add_note(&notelist, "LINUX", NT_PRXFPREG, &xfpu, sizeof(xfpu));
fitzhardinged65dcad2004-03-13 02:06:58 +00001121
1122 fill_fpu(&VG_(threads)[i], &fpu);
1123 add_note(&notelist, "CORE", NT_FPREGSET, &fpu, sizeof(fpu));
1124
1125 fill_prstatus(&VG_(threads)[i], &prstatus, si);
1126 add_note(&notelist, "CORE", NT_PRSTATUS, &prstatus, sizeof(prstatus));
1127 }
1128
1129 fill_prpsinfo(&VG_(threads)[tid], &prpsinfo);
1130 add_note(&notelist, "CORE", NT_PRPSINFO, &prpsinfo, sizeof(prpsinfo));
1131
1132 for(note = notelist, notesz = 0; note != NULL; note = note->next)
1133 notesz += note_size(note);
1134
1135 off = sizeof(ehdr) + sizeof(*phdrs) * num_phdrs;
1136
1137 phdrs[0].p_type = PT_NOTE;
1138 phdrs[0].p_offset = off;
1139 phdrs[0].p_vaddr = 0;
1140 phdrs[0].p_paddr = 0;
1141 phdrs[0].p_filesz = notesz;
1142 phdrs[0].p_memsz = 0;
1143 phdrs[0].p_flags = 0;
1144 phdrs[0].p_align = 0;
1145
1146 off += notesz;
1147
1148 off = PGROUNDUP(off);
1149
sewardjb5f6f512005-03-10 23:59:00 +00001150 for(seg = VG_(first_segment)(), idx = 1;
fitzhardinged65dcad2004-03-13 02:06:58 +00001151 seg != NULL;
sewardjb5f6f512005-03-10 23:59:00 +00001152 seg = VG_(next_segment)(seg)) {
fitzhardinged65dcad2004-03-13 02:06:58 +00001153 if (!may_dump(seg))
1154 continue;
1155
sewardjb5f6f512005-03-10 23:59:00 +00001156 fill_phdr(&phdrs[idx], seg, off, (seg->len + off) < max_size);
fitzhardinged65dcad2004-03-13 02:06:58 +00001157
sewardjb5f6f512005-03-10 23:59:00 +00001158 off += phdrs[idx].p_filesz;
1159
1160 idx++;
fitzhardinged65dcad2004-03-13 02:06:58 +00001161 }
1162
1163 /* write everything out */
1164 VG_(write)(core_fd, &ehdr, sizeof(ehdr));
1165 VG_(write)(core_fd, phdrs, sizeof(*phdrs) * num_phdrs);
1166
1167 for(note = notelist; note != NULL; note = note->next)
1168 write_note(core_fd, note);
1169
1170 VG_(lseek)(core_fd, phdrs[1].p_offset, VKI_SEEK_SET);
1171
sewardjb5f6f512005-03-10 23:59:00 +00001172 for(seg = VG_(first_segment)(), idx = 1;
fitzhardinged65dcad2004-03-13 02:06:58 +00001173 seg != NULL;
sewardjb5f6f512005-03-10 23:59:00 +00001174 seg = VG_(next_segment)(seg)) {
fitzhardinged65dcad2004-03-13 02:06:58 +00001175 if (!should_dump(seg))
1176 continue;
1177
sewardjb5f6f512005-03-10 23:59:00 +00001178 if (phdrs[idx].p_filesz > 0) {
1179 Int ret;
1180
1181 vg_assert(VG_(lseek)(core_fd, phdrs[idx].p_offset, VKI_SEEK_SET) == phdrs[idx].p_offset);
1182 vg_assert(seg->len >= phdrs[idx].p_filesz);
1183
1184 ret = VG_(write)(core_fd, (void *)seg->addr, phdrs[idx].p_filesz);
1185 }
1186 idx++;
fitzhardinged65dcad2004-03-13 02:06:58 +00001187 }
1188
1189 VG_(close)(core_fd);
1190}
njn277a6d62004-11-26 14:07:24 +00001191#endif
fitzhardinged65dcad2004-03-13 02:06:58 +00001192
jsgf855d93d2003-10-13 22:26:55 +00001193/*
sewardjb5f6f512005-03-10 23:59:00 +00001194 Perform the default action of a signal. If the signal is fatal, it
1195 marks all threads as needing to exit, but it doesn't actually kill
1196 the process or thread.
jsgf855d93d2003-10-13 22:26:55 +00001197
1198 If we're not being quiet, then print out some more detail about
1199 fatal signals (esp. core dumping signals).
1200 */
njn695c16e2005-03-27 03:40:28 +00001201static void default_action(const vki_siginfo_t *info, ThreadId tid)
jsgf855d93d2003-10-13 22:26:55 +00001202{
1203 Int sigNo = info->si_signo;
sewardjb5f6f512005-03-10 23:59:00 +00001204 Bool terminate = False; /* kills process */
1205 Bool core = False; /* kills process w/ core */
1206 struct vki_rlimit corelim;
1207 Bool could_core;
jsgf855d93d2003-10-13 22:26:55 +00001208
sewardjb5f6f512005-03-10 23:59:00 +00001209 vg_assert(VG_(is_running_thread)(tid));
1210
jsgf855d93d2003-10-13 22:26:55 +00001211 switch(sigNo) {
1212 case VKI_SIGQUIT: /* core */
1213 case VKI_SIGILL: /* core */
1214 case VKI_SIGABRT: /* core */
1215 case VKI_SIGFPE: /* core */
1216 case VKI_SIGSEGV: /* core */
1217 case VKI_SIGBUS: /* core */
1218 case VKI_SIGTRAP: /* core */
1219 case VKI_SIGXCPU: /* core */
1220 case VKI_SIGXFSZ: /* core */
1221 terminate = True;
1222 core = True;
1223 break;
1224
1225 case VKI_SIGHUP: /* term */
1226 case VKI_SIGINT: /* term */
1227 case VKI_SIGKILL: /* term - we won't see this */
1228 case VKI_SIGPIPE: /* term */
1229 case VKI_SIGALRM: /* term */
1230 case VKI_SIGTERM: /* term */
1231 case VKI_SIGUSR1: /* term */
1232 case VKI_SIGUSR2: /* term */
1233 case VKI_SIGIO: /* term */
1234 case VKI_SIGPWR: /* term */
1235 case VKI_SIGSYS: /* term */
1236 case VKI_SIGPROF: /* term */
1237 case VKI_SIGVTALRM: /* term */
1238 case VKI_SIGRTMIN ... VKI_SIGRTMAX: /* term */
1239 terminate = True;
1240 break;
1241 }
1242
1243 vg_assert(!core || (core && terminate));
1244
fitzhardinge98abfc72003-12-16 02:05:15 +00001245 if (VG_(clo_trace_signals))
sewardjb5f6f512005-03-10 23:59:00 +00001246 VG_(message)(Vg_DebugMsg, "delivering %d (code %d) to default handler; action: %s%s",
1247 sigNo, info->si_code, terminate ? "terminate" : "ignore", core ? "+core" : "");
fitzhardinge98abfc72003-12-16 02:05:15 +00001248
sewardjb5f6f512005-03-10 23:59:00 +00001249 if (!terminate)
1250 return; /* nothing to do */
fitzhardinge4a4d1082004-03-15 23:46:54 +00001251
sewardjb5f6f512005-03-10 23:59:00 +00001252 could_core = core;
1253
1254 if (core) {
1255 /* If they set the core-size limit to zero, don't generate a
1256 core file */
fitzhardinge61a53412004-03-15 23:44:11 +00001257
sewardjb5f6f512005-03-10 23:59:00 +00001258 VG_(getrlimit)(VKI_RLIMIT_CORE, &corelim);
fitzhardinge61a53412004-03-15 23:44:11 +00001259
sewardjb5f6f512005-03-10 23:59:00 +00001260 if (corelim.rlim_cur == 0)
1261 core = False;
1262 }
fitzhardinge61a53412004-03-15 23:44:11 +00001263
sewardjb5f6f512005-03-10 23:59:00 +00001264 if (VG_(clo_verbosity) > 1 || (could_core && info->si_code > VKI_SI_USER)) {
1265 VG_(message)(Vg_UserMsg, "");
1266 VG_(message)(Vg_UserMsg, "Process terminating with default action of signal %d (%s)%s",
1267 sigNo, signame(sigNo), core ? ": dumping core" : "");
jsgf855d93d2003-10-13 22:26:55 +00001268
sewardjb5f6f512005-03-10 23:59:00 +00001269 /* Be helpful - decode some more details about this fault */
1270 if (info->si_code > VKI_SI_USER) {
1271 const Char *event = NULL;
1272 Bool haveaddr = True;
jsgf855d93d2003-10-13 22:26:55 +00001273
sewardjb5f6f512005-03-10 23:59:00 +00001274 switch(sigNo) {
1275 case VKI_SIGSEGV:
1276 switch(info->si_code) {
1277 case 1: event = "Access not within mapped region"; break;
1278 case 2: event = "Bad permissions for mapped region"; break;
1279 case 128:
1280 /* General Protection Fault: The CPU/kernel
1281 isn't telling us anything useful, but this
1282 is commonly the result of exceeding a
1283 segment limit, such as the one imposed by
1284 --pointercheck=yes. */
1285 if (VG_(clo_pointercheck))
1286 event = "GPF (Pointer out of bounds?)";
1287 else
1288 event = "General Protection Fault";
1289 haveaddr = False;
jsgf855d93d2003-10-13 22:26:55 +00001290 break;
1291 }
sewardjb5f6f512005-03-10 23:59:00 +00001292 break;
jsgf855d93d2003-10-13 22:26:55 +00001293
sewardjb5f6f512005-03-10 23:59:00 +00001294 case VKI_SIGILL:
1295 switch(info->si_code) {
1296 case 1: event = "Illegal opcode"; break;
1297 case 2: event = "Illegal operand"; break;
1298 case 3: event = "Illegal addressing mode"; break;
1299 case 4: event = "Illegal trap"; break;
1300 case 5: event = "Privileged opcode"; break;
1301 case 6: event = "Privileged register"; break;
1302 case 7: event = "Coprocessor error"; break;
1303 case 8: event = "Internal stack error"; break;
1304 }
1305 break;
1306
1307 case VKI_SIGFPE:
1308 switch (info->si_code) {
1309 case 1: event = "Integer divide by zero"; break;
1310 case 2: event = "Integer overflow"; break;
1311 case 3: event = "FP divide by zero"; break;
1312 case 4: event = "FP overflow"; break;
1313 case 5: event = "FP underflow"; break;
1314 case 6: event = "FP inexact"; break;
1315 case 7: event = "FP invalid operation"; break;
1316 case 8: event = "FP subscript out of range"; break;
1317 }
1318 break;
1319
1320 case VKI_SIGBUS:
1321 switch (info->si_code) {
1322 case 1: event = "Invalid address alignment"; break;
1323 case 2: event = "Non-existent physical address"; break;
1324 case 3: event = "Hardware error"; break;
1325 }
1326 break;
1327 }
1328
1329 if (event != NULL) {
1330 if (haveaddr)
nethercote3b390c72003-11-13 17:53:43 +00001331 VG_(message)(Vg_UserMsg, " %s at address %p",
jsgf855d93d2003-10-13 22:26:55 +00001332 event, info->_sifields._sigfault._addr);
sewardjb5f6f512005-03-10 23:59:00 +00001333 else
1334 VG_(message)(Vg_UserMsg, " %s", event);
jsgf855d93d2003-10-13 22:26:55 +00001335 }
1336 }
fitzhardinge126c64f2003-12-08 21:58:37 +00001337
sewardjb5f6f512005-03-10 23:59:00 +00001338 if (tid != VG_INVALID_THREADID) {
njnd01fef72005-03-25 23:35:48 +00001339 VG_(get_and_pp_StackTrace)(tid, VG_(clo_backtrace_size));
fitzhardinge126c64f2003-12-08 21:58:37 +00001340 }
sewardjb5f6f512005-03-10 23:59:00 +00001341 }
1342
1343 if (VG_(is_action_requested)( "Attach to debugger", & VG_(clo_db_attach) )) {
1344 VG_(start_debugger)( tid );
1345 }
fitzhardinge126c64f2003-12-08 21:58:37 +00001346
njn277a6d62004-11-26 14:07:24 +00001347 // See comment above about this temporary disabling of core dumps.
1348 #if 0
sewardjb5f6f512005-03-10 23:59:00 +00001349 if (core) {
1350 const static struct vki_rlimit zero = { 0, 0 };
fitzhardinge4a4d1082004-03-15 23:46:54 +00001351
sewardjb5f6f512005-03-10 23:59:00 +00001352 make_coredump(tid, info, corelim.rlim_cur);
fitzhardinged65dcad2004-03-13 02:06:58 +00001353
sewardjb5f6f512005-03-10 23:59:00 +00001354 /* Make sure we don't get a confusing kernel-generated
1355 coredump when we finally exit */
1356 VG_(setrlimit)(VKI_RLIMIT_CORE, &zero);
1357 }
njn277a6d62004-11-26 14:07:24 +00001358 #endif
fitzhardinged65dcad2004-03-13 02:06:58 +00001359
sewardjb5f6f512005-03-10 23:59:00 +00001360 /* stash fatal signal in main thread */
1361 VG_(threads)[VG_(master_tid)].os_state.fatalsig = sigNo;
sewardjde4a1d02002-03-22 01:27:54 +00001362
sewardjb5f6f512005-03-10 23:59:00 +00001363 /* everyone dies */
1364 VG_(nuke_all_threads_except)(tid, VgSrc_FatalSig);
1365 VG_(threads)[tid].exitreason = VgSrc_FatalSig;
1366 VG_(threads)[tid].os_state.fatalsig = sigNo;
sewardjb48e5002002-05-13 00:16:03 +00001367}
1368
sewardjb5f6f512005-03-10 23:59:00 +00001369/*
1370 This does the business of delivering a signal to a thread. It may
1371 be called from either a real signal handler, or from normal code to
1372 cause the thread to enter the signal handler.
sewardj5e2f0012004-12-13 14:10:34 +00001373
sewardjb5f6f512005-03-10 23:59:00 +00001374 This updates the thread state, but it does not set it to be
1375 Runnable.
1376*/
njn9ec0f3e2005-03-13 06:00:47 +00001377static void deliver_signal ( ThreadId tid, const vki_siginfo_t *info )
sewardjde4a1d02002-03-22 01:27:54 +00001378{
jsgf855d93d2003-10-13 22:26:55 +00001379 Int sigNo = info->si_signo;
njn695c16e2005-03-27 03:40:28 +00001380 SCSS_Per_Signal *handler = &scss.scss_per_sig[sigNo];
fitzhardinge98abfc72003-12-16 02:05:15 +00001381 void *handler_fn;
jsgf855d93d2003-10-13 22:26:55 +00001382 ThreadState *tst = VG_(get_ThreadState)(tid);
1383
1384 if (VG_(clo_trace_signals))
sewardjb5f6f512005-03-10 23:59:00 +00001385 VG_(message)(Vg_DebugMsg,"delivering signal %d (%s):%d to thread %d",
1386 sigNo, signame(sigNo), info->si_code, tid );
jsgf855d93d2003-10-13 22:26:55 +00001387
sewardjb5f6f512005-03-10 23:59:00 +00001388 if (sigNo == VKI_SIGVGKILL) {
1389 /* If this is a SIGVGKILL, we're expecting it to interrupt any
1390 blocked syscall. It doesn't matter whether the VCPU state is
1391 set to restart or not, because we don't expect it will
1392 execute any more client instructions. */
1393 vg_assert(VG_(is_exiting)(tid));
jsgf855d93d2003-10-13 22:26:55 +00001394 return;
1395 }
1396
sewardjb5f6f512005-03-10 23:59:00 +00001397 /* If the client specifies SIG_IGN, treat it as SIG_DFL.
jsgf855d93d2003-10-13 22:26:55 +00001398
njn9ec0f3e2005-03-13 06:00:47 +00001399 If deliver_signal() is being called on a thread, we want
sewardjb5f6f512005-03-10 23:59:00 +00001400 the signal to get through no matter what; if they're ignoring
1401 it, then we do this override (this is so we can send it SIGSEGV,
1402 etc). */
fitzhardinge98abfc72003-12-16 02:05:15 +00001403 handler_fn = handler->scss_handler;
sewardjb5f6f512005-03-10 23:59:00 +00001404 if (handler_fn == VKI_SIG_IGN)
fitzhardinge98abfc72003-12-16 02:05:15 +00001405 handler_fn = VKI_SIG_DFL;
1406
1407 vg_assert(handler_fn != VKI_SIG_IGN);
jsgf855d93d2003-10-13 22:26:55 +00001408
fitzhardinge98abfc72003-12-16 02:05:15 +00001409 if (handler_fn == VKI_SIG_DFL) {
njn695c16e2005-03-27 03:40:28 +00001410 default_action(info, tid);
jsgf855d93d2003-10-13 22:26:55 +00001411 } else {
1412 /* Create a signal delivery frame, and set the client's %ESP and
1413 %EIP so that when execution continues, we will enter the
1414 signal handler with the frame on top of the client's stack,
sewardjb5f6f512005-03-10 23:59:00 +00001415 as it expects.
1416
1417 Signal delivery can fail if the client stack is too small or
1418 missing, and we can't push the frame. If that happens,
1419 push_signal_frame will cause the whole process to exit when
1420 we next hit the scheduler.
1421 */
jsgf855d93d2003-10-13 22:26:55 +00001422 vg_assert(VG_(is_valid_tid)(tid));
sewardjb5f6f512005-03-10 23:59:00 +00001423
njn695c16e2005-03-27 03:40:28 +00001424 push_signal_frame ( tid, info );
jsgf855d93d2003-10-13 22:26:55 +00001425
1426 if (handler->scss_flags & VKI_SA_ONESHOT) {
1427 /* Do the ONESHOT thing. */
1428 handler->scss_handler = VKI_SIG_DFL;
1429
nethercote9dd11512004-08-04 15:31:30 +00001430 handle_SCSS_change( False /* lazy update */ );
jsgf855d93d2003-10-13 22:26:55 +00001431 }
sewardjb5f6f512005-03-10 23:59:00 +00001432
1433 /* At this point:
1434 tst->sig_mask is the current signal mask
1435 tst->tmp_sig_mask is the same as sig_mask, unless we're in sigsuspend
1436 handler->scss_mask is the mask set by the handler
1437
1438 Handler gets a mask of tmp_sig_mask|handler_mask|signo
1439 */
1440 tst->sig_mask = tst->tmp_sig_mask;
1441 if (!(handler->scss_flags & VKI_SA_NOMASK)) {
1442 VG_(sigaddset_from_set)(&tst->sig_mask, &handler->scss_mask);
1443 VG_(sigaddset)(&tst->sig_mask, sigNo);
1444
1445 tst->tmp_sig_mask = tst->sig_mask;
1446 }
1447 }
1448
1449 /* Thread state is ready to go - just add Runnable */
1450}
1451
njn9ec0f3e2005-03-13 06:00:47 +00001452static void synth_fault_common(ThreadId tid, Addr addr, Int si_code)
1453{
1454 vki_siginfo_t info;
1455
1456 vg_assert(VG_(threads)[tid].status == VgTs_Runnable);
1457
1458 info.si_signo = VKI_SIGSEGV;
1459 info.si_code = si_code;
1460 info._sifields._sigfault._addr = (void*)addr;
1461
1462 /* If they're trying to block the signal, force it to be delivered */
1463 if (VG_(sigismember)(&VG_(threads)[tid].sig_mask, VKI_SIGSEGV))
1464 VG_(set_default_handler)(VKI_SIGSEGV);
1465
1466 deliver_signal(tid, &info);
1467}
1468
1469// Synthesize a fault where the address is OK, but the page
1470// permissions are bad.
1471void VG_(synth_fault_perms)(ThreadId tid, Addr addr)
1472{
1473 synth_fault_common(tid, addr, 2);
1474}
1475
1476// Synthesize a fault where the address there's nothing mapped at the address.
1477void VG_(synth_fault_mapping)(ThreadId tid, Addr addr)
1478{
1479 synth_fault_common(tid, addr, 1);
1480}
1481
1482// Synthesize a misc memory fault.
1483void VG_(synth_fault)(ThreadId tid)
1484{
1485 synth_fault_common(tid, 0, 0x80);
1486}
1487
1488// Synthesise a SIGILL.
1489void VG_(synth_sigill)(ThreadId tid, Addr addr)
1490{
1491 vki_siginfo_t info;
1492
1493 vg_assert(VG_(threads)[tid].status == VgTs_Runnable);
1494
1495 info.si_signo = VKI_SIGILL;
1496 info.si_code = 1; /* jrs: no idea what this should be */
1497 info._sifields._sigfault._addr = (void*)addr;
1498
1499 VG_(resume_scheduler)(tid);
1500 deliver_signal(tid, &info);
1501}
1502
sewardjb5f6f512005-03-10 23:59:00 +00001503/* Make a signal pending for a thread, for later delivery.
1504 VG_(poll_signals) will arrange for it to be delivered at the right
1505 time.
1506
1507 tid==0 means add it to the process-wide queue, and not sent it to a
1508 specific thread.
1509*/
sewardj2c5ffbe2005-03-12 13:32:06 +00001510static
sewardjb5f6f512005-03-10 23:59:00 +00001511void queue_signal(ThreadId tid, const vki_siginfo_t *si)
1512{
1513 ThreadState *tst;
1514 SigQueue *sq;
1515 vki_sigset_t savedmask;
1516
1517 tst = VG_(get_ThreadState)(tid);
1518
1519 /* Protect the signal queue against async deliveries */
njn444eba12005-05-12 03:47:31 +00001520 block_all_host_signals(&savedmask);
sewardjb5f6f512005-03-10 23:59:00 +00001521
1522 if (tst->sig_queue == NULL) {
1523 tst->sig_queue = VG_(arena_malloc)(VG_AR_CORE, sizeof(*tst->sig_queue));
1524 VG_(memset)(tst->sig_queue, 0, sizeof(*tst->sig_queue));
1525 }
1526 sq = tst->sig_queue;
1527
1528 if (VG_(clo_trace_signals))
1529 VG_(message)(Vg_DebugMsg, "Queueing signal %d (idx %d) to thread %d",
1530 si->si_signo, sq->next, tid);
1531
1532 /* Add signal to the queue. If the queue gets overrun, then old
1533 queued signals may get lost.
1534
1535 XXX We should also keep a sigset of pending signals, so that at
1536 least a non-siginfo signal gets deliviered.
1537 */
1538 if (sq->sigs[sq->next].si_signo != 0)
1539 VG_(message)(Vg_UserMsg, "Signal %d being dropped from thread %d's queue",
1540 sq->sigs[sq->next].si_signo, tid);
1541
1542 sq->sigs[sq->next] = *si;
1543 sq->next = (sq->next+1) % N_QUEUED_SIGNALS;
1544
njn444eba12005-05-12 03:47:31 +00001545 restore_all_host_signals(&savedmask);
sewardjb5f6f512005-03-10 23:59:00 +00001546}
1547
1548/*
1549 Returns the next queued signal for thread tid which is in "set".
1550 tid==0 means process-wide signal. Set si_signo to 0 when the
1551 signal has been delivered.
1552
1553 Must be called with all signals blocked, to protect against async
1554 deliveries.
1555*/
1556static vki_siginfo_t *next_queued(ThreadId tid, const vki_sigset_t *set)
1557{
1558 ThreadState *tst = VG_(get_ThreadState)(tid);
1559 SigQueue *sq;
1560 Int idx;
1561 vki_siginfo_t *ret = NULL;
1562
1563 sq = tst->sig_queue;
1564 if (sq == NULL)
1565 goto out;
jsgf855d93d2003-10-13 22:26:55 +00001566
sewardjb5f6f512005-03-10 23:59:00 +00001567 idx = sq->next;
1568 do {
1569 if (0)
1570 VG_(printf)("idx=%d si_signo=%d inset=%d\n", idx,
1571 sq->sigs[idx].si_signo, VG_(sigismember)(set, sq->sigs[idx].si_signo));
jsgf855d93d2003-10-13 22:26:55 +00001572
sewardjb5f6f512005-03-10 23:59:00 +00001573 if (sq->sigs[idx].si_signo != 0 && VG_(sigismember)(set, sq->sigs[idx].si_signo)) {
1574 if (VG_(clo_trace_signals))
1575 VG_(message)(Vg_DebugMsg, "Returning queued signal %d (idx %d) for thread %d",
1576 sq->sigs[idx].si_signo, idx, tid);
1577 ret = &sq->sigs[idx];
1578 goto out;
jsgf855d93d2003-10-13 22:26:55 +00001579 }
1580
sewardjb5f6f512005-03-10 23:59:00 +00001581 idx = (idx + 1) % N_QUEUED_SIGNALS;
1582 } while(idx != sq->next);
1583 out:
1584 return ret;
jsgf855d93d2003-10-13 22:26:55 +00001585}
1586
1587/*
sewardjb5f6f512005-03-10 23:59:00 +00001588 Receive an async signal from the kernel.
jsgf855d93d2003-10-13 22:26:55 +00001589
sewardjb5f6f512005-03-10 23:59:00 +00001590 This should only happen when the thread is blocked in a syscall,
1591 since that's the only time this set of signals is unblocked.
jsgf855d93d2003-10-13 22:26:55 +00001592*/
1593static
njn695c16e2005-03-27 03:40:28 +00001594void async_signalhandler ( Int sigNo, vki_siginfo_t *info, struct vki_ucontext *uc )
jsgf855d93d2003-10-13 22:26:55 +00001595{
sewardjb5f6f512005-03-10 23:59:00 +00001596 ThreadId tid = VG_(get_lwp_tid)(VG_(gettid)());
1597 ThreadState *tst = VG_(get_ThreadState)(tid);
jsgf855d93d2003-10-13 22:26:55 +00001598
sewardjb5f6f512005-03-10 23:59:00 +00001599 vg_assert(tst->status == VgTs_WaitSys);
jsgf855d93d2003-10-13 22:26:55 +00001600
sewardjb5f6f512005-03-10 23:59:00 +00001601 /* The thread isn't currently running, make it so before going on */
1602 VG_(set_running)(tid);
1603
1604 if (VG_(clo_trace_signals))
1605 VG_(message)(Vg_DebugMsg, "Async handler got signal %d for tid %d info %d",
1606 sigNo, tid, info->si_code);
1607
1608 /* Update thread state properly */
njn605f4882005-05-29 17:50:40 +00001609 VGP_(interrupted_syscall)(tid,
1610 VGP_UCONTEXT_INSTR_PTR(uc),
1611 VGP_UCONTEXT_SYSCALL_NUM(uc),
1612 VGP_UCONTEXT_SYSCALL_RET(uc),
njn695c16e2005-03-27 03:40:28 +00001613 !!(scss.scss_per_sig[sigNo].scss_flags & VKI_SA_RESTART));
sewardjb5f6f512005-03-10 23:59:00 +00001614
1615 /* Set up the thread's state to deliver a signal */
njn07ef6c02005-05-18 19:43:09 +00001616 if (!is_sig_ign(info->si_signo))
njn9ec0f3e2005-03-13 06:00:47 +00001617 deliver_signal(tid, info);
sewardjb5f6f512005-03-10 23:59:00 +00001618
1619 /* longjmp back to the thread's main loop to start executing the
1620 handler. */
1621 VG_(resume_scheduler)(tid);
1622
njn695c16e2005-03-27 03:40:28 +00001623 VG_(core_panic)("async_signalhandler: got unexpected signal while outside of scheduler");
jsgf855d93d2003-10-13 22:26:55 +00001624}
1625
sewardjb5f6f512005-03-10 23:59:00 +00001626/* Extend the stack to cover addr. maxsize is the limit the stack can grow to.
1627
1628 Returns True on success, False on failure.
1629
1630 Succeeds without doing anything if addr is already within a segment.
1631
1632 Failure could be caused by:
1633 - addr not below a growable segment
1634 - new stack size would exceed maxsize
1635 - mmap failed for some other reason
1636 */
1637Bool VG_(extend_stack)(Addr addr, UInt maxsize)
1638{
1639 Segment *seg;
1640 Addr base;
1641 UInt newsize;
1642
1643 /* Find the next Segment above addr */
1644 seg = VG_(find_segment)(addr);
1645 if (seg)
1646 return True;
1647
1648 /* now we know addr is definitely unmapped */
1649 seg = VG_(find_segment_above_unmapped)(addr);
1650
1651 /* If there isn't one, or it isn't growable, fail */
1652 if (seg == NULL ||
1653 !(seg->flags & SF_GROWDOWN) ||
1654 VG_(seg_contains)(seg, addr, sizeof(void *)))
1655 return False;
1656
1657 vg_assert(seg->addr > addr);
1658
1659 /* Create the mapping */
1660 base = PGROUNDDN(addr);
1661 newsize = seg->addr - base;
1662
1663 if (seg->len + newsize >= maxsize)
1664 return False;
1665
1666 if (VG_(mmap)((Char *)base, newsize,
1667 seg->prot,
1668 VKI_MAP_PRIVATE | VKI_MAP_FIXED | VKI_MAP_ANONYMOUS | VKI_MAP_CLIENT,
1669 seg->flags,
1670 -1, 0) == (void *)-1)
1671 return False;
1672
1673 if (0)
1674 VG_(printf)("extended stack: %p %d\n",
1675 base, newsize);
1676
1677 if (VG_(clo_sanity_level) > 2)
1678 VG_(sanity_check_general)(False);
1679
1680 return True;
1681}
1682
1683static void (*fault_catcher)(Int sig, Addr addr);
1684
1685void VG_(set_fault_catcher)(void (*catcher)(Int, Addr))
1686{
njn50ae1a72005-04-08 23:28:23 +00001687 vg_assert2(NULL == catcher || NULL == fault_catcher,
1688 "Fault catcher is already registered");
sewardjb5f6f512005-03-10 23:59:00 +00001689
1690 fault_catcher = catcher;
1691}
1692
1693
jsgf855d93d2003-10-13 22:26:55 +00001694/*
sewardj2a99cf62004-11-24 10:44:19 +00001695 Receive a sync signal from the host.
jsgf855d93d2003-10-13 22:26:55 +00001696*/
1697static
njn695c16e2005-03-27 03:40:28 +00001698void sync_signalhandler ( Int sigNo, vki_siginfo_t *info, struct vki_ucontext *uc )
jsgf855d93d2003-10-13 22:26:55 +00001699{
sewardjb5f6f512005-03-10 23:59:00 +00001700 ThreadId tid = VG_(get_lwp_tid)(VG_(gettid)());
jsgf855d93d2003-10-13 22:26:55 +00001701
1702 vg_assert(info != NULL);
1703 vg_assert(info->si_signo == sigNo);
1704 vg_assert(sigNo == VKI_SIGSEGV ||
1705 sigNo == VKI_SIGBUS ||
1706 sigNo == VKI_SIGFPE ||
sewardjb5f6f512005-03-10 23:59:00 +00001707 sigNo == VKI_SIGILL ||
1708 sigNo == VKI_SIGTRAP);
jsgf855d93d2003-10-13 22:26:55 +00001709
sewardjb5f6f512005-03-10 23:59:00 +00001710 if (info->si_code <= VKI_SI_USER) {
1711 /* If some user-process sent us one of these signals (ie,
1712 they're not the result of a faulting instruction), then treat
1713 it as an async signal. This is tricky because we could get
1714 this almost anywhere:
1715 - while generated client code
1716 Action: queue signal and return
1717 - while running Valgrind code
1718 Action: queue signal and return
1719 - while blocked in a syscall
1720 Action: make thread runnable, queue signal, resume scheduler
1721 */
1722 if (VG_(threads)[tid].status == VgTs_WaitSys) {
1723 /* Since this signal interrupted a syscall, it means the
1724 client's signal mask was applied, so we can't get here
1725 unless the client wants this signal right now. This means
1726 we can simply use the async_signalhandler. */
njn695c16e2005-03-27 03:40:28 +00001727 async_signalhandler(sigNo, info, uc);
1728 VG_(core_panic)("async_signalhandler returned!?\n");
sewardjb5f6f512005-03-10 23:59:00 +00001729 }
jsgf855d93d2003-10-13 22:26:55 +00001730
sewardjb5f6f512005-03-10 23:59:00 +00001731 if (info->_sifields._kill._pid == 0) {
1732 /* There's a per-user limit of pending siginfo signals. If
1733 you exceed this, by having more than that number of
1734 pending signals with siginfo, then new signals are
1735 delivered without siginfo. This condition can be caused
1736 by any unrelated program you're running at the same time
1737 as Valgrind, if it has a large number of pending siginfo
1738 signals which it isn't taking delivery of.
1739
1740 Since we depend on siginfo to work out why we were sent a
1741 signal and what we should do about it, we really can't
1742 continue unless we get it. */
1743 VG_(message)(Vg_UserMsg, "Signal %d (%s) appears to have lost its siginfo; I can't go on.",
1744 sigNo, signame(sigNo));
1745 VG_(message)(Vg_UserMsg, " This may be because one of your programs has consumed your");
1746 VG_(message)(Vg_UserMsg, " ration of siginfo structures.");
1747
1748 /* It's a fatal signal, so we force the default handler. */
1749 VG_(set_default_handler)(sigNo);
njn9ec0f3e2005-03-13 06:00:47 +00001750 deliver_signal(tid, info);
sewardjb5f6f512005-03-10 23:59:00 +00001751 VG_(resume_scheduler)(tid);
1752 VG_(exit)(99); /* If we can't resume, then just exit */
1753 }
1754
1755 if (VG_(clo_trace_signals))
1756 VG_(message)(Vg_DebugMsg, "Routing user-sent sync signal %d via queue",
1757 sigNo);
1758
1759 /* Since every thread has these signals unblocked, we can't rely
1760 on the kernel to route them properly, so we need to queue
1761 them manually. */
1762 if (info->si_code == VKI_SI_TKILL)
1763 queue_signal(tid, info); /* directed to us specifically */
1764 else
1765 queue_signal(0, info); /* shared pending */
1766
jsgf855d93d2003-10-13 22:26:55 +00001767 return;
sewardjb5f6f512005-03-10 23:59:00 +00001768 }
1769
1770 if (VG_(clo_trace_signals)) {
1771 VG_(message)(Vg_DebugMsg, "signal %d arrived ... si_code=%d, EIP=%p, eip=%p",
1772 sigNo, info->si_code,
1773 INSTR_PTR(VG_(threads)[tid].arch),
njnf6d228b2005-03-26 02:42:31 +00001774 VGP_UCONTEXT_INSTR_PTR(uc) );
jsgf855d93d2003-10-13 22:26:55 +00001775 }
sewardjb5f6f512005-03-10 23:59:00 +00001776 vg_assert(sigNo >= 1 && sigNo <= VG_(max_signal));
sewardjde4a1d02002-03-22 01:27:54 +00001777
fitzhardinge98abfc72003-12-16 02:05:15 +00001778 /* Special fault-handling case. We can now get signals which can
1779 act upon and immediately restart the faulting instruction.
1780 */
1781 if (info->si_signo == VKI_SIGSEGV) {
fitzhardinge98abfc72003-12-16 02:05:15 +00001782 Addr fault = (Addr)info->_sifields._sigfault._addr;
njncf45fd42004-11-24 16:30:22 +00001783 Addr esp = STACK_PTR(VG_(threads)[tid].arch);
sewardjb5f6f512005-03-10 23:59:00 +00001784 Segment* seg;
fitzhardinge98abfc72003-12-16 02:05:15 +00001785
1786 seg = VG_(find_segment)(fault);
sewardj548be6d2005-02-16 01:31:37 +00001787 if (seg == NULL)
1788 seg = VG_(find_segment_above_unmapped)(fault);
1789
fitzhardinge98abfc72003-12-16 02:05:15 +00001790 if (VG_(clo_trace_signals)) {
1791 if (seg == NULL)
1792 VG_(message)(Vg_DebugMsg,
sewardjb5f6f512005-03-10 23:59:00 +00001793 "SIGSEGV: si_code=%d faultaddr=%p tid=%d ESP=%p seg=NULL shad=%p-%p",
fitzhardinge98abfc72003-12-16 02:05:15 +00001794 info->si_code, fault, tid, esp,
1795 VG_(shadow_base), VG_(shadow_end));
1796 else
1797 VG_(message)(Vg_DebugMsg,
sewardjb5f6f512005-03-10 23:59:00 +00001798 "SIGSEGV: si_code=%d faultaddr=%p tid=%d ESP=%p seg=%p-%p fl=%x shad=%p-%p",
fitzhardinge98abfc72003-12-16 02:05:15 +00001799 info->si_code, fault, tid, esp, seg->addr, seg->addr+seg->len, seg->flags,
1800 VG_(shadow_base), VG_(shadow_end));
1801 }
sewardjb5f6f512005-03-10 23:59:00 +00001802 if (info->si_code == 1 /* SEGV_MAPERR */
njna60a7c12005-05-08 17:49:37 +00001803 && fault >= (esp - VGA_STACK_REDZONE_SZB)
njncafca7b2005-03-13 04:39:28 +00001804 && fault < VG_(client_end)) {
fitzhardinge98abfc72003-12-16 02:05:15 +00001805 /* If the fault address is above esp but below the current known
1806 stack segment base, and it was a fault because there was
1807 nothing mapped there (as opposed to a permissions fault),
1808 then extend the stack segment.
1809 */
njna60a7c12005-05-08 17:49:37 +00001810 Addr base = PGROUNDDN(esp - VGA_STACK_REDZONE_SZB);
njn50ba34e2005-04-04 02:41:42 +00001811 if (VG_(extend_stack)(base, VG_(threads)[tid].client_stack_szB)) {
sewardjb5f6f512005-03-10 23:59:00 +00001812 if (VG_(clo_trace_signals))
1813 VG_(message)(Vg_DebugMsg,
1814 " -> extended stack base to %p", PGROUNDDN(fault));
1815 return; // extension succeeded, restart instruction
1816 } else
1817 VG_(message)(Vg_UserMsg, "Stack overflow in thread %d: can't grow stack to %p",
1818 tid, fault);
1819
1820 /* Fall into normal signal handling for all other cases */
fitzhardinge98abfc72003-12-16 02:05:15 +00001821 } else if (info->si_code == 2 && /* SEGV_ACCERR */
1822 VG_(needs).shadow_memory &&
1823 VG_(is_shadow_addr)(fault)) {
1824 /* If there's a fault within the shadow memory range, and it
1825 is a permissions fault, then it means that the client is
1826 using some memory which had not previously been used.
1827 This catches those faults, makes the memory accessible,
nethercote7cc9c232004-01-21 15:08:04 +00001828 and calls the tool to initialize that page.
fitzhardinge98abfc72003-12-16 02:05:15 +00001829 */
1830 static Int recursion = 0;
1831
1832 if (recursion++ == 0) {
nethercote73b526f2004-10-31 18:48:21 +00001833 VG_(init_shadow_range)(PGROUNDDN(fault), VKI_PAGE_SIZE, True);
fitzhardinge98abfc72003-12-16 02:05:15 +00001834 recursion--;
1835 return;
1836 } else {
1837 /* otherwise fall into normal SEGV handling */
1838 recursion--;
1839 }
1840 }
1841 }
1842
sewardjb5f6f512005-03-10 23:59:00 +00001843 /* OK, this is a signal we really have to deal with. If it came
1844 from the client's code, then we can jump back into the scheduler
1845 and have it delivered. Otherwise it's a Valgrind bug. */
1846 {
njnd01fef72005-03-25 23:35:48 +00001847 Addr ips[ VG_(clo_backtrace_size) ];
sewardjb5f6f512005-03-10 23:59:00 +00001848 ThreadState *tst = VG_(get_ThreadState)(VG_(get_lwp_tid)(VG_(gettid)()));
jsgf855d93d2003-10-13 22:26:55 +00001849
sewardjb5f6f512005-03-10 23:59:00 +00001850 if (VG_(sigismember)(&tst->sig_mask, sigNo)) {
1851 /* signal is blocked, but they're not allowed to block faults */
1852 VG_(set_default_handler)(sigNo);
1853 }
1854
1855 if (!VG_(my_fault)) {
1856 /* Can't continue; must longjmp back to the scheduler and thus
1857 enter the sighandler immediately. */
njn9ec0f3e2005-03-13 06:00:47 +00001858 deliver_signal(tid, info);
sewardjb5f6f512005-03-10 23:59:00 +00001859 VG_(resume_scheduler)(tid);
1860 }
1861
1862 /* Check to see if someone is interested in faults. */
1863 if (fault_catcher) {
1864 (*fault_catcher)(sigNo, (Addr)info->_sifields._sigfault._addr);
1865
1866 /* If the catcher returns, then it didn't handle the fault,
1867 so carry on panicing. */
1868 }
1869
1870 /* If resume_scheduler returns or its our fault, it means we
1871 don't have longjmp set up, implying that we weren't running
1872 client code, and therefore it was actually generated by
1873 Valgrind internally.
1874 */
jsgf855d93d2003-10-13 22:26:55 +00001875 VG_(message)(Vg_DebugMsg,
1876 "INTERNAL ERROR: Valgrind received a signal %d (%s) - exiting",
1877 sigNo, signame(sigNo));
fitzhardinge98abfc72003-12-16 02:05:15 +00001878
jsgf855d93d2003-10-13 22:26:55 +00001879 VG_(message)(Vg_DebugMsg,
njnd0073f42005-05-14 17:00:25 +00001880 "si_code=%x; Faulting address: %p; sp: %p",
1881 info->si_code, info->_sifields._sigfault._addr,
1882 VGP_UCONTEXT_STACK_PTR(uc));
jsgf855d93d2003-10-13 22:26:55 +00001883
1884 if (0)
1885 VG_(kill_self)(sigNo); /* generate a core dump */
sewardjb5f6f512005-03-10 23:59:00 +00001886
njncafca7b2005-03-13 04:39:28 +00001887 if (tid == 0) /* could happen after everyone has exited */
1888 tid = VG_(master_tid);
1889 tst = VG_(get_ThreadState)(tid);
njnd01fef72005-03-25 23:35:48 +00001890 VG_(get_StackTrace2)(ips, VG_(clo_backtrace_size),
njnf6d228b2005-03-26 02:42:31 +00001891 VGP_UCONTEXT_INSTR_PTR(uc),
sewardj35165532005-04-30 18:47:48 +00001892 VGP_UCONTEXT_STACK_PTR(uc),
njnf6d228b2005-03-26 02:42:31 +00001893 VGP_UCONTEXT_FRAME_PTR(uc),
1894 VGP_UCONTEXT_STACK_PTR(uc),
njn990e90c2005-04-05 02:49:09 +00001895 tst->os_state.valgrind_stack_base +
1896 tst->os_state.valgrind_stack_szB);
njnd01fef72005-03-25 23:35:48 +00001897 VG_(core_panic_at)("Killed by fatal signal", ips);
jsgf855d93d2003-10-13 22:26:55 +00001898 }
1899}
1900
1901
1902/*
sewardjb5f6f512005-03-10 23:59:00 +00001903 Kill this thread. Makes it leave any syscall it might be currently
1904 blocked in, and return to the scheduler. This doesn't mark the thread
1905 as exiting; that's the caller's job.
jsgf855d93d2003-10-13 22:26:55 +00001906 */
sewardjb5f6f512005-03-10 23:59:00 +00001907static void sigvgkill_handler(int signo, vki_siginfo_t *si, struct vki_ucontext *uc)
jsgf855d93d2003-10-13 22:26:55 +00001908{
sewardjb5f6f512005-03-10 23:59:00 +00001909 ThreadId tid = VG_(get_lwp_tid)(VG_(gettid)());
1910
1911 if (VG_(clo_trace_signals))
1912 VG_(message)(Vg_DebugMsg, "sigvgkill for lwp %d tid %d", VG_(gettid)(), tid);
1913
1914 vg_assert(signo == VKI_SIGVGKILL);
jsgf855d93d2003-10-13 22:26:55 +00001915 vg_assert(si->si_signo == signo);
sewardjb5f6f512005-03-10 23:59:00 +00001916 vg_assert(VG_(threads)[tid].status == VgTs_WaitSys);
jsgf855d93d2003-10-13 22:26:55 +00001917
sewardjb5f6f512005-03-10 23:59:00 +00001918 VG_(set_running)(tid);
1919 VG_(post_syscall)(tid);
1920
1921 VG_(resume_scheduler)(tid);
1922
1923 VG_(core_panic)("sigvgkill_handler couldn't return to the scheduler\n");
sewardjde4a1d02002-03-22 01:27:54 +00001924}
1925
sewardjde4a1d02002-03-22 01:27:54 +00001926static __attribute((unused))
njn695c16e2005-03-27 03:40:28 +00001927void pp_ksigaction ( struct vki_sigaction* sa )
sewardjde4a1d02002-03-22 01:27:54 +00001928{
1929 Int i;
njn695c16e2005-03-27 03:40:28 +00001930 VG_(printf)("pp_ksigaction: handler %p, flags 0x%x, restorer %p\n",
nethercote73b526f2004-10-31 18:48:21 +00001931 sa->ksa_handler, (UInt)sa->sa_flags, sa->sa_restorer);
njn695c16e2005-03-27 03:40:28 +00001932 VG_(printf)("pp_ksigaction: { ");
sewardjb5f6f512005-03-10 23:59:00 +00001933 for (i = 1; i <= VG_(max_signal); i++)
nethercote73b526f2004-10-31 18:48:21 +00001934 if (VG_(sigismember(&(sa->sa_mask),i)))
sewardjde4a1d02002-03-22 01:27:54 +00001935 VG_(printf)("%d ", i);
1936 VG_(printf)("}\n");
1937}
1938
jsgf855d93d2003-10-13 22:26:55 +00001939/*
sewardjb5f6f512005-03-10 23:59:00 +00001940 Force signal handler to default
jsgf855d93d2003-10-13 22:26:55 +00001941 */
sewardjb5f6f512005-03-10 23:59:00 +00001942void VG_(set_default_handler)(Int signo)
1943{
1944 struct vki_sigaction sa;
1945
1946 sa.ksa_handler = VKI_SIG_DFL;
1947 sa.sa_flags = 0;
1948 sa.sa_restorer = 0;
1949 VG_(sigemptyset)(&sa.sa_mask);
1950
1951 VG_(do_sys_sigaction)(signo, &sa, NULL);
1952}
1953
1954/*
1955 Poll for pending signals, and set the next one up for delivery.
1956 */
1957void VG_(poll_signals)(ThreadId tid)
jsgf855d93d2003-10-13 22:26:55 +00001958{
1959 static const struct vki_timespec zero = { 0, 0 };
sewardjb5f6f512005-03-10 23:59:00 +00001960 vki_siginfo_t si, *sip;
1961 vki_sigset_t pollset;
1962 ThreadState *tst = VG_(get_ThreadState)(tid);
1963 Int i;
1964 vki_sigset_t saved_mask;
jsgf855d93d2003-10-13 22:26:55 +00001965
sewardjb5f6f512005-03-10 23:59:00 +00001966 /* look for all the signals this thread isn't blocking */
1967 for(i = 0; i < _VKI_NSIG_WORDS; i++)
1968 pollset.sig[i] = ~tst->sig_mask.sig[i];
jsgf855d93d2003-10-13 22:26:55 +00001969
sewardjb5f6f512005-03-10 23:59:00 +00001970 VG_(sigdelset)(&pollset, VKI_SIGVGCHLD); /* already dealt with */
jsgf855d93d2003-10-13 22:26:55 +00001971
sewardjb5f6f512005-03-10 23:59:00 +00001972 //VG_(printf)("tid %d pollset=%08x%08x\n", tid, pollset.sig[1], pollset.sig[0]);
jsgf855d93d2003-10-13 22:26:55 +00001973
njn444eba12005-05-12 03:47:31 +00001974 block_all_host_signals(&saved_mask); // protect signal queue
sewardjb5f6f512005-03-10 23:59:00 +00001975
1976 /* First look for any queued pending signals */
1977 sip = next_queued(tid, &pollset); /* this thread */
1978
1979 if (sip == NULL)
1980 sip = next_queued(0, &pollset); /* process-wide */
1981
1982 /* If there was nothing queued, ask the kernel for a pending signal */
1983 if (sip == NULL && VG_(sigtimedwait)(&pollset, &si, &zero) > 0) {
1984 if (VG_(clo_trace_signals))
1985 VG_(message)(Vg_DebugMsg, "poll_signals: got signal %d for thread %d", si.si_signo, tid);
1986 sip = &si;
thughes8abf3922004-10-16 10:59:49 +00001987 }
fitzhardingee1c06d82003-10-30 07:21:44 +00001988
sewardjb5f6f512005-03-10 23:59:00 +00001989 if (sip != NULL) {
1990 /* OK, something to do; deliver it */
1991 if (VG_(clo_trace_signals))
1992 VG_(message)(Vg_DebugMsg, "Polling found signal %d for tid %d",
1993 sip->si_signo, tid);
njn07ef6c02005-05-18 19:43:09 +00001994 if (!is_sig_ign(sip->si_signo))
njn9ec0f3e2005-03-13 06:00:47 +00001995 deliver_signal(tid, sip);
sewardjb5f6f512005-03-10 23:59:00 +00001996 else if (VG_(clo_trace_signals))
1997 VG_(message)(Vg_DebugMsg, " signal %d ignored", sip->si_signo);
1998
1999 sip->si_signo = 0; /* remove from signal queue, if that's
2000 where it came from */
jsgf855d93d2003-10-13 22:26:55 +00002001 }
2002
njn444eba12005-05-12 03:47:31 +00002003 restore_all_host_signals(&saved_mask);
sewardjb5f6f512005-03-10 23:59:00 +00002004}
2005
sewardj018f7622002-05-15 21:13:39 +00002006/* At startup, copy the process' real signal state to the SCSS.
2007 Whilst doing this, block all real signals. Then calculate SKSS and
2008 set the kernel to that. Also initialise DCSS.
sewardjde4a1d02002-03-22 01:27:54 +00002009*/
2010void VG_(sigstartup_actions) ( void )
2011{
2012 Int i, ret;
nethercote73b526f2004-10-31 18:48:21 +00002013 vki_sigset_t saved_procmask;
nethercote73b526f2004-10-31 18:48:21 +00002014 struct vki_sigaction sa;
sewardjde4a1d02002-03-22 01:27:54 +00002015
sewardj2e93c502002-04-12 11:12:52 +00002016 /* VG_(printf)("SIGSTARTUP\n"); */
jsgf855d93d2003-10-13 22:26:55 +00002017 /* Block all signals. saved_procmask remembers the previous mask,
2018 which the first thread inherits.
2019 */
njn444eba12005-05-12 03:47:31 +00002020 block_all_host_signals( &saved_procmask );
sewardjde4a1d02002-03-22 01:27:54 +00002021
sewardj018f7622002-05-15 21:13:39 +00002022 /* Copy per-signal settings to SCSS. */
nethercote73b526f2004-10-31 18:48:21 +00002023 for (i = 1; i <= _VKI_NSIG; i++) {
sewardj018f7622002-05-15 21:13:39 +00002024 /* Get the old host action */
nethercote73b526f2004-10-31 18:48:21 +00002025 ret = VG_(sigaction)(i, NULL, &sa);
sewardj018f7622002-05-15 21:13:39 +00002026
sewardjb5f6f512005-03-10 23:59:00 +00002027 if (ret != 0)
2028 break;
2029
2030 /* Try setting it back to see if this signal is really
2031 available */
2032 if (i >= VKI_SIGRTMIN) {
2033 struct vki_sigaction tsa;
2034
njn695c16e2005-03-27 03:40:28 +00002035 tsa.ksa_handler = (void *)sync_signalhandler;
sewardjb5f6f512005-03-10 23:59:00 +00002036 tsa.sa_flags = VKI_SA_SIGINFO;
2037 tsa.sa_restorer = 0;
2038 VG_(sigfillset)(&tsa.sa_mask);
2039
2040 /* try setting it to some arbitrary handler */
2041 if (VG_(sigaction)(i, &tsa, NULL) != 0) {
2042 /* failed - not really usable */
2043 break;
2044 }
2045
2046 ret = VG_(sigaction)(i, &sa, NULL);
2047 vg_assert(ret == 0);
2048 }
2049
2050 VG_(max_signal) = i;
2051
2052 if (VG_(clo_trace_signals) && VG_(clo_verbosity) > 2)
sewardj018f7622002-05-15 21:13:39 +00002053 VG_(printf)("snaffling handler 0x%x for signal %d\n",
2054 (Addr)(sa.ksa_handler), i );
2055
njn695c16e2005-03-27 03:40:28 +00002056 scss.scss_per_sig[i].scss_handler = sa.ksa_handler;
2057 scss.scss_per_sig[i].scss_flags = sa.sa_flags;
2058 scss.scss_per_sig[i].scss_mask = sa.sa_mask;
2059 scss.scss_per_sig[i].scss_restorer = sa.sa_restorer;
sewardj018f7622002-05-15 21:13:39 +00002060 }
2061
sewardjb5f6f512005-03-10 23:59:00 +00002062 if (VG_(clo_trace_signals))
2063 VG_(message)(Vg_DebugMsg, "Max kernel-supported signal is %d", VG_(max_signal));
2064
jsgf855d93d2003-10-13 22:26:55 +00002065 /* Our private internal signals are treated as ignored */
njn695c16e2005-03-27 03:40:28 +00002066 scss.scss_per_sig[VKI_SIGVGCHLD].scss_handler = VKI_SIG_IGN;
2067 scss.scss_per_sig[VKI_SIGVGCHLD].scss_flags = VKI_SA_SIGINFO;
2068 VG_(sigfillset)(&scss.scss_per_sig[VKI_SIGVGCHLD].scss_mask);
sewardjb5f6f512005-03-10 23:59:00 +00002069
njn695c16e2005-03-27 03:40:28 +00002070 scss.scss_per_sig[VKI_SIGVGKILL].scss_handler = VKI_SIG_IGN;
2071 scss.scss_per_sig[VKI_SIGVGKILL].scss_flags = VKI_SA_SIGINFO;
2072 VG_(sigfillset)(&scss.scss_per_sig[VKI_SIGVGKILL].scss_mask);
jsgf855d93d2003-10-13 22:26:55 +00002073
sewardj018f7622002-05-15 21:13:39 +00002074 /* Copy the process' signal mask into the root thread. */
sewardjb5f6f512005-03-10 23:59:00 +00002075 vg_assert(VG_(threads)[VG_(master_tid)].status == VgTs_Init);
2076 VG_(threads)[VG_(master_tid)].sig_mask = saved_procmask;
2077 VG_(threads)[VG_(master_tid)].tmp_sig_mask = saved_procmask;
sewardj7a61d912002-04-25 01:27:35 +00002078
sewardj018f7622002-05-15 21:13:39 +00002079 /* Calculate SKSS and apply it. This also sets the initial kernel
2080 mask we need to run with. */
nethercote9dd11512004-08-04 15:31:30 +00002081 handle_SCSS_change( True /* forced update */ );
jsgf855d93d2003-10-13 22:26:55 +00002082
sewardjb5f6f512005-03-10 23:59:00 +00002083 /* Leave with all signals still blocked; the thread scheduler loop
2084 will set the appropriate mask at the appropriate time. */
sewardjde4a1d02002-03-22 01:27:54 +00002085}
2086
sewardjde4a1d02002-03-22 01:27:54 +00002087/*--------------------------------------------------------------------*/
2088/*--- end vg_signals.c ---*/
2089/*--------------------------------------------------------------------*/