blob: 326de2470a073f271514c4f929f357158bf65a33 [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;
sewardjb5f6f512005-03-10 23:59:00 +0000306 else {
307 if (scss_handler == VKI_SIG_IGN)
308 skss_handler = VKI_SIG_IGN;
309 else
njn695c16e2005-03-27 03:40:28 +0000310 skss_handler = async_signalhandler;
sewardjb5f6f512005-03-10 23:59:00 +0000311 }
312 break;
313 }
sewardj018f7622002-05-15 21:13:39 +0000314
sewardj018f7622002-05-15 21:13:39 +0000315 /* Flags */
316
317 skss_flags = 0;
jsgf855d93d2003-10-13 22:26:55 +0000318
sewardjb5f6f512005-03-10 23:59:00 +0000319 /* SA_NOCLDSTOP, SA_NOCLDWAIT: pass to kernel */
320 skss_flags |= scss_flags & (VKI_SA_NOCLDSTOP | VKI_SA_NOCLDWAIT);
jsgf855d93d2003-10-13 22:26:55 +0000321
sewardj018f7622002-05-15 21:13:39 +0000322 /* SA_ONESHOT: ignore client setting */
sewardjb5f6f512005-03-10 23:59:00 +0000323
jsgf855d93d2003-10-13 22:26:55 +0000324 /* SA_RESTART: ignore client setting and always set it for us
325 (even though we never rely on the kernel to restart a
326 syscall, we observe whether it wanted to restart the syscall
sewardjb5f6f512005-03-10 23:59:00 +0000327 or not, which helps VGA_(interrupted_syscall)()) */
sewardj018f7622002-05-15 21:13:39 +0000328 skss_flags |= VKI_SA_RESTART;
jsgf855d93d2003-10-13 22:26:55 +0000329
330 /* SA_NOMASK: ignore it */
331
sewardj2342c972002-05-22 23:34:20 +0000332 /* SA_ONSTACK: client setting is irrelevant here */
sewardjb5f6f512005-03-10 23:59:00 +0000333 /* We don't set a signal stack, so ignore */
sewardj018f7622002-05-15 21:13:39 +0000334
jsgf855d93d2003-10-13 22:26:55 +0000335 /* always ask for SA_SIGINFO */
336 skss_flags |= VKI_SA_SIGINFO;
sewardj018f7622002-05-15 21:13:39 +0000337
fitzhardinge4f10ada2004-06-03 10:00:42 +0000338 /* use our own restorer */
339 skss_flags |= VKI_SA_RESTORER;
340
jsgf855d93d2003-10-13 22:26:55 +0000341 /* Create SKSS entry for this signal. */
sewardj6a3c26e2002-05-23 17:09:43 +0000342 if (sig != VKI_SIGKILL && sig != VKI_SIGSTOP)
343 dst->skss_per_sig[sig].skss_handler = skss_handler;
344 else
345 dst->skss_per_sig[sig].skss_handler = VKI_SIG_DFL;
346
sewardj018f7622002-05-15 21:13:39 +0000347 dst->skss_per_sig[sig].skss_flags = skss_flags;
348 }
349
350 /* Sanity checks. */
nethercote5fd72bb2004-11-04 19:28:38 +0000351 vg_assert(dst->skss_per_sig[VKI_SIGKILL].skss_handler == VKI_SIG_DFL);
352 vg_assert(dst->skss_per_sig[VKI_SIGSTOP].skss_handler == VKI_SIG_DFL);
sewardj018f7622002-05-15 21:13:39 +0000353
354 if (0)
355 pp_SKSS();
356}
357
358
359/* ---------------------------------------------------------------------
360 After a possible SCSS change, update SKSS and the kernel itself.
361 ------------------------------------------------------------------ */
362
nethercote9dd11512004-08-04 15:31:30 +0000363static void handle_SCSS_change ( Bool force_update )
sewardj018f7622002-05-15 21:13:39 +0000364{
nethercote73b526f2004-10-31 18:48:21 +0000365 Int res, sig;
366 SKSS skss_old;
367 struct vki_sigaction ksa, ksa_old;
sewardj018f7622002-05-15 21:13:39 +0000368
sewardj018f7622002-05-15 21:13:39 +0000369 /* Remember old SKSS and calculate new one. */
njn695c16e2005-03-27 03:40:28 +0000370 skss_old = skss;
371 calculate_SKSS_from_SCSS ( &skss );
sewardj018f7622002-05-15 21:13:39 +0000372
373 /* Compare the new SKSS entries vs the old ones, and update kernel
374 where they differ. */
sewardjb5f6f512005-03-10 23:59:00 +0000375 for (sig = 1; sig <= VG_(max_signal); sig++) {
sewardj018f7622002-05-15 21:13:39 +0000376
377 /* Trying to do anything with SIGKILL is pointless; just ignore
378 it. */
379 if (sig == VKI_SIGKILL || sig == VKI_SIGSTOP)
380 continue;
381
sewardj018f7622002-05-15 21:13:39 +0000382 if (!force_update) {
383 if ((skss_old.skss_per_sig[sig].skss_handler
njn695c16e2005-03-27 03:40:28 +0000384 == skss.skss_per_sig[sig].skss_handler)
sewardj018f7622002-05-15 21:13:39 +0000385 && (skss_old.skss_per_sig[sig].skss_flags
njn695c16e2005-03-27 03:40:28 +0000386 == skss.skss_per_sig[sig].skss_flags))
sewardj018f7622002-05-15 21:13:39 +0000387 /* no difference */
388 continue;
389 }
390
njn695c16e2005-03-27 03:40:28 +0000391 ksa.ksa_handler = skss.skss_per_sig[sig].skss_handler;
392 ksa.sa_flags = skss.skss_per_sig[sig].skss_flags;
nethercote73b526f2004-10-31 18:48:21 +0000393 ksa.sa_restorer = VG_(sigreturn);
fitzhardinge4f10ada2004-06-03 10:00:42 +0000394
sewardjb5f6f512005-03-10 23:59:00 +0000395 /* block all signals in handler */
nethercote73b526f2004-10-31 18:48:21 +0000396 VG_(sigfillset)( &ksa.sa_mask );
397 VG_(sigdelset)( &ksa.sa_mask, VKI_SIGKILL );
398 VG_(sigdelset)( &ksa.sa_mask, VKI_SIGSTOP );
sewardj018f7622002-05-15 21:13:39 +0000399
sewardjb5f6f512005-03-10 23:59:00 +0000400 if (VG_(clo_trace_signals) && VG_(clo_verbosity) > 2)
sewardj018f7622002-05-15 21:13:39 +0000401 VG_(message)(Vg_DebugMsg,
402 "setting ksig %d to: hdlr 0x%x, flags 0x%x, "
403 "mask(63..0) 0x%x 0x%x",
404 sig, ksa.ksa_handler,
nethercote73b526f2004-10-31 18:48:21 +0000405 ksa.sa_flags,
406 ksa.sa_mask.sig[1],
407 ksa.sa_mask.sig[0]
sewardj018f7622002-05-15 21:13:39 +0000408 );
409
nethercote73b526f2004-10-31 18:48:21 +0000410 res = VG_(sigaction)( sig, &ksa, &ksa_old );
sewardj018f7622002-05-15 21:13:39 +0000411 vg_assert(res == 0);
412
413 /* Since we got the old sigaction more or less for free, might
414 as well extract the maximum sanity-check value from it. */
415 if (!force_update) {
416 vg_assert(ksa_old.ksa_handler
417 == skss_old.skss_per_sig[sig].skss_handler);
nethercote73b526f2004-10-31 18:48:21 +0000418 vg_assert(ksa_old.sa_flags
sewardj018f7622002-05-15 21:13:39 +0000419 == skss_old.skss_per_sig[sig].skss_flags);
nethercote73b526f2004-10-31 18:48:21 +0000420 vg_assert(ksa_old.sa_restorer
fitzhardingedc4d4f42004-06-03 17:12:07 +0000421 == VG_(sigreturn));
nethercote73b526f2004-10-31 18:48:21 +0000422 VG_(sigaddset)( &ksa_old.sa_mask, VKI_SIGKILL );
423 VG_(sigaddset)( &ksa_old.sa_mask, VKI_SIGSTOP );
424 vg_assert(VG_(isfullsigset)( &ksa_old.sa_mask ));
sewardj018f7622002-05-15 21:13:39 +0000425 }
426 }
sewardj018f7622002-05-15 21:13:39 +0000427}
428
429
430/* ---------------------------------------------------------------------
431 Update/query SCSS in accordance with client requests.
432 ------------------------------------------------------------------ */
433
sewardj2342c972002-05-22 23:34:20 +0000434/* Logic for this alt-stack stuff copied directly from do_sigaltstack
435 in kernel/signal.[ch] */
436
437/* True if we are on the alternate signal stack. */
sewardjb5f6f512005-03-10 23:59:00 +0000438static Bool on_sig_stack ( ThreadId tid, Addr m_SP )
sewardj2342c972002-05-22 23:34:20 +0000439{
fitzhardinge98c4dc02004-03-16 08:27:29 +0000440 ThreadState *tst = VG_(get_ThreadState)(tid);
441
nethercote511e4062004-09-11 13:34:08 +0000442 return (m_SP - (Addr)tst->altstack.ss_sp < tst->altstack.ss_size);
sewardj2342c972002-05-22 23:34:20 +0000443}
444
nethercote511e4062004-09-11 13:34:08 +0000445static Int sas_ss_flags ( ThreadId tid, Addr m_SP )
sewardj2342c972002-05-22 23:34:20 +0000446{
fitzhardinge98c4dc02004-03-16 08:27:29 +0000447 ThreadState *tst = VG_(get_ThreadState)(tid);
448
449 return (tst->altstack.ss_size == 0
sewardj2342c972002-05-22 23:34:20 +0000450 ? VKI_SS_DISABLE
nethercote511e4062004-09-11 13:34:08 +0000451 : on_sig_stack(tid, m_SP) ? VKI_SS_ONSTACK : 0);
sewardj2342c972002-05-22 23:34:20 +0000452}
453
454
njn502badb2005-05-08 02:04:49 +0000455Int VG_(do_sys_sigaltstack) ( ThreadId tid, vki_stack_t* ss, vki_stack_t* oss )
sewardj2342c972002-05-22 23:34:20 +0000456{
njn502badb2005-05-08 02:04:49 +0000457 Addr m_SP;
sewardj2342c972002-05-22 23:34:20 +0000458
459 vg_assert(VG_(is_valid_tid)(tid));
njncf45fd42004-11-24 16:30:22 +0000460 m_SP = STACK_PTR(VG_(threads)[tid].arch);
sewardj2342c972002-05-22 23:34:20 +0000461
462 if (VG_(clo_trace_signals))
463 VG_(message)(Vg_DebugExtraMsg,
nethercote04d3a802004-11-16 18:26:11 +0000464 "sys_sigaltstack: tid %d, "
nethercote511e4062004-09-11 13:34:08 +0000465 "ss %p, oss %p (current SP %p)",
466 tid, (void*)ss, (void*)oss, (void*)m_SP );
sewardj2342c972002-05-22 23:34:20 +0000467
468 if (oss != NULL) {
fitzhardinge98c4dc02004-03-16 08:27:29 +0000469 oss->ss_sp = VG_(threads)[tid].altstack.ss_sp;
470 oss->ss_size = VG_(threads)[tid].altstack.ss_size;
nethercote511e4062004-09-11 13:34:08 +0000471 oss->ss_flags = VG_(threads)[tid].altstack.ss_flags | sas_ss_flags(tid, m_SP);
sewardj2342c972002-05-22 23:34:20 +0000472 }
473
474 if (ss != NULL) {
njncf45fd42004-11-24 16:30:22 +0000475 if (on_sig_stack(tid, STACK_PTR(VG_(threads)[tid].arch))) {
njn4fbc86c2005-05-08 00:45:11 +0000476 return -VKI_EPERM;
sewardj2342c972002-05-22 23:34:20 +0000477 }
478 if (ss->ss_flags != VKI_SS_DISABLE
479 && ss->ss_flags != VKI_SS_ONSTACK
480 && ss->ss_flags != 0) {
njn4fbc86c2005-05-08 00:45:11 +0000481 return -VKI_EINVAL;
sewardj2342c972002-05-22 23:34:20 +0000482 }
483 if (ss->ss_flags == VKI_SS_DISABLE) {
fitzhardinge98c4dc02004-03-16 08:27:29 +0000484 VG_(threads)[tid].altstack.ss_flags = VKI_SS_DISABLE;
sewardj2342c972002-05-22 23:34:20 +0000485 } else {
486 if (ss->ss_size < VKI_MINSIGSTKSZ) {
njn4fbc86c2005-05-08 00:45:11 +0000487 return -VKI_ENOMEM;
sewardj2342c972002-05-22 23:34:20 +0000488 }
jsgf855d93d2003-10-13 22:26:55 +0000489
nethercote20283c62004-11-04 19:43:22 +0000490 VG_(threads)[tid].altstack.ss_sp = ss->ss_sp;
491 VG_(threads)[tid].altstack.ss_size = ss->ss_size;
fitzhardinge98c4dc02004-03-16 08:27:29 +0000492 VG_(threads)[tid].altstack.ss_flags = 0;
sewardj2342c972002-05-22 23:34:20 +0000493 }
sewardj2342c972002-05-22 23:34:20 +0000494 }
njn4fbc86c2005-05-08 00:45:11 +0000495 return 0;
sewardj2342c972002-05-22 23:34:20 +0000496}
497
498
sewardjb5f6f512005-03-10 23:59:00 +0000499Int VG_(do_sys_sigaction) ( Int signo,
500 const struct vki_sigaction *new_act,
501 struct vki_sigaction *old_act )
sewardj018f7622002-05-15 21:13:39 +0000502{
sewardj018f7622002-05-15 21:13:39 +0000503 if (VG_(clo_trace_signals))
504 VG_(message)(Vg_DebugExtraMsg,
sewardjb5f6f512005-03-10 23:59:00 +0000505 "sys_sigaction: sigNo %d, "
nethercote93246cf2004-11-04 18:56:47 +0000506 "new %p, old %p, new flags 0x%llx",
sewardjb5f6f512005-03-10 23:59:00 +0000507 signo, (UWord)new_act, (UWord)old_act,
nethercote93246cf2004-11-04 18:56:47 +0000508 (ULong)(new_act ? new_act->sa_flags : 0) );
sewardj018f7622002-05-15 21:13:39 +0000509
510 /* Rule out various error conditions. The aim is to ensure that if
511 when the call is passed to the kernel it will definitely
512 succeed. */
513
514 /* Reject out-of-range signal numbers. */
sewardjb5f6f512005-03-10 23:59:00 +0000515 if (signo < 1 || signo > VG_(max_signal)) goto bad_signo;
sewardj018f7622002-05-15 21:13:39 +0000516
jsgf855d93d2003-10-13 22:26:55 +0000517 /* don't let them use our signals */
sewardjb5f6f512005-03-10 23:59:00 +0000518 if ( (signo > VKI_SIGVGRTUSERMAX)
jsgf855d93d2003-10-13 22:26:55 +0000519 && new_act
520 && !(new_act->ksa_handler == VKI_SIG_DFL || new_act->ksa_handler == VKI_SIG_IGN) )
nethercote9c42a0f2003-11-17 10:37:19 +0000521 goto bad_signo_reserved;
jsgf855d93d2003-10-13 22:26:55 +0000522
sewardj018f7622002-05-15 21:13:39 +0000523 /* Reject attempts to set a handler (or set ignore) for SIGKILL. */
524 if ( (signo == VKI_SIGKILL || signo == VKI_SIGSTOP)
525 && new_act
526 && new_act->ksa_handler != VKI_SIG_DFL)
527 goto bad_sigkill_or_sigstop;
528
529 /* If the client supplied non-NULL old_act, copy the relevant SCSS
530 entry into it. */
531 if (old_act) {
njn695c16e2005-03-27 03:40:28 +0000532 old_act->ksa_handler = scss.scss_per_sig[signo].scss_handler;
533 old_act->sa_flags = scss.scss_per_sig[signo].scss_flags;
534 old_act->sa_mask = scss.scss_per_sig[signo].scss_mask;
535 old_act->sa_restorer = scss.scss_per_sig[signo].scss_restorer;
sewardj018f7622002-05-15 21:13:39 +0000536 }
537
538 /* And now copy new SCSS entry from new_act. */
539 if (new_act) {
njn695c16e2005-03-27 03:40:28 +0000540 scss.scss_per_sig[signo].scss_handler = new_act->ksa_handler;
541 scss.scss_per_sig[signo].scss_flags = new_act->sa_flags;
542 scss.scss_per_sig[signo].scss_mask = new_act->sa_mask;
543 scss.scss_per_sig[signo].scss_restorer = new_act->sa_restorer;
sewardjb5f6f512005-03-10 23:59:00 +0000544
njn695c16e2005-03-27 03:40:28 +0000545 VG_(sigdelset)(&scss.scss_per_sig[signo].scss_mask, VKI_SIGKILL);
546 VG_(sigdelset)(&scss.scss_per_sig[signo].scss_mask, VKI_SIGSTOP);
sewardj018f7622002-05-15 21:13:39 +0000547 }
548
549 /* All happy bunnies ... */
550 if (new_act) {
nethercote9dd11512004-08-04 15:31:30 +0000551 handle_SCSS_change( False /* lazy update */ );
sewardj018f7622002-05-15 21:13:39 +0000552 }
sewardjb5f6f512005-03-10 23:59:00 +0000553 return 0;
sewardj018f7622002-05-15 21:13:39 +0000554
555 bad_signo:
sewardj9a3d8bd2005-05-23 14:47:52 +0000556 if (VG_(needs).core_errors && VG_(clo_verbosity) >= 1
557 && !VG_(clo_xml)) {
njn25e49d8e72002-09-23 09:36:25 +0000558 VG_(message)(Vg_UserMsg,
nethercote9c42a0f2003-11-17 10:37:19 +0000559 "Warning: bad signal number %d in sigaction()",
njn25e49d8e72002-09-23 09:36:25 +0000560 signo);
sewardj9a3d8bd2005-05-23 14:47:52 +0000561 }
sewardjb5f6f512005-03-10 23:59:00 +0000562 return -VKI_EINVAL;
sewardj018f7622002-05-15 21:13:39 +0000563
nethercote9c42a0f2003-11-17 10:37:19 +0000564 bad_signo_reserved:
sewardj9a3d8bd2005-05-23 14:47:52 +0000565 if (VG_(needs).core_errors && VG_(clo_verbosity) >= 1
566 && !VG_(clo_xml)) {
nethercote9c42a0f2003-11-17 10:37:19 +0000567 VG_(message)(Vg_UserMsg,
568 "Warning: ignored attempt to set %s handler in sigaction();",
569 signame(signo));
570 VG_(message)(Vg_UserMsg,
571 " the %s signal is used internally by Valgrind",
572 signame(signo));
fitzhardingebf459872003-11-18 16:55:33 +0000573 }
sewardjb5f6f512005-03-10 23:59:00 +0000574 return -VKI_EINVAL;
nethercote9c42a0f2003-11-17 10:37:19 +0000575
sewardj018f7622002-05-15 21:13:39 +0000576 bad_sigkill_or_sigstop:
sewardj9a3d8bd2005-05-23 14:47:52 +0000577 if (VG_(needs).core_errors && VG_(clo_verbosity) >= 1
578 && !VG_(clo_xml)) {
njn25e49d8e72002-09-23 09:36:25 +0000579 VG_(message)(Vg_UserMsg,
nethercote9c42a0f2003-11-17 10:37:19 +0000580 "Warning: ignored attempt to set %s handler in sigaction();",
jsgf855d93d2003-10-13 22:26:55 +0000581 signame(signo));
nethercote9c42a0f2003-11-17 10:37:19 +0000582 VG_(message)(Vg_UserMsg,
583 " the %s signal is uncatchable",
584 signame(signo));
sewardj9a3d8bd2005-05-23 14:47:52 +0000585 }
sewardjb5f6f512005-03-10 23:59:00 +0000586 return -VKI_EINVAL;
sewardj018f7622002-05-15 21:13:39 +0000587}
588
589
590static
591void do_sigprocmask_bitops ( Int vki_how,
nethercote73b526f2004-10-31 18:48:21 +0000592 vki_sigset_t* orig_set,
593 vki_sigset_t* modifier )
sewardj018f7622002-05-15 21:13:39 +0000594{
595 switch (vki_how) {
596 case VKI_SIG_BLOCK:
nethercote73b526f2004-10-31 18:48:21 +0000597 VG_(sigaddset_from_set)( orig_set, modifier );
sewardj018f7622002-05-15 21:13:39 +0000598 break;
599 case VKI_SIG_UNBLOCK:
nethercote73b526f2004-10-31 18:48:21 +0000600 VG_(sigdelset_from_set)( orig_set, modifier );
sewardj018f7622002-05-15 21:13:39 +0000601 break;
602 case VKI_SIG_SETMASK:
603 *orig_set = *modifier;
604 break;
605 default:
njne427a662002-10-02 11:08:25 +0000606 VG_(core_panic)("do_sigprocmask_bitops");
sewardj018f7622002-05-15 21:13:39 +0000607 break;
608 }
609}
610
jsgf855d93d2003-10-13 22:26:55 +0000611/*
612 This updates the thread's signal mask. There's no such thing as a
613 process-wide signal mask.
sewardj018f7622002-05-15 21:13:39 +0000614
615 Note that the thread signal masks are an implicit part of SCSS,
616 which is why this routine is allowed to mess with them.
617*/
618static
619void do_setmask ( ThreadId tid,
620 Int how,
nethercote73b526f2004-10-31 18:48:21 +0000621 vki_sigset_t* newset,
622 vki_sigset_t* oldset )
sewardj018f7622002-05-15 21:13:39 +0000623{
sewardj018f7622002-05-15 21:13:39 +0000624 if (VG_(clo_trace_signals))
sewardja464e5c2002-05-23 17:34:49 +0000625 VG_(message)(Vg_DebugExtraMsg,
jsgf855d93d2003-10-13 22:26:55 +0000626 "do_setmask: tid = %d how = %d (%s), set = %p %08x%08x",
627 tid, how,
628 how==VKI_SIG_BLOCK ? "SIG_BLOCK" : (
629 how==VKI_SIG_UNBLOCK ? "SIG_UNBLOCK" : (
630 how==VKI_SIG_SETMASK ? "SIG_SETMASK" : "???")),
nethercote73b526f2004-10-31 18:48:21 +0000631 newset, newset ? newset->sig[1] : 0, newset ? newset->sig[0] : 0
jsgf855d93d2003-10-13 22:26:55 +0000632 );
sewardj018f7622002-05-15 21:13:39 +0000633
jsgf855d93d2003-10-13 22:26:55 +0000634 /* Just do this thread. */
635 vg_assert(VG_(is_valid_tid)(tid));
636 if (oldset) {
sewardjb5f6f512005-03-10 23:59:00 +0000637 *oldset = VG_(threads)[tid].sig_mask;
jsgf855d93d2003-10-13 22:26:55 +0000638 if (VG_(clo_trace_signals))
639 VG_(message)(Vg_DebugExtraMsg,
640 "\toldset=%p %08x%08x",
nethercote73b526f2004-10-31 18:48:21 +0000641 oldset, oldset->sig[1], oldset->sig[0]);
sewardj018f7622002-05-15 21:13:39 +0000642 }
sewardj018f7622002-05-15 21:13:39 +0000643 if (newset) {
jsgf855d93d2003-10-13 22:26:55 +0000644 do_sigprocmask_bitops (how, &VG_(threads)[tid].sig_mask, newset );
nethercote73b526f2004-10-31 18:48:21 +0000645 VG_(sigdelset)(&VG_(threads)[tid].sig_mask, VKI_SIGKILL);
646 VG_(sigdelset)(&VG_(threads)[tid].sig_mask, VKI_SIGSTOP);
sewardjb5f6f512005-03-10 23:59:00 +0000647 VG_(threads)[tid].tmp_sig_mask = VG_(threads)[tid].sig_mask;
sewardj018f7622002-05-15 21:13:39 +0000648 }
649}
650
651
njn4fbc86c2005-05-08 00:45:11 +0000652int VG_(do_sys_sigprocmask) ( ThreadId tid,
sewardj018f7622002-05-15 21:13:39 +0000653 Int how,
nethercote73b526f2004-10-31 18:48:21 +0000654 vki_sigset_t* set,
655 vki_sigset_t* oldset )
sewardj018f7622002-05-15 21:13:39 +0000656{
jsgf855d93d2003-10-13 22:26:55 +0000657 switch(how) {
658 case VKI_SIG_BLOCK:
659 case VKI_SIG_UNBLOCK:
660 case VKI_SIG_SETMASK:
sewardj018f7622002-05-15 21:13:39 +0000661 vg_assert(VG_(is_valid_tid)(tid));
jsgf855d93d2003-10-13 22:26:55 +0000662 do_setmask ( tid, how, set, oldset );
sewardjb5f6f512005-03-10 23:59:00 +0000663 VG_(poll_signals)(tid); /* look for any newly deliverable signals */
njn4fbc86c2005-05-08 00:45:11 +0000664 return 0;
jsgf855d93d2003-10-13 22:26:55 +0000665
666 default:
sewardj018f7622002-05-15 21:13:39 +0000667 VG_(message)(Vg_DebugMsg,
njn02bc4b82005-05-15 17:28:26 +0000668 "sigprocmask: unknown 'how' field %d", how);
njn4fbc86c2005-05-08 00:45:11 +0000669 return -VKI_EINVAL;
sewardj018f7622002-05-15 21:13:39 +0000670 }
671}
672
673
sewardj018f7622002-05-15 21:13:39 +0000674/* ---------------------------------------------------------------------
675 LOW LEVEL STUFF TO DO WITH SIGNALS: IMPLEMENTATION
676 ------------------------------------------------------------------ */
sewardj77e466c2002-04-14 02:29:29 +0000677
sewardj2e93c502002-04-12 11:12:52 +0000678/* ---------------------------------------------------------------------
679 Handy utilities to block/restore all host signals.
680 ------------------------------------------------------------------ */
681
682/* Block all host signals, dumping the old mask in *saved_mask. */
njn444eba12005-05-12 03:47:31 +0000683static void block_all_host_signals ( /* OUT */ vki_sigset_t* saved_mask )
sewardj2e93c502002-04-12 11:12:52 +0000684{
685 Int ret;
nethercote73b526f2004-10-31 18:48:21 +0000686 vki_sigset_t block_procmask;
687 VG_(sigfillset)(&block_procmask);
688 ret = VG_(sigprocmask)
sewardj2e93c502002-04-12 11:12:52 +0000689 (VKI_SIG_SETMASK, &block_procmask, saved_mask);
690 vg_assert(ret == 0);
691}
692
693/* Restore the blocking mask using the supplied saved one. */
njn444eba12005-05-12 03:47:31 +0000694static void restore_all_host_signals ( /* IN */ vki_sigset_t* saved_mask )
sewardj2e93c502002-04-12 11:12:52 +0000695{
696 Int ret;
nethercote73b526f2004-10-31 18:48:21 +0000697 ret = VG_(sigprocmask)(VKI_SIG_SETMASK, saved_mask, NULL);
sewardj2e93c502002-04-12 11:12:52 +0000698 vg_assert(ret == 0);
699}
sewardjde4a1d02002-03-22 01:27:54 +0000700
njn444eba12005-05-12 03:47:31 +0000701void VG_(clear_out_queued_signals)( ThreadId tid, vki_sigset_t* saved_mask )
702{
703 block_all_host_signals(saved_mask);
704 if (VG_(threads)[tid].sig_queue != NULL) {
705 VG_(arena_free)(VG_AR_CORE, VG_(threads)[tid].sig_queue);
706 VG_(threads)[tid].sig_queue = NULL;
707 }
708 restore_all_host_signals(saved_mask);
709}
710
sewardjb5f6f512005-03-10 23:59:00 +0000711Bool VG_(client_signal_OK)(Int sigNo)
jsgf855d93d2003-10-13 22:26:55 +0000712{
sewardjb5f6f512005-03-10 23:59:00 +0000713 /* signal 0 is OK for kill */
714 Bool ret = sigNo >= 0 && sigNo <= VKI_SIGVGRTUSERMAX;
jsgf855d93d2003-10-13 22:26:55 +0000715
sewardjb5f6f512005-03-10 23:59:00 +0000716 //VG_(printf)("client_signal_OK(%d) -> %d\n", sigNo, ret);
jsgf855d93d2003-10-13 22:26:55 +0000717
718 return ret;
719}
720
sewardjde4a1d02002-03-22 01:27:54 +0000721/* ---------------------------------------------------------------------
722 The signal simulation proper. A simplified version of what the
723 Linux kernel does.
724 ------------------------------------------------------------------ */
725
sewardjde4a1d02002-03-22 01:27:54 +0000726/* Set up a stack frame (VgSigContext) for the client's signal
nethercotefedd8102004-09-13 15:19:34 +0000727 handler. */
sewardj2c5ffbe2005-03-12 13:32:06 +0000728static
njn695c16e2005-03-27 03:40:28 +0000729void push_signal_frame ( ThreadId tid, const vki_siginfo_t *siginfo )
sewardjde4a1d02002-03-22 01:27:54 +0000730{
nethercote6eec4602004-09-13 14:15:36 +0000731 Addr esp_top_of_frame;
sewardj2e93c502002-04-12 11:12:52 +0000732 ThreadState* tst;
jsgf855d93d2003-10-13 22:26:55 +0000733 Int sigNo = siginfo->si_signo;
sewardj2e93c502002-04-12 11:12:52 +0000734
sewardjb5f6f512005-03-10 23:59:00 +0000735 vg_assert(sigNo >= 1 && sigNo <= VG_(max_signal));
sewardj018f7622002-05-15 21:13:39 +0000736 vg_assert(VG_(is_valid_tid)(tid));
737 tst = & VG_(threads)[tid];
sewardj2e93c502002-04-12 11:12:52 +0000738
jsgf855d93d2003-10-13 22:26:55 +0000739 if (VG_(clo_trace_signals))
740 VG_(message)(Vg_DebugMsg,
njn695c16e2005-03-27 03:40:28 +0000741 "push_signal_frame (thread %d): signal %d", tid, sigNo);
jsgf855d93d2003-10-13 22:26:55 +0000742
sewardj2342c972002-05-22 23:34:20 +0000743 if (/* this signal asked to run on an alt stack */
njn695c16e2005-03-27 03:40:28 +0000744 (scss.scss_per_sig[sigNo].scss_flags & VKI_SA_ONSTACK )
sewardj2342c972002-05-22 23:34:20 +0000745 && /* there is a defined and enabled alt stack, which we're not
746 already using. Logic from get_sigframe in
747 arch/i386/kernel/signal.c. */
njncf45fd42004-11-24 16:30:22 +0000748 sas_ss_flags(tid, STACK_PTR(tst->arch)) == 0
sewardj2342c972002-05-22 23:34:20 +0000749 ) {
750 esp_top_of_frame
fitzhardinge98c4dc02004-03-16 08:27:29 +0000751 = (Addr)(tst->altstack.ss_sp) + tst->altstack.ss_size;
sewardj2342c972002-05-22 23:34:20 +0000752 if (VG_(clo_trace_signals))
753 VG_(message)(Vg_DebugMsg,
sewardjb5f6f512005-03-10 23:59:00 +0000754 "delivering signal %d (%s) to thread %d: on ALT STACK (%p-%p; %d bytes)",
755 sigNo, signame(sigNo), tid,
756 tst->altstack.ss_sp,
757 tst->altstack.ss_sp + tst->altstack.ss_size,
758 tst->altstack.ss_size );
njnfdc28af2003-02-24 10:36:48 +0000759
nethercote7cc9c232004-01-21 15:08:04 +0000760 /* Signal delivery to tools */
fitzhardinge98c4dc02004-03-16 08:27:29 +0000761 VG_TRACK( pre_deliver_signal, tid, sigNo, /*alt_stack*/True );
njnfdc28af2003-02-24 10:36:48 +0000762
sewardj2342c972002-05-22 23:34:20 +0000763 } else {
njna60a7c12005-05-08 17:49:37 +0000764 esp_top_of_frame = STACK_PTR(tst->arch) - VGA_STACK_REDZONE_SZB;
njnfdc28af2003-02-24 10:36:48 +0000765
nethercote7cc9c232004-01-21 15:08:04 +0000766 /* Signal delivery to tools */
fitzhardinge98c4dc02004-03-16 08:27:29 +0000767 VG_TRACK( pre_deliver_signal, tid, sigNo, /*alt_stack*/False );
sewardj2342c972002-05-22 23:34:20 +0000768 }
sewardjb5f6f512005-03-10 23:59:00 +0000769
njn695c16e2005-03-27 03:40:28 +0000770 vg_assert(scss.scss_per_sig[sigNo].scss_handler != VKI_SIG_IGN);
771 vg_assert(scss.scss_per_sig[sigNo].scss_handler != VKI_SIG_DFL);
sewardjb5f6f512005-03-10 23:59:00 +0000772
773 /* This may fail if the client stack is busted; if that happens,
774 the whole process will exit rather than simply calling the
775 signal handler. */
sewardj985fabb2005-04-24 14:18:14 +0000776 VG_(sigframe_create) (tid, esp_top_of_frame, siginfo,
777 scss.scss_per_sig[sigNo].scss_handler,
778 scss.scss_per_sig[sigNo].scss_flags,
779 &tst->sig_mask,
780 scss.scss_per_sig[sigNo].scss_restorer);
sewardjde4a1d02002-03-22 01:27:54 +0000781}
782
sewardjde4a1d02002-03-22 01:27:54 +0000783
jsgf855d93d2003-10-13 22:26:55 +0000784static const Char *signame(Int sigNo)
sewardjde4a1d02002-03-22 01:27:54 +0000785{
jsgf855d93d2003-10-13 22:26:55 +0000786 static Char buf[10];
sewardjb48e5002002-05-13 00:16:03 +0000787
jsgf855d93d2003-10-13 22:26:55 +0000788 switch(sigNo) {
789#define S(x) case VKI_##x: return #x
790 S(SIGHUP);
791 S(SIGINT);
792 S(SIGQUIT);
793 S(SIGILL);
794 S(SIGTRAP);
795 S(SIGABRT);
796 S(SIGBUS);
797 S(SIGFPE);
798 S(SIGKILL);
799 S(SIGUSR1);
800 S(SIGUSR2);
801 S(SIGSEGV);
802 S(SIGPIPE);
803 S(SIGALRM);
804 S(SIGTERM);
805 S(SIGSTKFLT);
806 S(SIGCHLD);
807 S(SIGCONT);
808 S(SIGSTOP);
809 S(SIGTSTP);
810 S(SIGTTIN);
811 S(SIGTTOU);
812 S(SIGURG);
813 S(SIGXCPU);
814 S(SIGXFSZ);
815 S(SIGVTALRM);
816 S(SIGPROF);
817 S(SIGWINCH);
818 S(SIGIO);
819 S(SIGPWR);
820 S(SIGUNUSED);
821#undef S
sewardjde4a1d02002-03-22 01:27:54 +0000822
jsgf855d93d2003-10-13 22:26:55 +0000823 case VKI_SIGRTMIN ... VKI_SIGRTMAX:
sewardjb5f6f512005-03-10 23:59:00 +0000824 VG_(sprintf)(buf, "SIGRT%d", sigNo-VKI_SIGRTMIN);
jsgf855d93d2003-10-13 22:26:55 +0000825 return buf;
sewardjde4a1d02002-03-22 01:27:54 +0000826
jsgf855d93d2003-10-13 22:26:55 +0000827 default:
828 VG_(sprintf)(buf, "SIG%d", sigNo);
829 return buf;
830 }
831}
sewardjde4a1d02002-03-22 01:27:54 +0000832
jsgf855d93d2003-10-13 22:26:55 +0000833/* Hit ourselves with a signal using the default handler */
834void VG_(kill_self)(Int sigNo)
835{
nethercote73b526f2004-10-31 18:48:21 +0000836 vki_sigset_t mask, origmask;
837 struct vki_sigaction sa, origsa;
sewardj018f7622002-05-15 21:13:39 +0000838
jsgf855d93d2003-10-13 22:26:55 +0000839 sa.ksa_handler = VKI_SIG_DFL;
nethercote73b526f2004-10-31 18:48:21 +0000840 sa.sa_flags = 0;
841 sa.sa_restorer = 0;
842 VG_(sigemptyset)(&sa.sa_mask);
sewardj2e93c502002-04-12 11:12:52 +0000843
nethercote73b526f2004-10-31 18:48:21 +0000844 VG_(sigaction)(sigNo, &sa, &origsa);
sewardj018f7622002-05-15 21:13:39 +0000845
sewardjb5f6f512005-03-10 23:59:00 +0000846 VG_(sigemptyset)(&mask);
847 VG_(sigaddset)(&mask, sigNo);
848 VG_(sigprocmask)(VKI_SIG_UNBLOCK, &mask, &origmask);
jsgf855d93d2003-10-13 22:26:55 +0000849
nethercote73b526f2004-10-31 18:48:21 +0000850 VG_(tkill)(VG_(getpid)(), sigNo);
jsgf855d93d2003-10-13 22:26:55 +0000851
nethercote73b526f2004-10-31 18:48:21 +0000852 VG_(sigaction)(sigNo, &origsa, NULL);
853 VG_(sigprocmask)(VKI_SIG_SETMASK, &origmask, NULL);
jsgf855d93d2003-10-13 22:26:55 +0000854}
855
njn277a6d62004-11-26 14:07:24 +0000856// Core dumping is disabled until someone can work out how to abstract out
857// the arch-specific and word-size-specific parts neatly.
njnbde30272004-11-29 15:45:31 +0000858//
859// Note that the code below is not 64-bit clean!
860//
njn277a6d62004-11-26 14:07:24 +0000861#if 0
fitzhardinged65dcad2004-03-13 02:06:58 +0000862/*
863 Dump core
864
865 Generate a standard ELF core file corresponding to the client state
866 at the time of a crash.
867 */
868#include <elf.h>
869#ifndef NT_PRXFPREG
870#define NT_PRXFPREG 0x46e62b7f /* copied from gdb5.1/include/elf/common.h */
871#endif /* NT_PRXFPREG */
872
873/* If true, then this Segment may be mentioned in the core */
874static Bool may_dump(const Segment *seg)
875{
sewardjb5f6f512005-03-10 23:59:00 +0000876 return (seg->flags & (SF_DEVICE|SF_VALGRIND)) == 0 && VG_(is_client_addr)(seg->addr);
fitzhardinged65dcad2004-03-13 02:06:58 +0000877}
878
879/* If true, then this Segment's contents will be in the core */
880static Bool should_dump(const Segment *seg)
881{
882 return may_dump(seg); // && (seg->prot & VKI_PROT_WRITE);
883}
884
885static void fill_ehdr(Elf32_Ehdr *ehdr, Int num_phdrs)
886{
njne1d981a2005-03-11 04:47:23 +0000887 VG_(memset)(ehdr, 0, sizeof(*ehdr));
fitzhardinged65dcad2004-03-13 02:06:58 +0000888
889 VG_(memcpy)(ehdr->e_ident, ELFMAG, SELFMAG);
njn35172bc2005-03-26 00:04:03 +0000890 ehdr->e_ident[EI_CLASS] = VGA_ELF_CLASS;
891 ehdr->e_ident[EI_DATA] = VGA_ELF_ENDIANNESS;
fitzhardinged65dcad2004-03-13 02:06:58 +0000892 ehdr->e_ident[EI_VERSION] = EV_CURRENT;
fitzhardinged65dcad2004-03-13 02:06:58 +0000893
894 ehdr->e_type = ET_CORE;
njn35172bc2005-03-26 00:04:03 +0000895 ehdr->e_machine = VGA_ELF_MACHINE;
fitzhardinged65dcad2004-03-13 02:06:58 +0000896 ehdr->e_version = EV_CURRENT;
897 ehdr->e_entry = 0;
898 ehdr->e_phoff = sizeof(Elf32_Ehdr);
899 ehdr->e_shoff = 0;
900 ehdr->e_flags = 0;
901 ehdr->e_ehsize = sizeof(Elf32_Ehdr);
902 ehdr->e_phentsize = sizeof(Elf32_Phdr);
903 ehdr->e_phnum = num_phdrs;
904 ehdr->e_shentsize = 0;
905 ehdr->e_shnum = 0;
906 ehdr->e_shstrndx = 0;
907
908}
909
910static void fill_phdr(Elf32_Phdr *phdr, const Segment *seg, UInt off, Bool write)
911{
912 write = write && should_dump(seg);
913
914 VG_(memset)(phdr, 0, sizeof(*phdr));
915
916 phdr->p_type = PT_LOAD;
917 phdr->p_offset = off;
918 phdr->p_vaddr = seg->addr;
919 phdr->p_paddr = 0;
920 phdr->p_filesz = write ? seg->len : 0;
921 phdr->p_memsz = seg->len;
922 phdr->p_flags = 0;
923
924 if (seg->prot & VKI_PROT_READ)
925 phdr->p_flags |= PF_R;
926 if (seg->prot & VKI_PROT_WRITE)
927 phdr->p_flags |= PF_W;
928 if (seg->prot & VKI_PROT_EXEC)
929 phdr->p_flags |= PF_X;
930
nethercote73b526f2004-10-31 18:48:21 +0000931 phdr->p_align = VKI_PAGE_SIZE;
fitzhardinged65dcad2004-03-13 02:06:58 +0000932}
933
934struct note {
935 struct note *next;
936 Elf32_Nhdr note;
937 Char name[0];
938};
939
940static UInt note_size(const struct note *n)
941{
942 return sizeof(Elf32_Nhdr) + ROUNDUP(VG_(strlen)(n->name)+1, 4) + ROUNDUP(n->note.n_descsz, 4);
943}
944
945static void add_note(struct note **list, const Char *name, UInt type, const void *data, UInt datasz)
946{
947 Int namelen = VG_(strlen)(name)+1;
948 Int notelen = sizeof(struct note) +
949 ROUNDUP(namelen, 4) +
950 ROUNDUP(datasz, 4);
951 struct note *n = VG_(arena_malloc)(VG_AR_CORE, notelen);
952
953 VG_(memset)(n, 0, notelen);
954
955 n->next = *list;
956 *list = n;
957
958 n->note.n_type = type;
959 n->note.n_namesz = namelen;
960 n->note.n_descsz = datasz;
961
962 VG_(memcpy)(n->name, name, namelen);
963 VG_(memcpy)(n->name+ROUNDUP(namelen,4), data, datasz);
964}
965
966static void write_note(Int fd, const struct note *n)
967{
968 VG_(write)(fd, &n->note, note_size(n));
969}
970
nethercote73b526f2004-10-31 18:48:21 +0000971static void fill_prpsinfo(const ThreadState *tst, struct vki_elf_prpsinfo *prpsinfo)
fitzhardinged65dcad2004-03-13 02:06:58 +0000972{
973 Char *name;
974
975 VG_(memset)(prpsinfo, 0, sizeof(*prpsinfo));
976
977 switch(tst->status) {
978 case VgTs_Runnable:
sewardjb5f6f512005-03-10 23:59:00 +0000979 case VgTs_Yielding:
fitzhardinged65dcad2004-03-13 02:06:58 +0000980 prpsinfo->pr_sname = 'R';
981 break;
982
fitzhardinged65dcad2004-03-13 02:06:58 +0000983 case VgTs_WaitSys:
fitzhardinged65dcad2004-03-13 02:06:58 +0000984 prpsinfo->pr_sname = 'S';
985 break;
986
sewardjb5f6f512005-03-10 23:59:00 +0000987 case VgTs_Zombie:
988 prpsinfo->pr_sname = 'Z';
989 break;
990
fitzhardinged65dcad2004-03-13 02:06:58 +0000991 case VgTs_Empty:
sewardjb5f6f512005-03-10 23:59:00 +0000992 case VgTs_Init:
993 prpsinfo->pr_sname = '?';
fitzhardinged65dcad2004-03-13 02:06:58 +0000994 break;
995 }
996
997 prpsinfo->pr_uid = 0;
998 prpsinfo->pr_gid = 0;
999
1000 name = VG_(resolve_filename)(VG_(clexecfd));
1001
1002 if (name != NULL) {
1003 Char *n = name+VG_(strlen)(name)-1;
1004
1005 while(n > name && *n != '/')
1006 n--;
1007 if (n != name)
1008 n++;
1009
1010 VG_(strncpy)(prpsinfo->pr_fname, n, sizeof(prpsinfo->pr_fname));
1011 }
1012}
1013
sewardjb5f6f512005-03-10 23:59:00 +00001014static void fill_prstatus(const ThreadState *tst,
1015 struct vki_elf_prstatus *prs,
1016 const vki_siginfo_t *si)
fitzhardinged65dcad2004-03-13 02:06:58 +00001017{
nethercote73b526f2004-10-31 18:48:21 +00001018 struct vki_user_regs_struct *regs;
fitzhardinged65dcad2004-03-13 02:06:58 +00001019
1020 VG_(memset)(prs, 0, sizeof(*prs));
1021
1022 prs->pr_info.si_signo = si->si_signo;
1023 prs->pr_info.si_code = si->si_code;
1024 prs->pr_info.si_errno = 0;
1025
1026 prs->pr_cursig = si->si_signo;
1027
sewardjb5f6f512005-03-10 23:59:00 +00001028 prs->pr_pid = tst->os_state.lwpid;
fitzhardinged65dcad2004-03-13 02:06:58 +00001029 prs->pr_ppid = 0;
sewardjb5f6f512005-03-10 23:59:00 +00001030 prs->pr_pgrp = VG_(getpgrp)();
1031 prs->pr_sid = VG_(getpgrp)();
fitzhardinged65dcad2004-03-13 02:06:58 +00001032
nethercote73b526f2004-10-31 18:48:21 +00001033 regs = (struct vki_user_regs_struct *)prs->pr_reg;
fitzhardinged65dcad2004-03-13 02:06:58 +00001034
1035 vg_assert(sizeof(*regs) == sizeof(prs->pr_reg));
1036
sewardj2a99cf62004-11-24 10:44:19 +00001037 VGA_(fill_elfregs_from_tst)(regs, &tst->arch);
fitzhardinged65dcad2004-03-13 02:06:58 +00001038}
1039
nethercote73b526f2004-10-31 18:48:21 +00001040static void fill_fpu(const ThreadState *tst, vki_elf_fpregset_t *fpu)
fitzhardinged65dcad2004-03-13 02:06:58 +00001041{
sewardj2a99cf62004-11-24 10:44:19 +00001042 VGA_(fill_elffpregs_from_tst)(fpu, &tst->arch);
fitzhardinged65dcad2004-03-13 02:06:58 +00001043}
1044
nethercote73b526f2004-10-31 18:48:21 +00001045static void fill_xfpu(const ThreadState *tst, vki_elf_fpxregset_t *xfpu)
fitzhardinged65dcad2004-03-13 02:06:58 +00001046{
sewardj2a99cf62004-11-24 10:44:19 +00001047 VGA_(fill_elffpxregs_from_tst)(xfpu, &tst->arch);
fitzhardinged65dcad2004-03-13 02:06:58 +00001048}
1049
nethercote73b526f2004-10-31 18:48:21 +00001050static void make_coredump(ThreadId tid, const vki_siginfo_t *si, UInt max_size)
fitzhardinged65dcad2004-03-13 02:06:58 +00001051{
1052 Char buf[1000];
1053 Char *basename = "vgcore";
1054 Char *coreext = "";
1055 Int seq = 0;
1056 Int core_fd;
1057 Segment *seg;
1058 Elf32_Ehdr ehdr;
1059 Elf32_Phdr *phdrs;
1060 Int num_phdrs;
sewardjb5f6f512005-03-10 23:59:00 +00001061 Int i, idx;
fitzhardinged65dcad2004-03-13 02:06:58 +00001062 UInt off;
1063 struct note *notelist, *note;
1064 UInt notesz;
nethercote73b526f2004-10-31 18:48:21 +00001065 struct vki_elf_prpsinfo prpsinfo;
1066 struct vki_elf_prstatus prstatus;
fitzhardinged65dcad2004-03-13 02:06:58 +00001067
nethercotef8548672004-06-21 12:42:35 +00001068 if (VG_(clo_log_name) != NULL) {
fitzhardinged65dcad2004-03-13 02:06:58 +00001069 coreext = ".core";
nethercotef8548672004-06-21 12:42:35 +00001070 basename = VG_(clo_log_name);
fitzhardinged65dcad2004-03-13 02:06:58 +00001071 }
1072
1073 for(;;) {
1074 if (seq == 0)
1075 VG_(sprintf)(buf, "%s%s.pid%d",
sewardjb5f6f512005-03-10 23:59:00 +00001076 basename, coreext, VG_(getpid)());
fitzhardinged65dcad2004-03-13 02:06:58 +00001077 else
1078 VG_(sprintf)(buf, "%s%s.pid%d.%d",
sewardjb5f6f512005-03-10 23:59:00 +00001079 basename, coreext, VG_(getpid)(), seq);
fitzhardinged65dcad2004-03-13 02:06:58 +00001080 seq++;
1081
1082 core_fd = VG_(open)(buf,
1083 VKI_O_CREAT|VKI_O_WRONLY|VKI_O_EXCL|VKI_O_TRUNC,
1084 VKI_S_IRUSR|VKI_S_IWUSR);
1085 if (core_fd >= 0)
1086 break;
1087
1088 if (core_fd != -VKI_EEXIST)
1089 return; /* can't create file */
1090 }
1091
1092 /* First, count how many memory segments to dump */
1093 num_phdrs = 1; /* start with notes */
1094 for(seg = VG_(first_segment)();
1095 seg != NULL;
1096 seg = VG_(next_segment)(seg)) {
1097 if (!may_dump(seg))
1098 continue;
1099
1100 num_phdrs++;
1101 }
1102
1103 fill_ehdr(&ehdr, num_phdrs);
1104
sewardjb5f6f512005-03-10 23:59:00 +00001105 notelist = NULL;
1106
fitzhardinged65dcad2004-03-13 02:06:58 +00001107 /* Second, work out their layout */
1108 phdrs = VG_(arena_malloc)(VG_AR_CORE, sizeof(*phdrs) * num_phdrs);
1109
1110 for(i = 1; i < VG_N_THREADS; i++) {
sewardj51ac0872004-12-21 01:20:49 +00001111 vki_elf_fpregset_t fpu;
1112 vki_elf_fpxregset_t xfpu;
fitzhardinged65dcad2004-03-13 02:06:58 +00001113
1114 if (VG_(threads)[i].status == VgTs_Empty)
1115 continue;
1116
sewardj51ac0872004-12-21 01:20:49 +00001117 fill_xfpu(&VG_(threads)[i], &xfpu);
1118 add_note(&notelist, "LINUX", NT_PRXFPREG, &xfpu, sizeof(xfpu));
fitzhardinged65dcad2004-03-13 02:06:58 +00001119
1120 fill_fpu(&VG_(threads)[i], &fpu);
1121 add_note(&notelist, "CORE", NT_FPREGSET, &fpu, sizeof(fpu));
1122
1123 fill_prstatus(&VG_(threads)[i], &prstatus, si);
1124 add_note(&notelist, "CORE", NT_PRSTATUS, &prstatus, sizeof(prstatus));
1125 }
1126
1127 fill_prpsinfo(&VG_(threads)[tid], &prpsinfo);
1128 add_note(&notelist, "CORE", NT_PRPSINFO, &prpsinfo, sizeof(prpsinfo));
1129
1130 for(note = notelist, notesz = 0; note != NULL; note = note->next)
1131 notesz += note_size(note);
1132
1133 off = sizeof(ehdr) + sizeof(*phdrs) * num_phdrs;
1134
1135 phdrs[0].p_type = PT_NOTE;
1136 phdrs[0].p_offset = off;
1137 phdrs[0].p_vaddr = 0;
1138 phdrs[0].p_paddr = 0;
1139 phdrs[0].p_filesz = notesz;
1140 phdrs[0].p_memsz = 0;
1141 phdrs[0].p_flags = 0;
1142 phdrs[0].p_align = 0;
1143
1144 off += notesz;
1145
1146 off = PGROUNDUP(off);
1147
sewardjb5f6f512005-03-10 23:59:00 +00001148 for(seg = VG_(first_segment)(), idx = 1;
fitzhardinged65dcad2004-03-13 02:06:58 +00001149 seg != NULL;
sewardjb5f6f512005-03-10 23:59:00 +00001150 seg = VG_(next_segment)(seg)) {
fitzhardinged65dcad2004-03-13 02:06:58 +00001151 if (!may_dump(seg))
1152 continue;
1153
sewardjb5f6f512005-03-10 23:59:00 +00001154 fill_phdr(&phdrs[idx], seg, off, (seg->len + off) < max_size);
fitzhardinged65dcad2004-03-13 02:06:58 +00001155
sewardjb5f6f512005-03-10 23:59:00 +00001156 off += phdrs[idx].p_filesz;
1157
1158 idx++;
fitzhardinged65dcad2004-03-13 02:06:58 +00001159 }
1160
1161 /* write everything out */
1162 VG_(write)(core_fd, &ehdr, sizeof(ehdr));
1163 VG_(write)(core_fd, phdrs, sizeof(*phdrs) * num_phdrs);
1164
1165 for(note = notelist; note != NULL; note = note->next)
1166 write_note(core_fd, note);
1167
1168 VG_(lseek)(core_fd, phdrs[1].p_offset, VKI_SEEK_SET);
1169
sewardjb5f6f512005-03-10 23:59:00 +00001170 for(seg = VG_(first_segment)(), idx = 1;
fitzhardinged65dcad2004-03-13 02:06:58 +00001171 seg != NULL;
sewardjb5f6f512005-03-10 23:59:00 +00001172 seg = VG_(next_segment)(seg)) {
fitzhardinged65dcad2004-03-13 02:06:58 +00001173 if (!should_dump(seg))
1174 continue;
1175
sewardjb5f6f512005-03-10 23:59:00 +00001176 if (phdrs[idx].p_filesz > 0) {
1177 Int ret;
1178
1179 vg_assert(VG_(lseek)(core_fd, phdrs[idx].p_offset, VKI_SEEK_SET) == phdrs[idx].p_offset);
1180 vg_assert(seg->len >= phdrs[idx].p_filesz);
1181
1182 ret = VG_(write)(core_fd, (void *)seg->addr, phdrs[idx].p_filesz);
1183 }
1184 idx++;
fitzhardinged65dcad2004-03-13 02:06:58 +00001185 }
1186
1187 VG_(close)(core_fd);
1188}
njn277a6d62004-11-26 14:07:24 +00001189#endif
fitzhardinged65dcad2004-03-13 02:06:58 +00001190
jsgf855d93d2003-10-13 22:26:55 +00001191/*
sewardjb5f6f512005-03-10 23:59:00 +00001192 Perform the default action of a signal. If the signal is fatal, it
1193 marks all threads as needing to exit, but it doesn't actually kill
1194 the process or thread.
jsgf855d93d2003-10-13 22:26:55 +00001195
1196 If we're not being quiet, then print out some more detail about
1197 fatal signals (esp. core dumping signals).
1198 */
njn695c16e2005-03-27 03:40:28 +00001199static void default_action(const vki_siginfo_t *info, ThreadId tid)
jsgf855d93d2003-10-13 22:26:55 +00001200{
1201 Int sigNo = info->si_signo;
sewardjb5f6f512005-03-10 23:59:00 +00001202 Bool terminate = False; /* kills process */
1203 Bool core = False; /* kills process w/ core */
1204 struct vki_rlimit corelim;
1205 Bool could_core;
jsgf855d93d2003-10-13 22:26:55 +00001206
sewardjb5f6f512005-03-10 23:59:00 +00001207 vg_assert(VG_(is_running_thread)(tid));
1208
jsgf855d93d2003-10-13 22:26:55 +00001209 switch(sigNo) {
1210 case VKI_SIGQUIT: /* core */
1211 case VKI_SIGILL: /* core */
1212 case VKI_SIGABRT: /* core */
1213 case VKI_SIGFPE: /* core */
1214 case VKI_SIGSEGV: /* core */
1215 case VKI_SIGBUS: /* core */
1216 case VKI_SIGTRAP: /* core */
1217 case VKI_SIGXCPU: /* core */
1218 case VKI_SIGXFSZ: /* core */
1219 terminate = True;
1220 core = True;
1221 break;
1222
1223 case VKI_SIGHUP: /* term */
1224 case VKI_SIGINT: /* term */
1225 case VKI_SIGKILL: /* term - we won't see this */
1226 case VKI_SIGPIPE: /* term */
1227 case VKI_SIGALRM: /* term */
1228 case VKI_SIGTERM: /* term */
1229 case VKI_SIGUSR1: /* term */
1230 case VKI_SIGUSR2: /* term */
1231 case VKI_SIGIO: /* term */
1232 case VKI_SIGPWR: /* term */
1233 case VKI_SIGSYS: /* term */
1234 case VKI_SIGPROF: /* term */
1235 case VKI_SIGVTALRM: /* term */
1236 case VKI_SIGRTMIN ... VKI_SIGRTMAX: /* term */
1237 terminate = True;
1238 break;
1239 }
1240
1241 vg_assert(!core || (core && terminate));
1242
fitzhardinge98abfc72003-12-16 02:05:15 +00001243 if (VG_(clo_trace_signals))
sewardjb5f6f512005-03-10 23:59:00 +00001244 VG_(message)(Vg_DebugMsg, "delivering %d (code %d) to default handler; action: %s%s",
1245 sigNo, info->si_code, terminate ? "terminate" : "ignore", core ? "+core" : "");
fitzhardinge98abfc72003-12-16 02:05:15 +00001246
sewardjb5f6f512005-03-10 23:59:00 +00001247 if (!terminate)
1248 return; /* nothing to do */
fitzhardinge4a4d1082004-03-15 23:46:54 +00001249
sewardjb5f6f512005-03-10 23:59:00 +00001250 could_core = core;
1251
1252 if (core) {
1253 /* If they set the core-size limit to zero, don't generate a
1254 core file */
fitzhardinge61a53412004-03-15 23:44:11 +00001255
sewardjb5f6f512005-03-10 23:59:00 +00001256 VG_(getrlimit)(VKI_RLIMIT_CORE, &corelim);
fitzhardinge61a53412004-03-15 23:44:11 +00001257
sewardjb5f6f512005-03-10 23:59:00 +00001258 if (corelim.rlim_cur == 0)
1259 core = False;
1260 }
fitzhardinge61a53412004-03-15 23:44:11 +00001261
sewardjb5f6f512005-03-10 23:59:00 +00001262 if (VG_(clo_verbosity) > 1 || (could_core && info->si_code > VKI_SI_USER)) {
1263 VG_(message)(Vg_UserMsg, "");
1264 VG_(message)(Vg_UserMsg, "Process terminating with default action of signal %d (%s)%s",
1265 sigNo, signame(sigNo), core ? ": dumping core" : "");
jsgf855d93d2003-10-13 22:26:55 +00001266
sewardjb5f6f512005-03-10 23:59:00 +00001267 /* Be helpful - decode some more details about this fault */
1268 if (info->si_code > VKI_SI_USER) {
1269 const Char *event = NULL;
1270 Bool haveaddr = True;
jsgf855d93d2003-10-13 22:26:55 +00001271
sewardjb5f6f512005-03-10 23:59:00 +00001272 switch(sigNo) {
1273 case VKI_SIGSEGV:
1274 switch(info->si_code) {
1275 case 1: event = "Access not within mapped region"; break;
1276 case 2: event = "Bad permissions for mapped region"; break;
1277 case 128:
1278 /* General Protection Fault: The CPU/kernel
1279 isn't telling us anything useful, but this
1280 is commonly the result of exceeding a
1281 segment limit, such as the one imposed by
1282 --pointercheck=yes. */
1283 if (VG_(clo_pointercheck))
1284 event = "GPF (Pointer out of bounds?)";
1285 else
1286 event = "General Protection Fault";
1287 haveaddr = False;
jsgf855d93d2003-10-13 22:26:55 +00001288 break;
1289 }
sewardjb5f6f512005-03-10 23:59:00 +00001290 break;
jsgf855d93d2003-10-13 22:26:55 +00001291
sewardjb5f6f512005-03-10 23:59:00 +00001292 case VKI_SIGILL:
1293 switch(info->si_code) {
1294 case 1: event = "Illegal opcode"; break;
1295 case 2: event = "Illegal operand"; break;
1296 case 3: event = "Illegal addressing mode"; break;
1297 case 4: event = "Illegal trap"; break;
1298 case 5: event = "Privileged opcode"; break;
1299 case 6: event = "Privileged register"; break;
1300 case 7: event = "Coprocessor error"; break;
1301 case 8: event = "Internal stack error"; break;
1302 }
1303 break;
1304
1305 case VKI_SIGFPE:
1306 switch (info->si_code) {
1307 case 1: event = "Integer divide by zero"; break;
1308 case 2: event = "Integer overflow"; break;
1309 case 3: event = "FP divide by zero"; break;
1310 case 4: event = "FP overflow"; break;
1311 case 5: event = "FP underflow"; break;
1312 case 6: event = "FP inexact"; break;
1313 case 7: event = "FP invalid operation"; break;
1314 case 8: event = "FP subscript out of range"; break;
1315 }
1316 break;
1317
1318 case VKI_SIGBUS:
1319 switch (info->si_code) {
1320 case 1: event = "Invalid address alignment"; break;
1321 case 2: event = "Non-existent physical address"; break;
1322 case 3: event = "Hardware error"; break;
1323 }
1324 break;
1325 }
1326
1327 if (event != NULL) {
1328 if (haveaddr)
nethercote3b390c72003-11-13 17:53:43 +00001329 VG_(message)(Vg_UserMsg, " %s at address %p",
jsgf855d93d2003-10-13 22:26:55 +00001330 event, info->_sifields._sigfault._addr);
sewardjb5f6f512005-03-10 23:59:00 +00001331 else
1332 VG_(message)(Vg_UserMsg, " %s", event);
jsgf855d93d2003-10-13 22:26:55 +00001333 }
1334 }
fitzhardinge126c64f2003-12-08 21:58:37 +00001335
sewardjb5f6f512005-03-10 23:59:00 +00001336 if (tid != VG_INVALID_THREADID) {
njnd01fef72005-03-25 23:35:48 +00001337 VG_(get_and_pp_StackTrace)(tid, VG_(clo_backtrace_size));
fitzhardinge126c64f2003-12-08 21:58:37 +00001338 }
sewardjb5f6f512005-03-10 23:59:00 +00001339 }
1340
1341 if (VG_(is_action_requested)( "Attach to debugger", & VG_(clo_db_attach) )) {
1342 VG_(start_debugger)( tid );
1343 }
fitzhardinge126c64f2003-12-08 21:58:37 +00001344
njn277a6d62004-11-26 14:07:24 +00001345 // See comment above about this temporary disabling of core dumps.
1346 #if 0
sewardjb5f6f512005-03-10 23:59:00 +00001347 if (core) {
1348 const static struct vki_rlimit zero = { 0, 0 };
fitzhardinge4a4d1082004-03-15 23:46:54 +00001349
sewardjb5f6f512005-03-10 23:59:00 +00001350 make_coredump(tid, info, corelim.rlim_cur);
fitzhardinged65dcad2004-03-13 02:06:58 +00001351
sewardjb5f6f512005-03-10 23:59:00 +00001352 /* Make sure we don't get a confusing kernel-generated
1353 coredump when we finally exit */
1354 VG_(setrlimit)(VKI_RLIMIT_CORE, &zero);
1355 }
njn277a6d62004-11-26 14:07:24 +00001356 #endif
fitzhardinged65dcad2004-03-13 02:06:58 +00001357
sewardjb5f6f512005-03-10 23:59:00 +00001358 /* stash fatal signal in main thread */
sewardj1d887112005-05-30 21:44:08 +00001359 // what's this for?
1360 //VG_(threads)[VG_(master_tid)].os_state.fatalsig = sigNo;
sewardjde4a1d02002-03-22 01:27:54 +00001361
sewardjb5f6f512005-03-10 23:59:00 +00001362 /* everyone dies */
1363 VG_(nuke_all_threads_except)(tid, VgSrc_FatalSig);
1364 VG_(threads)[tid].exitreason = VgSrc_FatalSig;
1365 VG_(threads)[tid].os_state.fatalsig = sigNo;
sewardjb48e5002002-05-13 00:16:03 +00001366}
1367
sewardjb5f6f512005-03-10 23:59:00 +00001368/*
1369 This does the business of delivering a signal to a thread. It may
1370 be called from either a real signal handler, or from normal code to
1371 cause the thread to enter the signal handler.
sewardj5e2f0012004-12-13 14:10:34 +00001372
sewardjb5f6f512005-03-10 23:59:00 +00001373 This updates the thread state, but it does not set it to be
1374 Runnable.
1375*/
njn9ec0f3e2005-03-13 06:00:47 +00001376static void deliver_signal ( ThreadId tid, const vki_siginfo_t *info )
sewardjde4a1d02002-03-22 01:27:54 +00001377{
jsgf855d93d2003-10-13 22:26:55 +00001378 Int sigNo = info->si_signo;
njn695c16e2005-03-27 03:40:28 +00001379 SCSS_Per_Signal *handler = &scss.scss_per_sig[sigNo];
fitzhardinge98abfc72003-12-16 02:05:15 +00001380 void *handler_fn;
jsgf855d93d2003-10-13 22:26:55 +00001381 ThreadState *tst = VG_(get_ThreadState)(tid);
1382
1383 if (VG_(clo_trace_signals))
sewardjb5f6f512005-03-10 23:59:00 +00001384 VG_(message)(Vg_DebugMsg,"delivering signal %d (%s):%d to thread %d",
1385 sigNo, signame(sigNo), info->si_code, tid );
jsgf855d93d2003-10-13 22:26:55 +00001386
sewardjb5f6f512005-03-10 23:59:00 +00001387 if (sigNo == VKI_SIGVGKILL) {
1388 /* If this is a SIGVGKILL, we're expecting it to interrupt any
1389 blocked syscall. It doesn't matter whether the VCPU state is
1390 set to restart or not, because we don't expect it will
1391 execute any more client instructions. */
1392 vg_assert(VG_(is_exiting)(tid));
jsgf855d93d2003-10-13 22:26:55 +00001393 return;
1394 }
1395
sewardjb5f6f512005-03-10 23:59:00 +00001396 /* If the client specifies SIG_IGN, treat it as SIG_DFL.
jsgf855d93d2003-10-13 22:26:55 +00001397
njn9ec0f3e2005-03-13 06:00:47 +00001398 If deliver_signal() is being called on a thread, we want
sewardjb5f6f512005-03-10 23:59:00 +00001399 the signal to get through no matter what; if they're ignoring
1400 it, then we do this override (this is so we can send it SIGSEGV,
1401 etc). */
fitzhardinge98abfc72003-12-16 02:05:15 +00001402 handler_fn = handler->scss_handler;
sewardjb5f6f512005-03-10 23:59:00 +00001403 if (handler_fn == VKI_SIG_IGN)
fitzhardinge98abfc72003-12-16 02:05:15 +00001404 handler_fn = VKI_SIG_DFL;
1405
1406 vg_assert(handler_fn != VKI_SIG_IGN);
jsgf855d93d2003-10-13 22:26:55 +00001407
fitzhardinge98abfc72003-12-16 02:05:15 +00001408 if (handler_fn == VKI_SIG_DFL) {
njn695c16e2005-03-27 03:40:28 +00001409 default_action(info, tid);
jsgf855d93d2003-10-13 22:26:55 +00001410 } else {
1411 /* Create a signal delivery frame, and set the client's %ESP and
1412 %EIP so that when execution continues, we will enter the
1413 signal handler with the frame on top of the client's stack,
sewardjb5f6f512005-03-10 23:59:00 +00001414 as it expects.
1415
1416 Signal delivery can fail if the client stack is too small or
1417 missing, and we can't push the frame. If that happens,
1418 push_signal_frame will cause the whole process to exit when
1419 we next hit the scheduler.
1420 */
jsgf855d93d2003-10-13 22:26:55 +00001421 vg_assert(VG_(is_valid_tid)(tid));
sewardjb5f6f512005-03-10 23:59:00 +00001422
njn695c16e2005-03-27 03:40:28 +00001423 push_signal_frame ( tid, info );
jsgf855d93d2003-10-13 22:26:55 +00001424
1425 if (handler->scss_flags & VKI_SA_ONESHOT) {
1426 /* Do the ONESHOT thing. */
1427 handler->scss_handler = VKI_SIG_DFL;
1428
nethercote9dd11512004-08-04 15:31:30 +00001429 handle_SCSS_change( False /* lazy update */ );
jsgf855d93d2003-10-13 22:26:55 +00001430 }
sewardjb5f6f512005-03-10 23:59:00 +00001431
1432 /* At this point:
1433 tst->sig_mask is the current signal mask
1434 tst->tmp_sig_mask is the same as sig_mask, unless we're in sigsuspend
1435 handler->scss_mask is the mask set by the handler
1436
1437 Handler gets a mask of tmp_sig_mask|handler_mask|signo
1438 */
1439 tst->sig_mask = tst->tmp_sig_mask;
1440 if (!(handler->scss_flags & VKI_SA_NOMASK)) {
1441 VG_(sigaddset_from_set)(&tst->sig_mask, &handler->scss_mask);
1442 VG_(sigaddset)(&tst->sig_mask, sigNo);
1443
1444 tst->tmp_sig_mask = tst->sig_mask;
1445 }
1446 }
1447
1448 /* Thread state is ready to go - just add Runnable */
1449}
1450
njn9ec0f3e2005-03-13 06:00:47 +00001451static void synth_fault_common(ThreadId tid, Addr addr, Int si_code)
1452{
1453 vki_siginfo_t info;
1454
1455 vg_assert(VG_(threads)[tid].status == VgTs_Runnable);
1456
1457 info.si_signo = VKI_SIGSEGV;
1458 info.si_code = si_code;
1459 info._sifields._sigfault._addr = (void*)addr;
1460
1461 /* If they're trying to block the signal, force it to be delivered */
1462 if (VG_(sigismember)(&VG_(threads)[tid].sig_mask, VKI_SIGSEGV))
1463 VG_(set_default_handler)(VKI_SIGSEGV);
1464
1465 deliver_signal(tid, &info);
1466}
1467
1468// Synthesize a fault where the address is OK, but the page
1469// permissions are bad.
1470void VG_(synth_fault_perms)(ThreadId tid, Addr addr)
1471{
1472 synth_fault_common(tid, addr, 2);
1473}
1474
1475// Synthesize a fault where the address there's nothing mapped at the address.
1476void VG_(synth_fault_mapping)(ThreadId tid, Addr addr)
1477{
1478 synth_fault_common(tid, addr, 1);
1479}
1480
1481// Synthesize a misc memory fault.
1482void VG_(synth_fault)(ThreadId tid)
1483{
1484 synth_fault_common(tid, 0, 0x80);
1485}
1486
1487// Synthesise a SIGILL.
1488void VG_(synth_sigill)(ThreadId tid, Addr addr)
1489{
1490 vki_siginfo_t info;
1491
1492 vg_assert(VG_(threads)[tid].status == VgTs_Runnable);
1493
1494 info.si_signo = VKI_SIGILL;
1495 info.si_code = 1; /* jrs: no idea what this should be */
1496 info._sifields._sigfault._addr = (void*)addr;
1497
1498 VG_(resume_scheduler)(tid);
1499 deliver_signal(tid, &info);
1500}
1501
sewardjb5f6f512005-03-10 23:59:00 +00001502/* Make a signal pending for a thread, for later delivery.
1503 VG_(poll_signals) will arrange for it to be delivered at the right
1504 time.
1505
1506 tid==0 means add it to the process-wide queue, and not sent it to a
1507 specific thread.
1508*/
sewardj2c5ffbe2005-03-12 13:32:06 +00001509static
sewardjb5f6f512005-03-10 23:59:00 +00001510void queue_signal(ThreadId tid, const vki_siginfo_t *si)
1511{
1512 ThreadState *tst;
1513 SigQueue *sq;
1514 vki_sigset_t savedmask;
1515
1516 tst = VG_(get_ThreadState)(tid);
1517
1518 /* Protect the signal queue against async deliveries */
njn444eba12005-05-12 03:47:31 +00001519 block_all_host_signals(&savedmask);
sewardjb5f6f512005-03-10 23:59:00 +00001520
1521 if (tst->sig_queue == NULL) {
1522 tst->sig_queue = VG_(arena_malloc)(VG_AR_CORE, sizeof(*tst->sig_queue));
1523 VG_(memset)(tst->sig_queue, 0, sizeof(*tst->sig_queue));
1524 }
1525 sq = tst->sig_queue;
1526
1527 if (VG_(clo_trace_signals))
1528 VG_(message)(Vg_DebugMsg, "Queueing signal %d (idx %d) to thread %d",
1529 si->si_signo, sq->next, tid);
1530
1531 /* Add signal to the queue. If the queue gets overrun, then old
1532 queued signals may get lost.
1533
1534 XXX We should also keep a sigset of pending signals, so that at
1535 least a non-siginfo signal gets deliviered.
1536 */
1537 if (sq->sigs[sq->next].si_signo != 0)
1538 VG_(message)(Vg_UserMsg, "Signal %d being dropped from thread %d's queue",
1539 sq->sigs[sq->next].si_signo, tid);
1540
1541 sq->sigs[sq->next] = *si;
1542 sq->next = (sq->next+1) % N_QUEUED_SIGNALS;
1543
njn444eba12005-05-12 03:47:31 +00001544 restore_all_host_signals(&savedmask);
sewardjb5f6f512005-03-10 23:59:00 +00001545}
1546
1547/*
1548 Returns the next queued signal for thread tid which is in "set".
1549 tid==0 means process-wide signal. Set si_signo to 0 when the
1550 signal has been delivered.
1551
1552 Must be called with all signals blocked, to protect against async
1553 deliveries.
1554*/
1555static vki_siginfo_t *next_queued(ThreadId tid, const vki_sigset_t *set)
1556{
1557 ThreadState *tst = VG_(get_ThreadState)(tid);
1558 SigQueue *sq;
1559 Int idx;
1560 vki_siginfo_t *ret = NULL;
1561
1562 sq = tst->sig_queue;
1563 if (sq == NULL)
1564 goto out;
jsgf855d93d2003-10-13 22:26:55 +00001565
sewardjb5f6f512005-03-10 23:59:00 +00001566 idx = sq->next;
1567 do {
1568 if (0)
1569 VG_(printf)("idx=%d si_signo=%d inset=%d\n", idx,
1570 sq->sigs[idx].si_signo, VG_(sigismember)(set, sq->sigs[idx].si_signo));
jsgf855d93d2003-10-13 22:26:55 +00001571
sewardjb5f6f512005-03-10 23:59:00 +00001572 if (sq->sigs[idx].si_signo != 0 && VG_(sigismember)(set, sq->sigs[idx].si_signo)) {
1573 if (VG_(clo_trace_signals))
1574 VG_(message)(Vg_DebugMsg, "Returning queued signal %d (idx %d) for thread %d",
1575 sq->sigs[idx].si_signo, idx, tid);
1576 ret = &sq->sigs[idx];
1577 goto out;
jsgf855d93d2003-10-13 22:26:55 +00001578 }
1579
sewardjb5f6f512005-03-10 23:59:00 +00001580 idx = (idx + 1) % N_QUEUED_SIGNALS;
1581 } while(idx != sq->next);
1582 out:
1583 return ret;
jsgf855d93d2003-10-13 22:26:55 +00001584}
1585
1586/*
sewardjb5f6f512005-03-10 23:59:00 +00001587 Receive an async signal from the kernel.
jsgf855d93d2003-10-13 22:26:55 +00001588
sewardjb5f6f512005-03-10 23:59:00 +00001589 This should only happen when the thread is blocked in a syscall,
1590 since that's the only time this set of signals is unblocked.
jsgf855d93d2003-10-13 22:26:55 +00001591*/
1592static
njn695c16e2005-03-27 03:40:28 +00001593void async_signalhandler ( Int sigNo, vki_siginfo_t *info, struct vki_ucontext *uc )
jsgf855d93d2003-10-13 22:26:55 +00001594{
sewardjb5f6f512005-03-10 23:59:00 +00001595 ThreadId tid = VG_(get_lwp_tid)(VG_(gettid)());
1596 ThreadState *tst = VG_(get_ThreadState)(tid);
jsgf855d93d2003-10-13 22:26:55 +00001597
sewardjb5f6f512005-03-10 23:59:00 +00001598 vg_assert(tst->status == VgTs_WaitSys);
jsgf855d93d2003-10-13 22:26:55 +00001599
sewardjb5f6f512005-03-10 23:59:00 +00001600 /* The thread isn't currently running, make it so before going on */
1601 VG_(set_running)(tid);
1602
1603 if (VG_(clo_trace_signals))
1604 VG_(message)(Vg_DebugMsg, "Async handler got signal %d for tid %d info %d",
1605 sigNo, tid, info->si_code);
1606
1607 /* Update thread state properly */
njn605f4882005-05-29 17:50:40 +00001608 VGP_(interrupted_syscall)(tid,
1609 VGP_UCONTEXT_INSTR_PTR(uc),
1610 VGP_UCONTEXT_SYSCALL_NUM(uc),
1611 VGP_UCONTEXT_SYSCALL_RET(uc),
njn695c16e2005-03-27 03:40:28 +00001612 !!(scss.scss_per_sig[sigNo].scss_flags & VKI_SA_RESTART));
sewardjb5f6f512005-03-10 23:59:00 +00001613
1614 /* Set up the thread's state to deliver a signal */
njn07ef6c02005-05-18 19:43:09 +00001615 if (!is_sig_ign(info->si_signo))
njn9ec0f3e2005-03-13 06:00:47 +00001616 deliver_signal(tid, info);
sewardjb5f6f512005-03-10 23:59:00 +00001617
1618 /* longjmp back to the thread's main loop to start executing the
1619 handler. */
1620 VG_(resume_scheduler)(tid);
1621
njn695c16e2005-03-27 03:40:28 +00001622 VG_(core_panic)("async_signalhandler: got unexpected signal while outside of scheduler");
jsgf855d93d2003-10-13 22:26:55 +00001623}
1624
sewardjb5f6f512005-03-10 23:59:00 +00001625/* Extend the stack to cover addr. maxsize is the limit the stack can grow to.
1626
1627 Returns True on success, False on failure.
1628
1629 Succeeds without doing anything if addr is already within a segment.
1630
1631 Failure could be caused by:
1632 - addr not below a growable segment
1633 - new stack size would exceed maxsize
1634 - mmap failed for some other reason
1635 */
1636Bool VG_(extend_stack)(Addr addr, UInt maxsize)
1637{
1638 Segment *seg;
1639 Addr base;
1640 UInt newsize;
1641
1642 /* Find the next Segment above addr */
1643 seg = VG_(find_segment)(addr);
1644 if (seg)
1645 return True;
1646
1647 /* now we know addr is definitely unmapped */
1648 seg = VG_(find_segment_above_unmapped)(addr);
1649
1650 /* If there isn't one, or it isn't growable, fail */
1651 if (seg == NULL ||
1652 !(seg->flags & SF_GROWDOWN) ||
1653 VG_(seg_contains)(seg, addr, sizeof(void *)))
1654 return False;
1655
1656 vg_assert(seg->addr > addr);
1657
1658 /* Create the mapping */
1659 base = PGROUNDDN(addr);
1660 newsize = seg->addr - base;
1661
1662 if (seg->len + newsize >= maxsize)
1663 return False;
1664
1665 if (VG_(mmap)((Char *)base, newsize,
1666 seg->prot,
1667 VKI_MAP_PRIVATE | VKI_MAP_FIXED | VKI_MAP_ANONYMOUS | VKI_MAP_CLIENT,
1668 seg->flags,
1669 -1, 0) == (void *)-1)
1670 return False;
1671
1672 if (0)
1673 VG_(printf)("extended stack: %p %d\n",
1674 base, newsize);
1675
1676 if (VG_(clo_sanity_level) > 2)
1677 VG_(sanity_check_general)(False);
1678
1679 return True;
1680}
1681
1682static void (*fault_catcher)(Int sig, Addr addr);
1683
1684void VG_(set_fault_catcher)(void (*catcher)(Int, Addr))
1685{
njn50ae1a72005-04-08 23:28:23 +00001686 vg_assert2(NULL == catcher || NULL == fault_catcher,
1687 "Fault catcher is already registered");
sewardjb5f6f512005-03-10 23:59:00 +00001688
1689 fault_catcher = catcher;
1690}
1691
1692
jsgf855d93d2003-10-13 22:26:55 +00001693/*
sewardj2a99cf62004-11-24 10:44:19 +00001694 Receive a sync signal from the host.
jsgf855d93d2003-10-13 22:26:55 +00001695*/
1696static
njn695c16e2005-03-27 03:40:28 +00001697void sync_signalhandler ( Int sigNo, vki_siginfo_t *info, struct vki_ucontext *uc )
jsgf855d93d2003-10-13 22:26:55 +00001698{
sewardjb5f6f512005-03-10 23:59:00 +00001699 ThreadId tid = VG_(get_lwp_tid)(VG_(gettid)());
jsgf855d93d2003-10-13 22:26:55 +00001700
1701 vg_assert(info != NULL);
1702 vg_assert(info->si_signo == sigNo);
1703 vg_assert(sigNo == VKI_SIGSEGV ||
1704 sigNo == VKI_SIGBUS ||
1705 sigNo == VKI_SIGFPE ||
sewardjb5f6f512005-03-10 23:59:00 +00001706 sigNo == VKI_SIGILL ||
1707 sigNo == VKI_SIGTRAP);
jsgf855d93d2003-10-13 22:26:55 +00001708
sewardjb5f6f512005-03-10 23:59:00 +00001709 if (info->si_code <= VKI_SI_USER) {
1710 /* If some user-process sent us one of these signals (ie,
1711 they're not the result of a faulting instruction), then treat
1712 it as an async signal. This is tricky because we could get
1713 this almost anywhere:
1714 - while generated client code
1715 Action: queue signal and return
1716 - while running Valgrind code
1717 Action: queue signal and return
1718 - while blocked in a syscall
1719 Action: make thread runnable, queue signal, resume scheduler
1720 */
1721 if (VG_(threads)[tid].status == VgTs_WaitSys) {
1722 /* Since this signal interrupted a syscall, it means the
1723 client's signal mask was applied, so we can't get here
1724 unless the client wants this signal right now. This means
1725 we can simply use the async_signalhandler. */
njn695c16e2005-03-27 03:40:28 +00001726 async_signalhandler(sigNo, info, uc);
1727 VG_(core_panic)("async_signalhandler returned!?\n");
sewardjb5f6f512005-03-10 23:59:00 +00001728 }
jsgf855d93d2003-10-13 22:26:55 +00001729
sewardjb5f6f512005-03-10 23:59:00 +00001730 if (info->_sifields._kill._pid == 0) {
1731 /* There's a per-user limit of pending siginfo signals. If
1732 you exceed this, by having more than that number of
1733 pending signals with siginfo, then new signals are
1734 delivered without siginfo. This condition can be caused
1735 by any unrelated program you're running at the same time
1736 as Valgrind, if it has a large number of pending siginfo
1737 signals which it isn't taking delivery of.
1738
1739 Since we depend on siginfo to work out why we were sent a
1740 signal and what we should do about it, we really can't
1741 continue unless we get it. */
1742 VG_(message)(Vg_UserMsg, "Signal %d (%s) appears to have lost its siginfo; I can't go on.",
1743 sigNo, signame(sigNo));
1744 VG_(message)(Vg_UserMsg, " This may be because one of your programs has consumed your");
1745 VG_(message)(Vg_UserMsg, " ration of siginfo structures.");
1746
1747 /* It's a fatal signal, so we force the default handler. */
1748 VG_(set_default_handler)(sigNo);
njn9ec0f3e2005-03-13 06:00:47 +00001749 deliver_signal(tid, info);
sewardjb5f6f512005-03-10 23:59:00 +00001750 VG_(resume_scheduler)(tid);
1751 VG_(exit)(99); /* If we can't resume, then just exit */
1752 }
1753
1754 if (VG_(clo_trace_signals))
1755 VG_(message)(Vg_DebugMsg, "Routing user-sent sync signal %d via queue",
1756 sigNo);
1757
1758 /* Since every thread has these signals unblocked, we can't rely
1759 on the kernel to route them properly, so we need to queue
1760 them manually. */
1761 if (info->si_code == VKI_SI_TKILL)
1762 queue_signal(tid, info); /* directed to us specifically */
1763 else
1764 queue_signal(0, info); /* shared pending */
1765
jsgf855d93d2003-10-13 22:26:55 +00001766 return;
sewardjb5f6f512005-03-10 23:59:00 +00001767 }
1768
1769 if (VG_(clo_trace_signals)) {
1770 VG_(message)(Vg_DebugMsg, "signal %d arrived ... si_code=%d, EIP=%p, eip=%p",
1771 sigNo, info->si_code,
1772 INSTR_PTR(VG_(threads)[tid].arch),
njnf6d228b2005-03-26 02:42:31 +00001773 VGP_UCONTEXT_INSTR_PTR(uc) );
jsgf855d93d2003-10-13 22:26:55 +00001774 }
sewardjb5f6f512005-03-10 23:59:00 +00001775 vg_assert(sigNo >= 1 && sigNo <= VG_(max_signal));
sewardjde4a1d02002-03-22 01:27:54 +00001776
fitzhardinge98abfc72003-12-16 02:05:15 +00001777 /* Special fault-handling case. We can now get signals which can
1778 act upon and immediately restart the faulting instruction.
1779 */
1780 if (info->si_signo == VKI_SIGSEGV) {
fitzhardinge98abfc72003-12-16 02:05:15 +00001781 Addr fault = (Addr)info->_sifields._sigfault._addr;
njncf45fd42004-11-24 16:30:22 +00001782 Addr esp = STACK_PTR(VG_(threads)[tid].arch);
sewardjb5f6f512005-03-10 23:59:00 +00001783 Segment* seg;
fitzhardinge98abfc72003-12-16 02:05:15 +00001784
1785 seg = VG_(find_segment)(fault);
sewardj548be6d2005-02-16 01:31:37 +00001786 if (seg == NULL)
1787 seg = VG_(find_segment_above_unmapped)(fault);
1788
fitzhardinge98abfc72003-12-16 02:05:15 +00001789 if (VG_(clo_trace_signals)) {
1790 if (seg == NULL)
1791 VG_(message)(Vg_DebugMsg,
sewardjb5f6f512005-03-10 23:59:00 +00001792 "SIGSEGV: si_code=%d faultaddr=%p tid=%d ESP=%p seg=NULL shad=%p-%p",
fitzhardinge98abfc72003-12-16 02:05:15 +00001793 info->si_code, fault, tid, esp,
1794 VG_(shadow_base), VG_(shadow_end));
1795 else
1796 VG_(message)(Vg_DebugMsg,
sewardjb5f6f512005-03-10 23:59:00 +00001797 "SIGSEGV: si_code=%d faultaddr=%p tid=%d ESP=%p seg=%p-%p fl=%x shad=%p-%p",
fitzhardinge98abfc72003-12-16 02:05:15 +00001798 info->si_code, fault, tid, esp, seg->addr, seg->addr+seg->len, seg->flags,
1799 VG_(shadow_base), VG_(shadow_end));
1800 }
sewardjb5f6f512005-03-10 23:59:00 +00001801 if (info->si_code == 1 /* SEGV_MAPERR */
njna60a7c12005-05-08 17:49:37 +00001802 && fault >= (esp - VGA_STACK_REDZONE_SZB)
njncafca7b2005-03-13 04:39:28 +00001803 && fault < VG_(client_end)) {
fitzhardinge98abfc72003-12-16 02:05:15 +00001804 /* If the fault address is above esp but below the current known
1805 stack segment base, and it was a fault because there was
1806 nothing mapped there (as opposed to a permissions fault),
1807 then extend the stack segment.
1808 */
njna60a7c12005-05-08 17:49:37 +00001809 Addr base = PGROUNDDN(esp - VGA_STACK_REDZONE_SZB);
njn50ba34e2005-04-04 02:41:42 +00001810 if (VG_(extend_stack)(base, VG_(threads)[tid].client_stack_szB)) {
sewardjb5f6f512005-03-10 23:59:00 +00001811 if (VG_(clo_trace_signals))
1812 VG_(message)(Vg_DebugMsg,
1813 " -> extended stack base to %p", PGROUNDDN(fault));
1814 return; // extension succeeded, restart instruction
1815 } else
1816 VG_(message)(Vg_UserMsg, "Stack overflow in thread %d: can't grow stack to %p",
1817 tid, fault);
1818
1819 /* Fall into normal signal handling for all other cases */
fitzhardinge98abfc72003-12-16 02:05:15 +00001820 } else if (info->si_code == 2 && /* SEGV_ACCERR */
1821 VG_(needs).shadow_memory &&
1822 VG_(is_shadow_addr)(fault)) {
1823 /* If there's a fault within the shadow memory range, and it
1824 is a permissions fault, then it means that the client is
1825 using some memory which had not previously been used.
1826 This catches those faults, makes the memory accessible,
nethercote7cc9c232004-01-21 15:08:04 +00001827 and calls the tool to initialize that page.
fitzhardinge98abfc72003-12-16 02:05:15 +00001828 */
1829 static Int recursion = 0;
1830
1831 if (recursion++ == 0) {
nethercote73b526f2004-10-31 18:48:21 +00001832 VG_(init_shadow_range)(PGROUNDDN(fault), VKI_PAGE_SIZE, True);
fitzhardinge98abfc72003-12-16 02:05:15 +00001833 recursion--;
1834 return;
1835 } else {
1836 /* otherwise fall into normal SEGV handling */
1837 recursion--;
1838 }
1839 }
1840 }
1841
sewardjb5f6f512005-03-10 23:59:00 +00001842 /* OK, this is a signal we really have to deal with. If it came
1843 from the client's code, then we can jump back into the scheduler
1844 and have it delivered. Otherwise it's a Valgrind bug. */
1845 {
njnd01fef72005-03-25 23:35:48 +00001846 Addr ips[ VG_(clo_backtrace_size) ];
sewardjb5f6f512005-03-10 23:59:00 +00001847 ThreadState *tst = VG_(get_ThreadState)(VG_(get_lwp_tid)(VG_(gettid)()));
jsgf855d93d2003-10-13 22:26:55 +00001848
sewardjb5f6f512005-03-10 23:59:00 +00001849 if (VG_(sigismember)(&tst->sig_mask, sigNo)) {
1850 /* signal is blocked, but they're not allowed to block faults */
1851 VG_(set_default_handler)(sigNo);
1852 }
1853
1854 if (!VG_(my_fault)) {
1855 /* Can't continue; must longjmp back to the scheduler and thus
1856 enter the sighandler immediately. */
njn9ec0f3e2005-03-13 06:00:47 +00001857 deliver_signal(tid, info);
sewardjb5f6f512005-03-10 23:59:00 +00001858 VG_(resume_scheduler)(tid);
1859 }
1860
1861 /* Check to see if someone is interested in faults. */
1862 if (fault_catcher) {
1863 (*fault_catcher)(sigNo, (Addr)info->_sifields._sigfault._addr);
1864
1865 /* If the catcher returns, then it didn't handle the fault,
1866 so carry on panicing. */
1867 }
1868
1869 /* If resume_scheduler returns or its our fault, it means we
1870 don't have longjmp set up, implying that we weren't running
1871 client code, and therefore it was actually generated by
1872 Valgrind internally.
1873 */
jsgf855d93d2003-10-13 22:26:55 +00001874 VG_(message)(Vg_DebugMsg,
1875 "INTERNAL ERROR: Valgrind received a signal %d (%s) - exiting",
1876 sigNo, signame(sigNo));
fitzhardinge98abfc72003-12-16 02:05:15 +00001877
jsgf855d93d2003-10-13 22:26:55 +00001878 VG_(message)(Vg_DebugMsg,
njnd0073f42005-05-14 17:00:25 +00001879 "si_code=%x; Faulting address: %p; sp: %p",
1880 info->si_code, info->_sifields._sigfault._addr,
1881 VGP_UCONTEXT_STACK_PTR(uc));
jsgf855d93d2003-10-13 22:26:55 +00001882
1883 if (0)
1884 VG_(kill_self)(sigNo); /* generate a core dump */
sewardjb5f6f512005-03-10 23:59:00 +00001885
sewardj1d887112005-05-30 21:44:08 +00001886 //if (tid == 0) /* could happen after everyone has exited */
1887 // tid = VG_(master_tid);
1888 vg_assert(tid != 0);
1889
njncafca7b2005-03-13 04:39:28 +00001890 tst = VG_(get_ThreadState)(tid);
njnd01fef72005-03-25 23:35:48 +00001891 VG_(get_StackTrace2)(ips, VG_(clo_backtrace_size),
njnf6d228b2005-03-26 02:42:31 +00001892 VGP_UCONTEXT_INSTR_PTR(uc),
sewardj35165532005-04-30 18:47:48 +00001893 VGP_UCONTEXT_STACK_PTR(uc),
njnf6d228b2005-03-26 02:42:31 +00001894 VGP_UCONTEXT_FRAME_PTR(uc),
1895 VGP_UCONTEXT_STACK_PTR(uc),
njn990e90c2005-04-05 02:49:09 +00001896 tst->os_state.valgrind_stack_base +
1897 tst->os_state.valgrind_stack_szB);
njnd01fef72005-03-25 23:35:48 +00001898 VG_(core_panic_at)("Killed by fatal signal", ips);
jsgf855d93d2003-10-13 22:26:55 +00001899 }
1900}
1901
1902
1903/*
sewardjb5f6f512005-03-10 23:59:00 +00001904 Kill this thread. Makes it leave any syscall it might be currently
1905 blocked in, and return to the scheduler. This doesn't mark the thread
1906 as exiting; that's the caller's job.
jsgf855d93d2003-10-13 22:26:55 +00001907 */
sewardjb5f6f512005-03-10 23:59:00 +00001908static void sigvgkill_handler(int signo, vki_siginfo_t *si, struct vki_ucontext *uc)
jsgf855d93d2003-10-13 22:26:55 +00001909{
sewardjb5f6f512005-03-10 23:59:00 +00001910 ThreadId tid = VG_(get_lwp_tid)(VG_(gettid)());
1911
1912 if (VG_(clo_trace_signals))
1913 VG_(message)(Vg_DebugMsg, "sigvgkill for lwp %d tid %d", VG_(gettid)(), tid);
1914
1915 vg_assert(signo == VKI_SIGVGKILL);
jsgf855d93d2003-10-13 22:26:55 +00001916 vg_assert(si->si_signo == signo);
sewardjb5f6f512005-03-10 23:59:00 +00001917 vg_assert(VG_(threads)[tid].status == VgTs_WaitSys);
jsgf855d93d2003-10-13 22:26:55 +00001918
sewardjb5f6f512005-03-10 23:59:00 +00001919 VG_(set_running)(tid);
1920 VG_(post_syscall)(tid);
1921
1922 VG_(resume_scheduler)(tid);
1923
1924 VG_(core_panic)("sigvgkill_handler couldn't return to the scheduler\n");
sewardjde4a1d02002-03-22 01:27:54 +00001925}
1926
sewardjde4a1d02002-03-22 01:27:54 +00001927static __attribute((unused))
njn695c16e2005-03-27 03:40:28 +00001928void pp_ksigaction ( struct vki_sigaction* sa )
sewardjde4a1d02002-03-22 01:27:54 +00001929{
1930 Int i;
njn695c16e2005-03-27 03:40:28 +00001931 VG_(printf)("pp_ksigaction: handler %p, flags 0x%x, restorer %p\n",
nethercote73b526f2004-10-31 18:48:21 +00001932 sa->ksa_handler, (UInt)sa->sa_flags, sa->sa_restorer);
njn695c16e2005-03-27 03:40:28 +00001933 VG_(printf)("pp_ksigaction: { ");
sewardjb5f6f512005-03-10 23:59:00 +00001934 for (i = 1; i <= VG_(max_signal); i++)
nethercote73b526f2004-10-31 18:48:21 +00001935 if (VG_(sigismember(&(sa->sa_mask),i)))
sewardjde4a1d02002-03-22 01:27:54 +00001936 VG_(printf)("%d ", i);
1937 VG_(printf)("}\n");
1938}
1939
jsgf855d93d2003-10-13 22:26:55 +00001940/*
sewardjb5f6f512005-03-10 23:59:00 +00001941 Force signal handler to default
jsgf855d93d2003-10-13 22:26:55 +00001942 */
sewardjb5f6f512005-03-10 23:59:00 +00001943void VG_(set_default_handler)(Int signo)
1944{
1945 struct vki_sigaction sa;
1946
1947 sa.ksa_handler = VKI_SIG_DFL;
1948 sa.sa_flags = 0;
1949 sa.sa_restorer = 0;
1950 VG_(sigemptyset)(&sa.sa_mask);
1951
1952 VG_(do_sys_sigaction)(signo, &sa, NULL);
1953}
1954
1955/*
1956 Poll for pending signals, and set the next one up for delivery.
1957 */
1958void VG_(poll_signals)(ThreadId tid)
jsgf855d93d2003-10-13 22:26:55 +00001959{
1960 static const struct vki_timespec zero = { 0, 0 };
sewardjb5f6f512005-03-10 23:59:00 +00001961 vki_siginfo_t si, *sip;
1962 vki_sigset_t pollset;
1963 ThreadState *tst = VG_(get_ThreadState)(tid);
1964 Int i;
1965 vki_sigset_t saved_mask;
jsgf855d93d2003-10-13 22:26:55 +00001966
sewardjb5f6f512005-03-10 23:59:00 +00001967 /* look for all the signals this thread isn't blocking */
1968 for(i = 0; i < _VKI_NSIG_WORDS; i++)
1969 pollset.sig[i] = ~tst->sig_mask.sig[i];
jsgf855d93d2003-10-13 22:26:55 +00001970
sewardjb5f6f512005-03-10 23:59:00 +00001971 //VG_(printf)("tid %d pollset=%08x%08x\n", tid, pollset.sig[1], pollset.sig[0]);
jsgf855d93d2003-10-13 22:26:55 +00001972
njn444eba12005-05-12 03:47:31 +00001973 block_all_host_signals(&saved_mask); // protect signal queue
sewardjb5f6f512005-03-10 23:59:00 +00001974
1975 /* First look for any queued pending signals */
1976 sip = next_queued(tid, &pollset); /* this thread */
1977
1978 if (sip == NULL)
1979 sip = next_queued(0, &pollset); /* process-wide */
1980
1981 /* If there was nothing queued, ask the kernel for a pending signal */
1982 if (sip == NULL && VG_(sigtimedwait)(&pollset, &si, &zero) > 0) {
1983 if (VG_(clo_trace_signals))
1984 VG_(message)(Vg_DebugMsg, "poll_signals: got signal %d for thread %d", si.si_signo, tid);
1985 sip = &si;
thughes8abf3922004-10-16 10:59:49 +00001986 }
fitzhardingee1c06d82003-10-30 07:21:44 +00001987
sewardjb5f6f512005-03-10 23:59:00 +00001988 if (sip != NULL) {
1989 /* OK, something to do; deliver it */
1990 if (VG_(clo_trace_signals))
1991 VG_(message)(Vg_DebugMsg, "Polling found signal %d for tid %d",
1992 sip->si_signo, tid);
njn07ef6c02005-05-18 19:43:09 +00001993 if (!is_sig_ign(sip->si_signo))
njn9ec0f3e2005-03-13 06:00:47 +00001994 deliver_signal(tid, sip);
sewardjb5f6f512005-03-10 23:59:00 +00001995 else if (VG_(clo_trace_signals))
1996 VG_(message)(Vg_DebugMsg, " signal %d ignored", sip->si_signo);
1997
1998 sip->si_signo = 0; /* remove from signal queue, if that's
1999 where it came from */
jsgf855d93d2003-10-13 22:26:55 +00002000 }
2001
njn444eba12005-05-12 03:47:31 +00002002 restore_all_host_signals(&saved_mask);
sewardjb5f6f512005-03-10 23:59:00 +00002003}
2004
sewardj018f7622002-05-15 21:13:39 +00002005/* At startup, copy the process' real signal state to the SCSS.
2006 Whilst doing this, block all real signals. Then calculate SKSS and
2007 set the kernel to that. Also initialise DCSS.
sewardjde4a1d02002-03-22 01:27:54 +00002008*/
2009void VG_(sigstartup_actions) ( void )
2010{
2011 Int i, ret;
nethercote73b526f2004-10-31 18:48:21 +00002012 vki_sigset_t saved_procmask;
nethercote73b526f2004-10-31 18:48:21 +00002013 struct vki_sigaction sa;
sewardjde4a1d02002-03-22 01:27:54 +00002014
sewardj2e93c502002-04-12 11:12:52 +00002015 /* VG_(printf)("SIGSTARTUP\n"); */
jsgf855d93d2003-10-13 22:26:55 +00002016 /* Block all signals. saved_procmask remembers the previous mask,
2017 which the first thread inherits.
2018 */
njn444eba12005-05-12 03:47:31 +00002019 block_all_host_signals( &saved_procmask );
sewardjde4a1d02002-03-22 01:27:54 +00002020
sewardj018f7622002-05-15 21:13:39 +00002021 /* Copy per-signal settings to SCSS. */
nethercote73b526f2004-10-31 18:48:21 +00002022 for (i = 1; i <= _VKI_NSIG; i++) {
sewardj018f7622002-05-15 21:13:39 +00002023 /* Get the old host action */
nethercote73b526f2004-10-31 18:48:21 +00002024 ret = VG_(sigaction)(i, NULL, &sa);
sewardj018f7622002-05-15 21:13:39 +00002025
sewardjb5f6f512005-03-10 23:59:00 +00002026 if (ret != 0)
2027 break;
2028
2029 /* Try setting it back to see if this signal is really
2030 available */
2031 if (i >= VKI_SIGRTMIN) {
2032 struct vki_sigaction tsa;
2033
njn695c16e2005-03-27 03:40:28 +00002034 tsa.ksa_handler = (void *)sync_signalhandler;
sewardjb5f6f512005-03-10 23:59:00 +00002035 tsa.sa_flags = VKI_SA_SIGINFO;
2036 tsa.sa_restorer = 0;
2037 VG_(sigfillset)(&tsa.sa_mask);
2038
2039 /* try setting it to some arbitrary handler */
2040 if (VG_(sigaction)(i, &tsa, NULL) != 0) {
2041 /* failed - not really usable */
2042 break;
2043 }
2044
2045 ret = VG_(sigaction)(i, &sa, NULL);
2046 vg_assert(ret == 0);
2047 }
2048
2049 VG_(max_signal) = i;
2050
2051 if (VG_(clo_trace_signals) && VG_(clo_verbosity) > 2)
sewardj018f7622002-05-15 21:13:39 +00002052 VG_(printf)("snaffling handler 0x%x for signal %d\n",
2053 (Addr)(sa.ksa_handler), i );
2054
njn695c16e2005-03-27 03:40:28 +00002055 scss.scss_per_sig[i].scss_handler = sa.ksa_handler;
2056 scss.scss_per_sig[i].scss_flags = sa.sa_flags;
2057 scss.scss_per_sig[i].scss_mask = sa.sa_mask;
2058 scss.scss_per_sig[i].scss_restorer = sa.sa_restorer;
sewardj018f7622002-05-15 21:13:39 +00002059 }
2060
sewardjb5f6f512005-03-10 23:59:00 +00002061 if (VG_(clo_trace_signals))
2062 VG_(message)(Vg_DebugMsg, "Max kernel-supported signal is %d", VG_(max_signal));
2063
jsgf855d93d2003-10-13 22:26:55 +00002064 /* Our private internal signals are treated as ignored */
njn695c16e2005-03-27 03:40:28 +00002065 scss.scss_per_sig[VKI_SIGVGKILL].scss_handler = VKI_SIG_IGN;
2066 scss.scss_per_sig[VKI_SIGVGKILL].scss_flags = VKI_SA_SIGINFO;
2067 VG_(sigfillset)(&scss.scss_per_sig[VKI_SIGVGKILL].scss_mask);
jsgf855d93d2003-10-13 22:26:55 +00002068
sewardj018f7622002-05-15 21:13:39 +00002069 /* Copy the process' signal mask into the root thread. */
sewardj1d887112005-05-30 21:44:08 +00002070 vg_assert(VG_(threads)[1].status == VgTs_Init);
2071 for (i = 2; i < VG_N_THREADS; i++)
2072 vg_assert(VG_(threads)[i].status == VgTs_Empty);
2073
2074 VG_(threads)[1].sig_mask = saved_procmask;
2075 VG_(threads)[1].tmp_sig_mask = saved_procmask;
sewardj7a61d912002-04-25 01:27:35 +00002076
sewardj018f7622002-05-15 21:13:39 +00002077 /* Calculate SKSS and apply it. This also sets the initial kernel
2078 mask we need to run with. */
nethercote9dd11512004-08-04 15:31:30 +00002079 handle_SCSS_change( True /* forced update */ );
jsgf855d93d2003-10-13 22:26:55 +00002080
sewardjb5f6f512005-03-10 23:59:00 +00002081 /* Leave with all signals still blocked; the thread scheduler loop
2082 will set the appropriate mask at the appropriate time. */
sewardjde4a1d02002-03-22 01:27:54 +00002083}
2084
sewardjde4a1d02002-03-22 01:27:54 +00002085/*--------------------------------------------------------------------*/
2086/*--- end vg_signals.c ---*/
2087/*--------------------------------------------------------------------*/