blob: 9198482b85ed343c595f7b9202fcaa275156f0f3 [file] [log] [blame]
sewardjde4a1d02002-03-22 01:27:54 +00001
2/*--------------------------------------------------------------------*/
njned6b8242005-06-01 00:03:17 +00003/*--- Implementation of POSIX signals. m_signals.c ---*/
sewardjde4a1d02002-03-22 01:27:54 +00004/*--------------------------------------------------------------------*/
njned6b8242005-06-01 00:03:17 +00005
sewardjde4a1d02002-03-22 01:27:54 +00006/*
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
njnc7561b92005-06-19 01:24:32 +000082#include "pub_core_basics.h"
sewardj45f4e7c2005-09-27 19:20:21 +000083#include "pub_core_debuglog.h"
njnc7561b92005-06-19 01:24:32 +000084#include "pub_core_threadstate.h"
sewardj45f4e7c2005-09-27 19:20:21 +000085#include "pub_core_clientstate.h"
njn2521d322005-05-08 14:45:13 +000086#include "pub_core_aspacemgr.h"
njn634a6522005-07-02 01:59:28 +000087#include "pub_core_debugger.h" // For VG_(start_debugger)
njnd2b17112005-04-19 04:10:25 +000088#include "pub_core_errormgr.h"
njn97405b22005-06-02 03:39:33 +000089#include "pub_core_libcbase.h"
njn132bfcc2005-06-04 19:16:06 +000090#include "pub_core_libcassert.h"
njn36a20fa2005-06-03 03:08:39 +000091#include "pub_core_libcprint.h"
njnf39e9a32005-06-12 02:43:17 +000092#include "pub_core_libcproc.h"
njnde62cbf2005-06-10 22:08:14 +000093#include "pub_core_libcsignal.h"
njnf536bbb2005-06-13 04:21:38 +000094#include "pub_core_machine.h"
njnaf1d7df2005-06-11 01:31:52 +000095#include "pub_core_mallocfree.h"
njn20242342005-05-16 23:31:24 +000096#include "pub_core_options.h"
njnc7561b92005-06-19 01:24:32 +000097#include "pub_core_scheduler.h"
njn0c246472005-05-31 01:00:08 +000098#include "pub_core_signals.h"
njn24a6efb2005-06-20 03:36:51 +000099#include "pub_core_sigframe.h" // For VG_(sigframe_create)()
njn945ed2e2005-06-24 03:28:30 +0000100#include "pub_core_stacks.h" // For VG_(change_stack)()
njn24a6efb2005-06-20 03:36:51 +0000101#include "pub_core_stacktrace.h" // For VG_(get_and_pp_StackTrace)()
njn9abd6082005-06-17 21:31:45 +0000102#include "pub_core_syscall.h"
njnc1b01812005-06-17 22:19:06 +0000103#include "pub_core_syswrap.h"
njn43b9a8a2005-05-10 04:37:01 +0000104#include "pub_core_tooliface.h"
sewardjcf4ac712005-11-01 00:03:40 +0000105#include "pub_core_coredump.h"
njn9abd6082005-06-17 21:31:45 +0000106#include "vki_unistd.h"
sewardj985fabb2005-04-24 14:18:14 +0000107
njnd2b17112005-04-19 04:10:25 +0000108
sewardj018f7622002-05-15 21:13:39 +0000109/* Define to give more sanity checking for signals. */
110#define DEBUG_SIGNALS
111
112
113/* ---------------------------------------------------------------------
114 Forwards decls.
115 ------------------------------------------------------------------ */
116
njn695c16e2005-03-27 03:40:28 +0000117static void sync_signalhandler ( Int sigNo, vki_siginfo_t *info, struct vki_ucontext * );
118static void async_signalhandler ( Int sigNo, vki_siginfo_t *info, struct vki_ucontext * );
sewardjb5f6f512005-03-10 23:59:00 +0000119static void sigvgkill_handler ( Int sigNo, vki_siginfo_t *info, struct vki_ucontext * );
sewardj018f7622002-05-15 21:13:39 +0000120
jsgf855d93d2003-10-13 22:26:55 +0000121static const Char *signame(Int sigNo);
sewardj018f7622002-05-15 21:13:39 +0000122
sewardjb5f6f512005-03-10 23:59:00 +0000123/* Maximum usable signal. */
124Int VG_(max_signal) = _VKI_NSIG;
nethercote759dda32004-08-07 18:16:56 +0000125
sewardjb5f6f512005-03-10 23:59:00 +0000126#define N_QUEUED_SIGNALS 8
nethercote759dda32004-08-07 18:16:56 +0000127
sewardjb5f6f512005-03-10 23:59:00 +0000128typedef struct SigQueue {
129 Int next;
130 vki_siginfo_t sigs[N_QUEUED_SIGNALS];
131} SigQueue;
nethercote759dda32004-08-07 18:16:56 +0000132
njn605f4882005-05-29 17:50:40 +0000133#if defined(VGP_x86_linux)
njnaf839f52005-06-23 03:27:57 +0000134# define VG_UCONTEXT_INSTR_PTR(uc) ((uc)->uc_mcontext.eip)
135# define VG_UCONTEXT_STACK_PTR(uc) ((uc)->uc_mcontext.esp)
136# define VG_UCONTEXT_FRAME_PTR(uc) ((uc)->uc_mcontext.ebp)
137# define VG_UCONTEXT_SYSCALL_NUM(uc) ((uc)->uc_mcontext.eax)
sewardjacaec5f2005-08-19 16:02:59 +0000138# define VG_UCONTEXT_SYSCALL_SYSRES(uc) \
sewardja8d8e232005-06-07 20:04:56 +0000139 /* Convert the value in uc_mcontext.eax into a SysRes. */ \
cerion85665ca2005-06-20 15:51:07 +0000140 VG_(mk_SysRes_x86_linux)( (uc)->uc_mcontext.eax )
sewardjacaec5f2005-08-19 16:02:59 +0000141# define VG_UCONTEXT_LINK_REG(uc) 0 /* Dude, where's my LR? */
sewardje7aa4ae2005-06-09 12:43:42 +0000142
njn605f4882005-05-29 17:50:40 +0000143#elif defined(VGP_amd64_linux)
njnaf839f52005-06-23 03:27:57 +0000144# define VG_UCONTEXT_INSTR_PTR(uc) ((uc)->uc_mcontext.rip)
145# define VG_UCONTEXT_STACK_PTR(uc) ((uc)->uc_mcontext.rsp)
146# define VG_UCONTEXT_FRAME_PTR(uc) ((uc)->uc_mcontext.rbp)
147# define VG_UCONTEXT_SYSCALL_NUM(uc) ((uc)->uc_mcontext.rax)
sewardjacaec5f2005-08-19 16:02:59 +0000148# define VG_UCONTEXT_SYSCALL_SYSRES(uc) \
sewardje7aa4ae2005-06-09 12:43:42 +0000149 /* Convert the value in uc_mcontext.rax into a SysRes. */ \
cerion85665ca2005-06-20 15:51:07 +0000150 VG_(mk_SysRes_amd64_linux)( (uc)->uc_mcontext.rax )
sewardjacaec5f2005-08-19 16:02:59 +0000151# define VG_UCONTEXT_LINK_REG(uc) 0 /* No LR on amd64 either */
sewardje7aa4ae2005-06-09 12:43:42 +0000152
cerion85665ca2005-06-20 15:51:07 +0000153#elif defined(VGP_ppc32_linux)
sewardja36dcfa2005-11-25 02:16:58 +0000154/* Comments from Paul Mackerras 25 Nov 05:
155
156 > I'm tracking down a problem where V's signal handling doesn't
157 > work properly on a ppc440gx running 2.4.20. The problem is that
158 > the ucontext being presented to V's sighandler seems completely
159 > bogus.
160
161 > V's kernel headers and hence ucontext layout are derived from
162 > 2.6.9. I compared include/asm-ppc/ucontext.h from 2.4.20 and
163 > 2.6.13.
164
165 > Can I just check my interpretation: the 2.4.20 one contains the
166 > uc_mcontext field in line, whereas the 2.6.13 one has a pointer
167 > to said struct? And so if V is using the 2.6.13 struct then a
168 > 2.4.20 one will make no sense to it.
169
170 Not quite... what is inline in the 2.4.20 version is a
171 sigcontext_struct, not an mcontext. The sigcontext looks like
172 this:
173
174 struct sigcontext_struct {
175 unsigned long _unused[4];
176 int signal;
177 unsigned long handler;
178 unsigned long oldmask;
179 struct pt_regs *regs;
180 };
181
182 The regs pointer of that struct ends up at the same offset as the
183 uc_regs of the 2.6 struct ucontext, and a struct pt_regs is the
184 same as the mc_gregs field of the mcontext. In fact the integer
185 regs are followed in memory by the floating point regs on 2.4.20.
186
187 Thus if you are using the 2.6 definitions, it should work on 2.4.20
188 provided that you go via uc->uc_regs rather than looking in
189 uc->uc_mcontext directly.
190
191 There is another subtlety: 2.4.20 doesn't save the vector regs when
192 delivering a signal, and 2.6.x only saves the vector regs if the
193 process has ever used an altivec instructions. If 2.6.x does save
194 the vector regs, it sets the MSR_VEC bit in
195 uc->uc_regs->mc_gregs[PT_MSR], otherwise it clears it. That bit
196 will always be clear under 2.4.20. So you can use that bit to tell
197 whether uc->uc_regs->mc_vregs is valid. */
198# define VG_UCONTEXT_INSTR_PTR(uc) ((uc)->uc_regs->mc_gregs[VKI_PT_NIP])
199# define VG_UCONTEXT_STACK_PTR(uc) ((uc)->uc_regs->mc_gregs[VKI_PT_R1])
200# define VG_UCONTEXT_FRAME_PTR(uc) ((uc)->uc_regs->mc_gregs[VKI_PT_R1])
201# define VG_UCONTEXT_SYSCALL_NUM(uc) ((uc)->uc_regs->mc_gregs[VKI_PT_R0])
sewardj39a7c1d2005-11-24 03:54:38 +0000202# define VG_UCONTEXT_SYSCALL_SYSRES(uc) \
203 /* Convert the values in uc_mcontext r3,cr into a SysRes. */ \
204 VG_(mk_SysRes_ppc32_linux)( \
sewardja36dcfa2005-11-25 02:16:58 +0000205 (uc)->uc_regs->mc_gregs[VKI_PT_R3], \
206 (((uc)->uc_regs->mc_gregs[VKI_PT_CCR] >> 28) & 1) \
sewardj39a7c1d2005-11-24 03:54:38 +0000207 )
sewardja36dcfa2005-11-25 02:16:58 +0000208# define VG_UCONTEXT_LINK_REG(uc) ((uc)->uc_regs->mc_gregs[VKI_PT_LNK])
cerion85665ca2005-06-20 15:51:07 +0000209
sewardj2c48c7b2005-11-29 13:05:56 +0000210#elif defined(VGP_ppc64_linux)
211# define VG_UCONTEXT_INSTR_PTR(uc) ((uc)->uc_mcontext.gp_regs[VKI_PT_NIP])
212# define VG_UCONTEXT_STACK_PTR(uc) ((uc)->uc_mcontext.gp_regs[VKI_PT_R1])
213# define VG_UCONTEXT_FRAME_PTR(uc) ((uc)->uc_mcontext.gp_regs[VKI_PT_R1])
214# define VG_UCONTEXT_SYSCALL_NUM(uc) ((uc)->uc_mcontext.gp_regs[VKI_PT_R0])
sewardjdcb6ec82006-01-19 03:44:10 +0000215#if 0
sewardj2c48c7b2005-11-29 13:05:56 +0000216# define VG_UCONTEXT_SYSCALL_SYSRES(uc) \
217 /* Convert the values in uc_mcontext r3,cr into a SysRes. */ \
218 VG_(mk_SysRes_ppc64_linux)( \
219 (uc)->uc_mcontext.gp_regs[VKI_PT_R3], \
220 (((uc)->uc_mcontext.gp_regs[VKI_PT_CCR] >> 28) & 1) \
221 )
sewardjdcb6ec82006-01-19 03:44:10 +0000222#else
223 /* Dubious hack: if there is an error, only consider the lowest 8
224 bits of r3. memcheck/tests/post-syscall shows a case where an
225 interrupted syscall should have produced a ucontext with 0x4
226 (VKI_EINTR) in r3 but is in fact producing 0x204. */
227 /* Awaiting clarification from PaulM. Evidently 0x204 is
228 ERESTART_RESTARTBLOCK, which shouldn't have made it into user
229 space. */
230 static inline SysRes VG_UCONTEXT_SYSCALL_SYSRES( struct vki_ucontext* uc )
231 {
232 ULong err = (uc->uc_mcontext.gp_regs[VKI_PT_CCR] >> 28) & 1;
233 ULong r3 = uc->uc_mcontext.gp_regs[VKI_PT_R3];
234 if (err) r3 &= 0xFF;
235 return VG_(mk_SysRes_ppc64_linux)( r3, err );
236 }
237#endif
sewardj2c48c7b2005-11-29 13:05:56 +0000238# define VG_UCONTEXT_LINK_REG(uc) ((uc)->uc_mcontext.gp_regs[VKI_PT_LNK])
239
njn605f4882005-05-29 17:50:40 +0000240#else
241# error Unknown platform
242#endif
243
nethercote759dda32004-08-07 18:16:56 +0000244/* ---------------------------------------------------------------------
sewardj018f7622002-05-15 21:13:39 +0000245 HIGH LEVEL STUFF TO DO WITH SIGNALS: POLICY (MOSTLY)
246 ------------------------------------------------------------------ */
247
sewardjde4a1d02002-03-22 01:27:54 +0000248/* ---------------------------------------------------------------------
sewardjde4a1d02002-03-22 01:27:54 +0000249 Signal state for this process.
250 ------------------------------------------------------------------ */
251
sewardj018f7622002-05-15 21:13:39 +0000252
nethercote73b526f2004-10-31 18:48:21 +0000253/* Base-ment of these arrays[_VKI_NSIG].
sewardjb48e5002002-05-13 00:16:03 +0000254
nethercote73b526f2004-10-31 18:48:21 +0000255 Valid signal numbers are 1 .. _VKI_NSIG inclusive.
sewardjb48e5002002-05-13 00:16:03 +0000256 Rather than subtracting 1 for indexing these arrays, which
257 is tedious and error-prone, they are simply dimensioned 1 larger,
258 and entry [0] is not used.
259 */
260
sewardjb48e5002002-05-13 00:16:03 +0000261
sewardj018f7622002-05-15 21:13:39 +0000262/* -----------------------------------------------------
263 Static client signal state (SCSS). This is the state
264 that the client thinks it has the kernel in.
265 SCSS records verbatim the client's settings. These
266 are mashed around only when SKSS is calculated from it.
267 -------------------------------------------------- */
sewardjb48e5002002-05-13 00:16:03 +0000268
sewardj018f7622002-05-15 21:13:39 +0000269typedef
270 struct {
271 void* scss_handler; /* VKI_SIG_DFL or VKI_SIG_IGN or ptr to
272 client's handler */
273 UInt scss_flags;
nethercote73b526f2004-10-31 18:48:21 +0000274 vki_sigset_t scss_mask;
sewardjb5f6f512005-03-10 23:59:00 +0000275 void* scss_restorer; /* where sigreturn goes */
sewardj018f7622002-05-15 21:13:39 +0000276 }
277 SCSS_Per_Signal;
sewardjb48e5002002-05-13 00:16:03 +0000278
sewardj018f7622002-05-15 21:13:39 +0000279typedef
280 struct {
sewardj2342c972002-05-22 23:34:20 +0000281 /* per-signal info */
nethercote73b526f2004-10-31 18:48:21 +0000282 SCSS_Per_Signal scss_per_sig[1+_VKI_NSIG];
sewardj2342c972002-05-22 23:34:20 +0000283
sewardj018f7622002-05-15 21:13:39 +0000284 /* Additional elements to SCSS not stored here:
285 - for each thread, the thread's blocking mask
286 - for each thread in WaitSIG, the set of waited-on sigs
287 */
288 }
289 SCSS;
sewardjb48e5002002-05-13 00:16:03 +0000290
njn695c16e2005-03-27 03:40:28 +0000291static SCSS scss;
sewardj018f7622002-05-15 21:13:39 +0000292
293
294/* -----------------------------------------------------
295 Static kernel signal state (SKSS). This is the state
296 that we have the kernel in. It is computed from SCSS.
297 -------------------------------------------------- */
298
299/* Let's do:
300 sigprocmask assigns to all thread masks
301 so that at least everything is always consistent
302 Flags:
jsgf855d93d2003-10-13 22:26:55 +0000303 SA_SIGINFO -- we always set it, and honour it for the client
sewardj018f7622002-05-15 21:13:39 +0000304 SA_NOCLDSTOP -- passed to kernel
sewardjb5f6f512005-03-10 23:59:00 +0000305 SA_ONESHOT or SA_RESETHAND -- pass through
jsgf855d93d2003-10-13 22:26:55 +0000306 SA_RESTART -- we observe this but set our handlers to always restart
307 SA_NOMASK or SA_NODEFER -- we observe this, but our handlers block everything
sewardjb5f6f512005-03-10 23:59:00 +0000308 SA_ONSTACK -- pass through
309 SA_NOCLDWAIT -- pass through
sewardjb48e5002002-05-13 00:16:03 +0000310*/
sewardjde4a1d02002-03-22 01:27:54 +0000311
sewardj77e466c2002-04-14 02:29:29 +0000312
sewardj018f7622002-05-15 21:13:39 +0000313typedef
314 struct {
315 void* skss_handler; /* VKI_SIG_DFL or VKI_SIG_IGN
316 or ptr to our handler */
317 UInt skss_flags;
318 /* There is no skss_mask, since we know that we will always ask
jsgf855d93d2003-10-13 22:26:55 +0000319 for all signals to be blocked in our sighandlers. */
sewardj018f7622002-05-15 21:13:39 +0000320 /* Also there is no skss_restorer. */
321 }
322 SKSS_Per_Signal;
sewardjde4a1d02002-03-22 01:27:54 +0000323
sewardj018f7622002-05-15 21:13:39 +0000324typedef
325 struct {
nethercote73b526f2004-10-31 18:48:21 +0000326 SKSS_Per_Signal skss_per_sig[1+_VKI_NSIG];
sewardj018f7622002-05-15 21:13:39 +0000327 }
328 SKSS;
329
njn695c16e2005-03-27 03:40:28 +0000330static SKSS skss;
sewardjde4a1d02002-03-22 01:27:54 +0000331
njn07ef6c02005-05-18 19:43:09 +0000332static Bool is_sig_ign(Int sigNo)
jsgf855d93d2003-10-13 22:26:55 +0000333{
nethercote73b526f2004-10-31 18:48:21 +0000334 vg_assert(sigNo >= 1 && sigNo <= _VKI_NSIG);
sewardj2e93c502002-04-12 11:12:52 +0000335
njn695c16e2005-03-27 03:40:28 +0000336 return scss.scss_per_sig[sigNo].scss_handler == VKI_SIG_IGN;
jsgf855d93d2003-10-13 22:26:55 +0000337}
sewardjb48e5002002-05-13 00:16:03 +0000338
sewardj018f7622002-05-15 21:13:39 +0000339/* ---------------------------------------------------------------------
340 Compute the SKSS required by the current SCSS.
341 ------------------------------------------------------------------ */
342
sewardj4f29ddf2002-05-03 22:29:04 +0000343static
sewardj018f7622002-05-15 21:13:39 +0000344void pp_SKSS ( void )
345{
346 Int sig;
347 VG_(printf)("\n\nSKSS:\n");
nethercote73b526f2004-10-31 18:48:21 +0000348 for (sig = 1; sig <= _VKI_NSIG; sig++) {
sewardj018f7622002-05-15 21:13:39 +0000349 VG_(printf)("sig %d: handler 0x%x, flags 0x%x\n", sig,
njn695c16e2005-03-27 03:40:28 +0000350 skss.skss_per_sig[sig].skss_handler,
351 skss.skss_per_sig[sig].skss_flags );
sewardj77e466c2002-04-14 02:29:29 +0000352
sewardj018f7622002-05-15 21:13:39 +0000353 }
sewardj018f7622002-05-15 21:13:39 +0000354}
355
sewardj018f7622002-05-15 21:13:39 +0000356/* This is the core, clever bit. Computation is as follows:
357
358 For each signal
359 handler = if client has a handler, then our handler
jsgf855d93d2003-10-13 22:26:55 +0000360 else if client is DFL, then our handler as well
361 else (client must be IGN)
sewardjb5f6f512005-03-10 23:59:00 +0000362 then hander is IGN
sewardj018f7622002-05-15 21:13:39 +0000363*/
364static
365void calculate_SKSS_from_SCSS ( SKSS* dst )
366{
367 Int sig;
sewardj018f7622002-05-15 21:13:39 +0000368 UInt scss_flags;
369 UInt skss_flags;
370
nethercote73b526f2004-10-31 18:48:21 +0000371 for (sig = 1; sig <= _VKI_NSIG; sig++) {
jsgf855d93d2003-10-13 22:26:55 +0000372 void *skss_handler;
373 void *scss_handler;
374
njn695c16e2005-03-27 03:40:28 +0000375 scss_handler = scss.scss_per_sig[sig].scss_handler;
376 scss_flags = scss.scss_per_sig[sig].scss_flags;
sewardj018f7622002-05-15 21:13:39 +0000377
jsgf855d93d2003-10-13 22:26:55 +0000378 switch(sig) {
379 case VKI_SIGSEGV:
380 case VKI_SIGBUS:
381 case VKI_SIGFPE:
382 case VKI_SIGILL:
sewardjb5f6f512005-03-10 23:59:00 +0000383 case VKI_SIGTRAP:
jsgf855d93d2003-10-13 22:26:55 +0000384 /* For these, we always want to catch them and report, even
385 if the client code doesn't. */
njn695c16e2005-03-27 03:40:28 +0000386 skss_handler = sync_signalhandler;
jsgf855d93d2003-10-13 22:26:55 +0000387 break;
388
sewardjb5f6f512005-03-10 23:59:00 +0000389 case VKI_SIGCONT:
390 /* Let the kernel handle SIGCONT unless the client is actually
391 catching it. */
njna530fc62005-03-13 04:46:36 +0000392 case VKI_SIGCHLD:
393 case VKI_SIGWINCH:
394 case VKI_SIGURG:
395 /* For signals which are have a default action of Ignore,
396 only set a handler if the client has set a signal handler.
397 Otherwise the kernel will interrupt a syscall which
398 wouldn't have otherwise been interrupted. */
njn695c16e2005-03-27 03:40:28 +0000399 if (scss.scss_per_sig[sig].scss_handler == VKI_SIG_DFL)
sewardjb5f6f512005-03-10 23:59:00 +0000400 skss_handler = VKI_SIG_DFL;
njn695c16e2005-03-27 03:40:28 +0000401 else if (scss.scss_per_sig[sig].scss_handler == VKI_SIG_IGN)
jsgf855d93d2003-10-13 22:26:55 +0000402 skss_handler = VKI_SIG_IGN;
sewardjb5f6f512005-03-10 23:59:00 +0000403 else
njn695c16e2005-03-27 03:40:28 +0000404 skss_handler = async_signalhandler;
jsgf855d93d2003-10-13 22:26:55 +0000405 break;
jsgf855d93d2003-10-13 22:26:55 +0000406
sewardjb5f6f512005-03-10 23:59:00 +0000407 default:
njna530fc62005-03-13 04:46:36 +0000408 // VKI_SIGVG* are runtime variables, so we can't make them
409 // cases in the switch, so we handle them in the 'default' case.
njn351d0062005-06-21 22:23:59 +0000410 if (sig == VG_SIGVGKILL)
sewardjb5f6f512005-03-10 23:59:00 +0000411 skss_handler = sigvgkill_handler;
sewardjb5f6f512005-03-10 23:59:00 +0000412 else {
413 if (scss_handler == VKI_SIG_IGN)
414 skss_handler = VKI_SIG_IGN;
415 else
njn695c16e2005-03-27 03:40:28 +0000416 skss_handler = async_signalhandler;
sewardjb5f6f512005-03-10 23:59:00 +0000417 }
418 break;
419 }
sewardj018f7622002-05-15 21:13:39 +0000420
sewardj018f7622002-05-15 21:13:39 +0000421 /* Flags */
422
423 skss_flags = 0;
jsgf855d93d2003-10-13 22:26:55 +0000424
sewardjb5f6f512005-03-10 23:59:00 +0000425 /* SA_NOCLDSTOP, SA_NOCLDWAIT: pass to kernel */
426 skss_flags |= scss_flags & (VKI_SA_NOCLDSTOP | VKI_SA_NOCLDWAIT);
jsgf855d93d2003-10-13 22:26:55 +0000427
sewardj018f7622002-05-15 21:13:39 +0000428 /* SA_ONESHOT: ignore client setting */
sewardjb5f6f512005-03-10 23:59:00 +0000429
sewardja8d8e232005-06-07 20:04:56 +0000430 /* SA_RESTART: ignore client setting and always set it for us.
431 Though we never rely on the kernel to restart a
jsgf855d93d2003-10-13 22:26:55 +0000432 syscall, we observe whether it wanted to restart the syscall
sewardja8d8e232005-06-07 20:04:56 +0000433 or not, which is needed by
434 VG_(fixup_guest_state_after_syscall_interrupted) */
sewardj018f7622002-05-15 21:13:39 +0000435 skss_flags |= VKI_SA_RESTART;
jsgf855d93d2003-10-13 22:26:55 +0000436
437 /* SA_NOMASK: ignore it */
438
sewardj2342c972002-05-22 23:34:20 +0000439 /* SA_ONSTACK: client setting is irrelevant here */
sewardjb5f6f512005-03-10 23:59:00 +0000440 /* We don't set a signal stack, so ignore */
sewardj018f7622002-05-15 21:13:39 +0000441
jsgf855d93d2003-10-13 22:26:55 +0000442 /* always ask for SA_SIGINFO */
443 skss_flags |= VKI_SA_SIGINFO;
sewardj018f7622002-05-15 21:13:39 +0000444
fitzhardinge4f10ada2004-06-03 10:00:42 +0000445 /* use our own restorer */
446 skss_flags |= VKI_SA_RESTORER;
447
jsgf855d93d2003-10-13 22:26:55 +0000448 /* Create SKSS entry for this signal. */
sewardj6a3c26e2002-05-23 17:09:43 +0000449 if (sig != VKI_SIGKILL && sig != VKI_SIGSTOP)
450 dst->skss_per_sig[sig].skss_handler = skss_handler;
451 else
452 dst->skss_per_sig[sig].skss_handler = VKI_SIG_DFL;
453
sewardj018f7622002-05-15 21:13:39 +0000454 dst->skss_per_sig[sig].skss_flags = skss_flags;
455 }
456
457 /* Sanity checks. */
nethercote5fd72bb2004-11-04 19:28:38 +0000458 vg_assert(dst->skss_per_sig[VKI_SIGKILL].skss_handler == VKI_SIG_DFL);
459 vg_assert(dst->skss_per_sig[VKI_SIGSTOP].skss_handler == VKI_SIG_DFL);
sewardj018f7622002-05-15 21:13:39 +0000460
461 if (0)
462 pp_SKSS();
463}
464
465
466/* ---------------------------------------------------------------------
467 After a possible SCSS change, update SKSS and the kernel itself.
468 ------------------------------------------------------------------ */
469
njn9abd6082005-06-17 21:31:45 +0000470// We need two levels of macro-expansion here to convert __NR_rt_sigreturn
471// to a number before converting it to a string... sigh.
sewardj03d8aa82005-10-14 11:25:49 +0000472extern void my_sigreturn(void);
njn9abd6082005-06-17 21:31:45 +0000473
474#if defined(VGP_x86_linux)
475# define _MYSIG(name) \
sewardjd9fc3822005-11-18 23:50:43 +0000476 ".text\n" \
njn9abd6082005-06-17 21:31:45 +0000477 "my_sigreturn:\n" \
478 " movl $" #name ", %eax\n" \
sewardj2fedc642005-11-19 02:02:57 +0000479 " int $0x80\n" \
480 ".previous\n"
njn9abd6082005-06-17 21:31:45 +0000481#elif defined(VGP_amd64_linux)
482# define _MYSIG(name) \
sewardjd9fc3822005-11-18 23:50:43 +0000483 ".text\n" \
njn9abd6082005-06-17 21:31:45 +0000484 "my_sigreturn:\n" \
485 " movq $" #name ", %rax\n" \
sewardj2fedc642005-11-19 02:02:57 +0000486 " syscall\n" \
487 ".previous\n"
cerion85665ca2005-06-20 15:51:07 +0000488#elif defined(VGP_ppc32_linux)
489# define _MYSIG(name) \
sewardjd9fc3822005-11-18 23:50:43 +0000490 ".text\n" \
cerion85665ca2005-06-20 15:51:07 +0000491 "my_sigreturn:\n" \
492 " li 0, " #name "\n" \
sewardj2fedc642005-11-19 02:02:57 +0000493 " sc\n" \
494 ".previous\n"
sewardj2c48c7b2005-11-29 13:05:56 +0000495#elif defined(VGP_ppc64_linux)
496# define _MYSIG(name) \
cerion297c88f2005-12-22 15:53:12 +0000497 ".align 2\n" \
498 ".globl my_sigreturn\n" \
499 ".section \".opd\",\"aw\"\n" \
500 ".align 3\n" \
sewardj2c48c7b2005-11-29 13:05:56 +0000501 "my_sigreturn:\n" \
cerion297c88f2005-12-22 15:53:12 +0000502 ".quad .my_sigreturn,.TOC.@tocbase,0\n" \
503 ".previous\n" \
504 ".type .my_sigreturn,@function\n" \
505 ".globl .my_sigreturn\n" \
506 ".my_sigreturn:\n" \
sewardj2c48c7b2005-11-29 13:05:56 +0000507 " li 0, " #name "\n" \
cerion297c88f2005-12-22 15:53:12 +0000508 " sc\n"
njn9abd6082005-06-17 21:31:45 +0000509#else
510# error Unknown platform
511#endif
512
513#define MYSIG(name) _MYSIG(name)
514asm(
515 MYSIG(__NR_rt_sigreturn)
516);
517
518
nethercote9dd11512004-08-04 15:31:30 +0000519static void handle_SCSS_change ( Bool force_update )
sewardj018f7622002-05-15 21:13:39 +0000520{
nethercote73b526f2004-10-31 18:48:21 +0000521 Int res, sig;
522 SKSS skss_old;
523 struct vki_sigaction ksa, ksa_old;
sewardj018f7622002-05-15 21:13:39 +0000524
sewardj018f7622002-05-15 21:13:39 +0000525 /* Remember old SKSS and calculate new one. */
njn695c16e2005-03-27 03:40:28 +0000526 skss_old = skss;
527 calculate_SKSS_from_SCSS ( &skss );
sewardj018f7622002-05-15 21:13:39 +0000528
529 /* Compare the new SKSS entries vs the old ones, and update kernel
530 where they differ. */
sewardjb5f6f512005-03-10 23:59:00 +0000531 for (sig = 1; sig <= VG_(max_signal); sig++) {
sewardj018f7622002-05-15 21:13:39 +0000532
533 /* Trying to do anything with SIGKILL is pointless; just ignore
534 it. */
535 if (sig == VKI_SIGKILL || sig == VKI_SIGSTOP)
536 continue;
537
sewardj018f7622002-05-15 21:13:39 +0000538 if (!force_update) {
539 if ((skss_old.skss_per_sig[sig].skss_handler
njn695c16e2005-03-27 03:40:28 +0000540 == skss.skss_per_sig[sig].skss_handler)
sewardj018f7622002-05-15 21:13:39 +0000541 && (skss_old.skss_per_sig[sig].skss_flags
njn695c16e2005-03-27 03:40:28 +0000542 == skss.skss_per_sig[sig].skss_flags))
sewardj018f7622002-05-15 21:13:39 +0000543 /* no difference */
544 continue;
545 }
546
njn695c16e2005-03-27 03:40:28 +0000547 ksa.ksa_handler = skss.skss_per_sig[sig].skss_handler;
548 ksa.sa_flags = skss.skss_per_sig[sig].skss_flags;
sewardjce2a6152005-07-08 18:25:13 +0000549# if !defined(VGP_ppc32_linux)
njn9abd6082005-06-17 21:31:45 +0000550 ksa.sa_restorer = my_sigreturn;
sewardjce2a6152005-07-08 18:25:13 +0000551# endif
sewardj162bebd2005-07-09 10:43:45 +0000552 /* Re above ifdef (also the assertion below), PaulM says:
553 The sa_restorer field is not used at all on ppc. Glibc
554 converts the sigaction you give it into a kernel sigaction,
555 but it doesn't put anything in the sa_restorer field.
556 */
fitzhardinge4f10ada2004-06-03 10:00:42 +0000557
sewardjb5f6f512005-03-10 23:59:00 +0000558 /* block all signals in handler */
nethercote73b526f2004-10-31 18:48:21 +0000559 VG_(sigfillset)( &ksa.sa_mask );
560 VG_(sigdelset)( &ksa.sa_mask, VKI_SIGKILL );
561 VG_(sigdelset)( &ksa.sa_mask, VKI_SIGSTOP );
sewardj018f7622002-05-15 21:13:39 +0000562
sewardjb5f6f512005-03-10 23:59:00 +0000563 if (VG_(clo_trace_signals) && VG_(clo_verbosity) > 2)
sewardj018f7622002-05-15 21:13:39 +0000564 VG_(message)(Vg_DebugMsg,
565 "setting ksig %d to: hdlr 0x%x, flags 0x%x, "
566 "mask(63..0) 0x%x 0x%x",
567 sig, ksa.ksa_handler,
nethercote73b526f2004-10-31 18:48:21 +0000568 ksa.sa_flags,
569 ksa.sa_mask.sig[1],
570 ksa.sa_mask.sig[0]
sewardj018f7622002-05-15 21:13:39 +0000571 );
572
nethercote73b526f2004-10-31 18:48:21 +0000573 res = VG_(sigaction)( sig, &ksa, &ksa_old );
sewardj018f7622002-05-15 21:13:39 +0000574 vg_assert(res == 0);
575
576 /* Since we got the old sigaction more or less for free, might
577 as well extract the maximum sanity-check value from it. */
578 if (!force_update) {
579 vg_assert(ksa_old.ksa_handler
580 == skss_old.skss_per_sig[sig].skss_handler);
nethercote73b526f2004-10-31 18:48:21 +0000581 vg_assert(ksa_old.sa_flags
sewardj018f7622002-05-15 21:13:39 +0000582 == skss_old.skss_per_sig[sig].skss_flags);
sewardjce2a6152005-07-08 18:25:13 +0000583# if !defined(VGP_ppc32_linux)
nethercote73b526f2004-10-31 18:48:21 +0000584 vg_assert(ksa_old.sa_restorer
njn9abd6082005-06-17 21:31:45 +0000585 == my_sigreturn);
sewardjce2a6152005-07-08 18:25:13 +0000586# endif
nethercote73b526f2004-10-31 18:48:21 +0000587 VG_(sigaddset)( &ksa_old.sa_mask, VKI_SIGKILL );
588 VG_(sigaddset)( &ksa_old.sa_mask, VKI_SIGSTOP );
589 vg_assert(VG_(isfullsigset)( &ksa_old.sa_mask ));
sewardj018f7622002-05-15 21:13:39 +0000590 }
591 }
sewardj018f7622002-05-15 21:13:39 +0000592}
593
594
595/* ---------------------------------------------------------------------
596 Update/query SCSS in accordance with client requests.
597 ------------------------------------------------------------------ */
598
sewardj2342c972002-05-22 23:34:20 +0000599/* Logic for this alt-stack stuff copied directly from do_sigaltstack
600 in kernel/signal.[ch] */
601
602/* True if we are on the alternate signal stack. */
sewardjb5f6f512005-03-10 23:59:00 +0000603static Bool on_sig_stack ( ThreadId tid, Addr m_SP )
sewardj2342c972002-05-22 23:34:20 +0000604{
fitzhardinge98c4dc02004-03-16 08:27:29 +0000605 ThreadState *tst = VG_(get_ThreadState)(tid);
606
nethercote511e4062004-09-11 13:34:08 +0000607 return (m_SP - (Addr)tst->altstack.ss_sp < tst->altstack.ss_size);
sewardj2342c972002-05-22 23:34:20 +0000608}
609
nethercote511e4062004-09-11 13:34:08 +0000610static Int sas_ss_flags ( ThreadId tid, Addr m_SP )
sewardj2342c972002-05-22 23:34:20 +0000611{
fitzhardinge98c4dc02004-03-16 08:27:29 +0000612 ThreadState *tst = VG_(get_ThreadState)(tid);
613
614 return (tst->altstack.ss_size == 0
sewardj2342c972002-05-22 23:34:20 +0000615 ? VKI_SS_DISABLE
nethercote511e4062004-09-11 13:34:08 +0000616 : on_sig_stack(tid, m_SP) ? VKI_SS_ONSTACK : 0);
sewardj2342c972002-05-22 23:34:20 +0000617}
618
619
sewardja8d8e232005-06-07 20:04:56 +0000620SysRes VG_(do_sys_sigaltstack) ( ThreadId tid, vki_stack_t* ss, vki_stack_t* oss )
sewardj2342c972002-05-22 23:34:20 +0000621{
njn502badb2005-05-08 02:04:49 +0000622 Addr m_SP;
sewardj2342c972002-05-22 23:34:20 +0000623
624 vg_assert(VG_(is_valid_tid)(tid));
njnf536bbb2005-06-13 04:21:38 +0000625 m_SP = VG_(get_SP)(tid);
sewardj2342c972002-05-22 23:34:20 +0000626
627 if (VG_(clo_trace_signals))
628 VG_(message)(Vg_DebugExtraMsg,
nethercote04d3a802004-11-16 18:26:11 +0000629 "sys_sigaltstack: tid %d, "
nethercote511e4062004-09-11 13:34:08 +0000630 "ss %p, oss %p (current SP %p)",
631 tid, (void*)ss, (void*)oss, (void*)m_SP );
sewardj2342c972002-05-22 23:34:20 +0000632
633 if (oss != NULL) {
fitzhardinge98c4dc02004-03-16 08:27:29 +0000634 oss->ss_sp = VG_(threads)[tid].altstack.ss_sp;
635 oss->ss_size = VG_(threads)[tid].altstack.ss_size;
nethercote511e4062004-09-11 13:34:08 +0000636 oss->ss_flags = VG_(threads)[tid].altstack.ss_flags | sas_ss_flags(tid, m_SP);
sewardj2342c972002-05-22 23:34:20 +0000637 }
638
639 if (ss != NULL) {
njnf536bbb2005-06-13 04:21:38 +0000640 if (on_sig_stack(tid, VG_(get_SP)(tid))) {
sewardja8d8e232005-06-07 20:04:56 +0000641 return VG_(mk_SysRes_Error)( VKI_EPERM );
sewardj2342c972002-05-22 23:34:20 +0000642 }
643 if (ss->ss_flags != VKI_SS_DISABLE
644 && ss->ss_flags != VKI_SS_ONSTACK
645 && ss->ss_flags != 0) {
sewardja8d8e232005-06-07 20:04:56 +0000646 return VG_(mk_SysRes_Error)( VKI_EINVAL );
sewardj2342c972002-05-22 23:34:20 +0000647 }
648 if (ss->ss_flags == VKI_SS_DISABLE) {
fitzhardinge98c4dc02004-03-16 08:27:29 +0000649 VG_(threads)[tid].altstack.ss_flags = VKI_SS_DISABLE;
sewardj2342c972002-05-22 23:34:20 +0000650 } else {
651 if (ss->ss_size < VKI_MINSIGSTKSZ) {
sewardja8d8e232005-06-07 20:04:56 +0000652 return VG_(mk_SysRes_Error)( VKI_ENOMEM );
sewardj2342c972002-05-22 23:34:20 +0000653 }
jsgf855d93d2003-10-13 22:26:55 +0000654
nethercote20283c62004-11-04 19:43:22 +0000655 VG_(threads)[tid].altstack.ss_sp = ss->ss_sp;
656 VG_(threads)[tid].altstack.ss_size = ss->ss_size;
fitzhardinge98c4dc02004-03-16 08:27:29 +0000657 VG_(threads)[tid].altstack.ss_flags = 0;
sewardj2342c972002-05-22 23:34:20 +0000658 }
sewardj2342c972002-05-22 23:34:20 +0000659 }
sewardja8d8e232005-06-07 20:04:56 +0000660 return VG_(mk_SysRes_Success)( 0 );
sewardj2342c972002-05-22 23:34:20 +0000661}
662
663
sewardja8d8e232005-06-07 20:04:56 +0000664SysRes VG_(do_sys_sigaction) ( Int signo,
665 const struct vki_sigaction *new_act,
666 struct vki_sigaction *old_act )
sewardj018f7622002-05-15 21:13:39 +0000667{
sewardj018f7622002-05-15 21:13:39 +0000668 if (VG_(clo_trace_signals))
669 VG_(message)(Vg_DebugExtraMsg,
sewardjb5f6f512005-03-10 23:59:00 +0000670 "sys_sigaction: sigNo %d, "
nethercote93246cf2004-11-04 18:56:47 +0000671 "new %p, old %p, new flags 0x%llx",
sewardjb5f6f512005-03-10 23:59:00 +0000672 signo, (UWord)new_act, (UWord)old_act,
nethercote93246cf2004-11-04 18:56:47 +0000673 (ULong)(new_act ? new_act->sa_flags : 0) );
sewardj018f7622002-05-15 21:13:39 +0000674
675 /* Rule out various error conditions. The aim is to ensure that if
676 when the call is passed to the kernel it will definitely
677 succeed. */
678
679 /* Reject out-of-range signal numbers. */
sewardjb5f6f512005-03-10 23:59:00 +0000680 if (signo < 1 || signo > VG_(max_signal)) goto bad_signo;
sewardj018f7622002-05-15 21:13:39 +0000681
jsgf855d93d2003-10-13 22:26:55 +0000682 /* don't let them use our signals */
njn351d0062005-06-21 22:23:59 +0000683 if ( (signo > VG_SIGVGRTUSERMAX)
jsgf855d93d2003-10-13 22:26:55 +0000684 && new_act
sewardja8d8e232005-06-07 20:04:56 +0000685 && !(new_act->ksa_handler == VKI_SIG_DFL
686 || new_act->ksa_handler == VKI_SIG_IGN) )
nethercote9c42a0f2003-11-17 10:37:19 +0000687 goto bad_signo_reserved;
jsgf855d93d2003-10-13 22:26:55 +0000688
sewardj018f7622002-05-15 21:13:39 +0000689 /* Reject attempts to set a handler (or set ignore) for SIGKILL. */
690 if ( (signo == VKI_SIGKILL || signo == VKI_SIGSTOP)
691 && new_act
692 && new_act->ksa_handler != VKI_SIG_DFL)
693 goto bad_sigkill_or_sigstop;
694
695 /* If the client supplied non-NULL old_act, copy the relevant SCSS
696 entry into it. */
697 if (old_act) {
njn695c16e2005-03-27 03:40:28 +0000698 old_act->ksa_handler = scss.scss_per_sig[signo].scss_handler;
699 old_act->sa_flags = scss.scss_per_sig[signo].scss_flags;
700 old_act->sa_mask = scss.scss_per_sig[signo].scss_mask;
701 old_act->sa_restorer = scss.scss_per_sig[signo].scss_restorer;
sewardj018f7622002-05-15 21:13:39 +0000702 }
703
704 /* And now copy new SCSS entry from new_act. */
705 if (new_act) {
njn695c16e2005-03-27 03:40:28 +0000706 scss.scss_per_sig[signo].scss_handler = new_act->ksa_handler;
707 scss.scss_per_sig[signo].scss_flags = new_act->sa_flags;
708 scss.scss_per_sig[signo].scss_mask = new_act->sa_mask;
709 scss.scss_per_sig[signo].scss_restorer = new_act->sa_restorer;
sewardjb5f6f512005-03-10 23:59:00 +0000710
njn695c16e2005-03-27 03:40:28 +0000711 VG_(sigdelset)(&scss.scss_per_sig[signo].scss_mask, VKI_SIGKILL);
712 VG_(sigdelset)(&scss.scss_per_sig[signo].scss_mask, VKI_SIGSTOP);
sewardj018f7622002-05-15 21:13:39 +0000713 }
714
715 /* All happy bunnies ... */
716 if (new_act) {
nethercote9dd11512004-08-04 15:31:30 +0000717 handle_SCSS_change( False /* lazy update */ );
sewardj018f7622002-05-15 21:13:39 +0000718 }
sewardja8d8e232005-06-07 20:04:56 +0000719 return VG_(mk_SysRes_Success)( 0 );
sewardj018f7622002-05-15 21:13:39 +0000720
721 bad_signo:
njn0087c502005-07-01 04:15:36 +0000722 if (VG_(showing_core_errors)()) {
njn25e49d8e72002-09-23 09:36:25 +0000723 VG_(message)(Vg_UserMsg,
nethercote9c42a0f2003-11-17 10:37:19 +0000724 "Warning: bad signal number %d in sigaction()",
njn25e49d8e72002-09-23 09:36:25 +0000725 signo);
sewardj9a3d8bd2005-05-23 14:47:52 +0000726 }
sewardja8d8e232005-06-07 20:04:56 +0000727 return VG_(mk_SysRes_Error)( VKI_EINVAL );
sewardj018f7622002-05-15 21:13:39 +0000728
nethercote9c42a0f2003-11-17 10:37:19 +0000729 bad_signo_reserved:
njn0087c502005-07-01 04:15:36 +0000730 if (VG_(showing_core_errors)()) {
nethercote9c42a0f2003-11-17 10:37:19 +0000731 VG_(message)(Vg_UserMsg,
732 "Warning: ignored attempt to set %s handler in sigaction();",
733 signame(signo));
734 VG_(message)(Vg_UserMsg,
735 " the %s signal is used internally by Valgrind",
736 signame(signo));
fitzhardingebf459872003-11-18 16:55:33 +0000737 }
sewardja8d8e232005-06-07 20:04:56 +0000738 return VG_(mk_SysRes_Error)( VKI_EINVAL );
nethercote9c42a0f2003-11-17 10:37:19 +0000739
sewardj018f7622002-05-15 21:13:39 +0000740 bad_sigkill_or_sigstop:
njn0087c502005-07-01 04:15:36 +0000741 if (VG_(showing_core_errors)()) {
njn25e49d8e72002-09-23 09:36:25 +0000742 VG_(message)(Vg_UserMsg,
nethercote9c42a0f2003-11-17 10:37:19 +0000743 "Warning: ignored attempt to set %s handler in sigaction();",
jsgf855d93d2003-10-13 22:26:55 +0000744 signame(signo));
nethercote9c42a0f2003-11-17 10:37:19 +0000745 VG_(message)(Vg_UserMsg,
746 " the %s signal is uncatchable",
747 signame(signo));
sewardj9a3d8bd2005-05-23 14:47:52 +0000748 }
sewardja8d8e232005-06-07 20:04:56 +0000749 return VG_(mk_SysRes_Error)( VKI_EINVAL );
sewardj018f7622002-05-15 21:13:39 +0000750}
751
752
753static
754void do_sigprocmask_bitops ( Int vki_how,
nethercote73b526f2004-10-31 18:48:21 +0000755 vki_sigset_t* orig_set,
756 vki_sigset_t* modifier )
sewardj018f7622002-05-15 21:13:39 +0000757{
758 switch (vki_how) {
759 case VKI_SIG_BLOCK:
nethercote73b526f2004-10-31 18:48:21 +0000760 VG_(sigaddset_from_set)( orig_set, modifier );
sewardj018f7622002-05-15 21:13:39 +0000761 break;
762 case VKI_SIG_UNBLOCK:
nethercote73b526f2004-10-31 18:48:21 +0000763 VG_(sigdelset_from_set)( orig_set, modifier );
sewardj018f7622002-05-15 21:13:39 +0000764 break;
765 case VKI_SIG_SETMASK:
766 *orig_set = *modifier;
767 break;
768 default:
njne427a662002-10-02 11:08:25 +0000769 VG_(core_panic)("do_sigprocmask_bitops");
sewardj018f7622002-05-15 21:13:39 +0000770 break;
771 }
772}
773
tomf7781e92005-11-02 15:31:21 +0000774static
775const Char *format_sigset ( const vki_sigset_t* set )
776{
777 static Char buf[128];
778 int w;
779
780 VG_(strcpy)(buf, "");
781
782 for (w = _VKI_NSIG_WORDS - 1; w >= 0; w--)
783 {
784#if _VKI_NSIG_BPW == 32
785 VG_(sprintf)(buf + VG_(strlen)(buf), "%08lx", set ? set->sig[w] : 0);
786#elif _VKI_NSIG_BPW == 64
787 VG_(sprintf)(buf + VG_(strlen)(buf), "%16lx", set ? set->sig[w] : 0);
788#else
789#error "Unsupported value for _VKI_NSIG_BPW"
790#endif
791 }
792
793 return buf;
794}
795
jsgf855d93d2003-10-13 22:26:55 +0000796/*
797 This updates the thread's signal mask. There's no such thing as a
798 process-wide signal mask.
sewardj018f7622002-05-15 21:13:39 +0000799
800 Note that the thread signal masks are an implicit part of SCSS,
801 which is why this routine is allowed to mess with them.
802*/
803static
804void do_setmask ( ThreadId tid,
805 Int how,
nethercote73b526f2004-10-31 18:48:21 +0000806 vki_sigset_t* newset,
807 vki_sigset_t* oldset )
sewardj018f7622002-05-15 21:13:39 +0000808{
sewardj018f7622002-05-15 21:13:39 +0000809 if (VG_(clo_trace_signals))
sewardja464e5c2002-05-23 17:34:49 +0000810 VG_(message)(Vg_DebugExtraMsg,
tomf7781e92005-11-02 15:31:21 +0000811 "do_setmask: tid = %d how = %d (%s), set = %p %s",
jsgf855d93d2003-10-13 22:26:55 +0000812 tid, how,
813 how==VKI_SIG_BLOCK ? "SIG_BLOCK" : (
814 how==VKI_SIG_UNBLOCK ? "SIG_UNBLOCK" : (
815 how==VKI_SIG_SETMASK ? "SIG_SETMASK" : "???")),
tomf7781e92005-11-02 15:31:21 +0000816 newset, format_sigset(newset));
sewardj018f7622002-05-15 21:13:39 +0000817
jsgf855d93d2003-10-13 22:26:55 +0000818 /* Just do this thread. */
819 vg_assert(VG_(is_valid_tid)(tid));
820 if (oldset) {
sewardjb5f6f512005-03-10 23:59:00 +0000821 *oldset = VG_(threads)[tid].sig_mask;
jsgf855d93d2003-10-13 22:26:55 +0000822 if (VG_(clo_trace_signals))
823 VG_(message)(Vg_DebugExtraMsg,
tom1399c742005-11-02 15:32:19 +0000824 "\toldset=%p %s",
tomf7781e92005-11-02 15:31:21 +0000825 oldset, format_sigset(oldset));
sewardj018f7622002-05-15 21:13:39 +0000826 }
sewardj018f7622002-05-15 21:13:39 +0000827 if (newset) {
jsgf855d93d2003-10-13 22:26:55 +0000828 do_sigprocmask_bitops (how, &VG_(threads)[tid].sig_mask, newset );
nethercote73b526f2004-10-31 18:48:21 +0000829 VG_(sigdelset)(&VG_(threads)[tid].sig_mask, VKI_SIGKILL);
830 VG_(sigdelset)(&VG_(threads)[tid].sig_mask, VKI_SIGSTOP);
sewardjb5f6f512005-03-10 23:59:00 +0000831 VG_(threads)[tid].tmp_sig_mask = VG_(threads)[tid].sig_mask;
sewardj018f7622002-05-15 21:13:39 +0000832 }
833}
834
835
sewardja8d8e232005-06-07 20:04:56 +0000836SysRes VG_(do_sys_sigprocmask) ( ThreadId tid,
837 Int how,
838 vki_sigset_t* set,
839 vki_sigset_t* oldset )
sewardj018f7622002-05-15 21:13:39 +0000840{
jsgf855d93d2003-10-13 22:26:55 +0000841 switch(how) {
842 case VKI_SIG_BLOCK:
843 case VKI_SIG_UNBLOCK:
844 case VKI_SIG_SETMASK:
sewardj018f7622002-05-15 21:13:39 +0000845 vg_assert(VG_(is_valid_tid)(tid));
jsgf855d93d2003-10-13 22:26:55 +0000846 do_setmask ( tid, how, set, oldset );
sewardja8d8e232005-06-07 20:04:56 +0000847 return VG_(mk_SysRes_Success)( 0 );
jsgf855d93d2003-10-13 22:26:55 +0000848
849 default:
sewardj018f7622002-05-15 21:13:39 +0000850 VG_(message)(Vg_DebugMsg,
njn02bc4b82005-05-15 17:28:26 +0000851 "sigprocmask: unknown 'how' field %d", how);
sewardja8d8e232005-06-07 20:04:56 +0000852 return VG_(mk_SysRes_Error)( VKI_EINVAL );
sewardj018f7622002-05-15 21:13:39 +0000853 }
854}
855
856
sewardj018f7622002-05-15 21:13:39 +0000857/* ---------------------------------------------------------------------
858 LOW LEVEL STUFF TO DO WITH SIGNALS: IMPLEMENTATION
859 ------------------------------------------------------------------ */
sewardj77e466c2002-04-14 02:29:29 +0000860
sewardj2e93c502002-04-12 11:12:52 +0000861/* ---------------------------------------------------------------------
862 Handy utilities to block/restore all host signals.
863 ------------------------------------------------------------------ */
864
865/* Block all host signals, dumping the old mask in *saved_mask. */
njn444eba12005-05-12 03:47:31 +0000866static void block_all_host_signals ( /* OUT */ vki_sigset_t* saved_mask )
sewardj2e93c502002-04-12 11:12:52 +0000867{
868 Int ret;
nethercote73b526f2004-10-31 18:48:21 +0000869 vki_sigset_t block_procmask;
870 VG_(sigfillset)(&block_procmask);
871 ret = VG_(sigprocmask)
sewardj2e93c502002-04-12 11:12:52 +0000872 (VKI_SIG_SETMASK, &block_procmask, saved_mask);
873 vg_assert(ret == 0);
874}
875
876/* Restore the blocking mask using the supplied saved one. */
njn444eba12005-05-12 03:47:31 +0000877static void restore_all_host_signals ( /* IN */ vki_sigset_t* saved_mask )
sewardj2e93c502002-04-12 11:12:52 +0000878{
879 Int ret;
nethercote73b526f2004-10-31 18:48:21 +0000880 ret = VG_(sigprocmask)(VKI_SIG_SETMASK, saved_mask, NULL);
sewardj2e93c502002-04-12 11:12:52 +0000881 vg_assert(ret == 0);
882}
sewardjde4a1d02002-03-22 01:27:54 +0000883
njn444eba12005-05-12 03:47:31 +0000884void VG_(clear_out_queued_signals)( ThreadId tid, vki_sigset_t* saved_mask )
885{
886 block_all_host_signals(saved_mask);
887 if (VG_(threads)[tid].sig_queue != NULL) {
888 VG_(arena_free)(VG_AR_CORE, VG_(threads)[tid].sig_queue);
889 VG_(threads)[tid].sig_queue = NULL;
890 }
891 restore_all_host_signals(saved_mask);
892}
893
sewardjde4a1d02002-03-22 01:27:54 +0000894/* ---------------------------------------------------------------------
895 The signal simulation proper. A simplified version of what the
896 Linux kernel does.
897 ------------------------------------------------------------------ */
898
sewardjde4a1d02002-03-22 01:27:54 +0000899/* Set up a stack frame (VgSigContext) for the client's signal
nethercotefedd8102004-09-13 15:19:34 +0000900 handler. */
sewardj2c5ffbe2005-03-12 13:32:06 +0000901static
njn695c16e2005-03-27 03:40:28 +0000902void push_signal_frame ( ThreadId tid, const vki_siginfo_t *siginfo )
sewardjde4a1d02002-03-22 01:27:54 +0000903{
nethercote6eec4602004-09-13 14:15:36 +0000904 Addr esp_top_of_frame;
sewardj2e93c502002-04-12 11:12:52 +0000905 ThreadState* tst;
jsgf855d93d2003-10-13 22:26:55 +0000906 Int sigNo = siginfo->si_signo;
sewardj2e93c502002-04-12 11:12:52 +0000907
sewardjb5f6f512005-03-10 23:59:00 +0000908 vg_assert(sigNo >= 1 && sigNo <= VG_(max_signal));
sewardj018f7622002-05-15 21:13:39 +0000909 vg_assert(VG_(is_valid_tid)(tid));
910 tst = & VG_(threads)[tid];
sewardj2e93c502002-04-12 11:12:52 +0000911
jsgf855d93d2003-10-13 22:26:55 +0000912 if (VG_(clo_trace_signals))
913 VG_(message)(Vg_DebugMsg,
njn695c16e2005-03-27 03:40:28 +0000914 "push_signal_frame (thread %d): signal %d", tid, sigNo);
jsgf855d93d2003-10-13 22:26:55 +0000915
sewardj2342c972002-05-22 23:34:20 +0000916 if (/* this signal asked to run on an alt stack */
njn695c16e2005-03-27 03:40:28 +0000917 (scss.scss_per_sig[sigNo].scss_flags & VKI_SA_ONSTACK )
sewardj2342c972002-05-22 23:34:20 +0000918 && /* there is a defined and enabled alt stack, which we're not
919 already using. Logic from get_sigframe in
920 arch/i386/kernel/signal.c. */
njnf536bbb2005-06-13 04:21:38 +0000921 sas_ss_flags(tid, VG_(get_SP)(tid)) == 0
sewardj2342c972002-05-22 23:34:20 +0000922 ) {
923 esp_top_of_frame
fitzhardinge98c4dc02004-03-16 08:27:29 +0000924 = (Addr)(tst->altstack.ss_sp) + tst->altstack.ss_size;
sewardj2342c972002-05-22 23:34:20 +0000925 if (VG_(clo_trace_signals))
926 VG_(message)(Vg_DebugMsg,
sewardjb5f6f512005-03-10 23:59:00 +0000927 "delivering signal %d (%s) to thread %d: on ALT STACK (%p-%p; %d bytes)",
928 sigNo, signame(sigNo), tid,
929 tst->altstack.ss_sp,
tom151a6392005-11-11 12:30:36 +0000930 (UChar *)tst->altstack.ss_sp + tst->altstack.ss_size,
sewardjb5f6f512005-03-10 23:59:00 +0000931 tst->altstack.ss_size );
njnfdc28af2003-02-24 10:36:48 +0000932
nethercote7cc9c232004-01-21 15:08:04 +0000933 /* Signal delivery to tools */
fitzhardinge98c4dc02004-03-16 08:27:29 +0000934 VG_TRACK( pre_deliver_signal, tid, sigNo, /*alt_stack*/True );
njnfdc28af2003-02-24 10:36:48 +0000935
sewardj2342c972002-05-22 23:34:20 +0000936 } else {
njnaf839f52005-06-23 03:27:57 +0000937 esp_top_of_frame = VG_(get_SP)(tid) - VG_STACK_REDZONE_SZB;
njnfdc28af2003-02-24 10:36:48 +0000938
nethercote7cc9c232004-01-21 15:08:04 +0000939 /* Signal delivery to tools */
fitzhardinge98c4dc02004-03-16 08:27:29 +0000940 VG_TRACK( pre_deliver_signal, tid, sigNo, /*alt_stack*/False );
sewardj2342c972002-05-22 23:34:20 +0000941 }
sewardjb5f6f512005-03-10 23:59:00 +0000942
njn695c16e2005-03-27 03:40:28 +0000943 vg_assert(scss.scss_per_sig[sigNo].scss_handler != VKI_SIG_IGN);
944 vg_assert(scss.scss_per_sig[sigNo].scss_handler != VKI_SIG_DFL);
sewardjb5f6f512005-03-10 23:59:00 +0000945
946 /* This may fail if the client stack is busted; if that happens,
947 the whole process will exit rather than simply calling the
948 signal handler. */
sewardj985fabb2005-04-24 14:18:14 +0000949 VG_(sigframe_create) (tid, esp_top_of_frame, siginfo,
950 scss.scss_per_sig[sigNo].scss_handler,
951 scss.scss_per_sig[sigNo].scss_flags,
952 &tst->sig_mask,
953 scss.scss_per_sig[sigNo].scss_restorer);
sewardjde4a1d02002-03-22 01:27:54 +0000954}
955
sewardjde4a1d02002-03-22 01:27:54 +0000956
jsgf855d93d2003-10-13 22:26:55 +0000957static const Char *signame(Int sigNo)
sewardjde4a1d02002-03-22 01:27:54 +0000958{
jsgf855d93d2003-10-13 22:26:55 +0000959 static Char buf[10];
sewardjb48e5002002-05-13 00:16:03 +0000960
jsgf855d93d2003-10-13 22:26:55 +0000961 switch(sigNo) {
962#define S(x) case VKI_##x: return #x
963 S(SIGHUP);
964 S(SIGINT);
965 S(SIGQUIT);
966 S(SIGILL);
967 S(SIGTRAP);
968 S(SIGABRT);
969 S(SIGBUS);
970 S(SIGFPE);
971 S(SIGKILL);
972 S(SIGUSR1);
973 S(SIGUSR2);
974 S(SIGSEGV);
975 S(SIGPIPE);
976 S(SIGALRM);
977 S(SIGTERM);
978 S(SIGSTKFLT);
979 S(SIGCHLD);
980 S(SIGCONT);
981 S(SIGSTOP);
982 S(SIGTSTP);
983 S(SIGTTIN);
984 S(SIGTTOU);
985 S(SIGURG);
986 S(SIGXCPU);
987 S(SIGXFSZ);
988 S(SIGVTALRM);
989 S(SIGPROF);
990 S(SIGWINCH);
991 S(SIGIO);
992 S(SIGPWR);
993 S(SIGUNUSED);
994#undef S
sewardjde4a1d02002-03-22 01:27:54 +0000995
jsgf855d93d2003-10-13 22:26:55 +0000996 case VKI_SIGRTMIN ... VKI_SIGRTMAX:
sewardjb5f6f512005-03-10 23:59:00 +0000997 VG_(sprintf)(buf, "SIGRT%d", sigNo-VKI_SIGRTMIN);
jsgf855d93d2003-10-13 22:26:55 +0000998 return buf;
sewardjde4a1d02002-03-22 01:27:54 +0000999
jsgf855d93d2003-10-13 22:26:55 +00001000 default:
1001 VG_(sprintf)(buf, "SIG%d", sigNo);
1002 return buf;
1003 }
1004}
sewardjde4a1d02002-03-22 01:27:54 +00001005
jsgf855d93d2003-10-13 22:26:55 +00001006/* Hit ourselves with a signal using the default handler */
1007void VG_(kill_self)(Int sigNo)
1008{
nethercote73b526f2004-10-31 18:48:21 +00001009 vki_sigset_t mask, origmask;
1010 struct vki_sigaction sa, origsa;
sewardj018f7622002-05-15 21:13:39 +00001011
jsgf855d93d2003-10-13 22:26:55 +00001012 sa.ksa_handler = VKI_SIG_DFL;
nethercote73b526f2004-10-31 18:48:21 +00001013 sa.sa_flags = 0;
1014 sa.sa_restorer = 0;
1015 VG_(sigemptyset)(&sa.sa_mask);
sewardj2e93c502002-04-12 11:12:52 +00001016
nethercote73b526f2004-10-31 18:48:21 +00001017 VG_(sigaction)(sigNo, &sa, &origsa);
sewardj018f7622002-05-15 21:13:39 +00001018
sewardjb5f6f512005-03-10 23:59:00 +00001019 VG_(sigemptyset)(&mask);
1020 VG_(sigaddset)(&mask, sigNo);
1021 VG_(sigprocmask)(VKI_SIG_UNBLOCK, &mask, &origmask);
jsgf855d93d2003-10-13 22:26:55 +00001022
tomb9b10c72005-07-20 16:05:28 +00001023 VG_(kill)(VG_(getpid)(), sigNo);
jsgf855d93d2003-10-13 22:26:55 +00001024
nethercote73b526f2004-10-31 18:48:21 +00001025 VG_(sigaction)(sigNo, &origsa, NULL);
1026 VG_(sigprocmask)(VKI_SIG_SETMASK, &origmask, NULL);
jsgf855d93d2003-10-13 22:26:55 +00001027}
1028
1029/*
sewardjb5f6f512005-03-10 23:59:00 +00001030 Perform the default action of a signal. If the signal is fatal, it
1031 marks all threads as needing to exit, but it doesn't actually kill
1032 the process or thread.
jsgf855d93d2003-10-13 22:26:55 +00001033
1034 If we're not being quiet, then print out some more detail about
1035 fatal signals (esp. core dumping signals).
1036 */
njn695c16e2005-03-27 03:40:28 +00001037static void default_action(const vki_siginfo_t *info, ThreadId tid)
jsgf855d93d2003-10-13 22:26:55 +00001038{
1039 Int sigNo = info->si_signo;
sewardjb5f6f512005-03-10 23:59:00 +00001040 Bool terminate = False; /* kills process */
1041 Bool core = False; /* kills process w/ core */
1042 struct vki_rlimit corelim;
1043 Bool could_core;
jsgf855d93d2003-10-13 22:26:55 +00001044
sewardjb5f6f512005-03-10 23:59:00 +00001045 vg_assert(VG_(is_running_thread)(tid));
1046
jsgf855d93d2003-10-13 22:26:55 +00001047 switch(sigNo) {
1048 case VKI_SIGQUIT: /* core */
1049 case VKI_SIGILL: /* core */
1050 case VKI_SIGABRT: /* core */
1051 case VKI_SIGFPE: /* core */
1052 case VKI_SIGSEGV: /* core */
1053 case VKI_SIGBUS: /* core */
1054 case VKI_SIGTRAP: /* core */
1055 case VKI_SIGXCPU: /* core */
1056 case VKI_SIGXFSZ: /* core */
1057 terminate = True;
1058 core = True;
1059 break;
1060
1061 case VKI_SIGHUP: /* term */
1062 case VKI_SIGINT: /* term */
1063 case VKI_SIGKILL: /* term - we won't see this */
1064 case VKI_SIGPIPE: /* term */
1065 case VKI_SIGALRM: /* term */
1066 case VKI_SIGTERM: /* term */
1067 case VKI_SIGUSR1: /* term */
1068 case VKI_SIGUSR2: /* term */
1069 case VKI_SIGIO: /* term */
1070 case VKI_SIGPWR: /* term */
1071 case VKI_SIGSYS: /* term */
1072 case VKI_SIGPROF: /* term */
1073 case VKI_SIGVTALRM: /* term */
1074 case VKI_SIGRTMIN ... VKI_SIGRTMAX: /* term */
1075 terminate = True;
1076 break;
1077 }
1078
1079 vg_assert(!core || (core && terminate));
1080
fitzhardinge98abfc72003-12-16 02:05:15 +00001081 if (VG_(clo_trace_signals))
sewardjb5f6f512005-03-10 23:59:00 +00001082 VG_(message)(Vg_DebugMsg, "delivering %d (code %d) to default handler; action: %s%s",
1083 sigNo, info->si_code, terminate ? "terminate" : "ignore", core ? "+core" : "");
fitzhardinge98abfc72003-12-16 02:05:15 +00001084
sewardjb5f6f512005-03-10 23:59:00 +00001085 if (!terminate)
1086 return; /* nothing to do */
fitzhardinge4a4d1082004-03-15 23:46:54 +00001087
sewardjb5f6f512005-03-10 23:59:00 +00001088 could_core = core;
1089
1090 if (core) {
1091 /* If they set the core-size limit to zero, don't generate a
1092 core file */
fitzhardinge61a53412004-03-15 23:44:11 +00001093
sewardjb5f6f512005-03-10 23:59:00 +00001094 VG_(getrlimit)(VKI_RLIMIT_CORE, &corelim);
fitzhardinge61a53412004-03-15 23:44:11 +00001095
sewardjb5f6f512005-03-10 23:59:00 +00001096 if (corelim.rlim_cur == 0)
1097 core = False;
1098 }
fitzhardinge61a53412004-03-15 23:44:11 +00001099
sewardjb5f6f512005-03-10 23:59:00 +00001100 if (VG_(clo_verbosity) > 1 || (could_core && info->si_code > VKI_SI_USER)) {
1101 VG_(message)(Vg_UserMsg, "");
sewardj45f4e7c2005-09-27 19:20:21 +00001102 VG_(message)(Vg_UserMsg,
1103 "Process terminating with default action of signal %d (%s)%s",
sewardjb5f6f512005-03-10 23:59:00 +00001104 sigNo, signame(sigNo), core ? ": dumping core" : "");
jsgf855d93d2003-10-13 22:26:55 +00001105
sewardjb5f6f512005-03-10 23:59:00 +00001106 /* Be helpful - decode some more details about this fault */
1107 if (info->si_code > VKI_SI_USER) {
1108 const Char *event = NULL;
1109 Bool haveaddr = True;
jsgf855d93d2003-10-13 22:26:55 +00001110
sewardjb5f6f512005-03-10 23:59:00 +00001111 switch(sigNo) {
1112 case VKI_SIGSEGV:
1113 switch(info->si_code) {
tom148250b2005-11-12 00:13:20 +00001114 case VKI_SEGV_MAPERR: event = "Access not within mapped region"; break;
1115 case VKI_SEGV_ACCERR: event = "Bad permissions for mapped region"; break;
sewardjb5f6f512005-03-10 23:59:00 +00001116 case 128:
1117 /* General Protection Fault: The CPU/kernel
1118 isn't telling us anything useful, but this
1119 is commonly the result of exceeding a
sewardj74b4cca2005-10-20 01:37:15 +00001120 segment limit. */
1121 event = "General Protection Fault";
sewardjb5f6f512005-03-10 23:59:00 +00001122 haveaddr = False;
jsgf855d93d2003-10-13 22:26:55 +00001123 break;
1124 }
sewardj45f4e7c2005-09-27 19:20:21 +00001125#if 0
1126 {
1127 HChar buf[110];
1128 VG_(am_show_nsegments)(0,"post segfault");
1129 VG_(sprintf)(buf, "/bin/cat /proc/%d/maps", VG_(getpid)());
1130 VG_(system)(buf);
1131 }
1132#endif
sewardjb5f6f512005-03-10 23:59:00 +00001133 break;
jsgf855d93d2003-10-13 22:26:55 +00001134
sewardjb5f6f512005-03-10 23:59:00 +00001135 case VKI_SIGILL:
1136 switch(info->si_code) {
tom148250b2005-11-12 00:13:20 +00001137 case VKI_ILL_ILLOPC: event = "Illegal opcode"; break;
1138 case VKI_ILL_ILLOPN: event = "Illegal operand"; break;
1139 case VKI_ILL_ILLADR: event = "Illegal addressing mode"; break;
1140 case VKI_ILL_ILLTRP: event = "Illegal trap"; break;
1141 case VKI_ILL_PRVOPC: event = "Privileged opcode"; break;
1142 case VKI_ILL_PRVREG: event = "Privileged register"; break;
1143 case VKI_ILL_COPROC: event = "Coprocessor error"; break;
1144 case VKI_ILL_BADSTK: event = "Internal stack error"; break;
sewardjb5f6f512005-03-10 23:59:00 +00001145 }
1146 break;
1147
1148 case VKI_SIGFPE:
1149 switch (info->si_code) {
tom148250b2005-11-12 00:13:20 +00001150 case VKI_FPE_INTDIV: event = "Integer divide by zero"; break;
1151 case VKI_FPE_INTOVF: event = "Integer overflow"; break;
1152 case VKI_FPE_FLTDIV: event = "FP divide by zero"; break;
1153 case VKI_FPE_FLTOVF: event = "FP overflow"; break;
1154 case VKI_FPE_FLTUND: event = "FP underflow"; break;
1155 case VKI_FPE_FLTRES: event = "FP inexact"; break;
1156 case VKI_FPE_FLTINV: event = "FP invalid operation"; break;
1157 case VKI_FPE_FLTSUB: event = "FP subscript out of range"; break;
sewardjb5f6f512005-03-10 23:59:00 +00001158 }
1159 break;
1160
1161 case VKI_SIGBUS:
1162 switch (info->si_code) {
tom148250b2005-11-12 00:13:20 +00001163 case VKI_BUS_ADRALN: event = "Invalid address alignment"; break;
1164 case VKI_BUS_ADRERR: event = "Non-existent physical address"; break;
1165 case VKI_BUS_OBJERR: event = "Hardware error"; break;
sewardjb5f6f512005-03-10 23:59:00 +00001166 }
1167 break;
1168 }
1169
1170 if (event != NULL) {
1171 if (haveaddr)
nethercote3b390c72003-11-13 17:53:43 +00001172 VG_(message)(Vg_UserMsg, " %s at address %p",
jsgf855d93d2003-10-13 22:26:55 +00001173 event, info->_sifields._sigfault._addr);
sewardjb5f6f512005-03-10 23:59:00 +00001174 else
1175 VG_(message)(Vg_UserMsg, " %s", event);
jsgf855d93d2003-10-13 22:26:55 +00001176 }
1177 }
fitzhardinge126c64f2003-12-08 21:58:37 +00001178
sewardjb5f6f512005-03-10 23:59:00 +00001179 if (tid != VG_INVALID_THREADID) {
njnd01fef72005-03-25 23:35:48 +00001180 VG_(get_and_pp_StackTrace)(tid, VG_(clo_backtrace_size));
fitzhardinge126c64f2003-12-08 21:58:37 +00001181 }
sewardjb5f6f512005-03-10 23:59:00 +00001182 }
1183
1184 if (VG_(is_action_requested)( "Attach to debugger", & VG_(clo_db_attach) )) {
1185 VG_(start_debugger)( tid );
1186 }
fitzhardinge126c64f2003-12-08 21:58:37 +00001187
sewardjb5f6f512005-03-10 23:59:00 +00001188 if (core) {
1189 const static struct vki_rlimit zero = { 0, 0 };
fitzhardinge4a4d1082004-03-15 23:46:54 +00001190
njn67229832005-08-28 04:38:12 +00001191 VG_(make_coredump)(tid, info, corelim.rlim_cur);
fitzhardinged65dcad2004-03-13 02:06:58 +00001192
sewardjb5f6f512005-03-10 23:59:00 +00001193 /* Make sure we don't get a confusing kernel-generated
1194 coredump when we finally exit */
1195 VG_(setrlimit)(VKI_RLIMIT_CORE, &zero);
1196 }
fitzhardinged65dcad2004-03-13 02:06:58 +00001197
sewardjb5f6f512005-03-10 23:59:00 +00001198 /* stash fatal signal in main thread */
sewardj1d887112005-05-30 21:44:08 +00001199 // what's this for?
1200 //VG_(threads)[VG_(master_tid)].os_state.fatalsig = sigNo;
sewardjde4a1d02002-03-22 01:27:54 +00001201
sewardjb5f6f512005-03-10 23:59:00 +00001202 /* everyone dies */
1203 VG_(nuke_all_threads_except)(tid, VgSrc_FatalSig);
1204 VG_(threads)[tid].exitreason = VgSrc_FatalSig;
1205 VG_(threads)[tid].os_state.fatalsig = sigNo;
sewardjb48e5002002-05-13 00:16:03 +00001206}
1207
sewardjb5f6f512005-03-10 23:59:00 +00001208/*
1209 This does the business of delivering a signal to a thread. It may
1210 be called from either a real signal handler, or from normal code to
1211 cause the thread to enter the signal handler.
sewardj5e2f0012004-12-13 14:10:34 +00001212
sewardjb5f6f512005-03-10 23:59:00 +00001213 This updates the thread state, but it does not set it to be
1214 Runnable.
1215*/
njn9ec0f3e2005-03-13 06:00:47 +00001216static void deliver_signal ( ThreadId tid, const vki_siginfo_t *info )
sewardjde4a1d02002-03-22 01:27:54 +00001217{
jsgf855d93d2003-10-13 22:26:55 +00001218 Int sigNo = info->si_signo;
njn695c16e2005-03-27 03:40:28 +00001219 SCSS_Per_Signal *handler = &scss.scss_per_sig[sigNo];
fitzhardinge98abfc72003-12-16 02:05:15 +00001220 void *handler_fn;
jsgf855d93d2003-10-13 22:26:55 +00001221 ThreadState *tst = VG_(get_ThreadState)(tid);
1222
1223 if (VG_(clo_trace_signals))
sewardjb5f6f512005-03-10 23:59:00 +00001224 VG_(message)(Vg_DebugMsg,"delivering signal %d (%s):%d to thread %d",
1225 sigNo, signame(sigNo), info->si_code, tid );
jsgf855d93d2003-10-13 22:26:55 +00001226
njn351d0062005-06-21 22:23:59 +00001227 if (sigNo == VG_SIGVGKILL) {
sewardjb5f6f512005-03-10 23:59:00 +00001228 /* If this is a SIGVGKILL, we're expecting it to interrupt any
1229 blocked syscall. It doesn't matter whether the VCPU state is
1230 set to restart or not, because we don't expect it will
1231 execute any more client instructions. */
1232 vg_assert(VG_(is_exiting)(tid));
jsgf855d93d2003-10-13 22:26:55 +00001233 return;
1234 }
1235
sewardjb5f6f512005-03-10 23:59:00 +00001236 /* If the client specifies SIG_IGN, treat it as SIG_DFL.
jsgf855d93d2003-10-13 22:26:55 +00001237
njn9ec0f3e2005-03-13 06:00:47 +00001238 If deliver_signal() is being called on a thread, we want
sewardjb5f6f512005-03-10 23:59:00 +00001239 the signal to get through no matter what; if they're ignoring
1240 it, then we do this override (this is so we can send it SIGSEGV,
1241 etc). */
fitzhardinge98abfc72003-12-16 02:05:15 +00001242 handler_fn = handler->scss_handler;
sewardjb5f6f512005-03-10 23:59:00 +00001243 if (handler_fn == VKI_SIG_IGN)
fitzhardinge98abfc72003-12-16 02:05:15 +00001244 handler_fn = VKI_SIG_DFL;
1245
1246 vg_assert(handler_fn != VKI_SIG_IGN);
jsgf855d93d2003-10-13 22:26:55 +00001247
fitzhardinge98abfc72003-12-16 02:05:15 +00001248 if (handler_fn == VKI_SIG_DFL) {
njn695c16e2005-03-27 03:40:28 +00001249 default_action(info, tid);
jsgf855d93d2003-10-13 22:26:55 +00001250 } else {
1251 /* Create a signal delivery frame, and set the client's %ESP and
1252 %EIP so that when execution continues, we will enter the
1253 signal handler with the frame on top of the client's stack,
sewardjb5f6f512005-03-10 23:59:00 +00001254 as it expects.
1255
1256 Signal delivery can fail if the client stack is too small or
1257 missing, and we can't push the frame. If that happens,
1258 push_signal_frame will cause the whole process to exit when
1259 we next hit the scheduler.
1260 */
jsgf855d93d2003-10-13 22:26:55 +00001261 vg_assert(VG_(is_valid_tid)(tid));
sewardjb5f6f512005-03-10 23:59:00 +00001262
njn695c16e2005-03-27 03:40:28 +00001263 push_signal_frame ( tid, info );
jsgf855d93d2003-10-13 22:26:55 +00001264
1265 if (handler->scss_flags & VKI_SA_ONESHOT) {
1266 /* Do the ONESHOT thing. */
1267 handler->scss_handler = VKI_SIG_DFL;
1268
nethercote9dd11512004-08-04 15:31:30 +00001269 handle_SCSS_change( False /* lazy update */ );
jsgf855d93d2003-10-13 22:26:55 +00001270 }
sewardjb5f6f512005-03-10 23:59:00 +00001271
1272 /* At this point:
1273 tst->sig_mask is the current signal mask
1274 tst->tmp_sig_mask is the same as sig_mask, unless we're in sigsuspend
1275 handler->scss_mask is the mask set by the handler
1276
1277 Handler gets a mask of tmp_sig_mask|handler_mask|signo
1278 */
1279 tst->sig_mask = tst->tmp_sig_mask;
1280 if (!(handler->scss_flags & VKI_SA_NOMASK)) {
1281 VG_(sigaddset_from_set)(&tst->sig_mask, &handler->scss_mask);
1282 VG_(sigaddset)(&tst->sig_mask, sigNo);
1283
1284 tst->tmp_sig_mask = tst->sig_mask;
1285 }
1286 }
1287
1288 /* Thread state is ready to go - just add Runnable */
1289}
1290
njn06244e72005-06-21 22:27:19 +00001291static void resume_scheduler(ThreadId tid)
1292{
1293 ThreadState *tst = VG_(get_ThreadState)(tid);
1294
1295 vg_assert(tst->os_state.lwpid == VG_(gettid)());
1296
1297 if (tst->sched_jmpbuf_valid) {
1298 /* Can't continue; must longjmp back to the scheduler and thus
1299 enter the sighandler immediately. */
sewardj45f4e7c2005-09-27 19:20:21 +00001300 __builtin_longjmp(tst->sched_jmpbuf, True);
njn06244e72005-06-21 22:27:19 +00001301 }
1302}
1303
njn9ec0f3e2005-03-13 06:00:47 +00001304static void synth_fault_common(ThreadId tid, Addr addr, Int si_code)
1305{
1306 vki_siginfo_t info;
1307
1308 vg_assert(VG_(threads)[tid].status == VgTs_Runnable);
1309
1310 info.si_signo = VKI_SIGSEGV;
1311 info.si_code = si_code;
1312 info._sifields._sigfault._addr = (void*)addr;
1313
1314 /* If they're trying to block the signal, force it to be delivered */
1315 if (VG_(sigismember)(&VG_(threads)[tid].sig_mask, VKI_SIGSEGV))
1316 VG_(set_default_handler)(VKI_SIGSEGV);
1317
1318 deliver_signal(tid, &info);
1319}
1320
1321// Synthesize a fault where the address is OK, but the page
1322// permissions are bad.
1323void VG_(synth_fault_perms)(ThreadId tid, Addr addr)
1324{
1325 synth_fault_common(tid, addr, 2);
1326}
1327
1328// Synthesize a fault where the address there's nothing mapped at the address.
1329void VG_(synth_fault_mapping)(ThreadId tid, Addr addr)
1330{
1331 synth_fault_common(tid, addr, 1);
1332}
1333
1334// Synthesize a misc memory fault.
1335void VG_(synth_fault)(ThreadId tid)
1336{
1337 synth_fault_common(tid, 0, 0x80);
1338}
1339
1340// Synthesise a SIGILL.
1341void VG_(synth_sigill)(ThreadId tid, Addr addr)
1342{
1343 vki_siginfo_t info;
1344
1345 vg_assert(VG_(threads)[tid].status == VgTs_Runnable);
1346
1347 info.si_signo = VKI_SIGILL;
tom148250b2005-11-12 00:13:20 +00001348 info.si_code = VKI_ILL_ILLOPC; /* jrs: no idea what this should be */
njn9ec0f3e2005-03-13 06:00:47 +00001349 info._sifields._sigfault._addr = (void*)addr;
1350
njn06244e72005-06-21 22:27:19 +00001351 resume_scheduler(tid);
njn9ec0f3e2005-03-13 06:00:47 +00001352 deliver_signal(tid, &info);
1353}
1354
sewardjb5f6f512005-03-10 23:59:00 +00001355/* Make a signal pending for a thread, for later delivery.
1356 VG_(poll_signals) will arrange for it to be delivered at the right
1357 time.
1358
1359 tid==0 means add it to the process-wide queue, and not sent it to a
1360 specific thread.
1361*/
sewardj2c5ffbe2005-03-12 13:32:06 +00001362static
sewardjb5f6f512005-03-10 23:59:00 +00001363void queue_signal(ThreadId tid, const vki_siginfo_t *si)
1364{
1365 ThreadState *tst;
1366 SigQueue *sq;
1367 vki_sigset_t savedmask;
1368
1369 tst = VG_(get_ThreadState)(tid);
1370
1371 /* Protect the signal queue against async deliveries */
njn444eba12005-05-12 03:47:31 +00001372 block_all_host_signals(&savedmask);
sewardjb5f6f512005-03-10 23:59:00 +00001373
1374 if (tst->sig_queue == NULL) {
1375 tst->sig_queue = VG_(arena_malloc)(VG_AR_CORE, sizeof(*tst->sig_queue));
1376 VG_(memset)(tst->sig_queue, 0, sizeof(*tst->sig_queue));
1377 }
1378 sq = tst->sig_queue;
1379
1380 if (VG_(clo_trace_signals))
1381 VG_(message)(Vg_DebugMsg, "Queueing signal %d (idx %d) to thread %d",
1382 si->si_signo, sq->next, tid);
1383
1384 /* Add signal to the queue. If the queue gets overrun, then old
1385 queued signals may get lost.
1386
1387 XXX We should also keep a sigset of pending signals, so that at
1388 least a non-siginfo signal gets deliviered.
1389 */
1390 if (sq->sigs[sq->next].si_signo != 0)
1391 VG_(message)(Vg_UserMsg, "Signal %d being dropped from thread %d's queue",
1392 sq->sigs[sq->next].si_signo, tid);
1393
1394 sq->sigs[sq->next] = *si;
1395 sq->next = (sq->next+1) % N_QUEUED_SIGNALS;
1396
njn444eba12005-05-12 03:47:31 +00001397 restore_all_host_signals(&savedmask);
sewardjb5f6f512005-03-10 23:59:00 +00001398}
1399
1400/*
1401 Returns the next queued signal for thread tid which is in "set".
1402 tid==0 means process-wide signal. Set si_signo to 0 when the
1403 signal has been delivered.
1404
1405 Must be called with all signals blocked, to protect against async
1406 deliveries.
1407*/
1408static vki_siginfo_t *next_queued(ThreadId tid, const vki_sigset_t *set)
1409{
1410 ThreadState *tst = VG_(get_ThreadState)(tid);
1411 SigQueue *sq;
1412 Int idx;
1413 vki_siginfo_t *ret = NULL;
1414
1415 sq = tst->sig_queue;
1416 if (sq == NULL)
1417 goto out;
jsgf855d93d2003-10-13 22:26:55 +00001418
sewardjb5f6f512005-03-10 23:59:00 +00001419 idx = sq->next;
1420 do {
1421 if (0)
1422 VG_(printf)("idx=%d si_signo=%d inset=%d\n", idx,
1423 sq->sigs[idx].si_signo, VG_(sigismember)(set, sq->sigs[idx].si_signo));
jsgf855d93d2003-10-13 22:26:55 +00001424
sewardjb5f6f512005-03-10 23:59:00 +00001425 if (sq->sigs[idx].si_signo != 0 && VG_(sigismember)(set, sq->sigs[idx].si_signo)) {
1426 if (VG_(clo_trace_signals))
1427 VG_(message)(Vg_DebugMsg, "Returning queued signal %d (idx %d) for thread %d",
1428 sq->sigs[idx].si_signo, idx, tid);
1429 ret = &sq->sigs[idx];
1430 goto out;
jsgf855d93d2003-10-13 22:26:55 +00001431 }
1432
sewardjb5f6f512005-03-10 23:59:00 +00001433 idx = (idx + 1) % N_QUEUED_SIGNALS;
1434 } while(idx != sq->next);
1435 out:
1436 return ret;
jsgf855d93d2003-10-13 22:26:55 +00001437}
1438
1439/*
sewardjb5f6f512005-03-10 23:59:00 +00001440 Receive an async signal from the kernel.
jsgf855d93d2003-10-13 22:26:55 +00001441
sewardjb5f6f512005-03-10 23:59:00 +00001442 This should only happen when the thread is blocked in a syscall,
1443 since that's the only time this set of signals is unblocked.
jsgf855d93d2003-10-13 22:26:55 +00001444*/
1445static
njn695c16e2005-03-27 03:40:28 +00001446void async_signalhandler ( Int sigNo, vki_siginfo_t *info, struct vki_ucontext *uc )
jsgf855d93d2003-10-13 22:26:55 +00001447{
sewardjb5f6f512005-03-10 23:59:00 +00001448 ThreadId tid = VG_(get_lwp_tid)(VG_(gettid)());
1449 ThreadState *tst = VG_(get_ThreadState)(tid);
jsgf855d93d2003-10-13 22:26:55 +00001450
sewardjb5f6f512005-03-10 23:59:00 +00001451 vg_assert(tst->status == VgTs_WaitSys);
jsgf855d93d2003-10-13 22:26:55 +00001452
tom9f4a7bf2005-11-13 00:01:20 +00001453#ifdef VGO_linux
1454 /* The linux kernel uses the top 16 bits of si_code for it's own
1455 use and only exports the bottom 16 bits to user space - at least
1456 that is the theory, but it turns out that there are some kernels
tomc8cb9d02005-11-14 14:37:02 +00001457 around that forget to mask out the top 16 bits so we do it here.
1458
1459 The kernel treats the bottom 16 bits as signed and (when it does
1460 mask them off) sign extends them when exporting to user space so
1461 we do the same thing here. */
tom95458c62005-11-13 11:52:39 +00001462 info->si_code = (Short)info->si_code;
tom9f4a7bf2005-11-13 00:01:20 +00001463#endif
1464
sewardjb5f6f512005-03-10 23:59:00 +00001465 /* The thread isn't currently running, make it so before going on */
1466 VG_(set_running)(tid);
1467
1468 if (VG_(clo_trace_signals))
1469 VG_(message)(Vg_DebugMsg, "Async handler got signal %d for tid %d info %d",
1470 sigNo, tid, info->si_code);
1471
1472 /* Update thread state properly */
sewardja8d8e232005-06-07 20:04:56 +00001473 VG_(fixup_guest_state_after_syscall_interrupted)(
1474 tid,
njnaf839f52005-06-23 03:27:57 +00001475 VG_UCONTEXT_INSTR_PTR(uc),
1476 VG_UCONTEXT_SYSCALL_NUM(uc),
1477 VG_UCONTEXT_SYSCALL_SYSRES(uc),
sewardja8d8e232005-06-07 20:04:56 +00001478 !!(scss.scss_per_sig[sigNo].scss_flags & VKI_SA_RESTART)
1479 );
sewardjb5f6f512005-03-10 23:59:00 +00001480
1481 /* Set up the thread's state to deliver a signal */
njn07ef6c02005-05-18 19:43:09 +00001482 if (!is_sig_ign(info->si_signo))
njn9ec0f3e2005-03-13 06:00:47 +00001483 deliver_signal(tid, info);
sewardjb5f6f512005-03-10 23:59:00 +00001484
1485 /* longjmp back to the thread's main loop to start executing the
1486 handler. */
njn06244e72005-06-21 22:27:19 +00001487 resume_scheduler(tid);
sewardjb5f6f512005-03-10 23:59:00 +00001488
njn695c16e2005-03-27 03:40:28 +00001489 VG_(core_panic)("async_signalhandler: got unexpected signal while outside of scheduler");
jsgf855d93d2003-10-13 22:26:55 +00001490}
1491
sewardjb5f6f512005-03-10 23:59:00 +00001492/* Extend the stack to cover addr. maxsize is the limit the stack can grow to.
1493
1494 Returns True on success, False on failure.
1495
1496 Succeeds without doing anything if addr is already within a segment.
1497
1498 Failure could be caused by:
1499 - addr not below a growable segment
1500 - new stack size would exceed maxsize
1501 - mmap failed for some other reason
1502 */
1503Bool VG_(extend_stack)(Addr addr, UInt maxsize)
1504{
sewardj45f4e7c2005-09-27 19:20:21 +00001505 SizeT udelta;
sewardjb5f6f512005-03-10 23:59:00 +00001506
1507 /* Find the next Segment above addr */
sewardj45f4e7c2005-09-27 19:20:21 +00001508 NSegment* seg = VG_(am_find_nsegment)(addr);
1509 NSegment* seg_next = seg ? VG_(am_next_nsegment)( seg, True/*fwds*/ )
1510 : NULL;
1511
1512 if (seg && seg->kind == SkAnonC)
1513 /* addr is already mapped. Nothing to do. */
sewardjb5f6f512005-03-10 23:59:00 +00001514 return True;
1515
sewardj45f4e7c2005-09-27 19:20:21 +00001516 /* Check that the requested new base is in a shrink-down
1517 reservation section which abuts an anonymous mapping that
1518 belongs to the client. */
1519 if ( ! (seg
1520 && seg->kind == SkResvn
1521 && seg->smode == SmUpper
1522 && seg_next
1523 && seg_next->kind == SkAnonC
1524 && seg->end+1 == seg_next->start))
sewardjb5f6f512005-03-10 23:59:00 +00001525 return False;
1526
sewardj45f4e7c2005-09-27 19:20:21 +00001527 udelta = VG_PGROUNDUP(seg_next->start - addr);
1528 VG_(debugLog)(1, "signals",
1529 "extending a stack base 0x%llx down by %lld\n",
1530 (ULong)seg_next->start, (ULong)udelta);
1531 if (! VG_(am_extend_into_adjacent_reservation_client)
1532 ( seg_next, -(SSizeT)udelta )) {
1533 VG_(debugLog)(1, "signals", "extending a stack base: FAILED\n");
sewardjb5f6f512005-03-10 23:59:00 +00001534 return False;
sewardj45f4e7c2005-09-27 19:20:21 +00001535 }
sewardjb5f6f512005-03-10 23:59:00 +00001536
rjwalsh0140af52005-06-04 20:42:33 +00001537 /* When we change the main stack, we have to let the stack handling
1538 code know about it. */
sewardj45f4e7c2005-09-27 19:20:21 +00001539 VG_(change_stack)(VG_(clstk_id), addr, VG_(clstk_end));
sewardjb5f6f512005-03-10 23:59:00 +00001540
1541 if (VG_(clo_sanity_level) > 2)
1542 VG_(sanity_check_general)(False);
1543
1544 return True;
1545}
1546
1547static void (*fault_catcher)(Int sig, Addr addr);
1548
1549void VG_(set_fault_catcher)(void (*catcher)(Int, Addr))
1550{
njn50ae1a72005-04-08 23:28:23 +00001551 vg_assert2(NULL == catcher || NULL == fault_catcher,
1552 "Fault catcher is already registered");
sewardjb5f6f512005-03-10 23:59:00 +00001553
1554 fault_catcher = catcher;
1555}
1556
1557
jsgf855d93d2003-10-13 22:26:55 +00001558/*
sewardj2a99cf62004-11-24 10:44:19 +00001559 Receive a sync signal from the host.
jsgf855d93d2003-10-13 22:26:55 +00001560*/
1561static
njn695c16e2005-03-27 03:40:28 +00001562void sync_signalhandler ( Int sigNo, vki_siginfo_t *info, struct vki_ucontext *uc )
jsgf855d93d2003-10-13 22:26:55 +00001563{
sewardjb5f6f512005-03-10 23:59:00 +00001564 ThreadId tid = VG_(get_lwp_tid)(VG_(gettid)());
jsgf855d93d2003-10-13 22:26:55 +00001565
1566 vg_assert(info != NULL);
1567 vg_assert(info->si_signo == sigNo);
1568 vg_assert(sigNo == VKI_SIGSEGV ||
1569 sigNo == VKI_SIGBUS ||
1570 sigNo == VKI_SIGFPE ||
sewardjb5f6f512005-03-10 23:59:00 +00001571 sigNo == VKI_SIGILL ||
1572 sigNo == VKI_SIGTRAP);
jsgf855d93d2003-10-13 22:26:55 +00001573
tom9f4a7bf2005-11-13 00:01:20 +00001574#ifdef VGO_linux
1575 /* The linux kernel uses the top 16 bits of si_code for it's own
1576 use and only exports the bottom 16 bits to user space - at least
1577 that is the theory, but it turns out that there are some kernels
tomc8cb9d02005-11-14 14:37:02 +00001578 around that forget to mask out the top 16 bits so we do it here.
1579
1580 The kernel treats the bottom 16 bits as signed and (when it does
1581 mask them off) sign extends them when exporting to user space so
1582 we do the same thing here. */
tom95458c62005-11-13 11:52:39 +00001583 info->si_code = (Short)info->si_code;
tom9f4a7bf2005-11-13 00:01:20 +00001584#endif
1585
sewardjb5f6f512005-03-10 23:59:00 +00001586 if (info->si_code <= VKI_SI_USER) {
1587 /* If some user-process sent us one of these signals (ie,
1588 they're not the result of a faulting instruction), then treat
1589 it as an async signal. This is tricky because we could get
1590 this almost anywhere:
1591 - while generated client code
1592 Action: queue signal and return
1593 - while running Valgrind code
1594 Action: queue signal and return
1595 - while blocked in a syscall
1596 Action: make thread runnable, queue signal, resume scheduler
1597 */
1598 if (VG_(threads)[tid].status == VgTs_WaitSys) {
1599 /* Since this signal interrupted a syscall, it means the
1600 client's signal mask was applied, so we can't get here
1601 unless the client wants this signal right now. This means
1602 we can simply use the async_signalhandler. */
njn695c16e2005-03-27 03:40:28 +00001603 async_signalhandler(sigNo, info, uc);
1604 VG_(core_panic)("async_signalhandler returned!?\n");
sewardjb5f6f512005-03-10 23:59:00 +00001605 }
jsgf855d93d2003-10-13 22:26:55 +00001606
sewardjb5f6f512005-03-10 23:59:00 +00001607 if (info->_sifields._kill._pid == 0) {
1608 /* There's a per-user limit of pending siginfo signals. If
1609 you exceed this, by having more than that number of
1610 pending signals with siginfo, then new signals are
1611 delivered without siginfo. This condition can be caused
1612 by any unrelated program you're running at the same time
1613 as Valgrind, if it has a large number of pending siginfo
1614 signals which it isn't taking delivery of.
1615
1616 Since we depend on siginfo to work out why we were sent a
1617 signal and what we should do about it, we really can't
1618 continue unless we get it. */
1619 VG_(message)(Vg_UserMsg, "Signal %d (%s) appears to have lost its siginfo; I can't go on.",
1620 sigNo, signame(sigNo));
1621 VG_(message)(Vg_UserMsg, " This may be because one of your programs has consumed your");
1622 VG_(message)(Vg_UserMsg, " ration of siginfo structures.");
njn504b72b2005-08-16 01:39:34 +00001623 VG_(printf)(
1624" For more information, see:\n"
1625" http://kerneltrap.org/mailarchive/1/message/25599/thread\n"
1626" Basically, some program on your system is building up a large queue of\n"
1627" pending signals, and this causes the siginfo data for other signals to\n"
1628" be dropped because it's exceeding a system limit. However, Valgrind\n"
1629" absolutely needs siginfo for SIGSEGV. A workaround is to track down the\n"
1630" offending program and avoid running it while using Valgrind, but there\n"
1631" is no easy way to do this. Apparently the problem was fixed in kernel\n"
1632" 2.6.12.\n");
sewardjb5f6f512005-03-10 23:59:00 +00001633
1634 /* It's a fatal signal, so we force the default handler. */
1635 VG_(set_default_handler)(sigNo);
njn9ec0f3e2005-03-13 06:00:47 +00001636 deliver_signal(tid, info);
njn06244e72005-06-21 22:27:19 +00001637 resume_scheduler(tid);
sewardjb5f6f512005-03-10 23:59:00 +00001638 VG_(exit)(99); /* If we can't resume, then just exit */
1639 }
1640
1641 if (VG_(clo_trace_signals))
1642 VG_(message)(Vg_DebugMsg, "Routing user-sent sync signal %d via queue",
1643 sigNo);
1644
1645 /* Since every thread has these signals unblocked, we can't rely
1646 on the kernel to route them properly, so we need to queue
1647 them manually. */
1648 if (info->si_code == VKI_SI_TKILL)
1649 queue_signal(tid, info); /* directed to us specifically */
1650 else
1651 queue_signal(0, info); /* shared pending */
1652
jsgf855d93d2003-10-13 22:26:55 +00001653 return;
sewardjb5f6f512005-03-10 23:59:00 +00001654 }
1655
1656 if (VG_(clo_trace_signals)) {
sewardj45f4e7c2005-09-27 19:20:21 +00001657 VG_(message)(Vg_DebugMsg, "signal %d arrived ... si_code=%d, "
1658 "EIP=%p, eip=%p",
njnf536bbb2005-06-13 04:21:38 +00001659 sigNo, info->si_code, VG_(get_IP)(tid),
njnaf839f52005-06-23 03:27:57 +00001660 VG_UCONTEXT_INSTR_PTR(uc) );
jsgf855d93d2003-10-13 22:26:55 +00001661 }
sewardjb5f6f512005-03-10 23:59:00 +00001662 vg_assert(sigNo >= 1 && sigNo <= VG_(max_signal));
sewardjde4a1d02002-03-22 01:27:54 +00001663
fitzhardinge98abfc72003-12-16 02:05:15 +00001664 /* Special fault-handling case. We can now get signals which can
1665 act upon and immediately restart the faulting instruction.
1666 */
1667 if (info->si_signo == VKI_SIGSEGV) {
fitzhardinge98abfc72003-12-16 02:05:15 +00001668 Addr fault = (Addr)info->_sifields._sigfault._addr;
njnf536bbb2005-06-13 04:21:38 +00001669 Addr esp = VG_(get_SP)(tid);
sewardj45f4e7c2005-09-27 19:20:21 +00001670 NSegment* seg = VG_(am_find_nsegment)(fault);
1671 NSegment* seg_next = seg ? VG_(am_next_nsegment)( seg, True/*fwds*/ )
1672 : NULL;
sewardj548be6d2005-02-16 01:31:37 +00001673
fitzhardinge98abfc72003-12-16 02:05:15 +00001674 if (VG_(clo_trace_signals)) {
1675 if (seg == NULL)
1676 VG_(message)(Vg_DebugMsg,
sewardj45f4e7c2005-09-27 19:20:21 +00001677 "SIGSEGV: si_code=%d faultaddr=%p tid=%d ESP=%p "
1678 "seg=NULL",
1679 info->si_code, fault, tid, esp);
fitzhardinge98abfc72003-12-16 02:05:15 +00001680 else
1681 VG_(message)(Vg_DebugMsg,
sewardj45f4e7c2005-09-27 19:20:21 +00001682 "SIGSEGV: si_code=%d faultaddr=%p tid=%d ESP=%p "
1683 "seg=%p-%p",
1684 info->si_code, fault, tid, esp, seg->start, seg->end);
fitzhardinge98abfc72003-12-16 02:05:15 +00001685 }
tom148250b2005-11-12 00:13:20 +00001686 if (info->si_code == VKI_SEGV_MAPERR
sewardj45f4e7c2005-09-27 19:20:21 +00001687 && seg
1688 && seg->kind == SkResvn
1689 && seg->smode == SmUpper
1690 && seg_next
1691 && seg_next->kind == SkAnonC
1692 && seg->end+1 == seg_next->start
1693 && fault >= (esp - VG_STACK_REDZONE_SZB)) {
fitzhardinge98abfc72003-12-16 02:05:15 +00001694 /* If the fault address is above esp but below the current known
1695 stack segment base, and it was a fault because there was
1696 nothing mapped there (as opposed to a permissions fault),
1697 then extend the stack segment.
1698 */
njnaf839f52005-06-23 03:27:57 +00001699 Addr base = VG_PGROUNDDN(esp - VG_STACK_REDZONE_SZB);
njn50ba34e2005-04-04 02:41:42 +00001700 if (VG_(extend_stack)(base, VG_(threads)[tid].client_stack_szB)) {
sewardjb5f6f512005-03-10 23:59:00 +00001701 if (VG_(clo_trace_signals))
1702 VG_(message)(Vg_DebugMsg,
sewardj45f4e7c2005-09-27 19:20:21 +00001703 " -> extended stack base to %p",
1704 VG_PGROUNDDN(fault));
sewardj0ec07f32006-01-12 12:32:32 +00001705 return; // extension succeeded, restart host (hence guest)
1706 // instruction
sewardjb5f6f512005-03-10 23:59:00 +00001707 } else
sewardj45f4e7c2005-09-27 19:20:21 +00001708 VG_(message)(Vg_UserMsg,
1709 "Stack overflow in thread %d: can't grow stack to %p",
sewardjb5f6f512005-03-10 23:59:00 +00001710 tid, fault);
fitzhardinge98abfc72003-12-16 02:05:15 +00001711 }
njnb69f7c12005-06-24 22:17:38 +00001712 /* Fall into normal signal handling for all other cases */
fitzhardinge98abfc72003-12-16 02:05:15 +00001713 }
1714
sewardjb5f6f512005-03-10 23:59:00 +00001715 /* OK, this is a signal we really have to deal with. If it came
1716 from the client's code, then we can jump back into the scheduler
1717 and have it delivered. Otherwise it's a Valgrind bug. */
1718 {
sewardjb5f6f512005-03-10 23:59:00 +00001719 ThreadState *tst = VG_(get_ThreadState)(VG_(get_lwp_tid)(VG_(gettid)()));
jsgf855d93d2003-10-13 22:26:55 +00001720
sewardjb5f6f512005-03-10 23:59:00 +00001721 if (VG_(sigismember)(&tst->sig_mask, sigNo)) {
1722 /* signal is blocked, but they're not allowed to block faults */
1723 VG_(set_default_handler)(sigNo);
1724 }
1725
sewardj0ec07f32006-01-12 12:32:32 +00001726 if (VG_(in_generated_code)) {
sewardjb5f6f512005-03-10 23:59:00 +00001727 /* Can't continue; must longjmp back to the scheduler and thus
1728 enter the sighandler immediately. */
njn9ec0f3e2005-03-13 06:00:47 +00001729 deliver_signal(tid, info);
njn06244e72005-06-21 22:27:19 +00001730 resume_scheduler(tid);
sewardjb5f6f512005-03-10 23:59:00 +00001731 }
1732
1733 /* Check to see if someone is interested in faults. */
1734 if (fault_catcher) {
1735 (*fault_catcher)(sigNo, (Addr)info->_sifields._sigfault._addr);
1736
1737 /* If the catcher returns, then it didn't handle the fault,
1738 so carry on panicing. */
1739 }
1740
1741 /* If resume_scheduler returns or its our fault, it means we
1742 don't have longjmp set up, implying that we weren't running
1743 client code, and therefore it was actually generated by
1744 Valgrind internally.
1745 */
jsgf855d93d2003-10-13 22:26:55 +00001746 VG_(message)(Vg_DebugMsg,
njn038ee9e2005-12-12 15:54:50 +00001747 "VALGRIND INTERNAL ERROR: Valgrind received a signal %d (%s) - exiting",
jsgf855d93d2003-10-13 22:26:55 +00001748 sigNo, signame(sigNo));
fitzhardinge98abfc72003-12-16 02:05:15 +00001749
jsgf855d93d2003-10-13 22:26:55 +00001750 VG_(message)(Vg_DebugMsg,
njnd0073f42005-05-14 17:00:25 +00001751 "si_code=%x; Faulting address: %p; sp: %p",
1752 info->si_code, info->_sifields._sigfault._addr,
njnaf839f52005-06-23 03:27:57 +00001753 VG_UCONTEXT_STACK_PTR(uc));
jsgf855d93d2003-10-13 22:26:55 +00001754
1755 if (0)
1756 VG_(kill_self)(sigNo); /* generate a core dump */
sewardjb5f6f512005-03-10 23:59:00 +00001757
sewardj1d887112005-05-30 21:44:08 +00001758 //if (tid == 0) /* could happen after everyone has exited */
1759 // tid = VG_(master_tid);
1760 vg_assert(tid != 0);
1761
njndb13c4f2005-06-01 00:00:46 +00001762 VG_(core_panic_at)("Killed by fatal signal",
njnaf839f52005-06-23 03:27:57 +00001763 VG_UCONTEXT_INSTR_PTR(uc),
1764 VG_UCONTEXT_STACK_PTR(uc),
sewardjacaec5f2005-08-19 16:02:59 +00001765 VG_UCONTEXT_FRAME_PTR(uc),
1766 VG_UCONTEXT_LINK_REG(uc));
jsgf855d93d2003-10-13 22:26:55 +00001767 }
1768}
1769
1770
1771/*
sewardjb5f6f512005-03-10 23:59:00 +00001772 Kill this thread. Makes it leave any syscall it might be currently
1773 blocked in, and return to the scheduler. This doesn't mark the thread
1774 as exiting; that's the caller's job.
jsgf855d93d2003-10-13 22:26:55 +00001775 */
sewardjb5f6f512005-03-10 23:59:00 +00001776static void sigvgkill_handler(int signo, vki_siginfo_t *si, struct vki_ucontext *uc)
jsgf855d93d2003-10-13 22:26:55 +00001777{
sewardjb5f6f512005-03-10 23:59:00 +00001778 ThreadId tid = VG_(get_lwp_tid)(VG_(gettid)());
1779
1780 if (VG_(clo_trace_signals))
1781 VG_(message)(Vg_DebugMsg, "sigvgkill for lwp %d tid %d", VG_(gettid)(), tid);
1782
njn351d0062005-06-21 22:23:59 +00001783 vg_assert(signo == VG_SIGVGKILL);
jsgf855d93d2003-10-13 22:26:55 +00001784 vg_assert(si->si_signo == signo);
sewardjb5f6f512005-03-10 23:59:00 +00001785 vg_assert(VG_(threads)[tid].status == VgTs_WaitSys);
jsgf855d93d2003-10-13 22:26:55 +00001786
sewardjb5f6f512005-03-10 23:59:00 +00001787 VG_(set_running)(tid);
1788 VG_(post_syscall)(tid);
1789
njn06244e72005-06-21 22:27:19 +00001790 resume_scheduler(tid);
sewardjb5f6f512005-03-10 23:59:00 +00001791
1792 VG_(core_panic)("sigvgkill_handler couldn't return to the scheduler\n");
sewardjde4a1d02002-03-22 01:27:54 +00001793}
1794
sewardjde4a1d02002-03-22 01:27:54 +00001795static __attribute((unused))
njn695c16e2005-03-27 03:40:28 +00001796void pp_ksigaction ( struct vki_sigaction* sa )
sewardjde4a1d02002-03-22 01:27:54 +00001797{
1798 Int i;
njn695c16e2005-03-27 03:40:28 +00001799 VG_(printf)("pp_ksigaction: handler %p, flags 0x%x, restorer %p\n",
nethercote73b526f2004-10-31 18:48:21 +00001800 sa->ksa_handler, (UInt)sa->sa_flags, sa->sa_restorer);
njn695c16e2005-03-27 03:40:28 +00001801 VG_(printf)("pp_ksigaction: { ");
sewardjb5f6f512005-03-10 23:59:00 +00001802 for (i = 1; i <= VG_(max_signal); i++)
nethercote73b526f2004-10-31 18:48:21 +00001803 if (VG_(sigismember(&(sa->sa_mask),i)))
sewardjde4a1d02002-03-22 01:27:54 +00001804 VG_(printf)("%d ", i);
1805 VG_(printf)("}\n");
1806}
1807
jsgf855d93d2003-10-13 22:26:55 +00001808/*
sewardjb5f6f512005-03-10 23:59:00 +00001809 Force signal handler to default
jsgf855d93d2003-10-13 22:26:55 +00001810 */
sewardjb5f6f512005-03-10 23:59:00 +00001811void VG_(set_default_handler)(Int signo)
1812{
1813 struct vki_sigaction sa;
1814
1815 sa.ksa_handler = VKI_SIG_DFL;
1816 sa.sa_flags = 0;
1817 sa.sa_restorer = 0;
1818 VG_(sigemptyset)(&sa.sa_mask);
1819
1820 VG_(do_sys_sigaction)(signo, &sa, NULL);
1821}
1822
1823/*
1824 Poll for pending signals, and set the next one up for delivery.
1825 */
1826void VG_(poll_signals)(ThreadId tid)
jsgf855d93d2003-10-13 22:26:55 +00001827{
1828 static const struct vki_timespec zero = { 0, 0 };
sewardjb5f6f512005-03-10 23:59:00 +00001829 vki_siginfo_t si, *sip;
1830 vki_sigset_t pollset;
1831 ThreadState *tst = VG_(get_ThreadState)(tid);
1832 Int i;
1833 vki_sigset_t saved_mask;
jsgf855d93d2003-10-13 22:26:55 +00001834
sewardjb5f6f512005-03-10 23:59:00 +00001835 /* look for all the signals this thread isn't blocking */
1836 for(i = 0; i < _VKI_NSIG_WORDS; i++)
1837 pollset.sig[i] = ~tst->sig_mask.sig[i];
jsgf855d93d2003-10-13 22:26:55 +00001838
sewardjb5f6f512005-03-10 23:59:00 +00001839 //VG_(printf)("tid %d pollset=%08x%08x\n", tid, pollset.sig[1], pollset.sig[0]);
jsgf855d93d2003-10-13 22:26:55 +00001840
njn444eba12005-05-12 03:47:31 +00001841 block_all_host_signals(&saved_mask); // protect signal queue
sewardjb5f6f512005-03-10 23:59:00 +00001842
1843 /* First look for any queued pending signals */
1844 sip = next_queued(tid, &pollset); /* this thread */
1845
1846 if (sip == NULL)
1847 sip = next_queued(0, &pollset); /* process-wide */
1848
1849 /* If there was nothing queued, ask the kernel for a pending signal */
1850 if (sip == NULL && VG_(sigtimedwait)(&pollset, &si, &zero) > 0) {
1851 if (VG_(clo_trace_signals))
sewardja8d8e232005-06-07 20:04:56 +00001852 VG_(message)(Vg_DebugMsg, "poll_signals: got signal %d "
1853 "for thread %d", si.si_signo, tid);
sewardjb5f6f512005-03-10 23:59:00 +00001854 sip = &si;
thughes8abf3922004-10-16 10:59:49 +00001855 }
fitzhardingee1c06d82003-10-30 07:21:44 +00001856
sewardjb5f6f512005-03-10 23:59:00 +00001857 if (sip != NULL) {
1858 /* OK, something to do; deliver it */
1859 if (VG_(clo_trace_signals))
1860 VG_(message)(Vg_DebugMsg, "Polling found signal %d for tid %d",
1861 sip->si_signo, tid);
njn07ef6c02005-05-18 19:43:09 +00001862 if (!is_sig_ign(sip->si_signo))
njn9ec0f3e2005-03-13 06:00:47 +00001863 deliver_signal(tid, sip);
sewardjb5f6f512005-03-10 23:59:00 +00001864 else if (VG_(clo_trace_signals))
1865 VG_(message)(Vg_DebugMsg, " signal %d ignored", sip->si_signo);
1866
1867 sip->si_signo = 0; /* remove from signal queue, if that's
1868 where it came from */
jsgf855d93d2003-10-13 22:26:55 +00001869 }
1870
njn444eba12005-05-12 03:47:31 +00001871 restore_all_host_signals(&saved_mask);
sewardjb5f6f512005-03-10 23:59:00 +00001872}
1873
sewardj018f7622002-05-15 21:13:39 +00001874/* At startup, copy the process' real signal state to the SCSS.
1875 Whilst doing this, block all real signals. Then calculate SKSS and
1876 set the kernel to that. Also initialise DCSS.
sewardjde4a1d02002-03-22 01:27:54 +00001877*/
1878void VG_(sigstartup_actions) ( void )
1879{
1880 Int i, ret;
nethercote73b526f2004-10-31 18:48:21 +00001881 vki_sigset_t saved_procmask;
nethercote73b526f2004-10-31 18:48:21 +00001882 struct vki_sigaction sa;
sewardjde4a1d02002-03-22 01:27:54 +00001883
sewardj2e93c502002-04-12 11:12:52 +00001884 /* VG_(printf)("SIGSTARTUP\n"); */
jsgf855d93d2003-10-13 22:26:55 +00001885 /* Block all signals. saved_procmask remembers the previous mask,
1886 which the first thread inherits.
1887 */
njn444eba12005-05-12 03:47:31 +00001888 block_all_host_signals( &saved_procmask );
sewardjde4a1d02002-03-22 01:27:54 +00001889
sewardj018f7622002-05-15 21:13:39 +00001890 /* Copy per-signal settings to SCSS. */
nethercote73b526f2004-10-31 18:48:21 +00001891 for (i = 1; i <= _VKI_NSIG; i++) {
sewardj018f7622002-05-15 21:13:39 +00001892 /* Get the old host action */
nethercote73b526f2004-10-31 18:48:21 +00001893 ret = VG_(sigaction)(i, NULL, &sa);
sewardj018f7622002-05-15 21:13:39 +00001894
sewardjb5f6f512005-03-10 23:59:00 +00001895 if (ret != 0)
1896 break;
1897
1898 /* Try setting it back to see if this signal is really
1899 available */
1900 if (i >= VKI_SIGRTMIN) {
1901 struct vki_sigaction tsa;
1902
njn695c16e2005-03-27 03:40:28 +00001903 tsa.ksa_handler = (void *)sync_signalhandler;
sewardjb5f6f512005-03-10 23:59:00 +00001904 tsa.sa_flags = VKI_SA_SIGINFO;
1905 tsa.sa_restorer = 0;
1906 VG_(sigfillset)(&tsa.sa_mask);
1907
1908 /* try setting it to some arbitrary handler */
1909 if (VG_(sigaction)(i, &tsa, NULL) != 0) {
1910 /* failed - not really usable */
1911 break;
1912 }
1913
1914 ret = VG_(sigaction)(i, &sa, NULL);
1915 vg_assert(ret == 0);
1916 }
1917
1918 VG_(max_signal) = i;
1919
1920 if (VG_(clo_trace_signals) && VG_(clo_verbosity) > 2)
sewardj018f7622002-05-15 21:13:39 +00001921 VG_(printf)("snaffling handler 0x%x for signal %d\n",
1922 (Addr)(sa.ksa_handler), i );
1923
njn695c16e2005-03-27 03:40:28 +00001924 scss.scss_per_sig[i].scss_handler = sa.ksa_handler;
1925 scss.scss_per_sig[i].scss_flags = sa.sa_flags;
1926 scss.scss_per_sig[i].scss_mask = sa.sa_mask;
1927 scss.scss_per_sig[i].scss_restorer = sa.sa_restorer;
sewardj018f7622002-05-15 21:13:39 +00001928 }
1929
sewardjb5f6f512005-03-10 23:59:00 +00001930 if (VG_(clo_trace_signals))
1931 VG_(message)(Vg_DebugMsg, "Max kernel-supported signal is %d", VG_(max_signal));
1932
jsgf855d93d2003-10-13 22:26:55 +00001933 /* Our private internal signals are treated as ignored */
njn351d0062005-06-21 22:23:59 +00001934 scss.scss_per_sig[VG_SIGVGKILL].scss_handler = VKI_SIG_IGN;
1935 scss.scss_per_sig[VG_SIGVGKILL].scss_flags = VKI_SA_SIGINFO;
1936 VG_(sigfillset)(&scss.scss_per_sig[VG_SIGVGKILL].scss_mask);
jsgf855d93d2003-10-13 22:26:55 +00001937
sewardj018f7622002-05-15 21:13:39 +00001938 /* Copy the process' signal mask into the root thread. */
sewardj1d887112005-05-30 21:44:08 +00001939 vg_assert(VG_(threads)[1].status == VgTs_Init);
1940 for (i = 2; i < VG_N_THREADS; i++)
1941 vg_assert(VG_(threads)[i].status == VgTs_Empty);
1942
1943 VG_(threads)[1].sig_mask = saved_procmask;
1944 VG_(threads)[1].tmp_sig_mask = saved_procmask;
sewardj7a61d912002-04-25 01:27:35 +00001945
sewardj018f7622002-05-15 21:13:39 +00001946 /* Calculate SKSS and apply it. This also sets the initial kernel
1947 mask we need to run with. */
nethercote9dd11512004-08-04 15:31:30 +00001948 handle_SCSS_change( True /* forced update */ );
jsgf855d93d2003-10-13 22:26:55 +00001949
sewardjb5f6f512005-03-10 23:59:00 +00001950 /* Leave with all signals still blocked; the thread scheduler loop
1951 will set the appropriate mask at the appropriate time. */
sewardjde4a1d02002-03-22 01:27:54 +00001952}
1953
sewardjde4a1d02002-03-22 01:27:54 +00001954/*--------------------------------------------------------------------*/
njned6b8242005-06-01 00:03:17 +00001955/*--- end ---*/
sewardjde4a1d02002-03-22 01:27:54 +00001956/*--------------------------------------------------------------------*/