blob: 0a3d82f92937d4e7658540a9e84c5ba501afc860 [file] [log] [blame]
sewardje663cb92002-04-12 10:26:32 +00001
2/*--------------------------------------------------------------------*/
njn278b3d62005-05-30 23:20:51 +00003/*--- Thread scheduling. scheduler.c ---*/
sewardje663cb92002-04-12 10:26:32 +00004/*--------------------------------------------------------------------*/
5
6/*
njnc0ae7052005-08-25 22:55:19 +00007 This file is part of Valgrind, a dynamic binary instrumentation
8 framework.
sewardje663cb92002-04-12 10:26:32 +00009
sewardj9eecbbb2010-05-03 21:37:12 +000010 Copyright (C) 2000-2010 Julian Seward
sewardje663cb92002-04-12 10:26:32 +000011 jseward@acm.org
sewardje663cb92002-04-12 10:26:32 +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.
sewardje663cb92002-04-12 10:26:32 +000029*/
30
sewardjb5f6f512005-03-10 23:59:00 +000031/*
32 Overview
33
34 Valgrind tries to emulate the kernel's threading as closely as
35 possible. The client does all threading via the normal syscalls
36 (on Linux: clone, etc). Valgrind emulates this by creating exactly
37 the same process structure as would be created without Valgrind.
38 There are no extra threads.
39
40 The main difference is that Valgrind only allows one client thread
sewardjad0a3a82006-12-17 18:58:55 +000041 to run at once. This is controlled with the CPU Big Lock,
42 "the_BigLock". Any time a thread wants to run client code or
sewardjb5f6f512005-03-10 23:59:00 +000043 manipulate any shared state (which is anything other than its own
sewardjad0a3a82006-12-17 18:58:55 +000044 ThreadState entry), it must hold the_BigLock.
sewardjb5f6f512005-03-10 23:59:00 +000045
46 When a thread is about to block in a blocking syscall, it releases
sewardjad0a3a82006-12-17 18:58:55 +000047 the_BigLock, and re-takes it when it becomes runnable again (either
sewardjb5f6f512005-03-10 23:59:00 +000048 because the syscall finished, or we took a signal).
49
50 VG_(scheduler) therefore runs in each thread. It returns only when
51 the thread is exiting, either because it exited itself, or it was
52 told to exit by another thread.
53
54 This file is almost entirely OS-independent. The details of how
55 the OS handles threading and signalling are abstracted away and
njn12771092005-06-18 02:18:04 +000056 implemented elsewhere. [Some of the functions have worked their
57 way back for the moment, until we do an OS port in earnest...]
sewardjb5f6f512005-03-10 23:59:00 +000058 */
59
njnc7561b92005-06-19 01:24:32 +000060#include "pub_core_basics.h"
sewardjf9d2f9b2006-11-17 20:00:57 +000061#include "pub_core_debuglog.h"
sewardj4cfea4f2006-10-14 19:26:10 +000062#include "pub_core_vki.h"
sewardjf54342a2006-10-17 01:51:24 +000063#include "pub_core_vkiscnums.h" // __NR_sched_yield
sewardj6c591e12011-04-11 16:17:51 +000064#include "pub_core_libcsetjmp.h" // to keep _threadstate.h happy
njnc7561b92005-06-19 01:24:32 +000065#include "pub_core_threadstate.h"
njn04e16982005-05-31 00:23:43 +000066#include "pub_core_aspacemgr.h"
njn93fe3b22005-12-21 20:22:52 +000067#include "pub_core_clreq.h" // for VG_USERREQ__*
njn36b66df2005-05-12 05:13:04 +000068#include "pub_core_dispatch.h"
njnf4c50162005-06-20 14:18:12 +000069#include "pub_core_errormgr.h" // For VG_(get_n_errs_found)()
njn97405b22005-06-02 03:39:33 +000070#include "pub_core_libcbase.h"
njn132bfcc2005-06-04 19:16:06 +000071#include "pub_core_libcassert.h"
njn36a20fa2005-06-03 03:08:39 +000072#include "pub_core_libcprint.h"
njnf39e9a32005-06-12 02:43:17 +000073#include "pub_core_libcproc.h"
njnde62cbf2005-06-10 22:08:14 +000074#include "pub_core_libcsignal.h"
njnf76d27a2009-05-28 01:53:07 +000075#if defined(VGO_darwin)
76#include "pub_core_mach.h"
77#endif
njnf536bbb2005-06-13 04:21:38 +000078#include "pub_core_machine.h"
njnaf1d7df2005-06-11 01:31:52 +000079#include "pub_core_mallocfree.h"
njn20242342005-05-16 23:31:24 +000080#include "pub_core_options.h"
njn717cde52005-05-10 02:47:21 +000081#include "pub_core_replacemalloc.h"
njn0c246472005-05-31 01:00:08 +000082#include "pub_core_signals.h"
njn945ed2e2005-06-24 03:28:30 +000083#include "pub_core_stacks.h"
njnf4c50162005-06-20 14:18:12 +000084#include "pub_core_stacktrace.h" // For VG_(get_and_pp_StackTrace)()
njn9abd6082005-06-17 21:31:45 +000085#include "pub_core_syscall.h"
njnc1b01812005-06-17 22:19:06 +000086#include "pub_core_syswrap.h"
njn43b9a8a2005-05-10 04:37:01 +000087#include "pub_core_tooliface.h"
njnf4c50162005-06-20 14:18:12 +000088#include "pub_core_translate.h" // For VG_(translate)()
njn8bddf582005-05-13 23:40:55 +000089#include "pub_core_transtab.h"
sewardjc8259b82009-04-22 22:42:10 +000090#include "pub_core_debuginfo.h" // VG_(di_notify_pdb_debuginfo)
njn278b3d62005-05-30 23:20:51 +000091#include "priv_sema.h"
sewardjf54342a2006-10-17 01:51:24 +000092#include "pub_core_scheduler.h" // self
tomd2645142009-10-29 09:27:11 +000093#include "pub_core_redir.h"
sewardje663cb92002-04-12 10:26:32 +000094
sewardj63fed7f2006-01-17 02:02:47 +000095
sewardje663cb92002-04-12 10:26:32 +000096/* ---------------------------------------------------------------------
97 Types and globals for the scheduler.
98 ------------------------------------------------------------------ */
99
njnc7561b92005-06-19 01:24:32 +0000100/* ThreadId and ThreadState are defined elsewhere*/
sewardje663cb92002-04-12 10:26:32 +0000101
njn14319cc2005-03-13 06:26:22 +0000102/* Defines the thread-scheduling timeslice, in terms of the number of
103 basic blocks we attempt to run each thread for. Smaller values
104 give finer interleaving but much increased scheduling overheads. */
sewardjea3a99f2006-05-07 14:37:03 +0000105#define SCHEDULING_QUANTUM 100000
njn14319cc2005-03-13 06:26:22 +0000106
sewardj0ec07f32006-01-12 12:32:32 +0000107/* If False, a fault is Valgrind-internal (ie, a bug) */
108Bool VG_(in_generated_code) = False;
njn25e49d8e72002-09-23 09:36:25 +0000109
njnde583aa2005-05-11 18:57:02 +0000110/* Counts downwards in VG_(run_innerloop). */
111UInt VG_(dispatch_ctr);
112
njn394213a2005-06-19 18:38:24 +0000113/* 64-bit counter for the number of basic blocks done. */
114static ULong bbs_done = 0;
115
sewardje663cb92002-04-12 10:26:32 +0000116/* Forwards */
sewardjb5f6f512005-03-10 23:59:00 +0000117static void do_client_request ( ThreadId tid );
118static void scheduler_sanity ( ThreadId tid );
119static void mostly_clear_thread_record ( ThreadId tid );
sewardjd140e442002-05-29 01:21:19 +0000120
nethercote844e7122004-08-02 15:27:22 +0000121/* Stats. */
njn0fd92f42005-10-06 03:32:42 +0000122static ULong n_scheduling_events_MINOR = 0;
123static ULong n_scheduling_events_MAJOR = 0;
nethercote844e7122004-08-02 15:27:22 +0000124
njn6676d5b2005-06-19 18:49:19 +0000125/* Sanity checking counts. */
126static UInt sanity_fast_count = 0;
127static UInt sanity_slow_count = 0;
sewardjb5f6f512005-03-10 23:59:00 +0000128
nethercote844e7122004-08-02 15:27:22 +0000129void VG_(print_scheduler_stats)(void)
130{
131 VG_(message)(Vg_DebugMsg,
sewardj738856f2009-07-15 14:48:32 +0000132 "scheduler: %'llu jumps (bb entries).\n", bbs_done );
njn394213a2005-06-19 18:38:24 +0000133 VG_(message)(Vg_DebugMsg,
sewardj738856f2009-07-15 14:48:32 +0000134 "scheduler: %'llu/%'llu major/minor sched events.\n",
nethercote844e7122004-08-02 15:27:22 +0000135 n_scheduling_events_MAJOR, n_scheduling_events_MINOR);
njn6676d5b2005-06-19 18:49:19 +0000136 VG_(message)(Vg_DebugMsg,
sewardj738856f2009-07-15 14:48:32 +0000137 " sanity: %d cheap, %d expensive checks.\n",
njn6676d5b2005-06-19 18:49:19 +0000138 sanity_fast_count, sanity_slow_count );
nethercote844e7122004-08-02 15:27:22 +0000139}
140
sewardjb5f6f512005-03-10 23:59:00 +0000141/* CPU semaphore, so that threads can run exclusively */
sewardjad0a3a82006-12-17 18:58:55 +0000142static vg_sema_t the_BigLock;
sewardjb5f6f512005-03-10 23:59:00 +0000143
144
sewardje663cb92002-04-12 10:26:32 +0000145/* ---------------------------------------------------------------------
146 Helper functions for the scheduler.
147 ------------------------------------------------------------------ */
148
sewardje663cb92002-04-12 10:26:32 +0000149static
150void print_sched_event ( ThreadId tid, Char* what )
151{
sewardj738856f2009-07-15 14:48:32 +0000152 VG_(message)(Vg_DebugMsg, " SCHED[%d]: %s\n", tid, what );
sewardj8937c812002-04-12 20:12:20 +0000153}
154
sewardj8937c812002-04-12 20:12:20 +0000155static
sewardjb5f6f512005-03-10 23:59:00 +0000156HChar* name_of_sched_event ( UInt event )
sewardje663cb92002-04-12 10:26:32 +0000157{
158 switch (event) {
sewardja0fef1b2005-11-03 13:46:30 +0000159 case VEX_TRC_JMP_SYS_SYSCALL: return "SYSCALL";
160 case VEX_TRC_JMP_SYS_INT32: return "INT32";
161 case VEX_TRC_JMP_SYS_INT128: return "INT128";
njnf76d27a2009-05-28 01:53:07 +0000162 case VEX_TRC_JMP_SYS_INT129: return "INT129";
163 case VEX_TRC_JMP_SYS_INT130: return "INT130";
sewardja0fef1b2005-11-03 13:46:30 +0000164 case VEX_TRC_JMP_SYS_SYSENTER: return "SYSENTER";
sewardjd79ef682004-11-26 13:25:17 +0000165 case VEX_TRC_JMP_CLIENTREQ: return "CLIENTREQ";
166 case VEX_TRC_JMP_YIELD: return "YIELD";
sewardj45f02c42005-02-05 18:27:14 +0000167 case VEX_TRC_JMP_NODECODE: return "NODECODE";
sewardj1f430d32005-12-16 01:07:11 +0000168 case VEX_TRC_JMP_MAPFAIL: return "MAPFAIL";
tom360ed5d2006-01-13 09:26:23 +0000169 case VEX_TRC_JMP_NOREDIR: return "NOREDIR";
sewardj1f430d32005-12-16 01:07:11 +0000170 case VEX_TRC_JMP_EMWARN: return "EMWARN";
171 case VEX_TRC_JMP_TINVAL: return "TINVAL";
172 case VG_TRC_INVARIANT_FAILED: return "INVFAILED";
sewardje663cb92002-04-12 10:26:32 +0000173 case VG_TRC_INNER_COUNTERZERO: return "COUNTERZERO";
174 case VG_TRC_INNER_FASTMISS: return "FASTMISS";
sewardjb5f6f512005-03-10 23:59:00 +0000175 case VG_TRC_FAULT_SIGNAL: return "FAULTSIGNAL";
sewardje663cb92002-04-12 10:26:32 +0000176 default: return "??UNKNOWN??";
177 }
178}
179
sewardje663cb92002-04-12 10:26:32 +0000180/* Allocate a completely empty ThreadState record. */
sewardjb5f6f512005-03-10 23:59:00 +0000181ThreadId VG_(alloc_ThreadState) ( void )
sewardje663cb92002-04-12 10:26:32 +0000182{
183 Int i;
sewardj6072c362002-04-19 14:40:57 +0000184 for (i = 1; i < VG_N_THREADS; i++) {
sewardjb5f6f512005-03-10 23:59:00 +0000185 if (VG_(threads)[i].status == VgTs_Empty) {
186 VG_(threads)[i].status = VgTs_Init;
187 VG_(threads)[i].exitreason = VgSrc_None;
sewardje663cb92002-04-12 10:26:32 +0000188 return i;
sewardjb5f6f512005-03-10 23:59:00 +0000189 }
sewardje663cb92002-04-12 10:26:32 +0000190 }
191 VG_(printf)("vg_alloc_ThreadState: no free slots available\n");
192 VG_(printf)("Increase VG_N_THREADS, rebuild and try again.\n");
njne427a662002-10-02 11:08:25 +0000193 VG_(core_panic)("VG_N_THREADS is too low");
sewardje663cb92002-04-12 10:26:32 +0000194 /*NOTREACHED*/
195}
196
sewardjb5f6f512005-03-10 23:59:00 +0000197/*
sewardjad0a3a82006-12-17 18:58:55 +0000198 Mark a thread as Runnable. This will block until the_BigLock is
sewardjb5f6f512005-03-10 23:59:00 +0000199 available, so that we get exclusive access to all the shared
sewardjad0a3a82006-12-17 18:58:55 +0000200 structures and the CPU. Up until we get the_BigLock, we must not
sewardjb5f6f512005-03-10 23:59:00 +0000201 touch any shared state.
202
203 When this returns, we'll actually be running.
204 */
sewardjad0a3a82006-12-17 18:58:55 +0000205void VG_(acquire_BigLock)(ThreadId tid, HChar* who)
sewardjb5f6f512005-03-10 23:59:00 +0000206{
sewardjf54342a2006-10-17 01:51:24 +0000207 ThreadState *tst;
208
209#if 0
210 if (VG_(clo_trace_sched)) {
211 HChar buf[100];
212 vg_assert(VG_(strlen)(who) <= 100-50);
213 VG_(sprintf)(buf, "waiting for lock (%s)", who);
214 print_sched_event(tid, buf);
215 }
216#endif
217
sewardjad0a3a82006-12-17 18:58:55 +0000218 /* First, acquire the_BigLock. We can't do anything else safely
219 prior to this point. Even doing debug printing prior to this
220 point is, technically, wrong. */
njnf76d27a2009-05-28 01:53:07 +0000221 ML_(sema_down)(&the_BigLock, False/*not LL*/);
sewardjf54342a2006-10-17 01:51:24 +0000222
223 tst = VG_(get_ThreadState)(tid);
sewardjb5f6f512005-03-10 23:59:00 +0000224
225 vg_assert(tst->status != VgTs_Runnable);
226
227 tst->status = VgTs_Runnable;
sewardjf54342a2006-10-17 01:51:24 +0000228
njnc7561b92005-06-19 01:24:32 +0000229 if (VG_(running_tid) != VG_INVALID_THREADID)
230 VG_(printf)("tid %d found %d running\n", tid, VG_(running_tid));
231 vg_assert(VG_(running_tid) == VG_INVALID_THREADID);
232 VG_(running_tid) = tid;
sewardjb5f6f512005-03-10 23:59:00 +0000233
sewardj7cf4e6b2008-05-01 20:24:26 +0000234 { Addr gsp = VG_(get_SP)(tid);
235 VG_(unknown_SP_update)(gsp, gsp, 0/*unknown origin*/);
236 }
tome0008d62005-11-10 15:02:42 +0000237
sewardjf54342a2006-10-17 01:51:24 +0000238 if (VG_(clo_trace_sched)) {
239 HChar buf[150];
240 vg_assert(VG_(strlen)(who) <= 150-50);
241 VG_(sprintf)(buf, " acquired lock (%s)", who);
242 print_sched_event(tid, buf);
243 }
sewardjb5f6f512005-03-10 23:59:00 +0000244}
245
sewardjb5f6f512005-03-10 23:59:00 +0000246/*
247 Set a thread into a sleeping state, and give up exclusive access to
248 the CPU. On return, the thread must be prepared to block until it
249 is ready to run again (generally this means blocking in a syscall,
250 but it may mean that we remain in a Runnable state and we're just
251 yielding the CPU to another thread).
252 */
sewardjad0a3a82006-12-17 18:58:55 +0000253void VG_(release_BigLock)(ThreadId tid, ThreadStatus sleepstate, HChar* who)
sewardjb5f6f512005-03-10 23:59:00 +0000254{
255 ThreadState *tst = VG_(get_ThreadState)(tid);
256
257 vg_assert(tst->status == VgTs_Runnable);
258
259 vg_assert(sleepstate == VgTs_WaitSys ||
260 sleepstate == VgTs_Yielding);
261
262 tst->status = sleepstate;
263
njnc7561b92005-06-19 01:24:32 +0000264 vg_assert(VG_(running_tid) == tid);
265 VG_(running_tid) = VG_INVALID_THREADID;
sewardjb5f6f512005-03-10 23:59:00 +0000266
sewardjf54342a2006-10-17 01:51:24 +0000267 if (VG_(clo_trace_sched)) {
268 Char buf[200];
269 vg_assert(VG_(strlen)(who) <= 200-100);
270 VG_(sprintf)(buf, "releasing lock (%s) -> %s",
271 who, VG_(name_of_ThreadStatus)(sleepstate));
272 print_sched_event(tid, buf);
273 }
274
sewardjad0a3a82006-12-17 18:58:55 +0000275 /* Release the_BigLock; this will reschedule any runnable
sewardjb5f6f512005-03-10 23:59:00 +0000276 thread. */
njnf76d27a2009-05-28 01:53:07 +0000277 ML_(sema_up)(&the_BigLock, False/*not LL*/);
nethercote75d26242004-08-01 22:59:18 +0000278}
279
njnf76d27a2009-05-28 01:53:07 +0000280/* See pub_core_scheduler.h for description */
281void VG_(acquire_BigLock_LL) ( HChar* who )
282{
283 ML_(sema_down)(&the_BigLock, True/*LL*/);
284}
285
286/* See pub_core_scheduler.h for description */
287void VG_(release_BigLock_LL) ( HChar* who )
288{
289 ML_(sema_up)(&the_BigLock, True/*LL*/);
290}
291
292
sewardjb5f6f512005-03-10 23:59:00 +0000293/* Clear out the ThreadState and release the semaphore. Leaves the
294 ThreadState in VgTs_Zombie state, so that it doesn't get
295 reallocated until the caller is really ready. */
296void VG_(exit_thread)(ThreadId tid)
297{
298 vg_assert(VG_(is_valid_tid)(tid));
299 vg_assert(VG_(is_running_thread)(tid));
300 vg_assert(VG_(is_exiting)(tid));
301
sewardjb5f6f512005-03-10 23:59:00 +0000302 mostly_clear_thread_record(tid);
njnc7561b92005-06-19 01:24:32 +0000303 VG_(running_tid) = VG_INVALID_THREADID;
sewardjb5f6f512005-03-10 23:59:00 +0000304
305 /* There should still be a valid exitreason for this thread */
306 vg_assert(VG_(threads)[tid].exitreason != VgSrc_None);
307
sewardjf54342a2006-10-17 01:51:24 +0000308 if (VG_(clo_trace_sched))
309 print_sched_event(tid, "release lock in VG_(exit_thread)");
310
njnf76d27a2009-05-28 01:53:07 +0000311 ML_(sema_up)(&the_BigLock, False/*not LL*/);
sewardjb5f6f512005-03-10 23:59:00 +0000312}
313
sewardjf54342a2006-10-17 01:51:24 +0000314/* If 'tid' is blocked in a syscall, send it SIGVGKILL so as to get it
315 out of the syscall and onto doing the next thing, whatever that is.
316 If it isn't blocked in a syscall, has no effect on the thread. */
317void VG_(get_thread_out_of_syscall)(ThreadId tid)
sewardjb5f6f512005-03-10 23:59:00 +0000318{
319 vg_assert(VG_(is_valid_tid)(tid));
320 vg_assert(!VG_(is_running_thread)(tid));
sewardjb5f6f512005-03-10 23:59:00 +0000321
322 if (VG_(threads)[tid].status == VgTs_WaitSys) {
njnf76d27a2009-05-28 01:53:07 +0000323 if (VG_(clo_trace_signals)) {
sewardjf54342a2006-10-17 01:51:24 +0000324 VG_(message)(Vg_DebugMsg,
sewardj738856f2009-07-15 14:48:32 +0000325 "get_thread_out_of_syscall zaps tid %d lwp %d\n",
sewardjb5f6f512005-03-10 23:59:00 +0000326 tid, VG_(threads)[tid].os_state.lwpid);
njnf76d27a2009-05-28 01:53:07 +0000327 }
328# if defined(VGO_darwin)
329 {
330 // GrP fixme use mach primitives on darwin?
331 // GrP fixme thread_abort_safely?
332 // GrP fixme race for thread with WaitSys set but not in syscall yet?
333 extern kern_return_t thread_abort(mach_port_t);
334 thread_abort(VG_(threads)[tid].os_state.lwpid);
335 }
336# else
337 {
338 __attribute__((unused))
339 Int r = VG_(tkill)(VG_(threads)[tid].os_state.lwpid, VG_SIGVGKILL);
340 /* JRS 2009-Mar-20: should we assert for r==0 (tkill succeeded)?
341 I'm really not sure. Here's a race scenario which argues
342 that we shoudn't; but equally I'm not sure the scenario is
343 even possible, because of constraints caused by the question
344 of who holds the BigLock when.
345
346 Target thread tid does sys_read on a socket and blocks. This
347 function gets called, and we observe correctly that tid's
348 status is WaitSys but then for whatever reason this function
349 goes very slowly for a while. Then data arrives from
350 wherever, tid's sys_read returns, tid exits. Then we do
351 tkill on tid, but tid no longer exists; tkill returns an
352 error code and the assert fails. */
353 /* vg_assert(r == 0); */
354 }
355# endif
sewardjb5f6f512005-03-10 23:59:00 +0000356 }
357}
358
359/*
360 Yield the CPU for a short time to let some other thread run.
361 */
362void VG_(vg_yield)(void)
363{
njnc7561b92005-06-19 01:24:32 +0000364 ThreadId tid = VG_(running_tid);
sewardjb5f6f512005-03-10 23:59:00 +0000365
366 vg_assert(tid != VG_INVALID_THREADID);
367 vg_assert(VG_(threads)[tid].os_state.lwpid == VG_(gettid)());
368
sewardjad0a3a82006-12-17 18:58:55 +0000369 VG_(release_BigLock)(tid, VgTs_Yielding, "VG_(vg_yield)");
sewardjb5f6f512005-03-10 23:59:00 +0000370
371 /*
372 Tell the kernel we're yielding.
373 */
sewardjf54342a2006-10-17 01:51:24 +0000374 VG_(do_syscall0)(__NR_sched_yield);
sewardjb5f6f512005-03-10 23:59:00 +0000375
sewardjad0a3a82006-12-17 18:58:55 +0000376 VG_(acquire_BigLock)(tid, "VG_(vg_yield)");
sewardjb5f6f512005-03-10 23:59:00 +0000377}
378
379
sewardj0ec07f32006-01-12 12:32:32 +0000380/* Set the standard set of blocked signals, used whenever we're not
njn9fc31122005-05-11 18:48:33 +0000381 running a client syscall. */
njn1dcee092009-02-24 03:07:37 +0000382static void block_signals(void)
njn9fc31122005-05-11 18:48:33 +0000383{
384 vki_sigset_t mask;
385
386 VG_(sigfillset)(&mask);
387
388 /* Don't block these because they're synchronous */
389 VG_(sigdelset)(&mask, VKI_SIGSEGV);
390 VG_(sigdelset)(&mask, VKI_SIGBUS);
391 VG_(sigdelset)(&mask, VKI_SIGFPE);
392 VG_(sigdelset)(&mask, VKI_SIGILL);
393 VG_(sigdelset)(&mask, VKI_SIGTRAP);
394
395 /* Can't block these anyway */
396 VG_(sigdelset)(&mask, VKI_SIGSTOP);
397 VG_(sigdelset)(&mask, VKI_SIGKILL);
398
njn9fc31122005-05-11 18:48:33 +0000399 VG_(sigprocmask)(VKI_SIG_SETMASK, &mask, NULL);
400}
401
njn8aa35852005-06-10 22:59:56 +0000402static void os_state_clear(ThreadState *tst)
403{
sewardj45f4e7c2005-09-27 19:20:21 +0000404 tst->os_state.lwpid = 0;
njn8aa35852005-06-10 22:59:56 +0000405 tst->os_state.threadgroup = 0;
njnf76d27a2009-05-28 01:53:07 +0000406# if defined(VGO_linux)
407 /* no other fields to clear */
408# elif defined(VGO_aix5)
sewardjf54342a2006-10-17 01:51:24 +0000409 tst->os_state.cancel_async = False;
410 tst->os_state.cancel_disabled = False;
411 tst->os_state.cancel_progress = Canc_NoRequest;
njnf76d27a2009-05-28 01:53:07 +0000412# elif defined(VGO_darwin)
413 tst->os_state.post_mach_trap_fn = NULL;
414 tst->os_state.pthread = 0;
415 tst->os_state.func_arg = 0;
416 VG_(memset)(&tst->os_state.child_go, 0, sizeof(tst->os_state.child_go));
417 VG_(memset)(&tst->os_state.child_done, 0, sizeof(tst->os_state.child_done));
418 tst->os_state.wq_jmpbuf_valid = False;
419 tst->os_state.remote_port = 0;
420 tst->os_state.msgh_id = 0;
421 VG_(memset)(&tst->os_state.mach_args, 0, sizeof(tst->os_state.mach_args));
422# else
423# error "Unknown OS"
sewardjf54342a2006-10-17 01:51:24 +0000424# endif
njn8aa35852005-06-10 22:59:56 +0000425}
426
427static void os_state_init(ThreadState *tst)
428{
sewardj45f4e7c2005-09-27 19:20:21 +0000429 tst->os_state.valgrind_stack_base = 0;
430 tst->os_state.valgrind_stack_init_SP = 0;
njn8aa35852005-06-10 22:59:56 +0000431 os_state_clear(tst);
432}
433
sewardj20917d82002-05-28 01:36:45 +0000434static
435void mostly_clear_thread_record ( ThreadId tid )
436{
sewardjb5f6f512005-03-10 23:59:00 +0000437 vki_sigset_t savedmask;
438
sewardj20917d82002-05-28 01:36:45 +0000439 vg_assert(tid >= 0 && tid < VG_N_THREADS);
njnaf839f52005-06-23 03:27:57 +0000440 VG_(cleanup_thread)(&VG_(threads)[tid].arch);
sewardjb5f6f512005-03-10 23:59:00 +0000441 VG_(threads)[tid].tid = tid;
442
443 /* Leave the thread in Zombie, so that it doesn't get reallocated
444 until the caller is finally done with the thread stack. */
445 VG_(threads)[tid].status = VgTs_Zombie;
446
nethercote73b526f2004-10-31 18:48:21 +0000447 VG_(sigemptyset)(&VG_(threads)[tid].sig_mask);
sewardjb5f6f512005-03-10 23:59:00 +0000448 VG_(sigemptyset)(&VG_(threads)[tid].tmp_sig_mask);
jsgf855d93d2003-10-13 22:26:55 +0000449
njn8aa35852005-06-10 22:59:56 +0000450 os_state_clear(&VG_(threads)[tid]);
fitzhardinge28428592004-03-16 22:07:12 +0000451
452 /* start with no altstack */
453 VG_(threads)[tid].altstack.ss_sp = (void *)0xdeadbeef;
454 VG_(threads)[tid].altstack.ss_size = 0;
455 VG_(threads)[tid].altstack.ss_flags = VKI_SS_DISABLE;
sewardjb5f6f512005-03-10 23:59:00 +0000456
njn444eba12005-05-12 03:47:31 +0000457 VG_(clear_out_queued_signals)(tid, &savedmask);
sewardjb5f6f512005-03-10 23:59:00 +0000458
459 VG_(threads)[tid].sched_jmpbuf_valid = False;
sewardj20917d82002-05-28 01:36:45 +0000460}
461
njn3f8c4372005-03-13 04:43:10 +0000462/*
sewardj0ec07f32006-01-12 12:32:32 +0000463 Called in the child after fork. If the parent has multiple
464 threads, then we've inherited a VG_(threads) array describing them,
465 but only the thread which called fork() is actually alive in the
466 child. This functions needs to clean up all those other thread
467 structures.
njn3f8c4372005-03-13 04:43:10 +0000468
469 Whichever tid in the parent which called fork() becomes the
470 master_tid in the child. That's because the only living slot in
471 VG_(threads) in the child after fork is VG_(threads)[tid], and it
472 would be too hard to try to re-number the thread and relocate the
473 thread state down to VG_(threads)[1].
474
sewardjad0a3a82006-12-17 18:58:55 +0000475 This function also needs to reinitialize the_BigLock, since
476 otherwise we may end up sharing its state with the parent, which
477 would be deeply confusing.
njn3f8c4372005-03-13 04:43:10 +0000478*/
sewardjb5f6f512005-03-10 23:59:00 +0000479static void sched_fork_cleanup(ThreadId me)
480{
481 ThreadId tid;
njnc7561b92005-06-19 01:24:32 +0000482 vg_assert(VG_(running_tid) == me);
sewardjb5f6f512005-03-10 23:59:00 +0000483
njnf76d27a2009-05-28 01:53:07 +0000484# if defined(VGO_darwin)
485 // GrP fixme hack reset Mach ports
486 VG_(mach_init)();
487# endif
488
sewardjb5f6f512005-03-10 23:59:00 +0000489 VG_(threads)[me].os_state.lwpid = VG_(gettid)();
490 VG_(threads)[me].os_state.threadgroup = VG_(getpid)();
491
492 /* clear out all the unused thread slots */
493 for (tid = 1; tid < VG_N_THREADS; tid++) {
njn3f8c4372005-03-13 04:43:10 +0000494 if (tid != me) {
495 mostly_clear_thread_record(tid);
sewardjb5f6f512005-03-10 23:59:00 +0000496 VG_(threads)[tid].status = VgTs_Empty;
sewardja8d8e232005-06-07 20:04:56 +0000497 VG_(clear_syscallInfo)(tid);
njn3f8c4372005-03-13 04:43:10 +0000498 }
sewardjb5f6f512005-03-10 23:59:00 +0000499 }
500
501 /* re-init and take the sema */
sewardjad0a3a82006-12-17 18:58:55 +0000502 ML_(sema_deinit)(&the_BigLock);
503 ML_(sema_init)(&the_BigLock);
njnf76d27a2009-05-28 01:53:07 +0000504 ML_(sema_down)(&the_BigLock, False/*not LL*/);
sewardjb5f6f512005-03-10 23:59:00 +0000505}
sewardj20917d82002-05-28 01:36:45 +0000506
jsgf855d93d2003-10-13 22:26:55 +0000507
sewardjde764e82007-11-09 23:13:22 +0000508/* First phase of initialisation of the scheduler. Initialise the
509 bigLock, zeroise the VG_(threads) structure and decide on the
510 ThreadId of the root thread.
sewardje663cb92002-04-12 10:26:32 +0000511*/
sewardjde764e82007-11-09 23:13:22 +0000512ThreadId VG_(scheduler_init_phase1) ( void )
sewardje663cb92002-04-12 10:26:32 +0000513{
thughesc37184f2004-09-11 14:16:57 +0000514 Int i;
sewardje663cb92002-04-12 10:26:32 +0000515 ThreadId tid_main;
516
sewardjde764e82007-11-09 23:13:22 +0000517 VG_(debugLog)(1,"sched","sched_init_phase1\n");
sewardj45f4e7c2005-09-27 19:20:21 +0000518
sewardjad0a3a82006-12-17 18:58:55 +0000519 ML_(sema_init)(&the_BigLock);
sewardjb5f6f512005-03-10 23:59:00 +0000520
sewardj6072c362002-04-19 14:40:57 +0000521 for (i = 0 /* NB; not 1 */; i < VG_N_THREADS; i++) {
sewardjc793fd32005-05-31 17:24:49 +0000522 /* Paranoia .. completely zero it out. */
523 VG_(memset)( & VG_(threads)[i], 0, sizeof( VG_(threads)[i] ) );
524
525 VG_(threads)[i].sig_queue = NULL;
sewardjb5f6f512005-03-10 23:59:00 +0000526
njn8aa35852005-06-10 22:59:56 +0000527 os_state_init(&VG_(threads)[i]);
sewardj20917d82002-05-28 01:36:45 +0000528 mostly_clear_thread_record(i);
sewardjb5f6f512005-03-10 23:59:00 +0000529
njn50ba34e2005-04-04 02:41:42 +0000530 VG_(threads)[i].status = VgTs_Empty;
531 VG_(threads)[i].client_stack_szB = 0;
532 VG_(threads)[i].client_stack_highest_word = (Addr)NULL;
sewardje663cb92002-04-12 10:26:32 +0000533 }
534
sewardjb5f6f512005-03-10 23:59:00 +0000535 tid_main = VG_(alloc_ThreadState)();
sewardjde764e82007-11-09 23:13:22 +0000536
sewardj95d86c02007-12-18 01:49:23 +0000537 /* Bleh. Unfortunately there are various places in the system that
538 assume that the main thread has a ThreadId of 1.
539 - Helgrind (possibly)
540 - stack overflow message in default_action() in m_signals.c
541 - definitely a lot more places
542 */
543 vg_assert(tid_main == 1);
544
sewardjde764e82007-11-09 23:13:22 +0000545 return tid_main;
546}
547
548
549/* Second phase of initialisation of the scheduler. Given the root
550 ThreadId computed by first phase of initialisation, fill in stack
551 details and acquire bigLock. Initialise the scheduler. This is
552 called at startup. The caller subsequently initialises the guest
553 state components of this main thread.
554*/
555void VG_(scheduler_init_phase2) ( ThreadId tid_main,
556 Addr clstack_end,
557 SizeT clstack_size )
558{
559 VG_(debugLog)(1,"sched","sched_init_phase2: tid_main=%d, "
560 "cls_end=0x%lx, cls_sz=%ld\n",
561 tid_main, clstack_end, clstack_size);
562
563 vg_assert(VG_IS_PAGE_ALIGNED(clstack_end+1));
564 vg_assert(VG_IS_PAGE_ALIGNED(clstack_size));
sewardj5f07b662002-04-23 16:52:51 +0000565
njn50ba34e2005-04-04 02:41:42 +0000566 VG_(threads)[tid_main].client_stack_highest_word
sewardj45f4e7c2005-09-27 19:20:21 +0000567 = clstack_end + 1 - sizeof(UWord);
568 VG_(threads)[tid_main].client_stack_szB
569 = clstack_size;
sewardjbf290b92002-05-01 02:28:01 +0000570
njne9ba34a2008-10-13 04:19:15 +0000571 VG_(atfork)(NULL, NULL, sched_fork_cleanup);
sewardje663cb92002-04-12 10:26:32 +0000572}
573
574
sewardje663cb92002-04-12 10:26:32 +0000575/* ---------------------------------------------------------------------
sewardj0ec07f32006-01-12 12:32:32 +0000576 Helpers for running translations.
577 ------------------------------------------------------------------ */
578
579/* Use gcc's built-in setjmp/longjmp. longjmp must not restore signal
580 mask state, but does need to pass "val" through. */
581#define SCHEDSETJMP(tid, jumped, stmt) \
582 do { \
583 ThreadState * volatile _qq_tst = VG_(get_ThreadState)(tid); \
584 \
sewardj6c591e12011-04-11 16:17:51 +0000585 (jumped) = VG_MINIMAL_SETJMP(_qq_tst->sched_jmpbuf); \
sewardj0ec07f32006-01-12 12:32:32 +0000586 if ((jumped) == 0) { \
587 vg_assert(!_qq_tst->sched_jmpbuf_valid); \
588 _qq_tst->sched_jmpbuf_valid = True; \
589 stmt; \
590 } else if (VG_(clo_trace_sched)) \
591 VG_(printf)("SCHEDSETJMP(line %d) tid %d, jumped=%d\n", \
592 __LINE__, tid, jumped); \
593 vg_assert(_qq_tst->sched_jmpbuf_valid); \
594 _qq_tst->sched_jmpbuf_valid = False; \
595 } while(0)
596
597
598/* Do various guest state alignment checks prior to running a thread.
599 Specifically, check that what we have matches Vex's guest state
sewardj7cf4e6b2008-05-01 20:24:26 +0000600 layout requirements. See libvex.h for details, but in short the
601 requirements are: There must be no holes in between the primary
602 guest state, its two copies, and the spill area. In short, all 4
603 areas must have a 16-aligned size and be 16-aligned, and placed
604 back-to-back. */
605static void do_pre_run_checks ( ThreadState* tst )
sewardj0ec07f32006-01-12 12:32:32 +0000606{
sewardj7cf4e6b2008-05-01 20:24:26 +0000607 Addr a_vex = (Addr) & tst->arch.vex;
608 Addr a_vexsh1 = (Addr) & tst->arch.vex_shadow1;
609 Addr a_vexsh2 = (Addr) & tst->arch.vex_shadow2;
610 Addr a_spill = (Addr) & tst->arch.vex_spill;
611 UInt sz_vex = (UInt) sizeof tst->arch.vex;
612 UInt sz_vexsh1 = (UInt) sizeof tst->arch.vex_shadow1;
613 UInt sz_vexsh2 = (UInt) sizeof tst->arch.vex_shadow2;
614 UInt sz_spill = (UInt) sizeof tst->arch.vex_spill;
sewardj0ec07f32006-01-12 12:32:32 +0000615
616 if (0)
sewardj7cf4e6b2008-05-01 20:24:26 +0000617 VG_(printf)("gst %p %d, sh1 %p %d, "
618 "sh2 %p %d, spill %p %d\n",
619 (void*)a_vex, sz_vex,
620 (void*)a_vexsh1, sz_vexsh1,
621 (void*)a_vexsh2, sz_vexsh2,
sewardj0ec07f32006-01-12 12:32:32 +0000622 (void*)a_spill, sz_spill );
623
sewardj7cf4e6b2008-05-01 20:24:26 +0000624 vg_assert(VG_IS_16_ALIGNED(sz_vex));
625 vg_assert(VG_IS_16_ALIGNED(sz_vexsh1));
626 vg_assert(VG_IS_16_ALIGNED(sz_vexsh2));
sewardj0ec07f32006-01-12 12:32:32 +0000627 vg_assert(VG_IS_16_ALIGNED(sz_spill));
628
sewardj7cf4e6b2008-05-01 20:24:26 +0000629 vg_assert(VG_IS_16_ALIGNED(a_vex));
630 vg_assert(VG_IS_16_ALIGNED(a_vexsh1));
631 vg_assert(VG_IS_16_ALIGNED(a_vexsh2));
632 vg_assert(VG_IS_16_ALIGNED(a_spill));
sewardj0ec07f32006-01-12 12:32:32 +0000633
sewardj7cf4e6b2008-05-01 20:24:26 +0000634 /* Check that the guest state and its two shadows have the same
635 size, and that there are no holes in between. The latter is
636 important because Memcheck assumes that it can reliably access
637 the shadows by indexing off a pointer to the start of the
638 primary guest state area. */
639 vg_assert(sz_vex == sz_vexsh1);
640 vg_assert(sz_vex == sz_vexsh2);
641 vg_assert(a_vex + 1 * sz_vex == a_vexsh1);
642 vg_assert(a_vex + 2 * sz_vex == a_vexsh2);
643 /* Also check there's no hole between the second shadow area and
644 the spill area. */
sewardj0ec07f32006-01-12 12:32:32 +0000645 vg_assert(sz_spill == LibVEX_N_SPILL_BYTES);
sewardj7cf4e6b2008-05-01 20:24:26 +0000646 vg_assert(a_vex + 3 * sz_vex == a_spill);
sewardj0ec07f32006-01-12 12:32:32 +0000647
sewardj565dc132010-08-06 08:01:47 +0000648# if defined(VGA_amd64)
649 /* x86/amd64 XMM regs must form an array, ie, have no
650 holes in between. */
651 vg_assert(
652 (offsetof(VexGuestAMD64State,guest_XMM16)
653 - offsetof(VexGuestAMD64State,guest_XMM0))
654 == (17/*#regs*/-1) * 16/*bytes per reg*/
655 );
656# endif
657
sewardj0ec07f32006-01-12 12:32:32 +0000658# if defined(VGA_ppc32) || defined(VGA_ppc64)
659 /* ppc guest_state vector regs must be 16 byte aligned for
sewardj7cf4e6b2008-05-01 20:24:26 +0000660 loads/stores. This is important! */
sewardjf34eb492011-04-15 11:57:05 +0000661 vg_assert(VG_IS_16_ALIGNED(& tst->arch.vex.guest_VSR0));
662 vg_assert(VG_IS_16_ALIGNED(& tst->arch.vex_shadow1.guest_VSR0));
663 vg_assert(VG_IS_16_ALIGNED(& tst->arch.vex_shadow2.guest_VSR0));
sewardj7cf4e6b2008-05-01 20:24:26 +0000664 /* be extra paranoid .. */
sewardjf34eb492011-04-15 11:57:05 +0000665 vg_assert(VG_IS_16_ALIGNED(& tst->arch.vex.guest_VSR1));
666 vg_assert(VG_IS_16_ALIGNED(& tst->arch.vex_shadow1.guest_VSR1));
667 vg_assert(VG_IS_16_ALIGNED(& tst->arch.vex_shadow2.guest_VSR1));
sewardj565dc132010-08-06 08:01:47 +0000668# endif
sewardj59570ff2010-01-01 11:59:33 +0000669
670# if defined(VGA_arm)
671 /* arm guest_state VFP regs must be 8 byte aligned for
672 loads/stores. */
673 vg_assert(VG_IS_8_ALIGNED(& tst->arch.vex.guest_D0));
674 vg_assert(VG_IS_8_ALIGNED(& tst->arch.vex_shadow1.guest_D0));
675 vg_assert(VG_IS_8_ALIGNED(& tst->arch.vex_shadow2.guest_D0));
676 /* be extra paranoid .. */
677 vg_assert(VG_IS_8_ALIGNED(& tst->arch.vex.guest_D1));
678 vg_assert(VG_IS_8_ALIGNED(& tst->arch.vex_shadow1.guest_D1));
679 vg_assert(VG_IS_8_ALIGNED(& tst->arch.vex_shadow2.guest_D1));
680# endif
sewardjb5b87402011-03-07 16:05:35 +0000681
682# if defined(VGA_s390x)
683 /* no special requirements */
684# endif
sewardj0ec07f32006-01-12 12:32:32 +0000685}
686
687
688/* Run the thread tid for a while, and return a VG_TRC_* value
689 indicating why VG_(run_innerloop) stopped. */
690static UInt run_thread_for_a_while ( ThreadId tid )
691{
692 volatile Int jumped;
sewardj1a85f4f2006-01-12 21:15:35 +0000693 volatile ThreadState* tst = NULL; /* stop gcc complaining */
sewardj0ec07f32006-01-12 12:32:32 +0000694 volatile UInt trc;
695 volatile Int dispatch_ctr_SAVED;
696 volatile Int done_this_time;
697
698 /* Paranoia */
699 vg_assert(VG_(is_valid_tid)(tid));
700 vg_assert(VG_(is_running_thread)(tid));
701 vg_assert(!VG_(is_exiting)(tid));
702
703 tst = VG_(get_ThreadState)(tid);
sewardj7cf4e6b2008-05-01 20:24:26 +0000704 do_pre_run_checks( (ThreadState*)tst );
sewardj0ec07f32006-01-12 12:32:32 +0000705 /* end Paranoia */
706
707 trc = 0;
708 dispatch_ctr_SAVED = VG_(dispatch_ctr);
709
sewardjf54342a2006-10-17 01:51:24 +0000710# if defined(VGP_ppc32_aix5) || defined(VGP_ppc64_aix5)
711 /* On AIX, we need to get a plausible value for SPRG3 for this
712 thread, since it's used I think as a thread-state pointer. It
713 is presumably set by the kernel for each dispatched thread and
714 cannot be changed by user space. It therefore seems safe enough
715 to copy the host's value of it into the guest state at the point
716 the thread is dispatched.
717 (Later): Hmm, looks like SPRG3 is only used in 32-bit mode.
718 Oh well. */
719 { UWord host_sprg3;
720 __asm__ __volatile__( "mfspr %0,259\n" : "=b"(host_sprg3) );
721 VG_(threads)[tid].arch.vex.guest_SPRG3_RO = host_sprg3;
722 vg_assert(sizeof(VG_(threads)[tid].arch.vex.guest_SPRG3_RO) == sizeof(void*));
723 }
724# endif
725
sewardj0ec07f32006-01-12 12:32:32 +0000726 /* there should be no undealt-with signals */
727 //vg_assert(VG_(threads)[tid].siginfo.si_signo == 0);
728
sewardjf54342a2006-10-17 01:51:24 +0000729 if (0) {
730 vki_sigset_t m;
731 Int i, err = VG_(sigprocmask)(VKI_SIG_SETMASK, NULL, &m);
732 vg_assert(err == 0);
733 VG_(printf)("tid %d: entering code with unblocked signals: ", tid);
734 for (i = 1; i <= _VKI_NSIG; i++)
735 if (!VG_(sigismember)(&m, i))
736 VG_(printf)("%d ", i);
737 VG_(printf)("\n");
738 }
739
sewardj97561812006-12-23 01:21:12 +0000740 // Tell the tool this thread is about to run client code
njn3e32c872006-12-24 07:51:17 +0000741 VG_TRACK( start_client_code, tid, bbs_done );
sewardj97561812006-12-23 01:21:12 +0000742
sewardj0ec07f32006-01-12 12:32:32 +0000743 vg_assert(VG_(in_generated_code) == False);
744 VG_(in_generated_code) = True;
745
746 SCHEDSETJMP(
747 tid,
748 jumped,
749 trc = (UInt)VG_(run_innerloop)( (void*)&tst->arch.vex,
750 VG_(clo_profile_flags) > 0 ? 1 : 0 )
751 );
752
sewardjde764e82007-11-09 23:13:22 +0000753 vg_assert(VG_(in_generated_code) == True);
sewardj0ec07f32006-01-12 12:32:32 +0000754 VG_(in_generated_code) = False;
755
756 if (jumped) {
757 /* We get here if the client took a fault that caused our signal
758 handler to longjmp. */
759 vg_assert(trc == 0);
760 trc = VG_TRC_FAULT_SIGNAL;
njn1dcee092009-02-24 03:07:37 +0000761 block_signals();
sewardj0ec07f32006-01-12 12:32:32 +0000762 }
763
764 done_this_time = (Int)dispatch_ctr_SAVED - (Int)VG_(dispatch_ctr) - 0;
765
766 vg_assert(done_this_time >= 0);
767 bbs_done += (ULong)done_this_time;
768
sewardj97561812006-12-23 01:21:12 +0000769 // Tell the tool this thread has stopped running client code
njn3e32c872006-12-24 07:51:17 +0000770 VG_TRACK( stop_client_code, tid, bbs_done );
sewardj97561812006-12-23 01:21:12 +0000771
sewardj0ec07f32006-01-12 12:32:32 +0000772 return trc;
773}
774
775
776/* Run a no-redir translation just once, and return the resulting
777 VG_TRC_* value. */
778static UInt run_noredir_translation ( Addr hcode, ThreadId tid )
779{
780 volatile Int jumped;
781 volatile ThreadState* tst;
782 volatile UWord argblock[4];
sewardj97561812006-12-23 01:21:12 +0000783 volatile UInt retval;
sewardj0ec07f32006-01-12 12:32:32 +0000784
785 /* Paranoia */
786 vg_assert(VG_(is_valid_tid)(tid));
787 vg_assert(VG_(is_running_thread)(tid));
788 vg_assert(!VG_(is_exiting)(tid));
789
790 tst = VG_(get_ThreadState)(tid);
sewardj7cf4e6b2008-05-01 20:24:26 +0000791 do_pre_run_checks( (ThreadState*)tst );
sewardj0ec07f32006-01-12 12:32:32 +0000792 /* end Paranoia */
793
794# if defined(VGA_ppc32) || defined(VGA_ppc64)
795 /* I don't think we need to clear this thread's guest_RESVN here,
796 because we can only get here if run_thread_for_a_while() has
797 been used immediately before, on this same thread. */
798# endif
799
sewardj74d6e0e2006-01-13 13:04:03 +0000800 /* There can be 3 outcomes from VG_(run_a_noredir_translation):
801
802 - a signal occurred and the sighandler longjmp'd. Then both [2]
803 and [3] are unchanged - hence zero.
804
805 - translation ran normally, set [2] (next guest IP) and set [3]
806 to whatever [1] was beforehand, indicating a normal (boring)
807 jump to the next block.
808
809 - translation ran normally, set [2] (next guest IP) and set [3]
810 to something different from [1] beforehand, which indicates a
811 TRC_ value.
812 */
sewardj0ec07f32006-01-12 12:32:32 +0000813 argblock[0] = (UWord)hcode;
814 argblock[1] = (UWord)&VG_(threads)[tid].arch.vex;
sewardj74d6e0e2006-01-13 13:04:03 +0000815 argblock[2] = 0; /* next guest IP is written here */
816 argblock[3] = 0; /* guest state ptr afterwards is written here */
sewardj0ec07f32006-01-12 12:32:32 +0000817
sewardj97561812006-12-23 01:21:12 +0000818 // Tell the tool this thread is about to run client code
njn3e32c872006-12-24 07:51:17 +0000819 VG_TRACK( start_client_code, tid, bbs_done );
sewardj97561812006-12-23 01:21:12 +0000820
sewardj0ec07f32006-01-12 12:32:32 +0000821 vg_assert(VG_(in_generated_code) == False);
822 VG_(in_generated_code) = True;
823
824 SCHEDSETJMP(
825 tid,
826 jumped,
827 VG_(run_a_noredir_translation)( &argblock[0] )
828 );
829
830 VG_(in_generated_code) = False;
831
832 if (jumped) {
833 /* We get here if the client took a fault that caused our signal
834 handler to longjmp. */
sewardj74d6e0e2006-01-13 13:04:03 +0000835 vg_assert(argblock[2] == 0); /* next guest IP was not written */
836 vg_assert(argblock[3] == 0); /* trc was not written */
njn1dcee092009-02-24 03:07:37 +0000837 block_signals();
sewardj97561812006-12-23 01:21:12 +0000838 retval = VG_TRC_FAULT_SIGNAL;
sewardj0ec07f32006-01-12 12:32:32 +0000839 } else {
840 /* store away the guest program counter */
841 VG_(set_IP)( tid, argblock[2] );
842 if (argblock[3] == argblock[1])
843 /* the guest state pointer afterwards was unchanged */
sewardj97561812006-12-23 01:21:12 +0000844 retval = VG_TRC_BORING;
sewardj0ec07f32006-01-12 12:32:32 +0000845 else
sewardj97561812006-12-23 01:21:12 +0000846 retval = (UInt)argblock[3];
sewardj0ec07f32006-01-12 12:32:32 +0000847 }
sewardj97561812006-12-23 01:21:12 +0000848
849 bbs_done++;
850
851 // Tell the tool this thread has stopped running client code
njn3e32c872006-12-24 07:51:17 +0000852 VG_TRACK( stop_client_code, tid, bbs_done );
sewardj97561812006-12-23 01:21:12 +0000853
854 return retval;
sewardj0ec07f32006-01-12 12:32:32 +0000855}
856
sewardj0ec07f32006-01-12 12:32:32 +0000857
858/* ---------------------------------------------------------------------
sewardje663cb92002-04-12 10:26:32 +0000859 The scheduler proper.
860 ------------------------------------------------------------------ */
861
sewardjb5f6f512005-03-10 23:59:00 +0000862static void handle_tt_miss ( ThreadId tid )
sewardje663cb92002-04-12 10:26:32 +0000863{
sewardjb5f6f512005-03-10 23:59:00 +0000864 Bool found;
njnf536bbb2005-06-13 04:21:38 +0000865 Addr ip = VG_(get_IP)(tid);
sewardjb5f6f512005-03-10 23:59:00 +0000866
867 /* Trivial event. Miss in the fast-cache. Do a full
868 lookup for it. */
njnf536bbb2005-06-13 04:21:38 +0000869 found = VG_(search_transtab)( NULL, ip, True/*upd_fast_cache*/ );
sewardj5d0d1f32010-03-14 15:09:27 +0000870 if (UNLIKELY(!found)) {
sewardjb5f6f512005-03-10 23:59:00 +0000871 /* Not found; we need to request a translation. */
sewardj0ec07f32006-01-12 12:32:32 +0000872 if (VG_(translate)( tid, ip, /*debug*/False, 0/*not verbose*/,
873 bbs_done, True/*allow redirection*/ )) {
sewardjb5f6f512005-03-10 23:59:00 +0000874 found = VG_(search_transtab)( NULL, ip, True );
njn50ae1a72005-04-08 23:28:23 +0000875 vg_assert2(found, "VG_TRC_INNER_FASTMISS: missing tt_fast entry");
876
sewardjb5f6f512005-03-10 23:59:00 +0000877 } else {
878 // If VG_(translate)() fails, it's because it had to throw a
879 // signal because the client jumped to a bad address. That
880 // means that either a signal has been set up for delivery,
881 // or the thread has been marked for termination. Either
882 // way, we just need to go back into the scheduler loop.
883 }
884 }
885}
886
njnf76d27a2009-05-28 01:53:07 +0000887static void handle_syscall(ThreadId tid, UInt trc)
sewardjb5f6f512005-03-10 23:59:00 +0000888{
sewardj1ac9d0c2007-05-01 14:18:48 +0000889 ThreadState * volatile tst = VG_(get_ThreadState)(tid);
sewardjb5f6f512005-03-10 23:59:00 +0000890 Bool jumped;
891
892 /* Syscall may or may not block; either way, it will be
893 complete by the time this call returns, and we'll be
894 runnable again. We could take a signal while the
895 syscall runs. */
sewardj45f4e7c2005-09-27 19:20:21 +0000896
897 if (VG_(clo_sanity_level >= 3))
898 VG_(am_do_sync_check)("(BEFORE SYSCALL)",__FILE__,__LINE__);
899
njnf76d27a2009-05-28 01:53:07 +0000900 SCHEDSETJMP(tid, jumped, VG_(client_syscall)(tid, trc));
sewardjb5f6f512005-03-10 23:59:00 +0000901
sewardj45f4e7c2005-09-27 19:20:21 +0000902 if (VG_(clo_sanity_level >= 3))
903 VG_(am_do_sync_check)("(AFTER SYSCALL)",__FILE__,__LINE__);
904
sewardjb5f6f512005-03-10 23:59:00 +0000905 if (!VG_(is_running_thread)(tid))
njnc7561b92005-06-19 01:24:32 +0000906 VG_(printf)("tid %d not running; VG_(running_tid)=%d, tid %d status %d\n",
907 tid, VG_(running_tid), tid, tst->status);
sewardjb5f6f512005-03-10 23:59:00 +0000908 vg_assert(VG_(is_running_thread)(tid));
909
910 if (jumped) {
njn1dcee092009-02-24 03:07:37 +0000911 block_signals();
sewardjb5f6f512005-03-10 23:59:00 +0000912 VG_(poll_signals)(tid);
913 }
914}
915
sewardja591a052006-01-12 14:04:46 +0000916/* tid just requested a jump to the noredir version of its current
917 program counter. So make up that translation if needed, run it,
918 and return the resulting thread return code. */
919static UInt/*trc*/ handle_noredir_jump ( ThreadId tid )
920{
921 AddrH hcode = 0;
922 Addr ip = VG_(get_IP)(tid);
923
924 Bool found = VG_(search_unredir_transtab)( &hcode, ip );
925 if (!found) {
926 /* Not found; we need to request a translation. */
927 if (VG_(translate)( tid, ip, /*debug*/False, 0/*not verbose*/, bbs_done,
928 False/*NO REDIRECTION*/ )) {
929
930 found = VG_(search_unredir_transtab)( &hcode, ip );
931 vg_assert2(found, "unredir translation missing after creation?!");
932
933 } else {
934 // If VG_(translate)() fails, it's because it had to throw a
935 // signal because the client jumped to a bad address. That
936 // means that either a signal has been set up for delivery,
937 // or the thread has been marked for termination. Either
938 // way, we just need to go back into the scheduler loop.
939 return VG_TRC_BORING;
940 }
941
942 }
943
944 vg_assert(found);
945 vg_assert(hcode != 0);
946
947 /* Otherwise run it and return the resulting VG_TRC_* value. */
948 return run_noredir_translation( hcode, tid );
949}
950
951
sewardjb5f6f512005-03-10 23:59:00 +0000952/*
953 Run a thread until it wants to exit.
954
sewardjad0a3a82006-12-17 18:58:55 +0000955 We assume that the caller has already called VG_(acquire_BigLock) for
sewardjb5f6f512005-03-10 23:59:00 +0000956 us, so we own the VCPU. Also, all signals are blocked.
957 */
958VgSchedReturnCode VG_(scheduler) ( ThreadId tid )
959{
sewardje663cb92002-04-12 10:26:32 +0000960 UInt trc;
sewardjb5f6f512005-03-10 23:59:00 +0000961 ThreadState *tst = VG_(get_ThreadState)(tid);
sewardje663cb92002-04-12 10:26:32 +0000962
sewardjc24be7a2005-03-15 01:40:12 +0000963 if (VG_(clo_trace_sched))
964 print_sched_event(tid, "entering VG_(scheduler)");
965
sewardjb5f6f512005-03-10 23:59:00 +0000966 /* set the proper running signal mask */
njn1dcee092009-02-24 03:07:37 +0000967 block_signals();
sewardjb5f6f512005-03-10 23:59:00 +0000968
969 vg_assert(VG_(is_running_thread)(tid));
sewardje663cb92002-04-12 10:26:32 +0000970
njn14319cc2005-03-13 06:26:22 +0000971 VG_(dispatch_ctr) = SCHEDULING_QUANTUM + 1;
sewardj6072c362002-04-19 14:40:57 +0000972
sewardjf54342a2006-10-17 01:51:24 +0000973 while (!VG_(is_exiting)(tid)) {
974
sewardjb5f6f512005-03-10 23:59:00 +0000975 if (VG_(dispatch_ctr) == 1) {
sewardjf54342a2006-10-17 01:51:24 +0000976
977# if defined(VGP_ppc32_aix5) || defined(VGP_ppc64_aix5)
978 /* Note: count runnable threads before dropping The Lock. */
979 Int rt = VG_(count_runnable_threads)();
980# endif
981
982 /* Our slice is done, so yield the CPU to another thread. On
983 Linux, this doesn't sleep between sleeping and running,
984 since that would take too much time. On AIX, we have to
985 prod the scheduler to get it consider other threads; not
986 doing so appears to cause very long delays before other
987 runnable threads get rescheduled. */
988
989 /* 4 July 06: it seems that a zero-length nsleep is needed to
990 cause async thread cancellation (canceller.c) to terminate
991 in finite time; else it is in some kind of race/starvation
992 situation and completion is arbitrarily delayed (although
993 this is not a deadlock).
994
995 Unfortunately these sleeps cause MPI jobs not to terminate
996 sometimes (some kind of livelock). So sleeping once
997 every N opportunities appears to work. */
998
999 /* 3 Aug 06: doing sys__nsleep works but crashes some apps.
1000 sys_yield also helps the problem, whilst not crashing apps. */
1001
sewardjad0a3a82006-12-17 18:58:55 +00001002 VG_(release_BigLock)(tid, VgTs_Yielding,
1003 "VG_(scheduler):timeslice");
sewardjf54342a2006-10-17 01:51:24 +00001004 /* ------------ now we don't have The Lock ------------ */
1005
1006# if defined(VGP_ppc32_aix5) || defined(VGP_ppc64_aix5)
1007 { static Int ctr=0;
1008 vg_assert(__NR_AIX5__nsleep != __NR_AIX5_UNKNOWN);
1009 vg_assert(__NR_AIX5_yield != __NR_AIX5_UNKNOWN);
1010 if (1 && rt > 0 && ((++ctr % 3) == 0)) {
1011 //struct vki_timespec ts;
1012 //ts.tv_sec = 0;
1013 //ts.tv_nsec = 0*1000*1000;
1014 //VG_(do_syscall2)(__NR_AIX5__nsleep, (UWord)&ts, (UWord)NULL);
1015 VG_(do_syscall0)(__NR_AIX5_yield);
1016 }
1017 }
1018# endif
1019
sewardjad0a3a82006-12-17 18:58:55 +00001020 VG_(acquire_BigLock)(tid, "VG_(scheduler):timeslice");
sewardjf54342a2006-10-17 01:51:24 +00001021 /* ------------ now we do have The Lock ------------ */
sewardje663cb92002-04-12 10:26:32 +00001022
sewardjb5f6f512005-03-10 23:59:00 +00001023 /* OK, do some relatively expensive housekeeping stuff */
1024 scheduler_sanity(tid);
1025 VG_(sanity_check_general)(False);
sewardje663cb92002-04-12 10:26:32 +00001026
sewardjb5f6f512005-03-10 23:59:00 +00001027 /* Look for any pending signals for this thread, and set them up
1028 for delivery */
1029 VG_(poll_signals)(tid);
sewardje663cb92002-04-12 10:26:32 +00001030
sewardjb5f6f512005-03-10 23:59:00 +00001031 if (VG_(is_exiting)(tid))
1032 break; /* poll_signals picked up a fatal signal */
sewardje663cb92002-04-12 10:26:32 +00001033
sewardjb5f6f512005-03-10 23:59:00 +00001034 /* For stats purposes only. */
1035 n_scheduling_events_MAJOR++;
sewardje663cb92002-04-12 10:26:32 +00001036
sewardjb5f6f512005-03-10 23:59:00 +00001037 /* Figure out how many bbs to ask vg_run_innerloop to do. Note
1038 that it decrements the counter before testing it for zero, so
1039 that if tst->dispatch_ctr is set to N you get at most N-1
1040 iterations. Also this means that tst->dispatch_ctr must
1041 exceed zero before entering the innerloop. Also also, the
1042 decrement is done before the bb is actually run, so you
1043 always get at least one decrement even if nothing happens. */
njn14319cc2005-03-13 06:26:22 +00001044 VG_(dispatch_ctr) = SCHEDULING_QUANTUM + 1;
jsgf855d93d2003-10-13 22:26:55 +00001045
sewardjb5f6f512005-03-10 23:59:00 +00001046 /* paranoia ... */
1047 vg_assert(tst->tid == tid);
1048 vg_assert(tst->os_state.lwpid == VG_(gettid)());
sewardje663cb92002-04-12 10:26:32 +00001049 }
1050
sewardjb5f6f512005-03-10 23:59:00 +00001051 /* For stats purposes only. */
1052 n_scheduling_events_MINOR++;
sewardje663cb92002-04-12 10:26:32 +00001053
1054 if (0)
sewardj738856f2009-07-15 14:48:32 +00001055 VG_(message)(Vg_DebugMsg, "thread %d: running for %d bbs\n",
1056 tid, VG_(dispatch_ctr) - 1 );
sewardje663cb92002-04-12 10:26:32 +00001057
sewardjb5f6f512005-03-10 23:59:00 +00001058 trc = run_thread_for_a_while ( tid );
sewardje663cb92002-04-12 10:26:32 +00001059
sewardjb5f6f512005-03-10 23:59:00 +00001060 if (VG_(clo_trace_sched) && VG_(clo_verbosity) > 2) {
1061 Char buf[50];
1062 VG_(sprintf)(buf, "TRC: %s", name_of_sched_event(trc));
1063 print_sched_event(tid, buf);
sewardje663cb92002-04-12 10:26:32 +00001064 }
1065
sewardj0ec07f32006-01-12 12:32:32 +00001066 if (trc == VEX_TRC_JMP_NOREDIR) {
1067 /* If we got a request to run a no-redir version of
1068 something, do so now -- handle_noredir_jump just (creates
1069 and) runs that one translation. The flip side is that the
1070 noredir translation can't itself return another noredir
1071 request -- that would be nonsensical. It can, however,
1072 return VG_TRC_BORING, which just means keep going as
1073 normal. */
1074 trc = handle_noredir_jump(tid);
1075 vg_assert(trc != VEX_TRC_JMP_NOREDIR);
1076 }
1077
1078 switch (trc) {
1079 case VG_TRC_BORING:
1080 /* no special event, just keep going. */
1081 break;
1082
sewardjb5f6f512005-03-10 23:59:00 +00001083 case VG_TRC_INNER_FASTMISS:
1084 vg_assert(VG_(dispatch_ctr) > 1);
1085 handle_tt_miss(tid);
1086 break;
1087
1088 case VEX_TRC_JMP_CLIENTREQ:
1089 do_client_request(tid);
1090 break;
sewardja0fef1b2005-11-03 13:46:30 +00001091
1092 case VEX_TRC_JMP_SYS_INT128: /* x86-linux */
njnf76d27a2009-05-28 01:53:07 +00001093 case VEX_TRC_JMP_SYS_INT129: /* x86-darwin */
1094 case VEX_TRC_JMP_SYS_INT130: /* x86-darwin */
1095 case VEX_TRC_JMP_SYS_SYSCALL: /* amd64-linux, ppc32-linux, amd64-darwin */
1096 handle_syscall(tid, trc);
sewardjb5f6f512005-03-10 23:59:00 +00001097 if (VG_(clo_sanity_level) > 2)
1098 VG_(sanity_check_general)(True); /* sanity-check every syscall */
1099 break;
sewardje663cb92002-04-12 10:26:32 +00001100
sewardjb5f6f512005-03-10 23:59:00 +00001101 case VEX_TRC_JMP_YIELD:
1102 /* Explicit yield, because this thread is in a spin-lock
sewardj3fc75752005-03-12 15:16:31 +00001103 or something. Only let the thread run for a short while
1104 longer. Because swapping to another thread is expensive,
1105 we're prepared to let this thread eat a little more CPU
1106 before swapping to another. That means that short term
1107 spins waiting for hardware to poke memory won't cause a
1108 thread swap. */
sewardj3a74fb02006-03-16 11:31:29 +00001109 if (VG_(dispatch_ctr) > 2000)
1110 VG_(dispatch_ctr) = 2000;
sewardjb5f6f512005-03-10 23:59:00 +00001111 break;
sewardje663cb92002-04-12 10:26:32 +00001112
sewardjb5f6f512005-03-10 23:59:00 +00001113 case VG_TRC_INNER_COUNTERZERO:
1114 /* Timeslice is out. Let a new thread be scheduled. */
1115 vg_assert(VG_(dispatch_ctr) == 1);
1116 break;
sewardje663cb92002-04-12 10:26:32 +00001117
sewardjb5f6f512005-03-10 23:59:00 +00001118 case VG_TRC_FAULT_SIGNAL:
1119 /* Everything should be set up (either we're exiting, or
1120 about to start in a signal handler). */
1121 break;
sewardj9d1b5d32002-04-17 19:40:49 +00001122
sewardj07bdc5e2005-03-11 13:19:47 +00001123 case VEX_TRC_JMP_MAPFAIL:
1124 /* Failure of arch-specific address translation (x86/amd64
1125 segment override use) */
1126 /* jrs 2005 03 11: is this correct? */
1127 VG_(synth_fault)(tid);
1128 break;
1129
sewardjb5f6f512005-03-10 23:59:00 +00001130 case VEX_TRC_JMP_EMWARN: {
1131 static Int counts[EmWarn_NUMBER];
1132 static Bool counts_initted = False;
1133 VexEmWarn ew;
1134 HChar* what;
1135 Bool show;
1136 Int q;
1137 if (!counts_initted) {
1138 counts_initted = True;
1139 for (q = 0; q < EmWarn_NUMBER; q++)
1140 counts[q] = 0;
1141 }
1142 ew = (VexEmWarn)VG_(threads)[tid].arch.vex.guest_EMWARN;
1143 what = (ew < 0 || ew >= EmWarn_NUMBER)
1144 ? "unknown (?!)"
1145 : LibVEX_EmWarn_string(ew);
1146 show = (ew < 0 || ew >= EmWarn_NUMBER)
1147 ? True
1148 : counts[ew]++ < 3;
sewardjd68ac3e2006-01-20 14:31:57 +00001149 if (show && VG_(clo_show_emwarns) && !VG_(clo_xml)) {
sewardjb5f6f512005-03-10 23:59:00 +00001150 VG_(message)( Vg_UserMsg,
sewardj738856f2009-07-15 14:48:32 +00001151 "Emulation warning: unsupported action:\n");
1152 VG_(message)( Vg_UserMsg, " %s\n", what);
njnd01fef72005-03-25 23:35:48 +00001153 VG_(get_and_pp_StackTrace)( tid, VG_(clo_backtrace_size) );
sewardjb5f6f512005-03-10 23:59:00 +00001154 }
1155 break;
1156 }
sewardje663cb92002-04-12 10:26:32 +00001157
sewardjd68ac3e2006-01-20 14:31:57 +00001158 case VEX_TRC_JMP_EMFAIL: {
1159 VexEmWarn ew;
1160 HChar* what;
1161 ew = (VexEmWarn)VG_(threads)[tid].arch.vex.guest_EMWARN;
1162 what = (ew < 0 || ew >= EmWarn_NUMBER)
1163 ? "unknown (?!)"
1164 : LibVEX_EmWarn_string(ew);
1165 VG_(message)( Vg_UserMsg,
sewardj738856f2009-07-15 14:48:32 +00001166 "Emulation fatal error -- Valgrind cannot continue:\n");
1167 VG_(message)( Vg_UserMsg, " %s\n", what);
sewardjd68ac3e2006-01-20 14:31:57 +00001168 VG_(get_and_pp_StackTrace)( tid, VG_(clo_backtrace_size) );
sewardj738856f2009-07-15 14:48:32 +00001169 VG_(message)(Vg_UserMsg, "\n");
1170 VG_(message)(Vg_UserMsg, "Valgrind has to exit now. Sorry.\n");
1171 VG_(message)(Vg_UserMsg, "\n");
sewardjd68ac3e2006-01-20 14:31:57 +00001172 VG_(exit)(1);
1173 break;
1174 }
1175
sewardj4f9d6742007-08-29 09:11:35 +00001176 case VEX_TRC_JMP_SIGTRAP:
sewardj86df1552006-02-07 20:56:41 +00001177 VG_(synth_sigtrap)(tid);
1178 break;
1179
sewardj4f9d6742007-08-29 09:11:35 +00001180 case VEX_TRC_JMP_SIGSEGV:
1181 VG_(synth_fault)(tid);
1182 break;
1183
sewardj1c0ce7a2009-07-01 08:10:49 +00001184 case VEX_TRC_JMP_SIGBUS:
1185 VG_(synth_sigbus)(tid);
1186 break;
1187
sewardjb5f6f512005-03-10 23:59:00 +00001188 case VEX_TRC_JMP_NODECODE:
sewardj738856f2009-07-15 14:48:32 +00001189 VG_(umsg)(
1190 "valgrind: Unrecognised instruction at address %#lx.\n",
njn81dd3ad2009-05-21 02:03:08 +00001191 VG_(get_IP)(tid));
njnaaa6dc32011-01-18 05:16:21 +00001192 VG_(get_and_pp_StackTrace)(tid, 50);
sewardj738856f2009-07-15 14:48:32 +00001193#define M(a) VG_(umsg)(a "\n");
njn7cf66582005-10-15 17:18:08 +00001194 M("Your program just tried to execute an instruction that Valgrind" );
1195 M("did not recognise. There are two possible reasons for this." );
1196 M("1. Your program has a bug and erroneously jumped to a non-code" );
1197 M(" location. If you are running Memcheck and you just saw a" );
1198 M(" warning about a bad jump, it's probably your program's fault.");
1199 M("2. The instruction is legitimate but Valgrind doesn't handle it,");
1200 M(" i.e. it's Valgrind's fault. If you think this is the case or");
njnec4d5132006-03-21 23:15:43 +00001201 M(" you are not sure, please let us know and we'll try to fix it.");
njn7cf66582005-10-15 17:18:08 +00001202 M("Either way, Valgrind will now raise a SIGILL signal which will" );
1203 M("probably kill your program." );
njnd5021362005-09-29 00:35:18 +00001204#undef M
njnf536bbb2005-06-13 04:21:38 +00001205 VG_(synth_sigill)(tid, VG_(get_IP)(tid));
sewardjb5f6f512005-03-10 23:59:00 +00001206 break;
sewardje663cb92002-04-12 10:26:32 +00001207
cerion85665ca2005-06-20 15:51:07 +00001208 case VEX_TRC_JMP_TINVAL:
cerion85665ca2005-06-20 15:51:07 +00001209 VG_(discard_translations)(
1210 (Addr64)VG_(threads)[tid].arch.vex.guest_TISTART,
sewardj45f4e7c2005-09-27 19:20:21 +00001211 VG_(threads)[tid].arch.vex.guest_TILEN,
1212 "scheduler(VEX_TRC_JMP_TINVAL)"
sewardj487ac702005-06-21 12:52:38 +00001213 );
cerion85665ca2005-06-20 15:51:07 +00001214 if (0)
1215 VG_(printf)("dump translations done.\n");
cerion85665ca2005-06-20 15:51:07 +00001216 break;
1217
sewardje3a384b2005-07-29 08:51:34 +00001218 case VG_TRC_INVARIANT_FAILED:
1219 /* This typically happens if, after running generated code,
1220 it is detected that host CPU settings (eg, FPU/Vector
1221 control words) are not as they should be. Vex's code
1222 generation specifies the state such control words should
1223 be in on entry to Vex-generated code, and they should be
1224 unchanged on exit from it. Failure of this assertion
1225 usually means a bug in Vex's code generation. */
sewardj59570ff2010-01-01 11:59:33 +00001226 //{ UInt xx;
1227 // __asm__ __volatile__ (
1228 // "\t.word 0xEEF12A10\n" // fmrx r2,fpscr
1229 // "\tmov %0, r2" : "=r"(xx) : : "r2" );
1230 // VG_(printf)("QQQQ new fpscr = %08x\n", xx);
1231 //}
sewardje3a384b2005-07-29 08:51:34 +00001232 vg_assert2(0, "VG_(scheduler), phase 3: "
1233 "run_innerloop detected host "
1234 "state invariant failure", trc);
1235
sewardja0fef1b2005-11-03 13:46:30 +00001236 case VEX_TRC_JMP_SYS_SYSENTER:
sewardj5438a012005-08-07 14:49:27 +00001237 /* Do whatever simulation is appropriate for an x86 sysenter
1238 instruction. Note that it is critical to set this thread's
1239 guest_EIP to point at the code to execute after the
1240 sysenter, since Vex-generated code will not have set it --
1241 vex does not know what it should be. Vex sets the next
njncda2f0f2009-05-18 02:12:08 +00001242 address to zero, so if you don't set guest_EIP, the thread
1243 will jump to zero afterwards and probably die as a result. */
1244# if defined(VGP_x86_linux)
sewardj5438a012005-08-07 14:49:27 +00001245 vg_assert2(0, "VG_(scheduler), phase 3: "
njncda2f0f2009-05-18 02:12:08 +00001246 "sysenter_x86 on x86-linux is not supported");
njnf76d27a2009-05-28 01:53:07 +00001247# elif defined(VGP_x86_darwin)
1248 /* return address in client edx */
1249 VG_(threads)[tid].arch.vex.guest_EIP
1250 = VG_(threads)[tid].arch.vex.guest_EDX;
1251 handle_syscall(tid, trc);
sewardj5438a012005-08-07 14:49:27 +00001252# else
1253 vg_assert2(0, "VG_(scheduler), phase 3: "
1254 "sysenter_x86 on non-x86 platform?!?!");
1255# endif
njnf76d27a2009-05-28 01:53:07 +00001256 break;
sewardj5438a012005-08-07 14:49:27 +00001257
sewardjb5f6f512005-03-10 23:59:00 +00001258 default:
njn50ae1a72005-04-08 23:28:23 +00001259 vg_assert2(0, "VG_(scheduler), phase 3: "
1260 "unexpected thread return code (%u)", trc);
sewardjb5f6f512005-03-10 23:59:00 +00001261 /* NOTREACHED */
1262 break;
sewardje663cb92002-04-12 10:26:32 +00001263
1264 } /* switch (trc) */
nethercote238a3c32004-08-09 13:13:31 +00001265 }
sewardjc24be7a2005-03-15 01:40:12 +00001266
1267 if (VG_(clo_trace_sched))
1268 print_sched_event(tid, "exiting VG_(scheduler)");
1269
sewardjb5f6f512005-03-10 23:59:00 +00001270 vg_assert(VG_(is_exiting)(tid));
thughes513197c2004-06-13 12:07:53 +00001271
sewardjb5f6f512005-03-10 23:59:00 +00001272 return tst->exitreason;
sewardj20917d82002-05-28 01:36:45 +00001273}
1274
1275
sewardjb5f6f512005-03-10 23:59:00 +00001276/*
1277 This causes all threads to forceably exit. They aren't actually
1278 dead by the time this returns; you need to call
njnaf839f52005-06-23 03:27:57 +00001279 VG_(reap_threads)() to wait for them.
sewardjb5f6f512005-03-10 23:59:00 +00001280 */
1281void VG_(nuke_all_threads_except) ( ThreadId me, VgSchedReturnCode src )
sewardjccef2e62002-05-29 19:26:32 +00001282{
1283 ThreadId tid;
sewardjb5f6f512005-03-10 23:59:00 +00001284
1285 vg_assert(VG_(is_running_thread)(me));
sewardj45f02c42005-02-05 18:27:14 +00001286
sewardjccef2e62002-05-29 19:26:32 +00001287 for (tid = 1; tid < VG_N_THREADS; tid++) {
1288 if (tid == me
jsgf855d93d2003-10-13 22:26:55 +00001289 || VG_(threads)[tid].status == VgTs_Empty)
sewardjccef2e62002-05-29 19:26:32 +00001290 continue;
sewardjb5f6f512005-03-10 23:59:00 +00001291 if (0)
sewardjef037c72002-05-30 00:40:03 +00001292 VG_(printf)(
1293 "VG_(nuke_all_threads_except): nuking tid %d\n", tid);
sewardjb5f6f512005-03-10 23:59:00 +00001294
1295 VG_(threads)[tid].exitreason = src;
sewardja8d8e232005-06-07 20:04:56 +00001296 if (src == VgSrc_FatalSig)
1297 VG_(threads)[tid].os_state.fatalsig = VKI_SIGKILL;
sewardjf54342a2006-10-17 01:51:24 +00001298 VG_(get_thread_out_of_syscall)(tid);
sewardjccef2e62002-05-29 19:26:32 +00001299 }
1300}
1301
1302
njnd3040452003-05-19 15:04:06 +00001303/* ---------------------------------------------------------------------
sewardjb5f6f512005-03-10 23:59:00 +00001304 Specifying shadow register values
njnd3040452003-05-19 15:04:06 +00001305 ------------------------------------------------------------------ */
1306
njnf536bbb2005-06-13 04:21:38 +00001307#if defined(VGA_x86)
njnaf839f52005-06-23 03:27:57 +00001308# define VG_CLREQ_ARGS guest_EAX
1309# define VG_CLREQ_RET guest_EDX
njnf536bbb2005-06-13 04:21:38 +00001310#elif defined(VGA_amd64)
njnaf839f52005-06-23 03:27:57 +00001311# define VG_CLREQ_ARGS guest_RAX
1312# define VG_CLREQ_RET guest_RDX
sewardj2c48c7b2005-11-29 13:05:56 +00001313#elif defined(VGA_ppc32) || defined(VGA_ppc64)
njnaf839f52005-06-23 03:27:57 +00001314# define VG_CLREQ_ARGS guest_GPR4
1315# define VG_CLREQ_RET guest_GPR3
sewardj59570ff2010-01-01 11:59:33 +00001316#elif defined(VGA_arm)
1317# define VG_CLREQ_ARGS guest_R4
1318# define VG_CLREQ_RET guest_R3
sewardjb5b87402011-03-07 16:05:35 +00001319#elif defined (VGA_s390x)
1320# define VG_CLREQ_ARGS guest_r2
1321# define VG_CLREQ_RET guest_r3
njnf536bbb2005-06-13 04:21:38 +00001322#else
1323# error Unknown arch
1324#endif
1325
njnaf839f52005-06-23 03:27:57 +00001326#define CLREQ_ARGS(regs) ((regs).vex.VG_CLREQ_ARGS)
1327#define CLREQ_RET(regs) ((regs).vex.VG_CLREQ_RET)
1328#define O_CLREQ_RET (offsetof(VexGuestArchState, VG_CLREQ_RET))
njnf536bbb2005-06-13 04:21:38 +00001329
njn502badb2005-05-08 02:04:49 +00001330// These macros write a value to a client's thread register, and tell the
1331// tool that it's happened (if necessary).
1332
1333#define SET_CLREQ_RETVAL(zztid, zzval) \
1334 do { CLREQ_RET(VG_(threads)[zztid].arch) = (zzval); \
1335 VG_TRACK( post_reg_write, \
1336 Vg_CoreClientReq, zztid, O_CLREQ_RET, sizeof(UWord)); \
1337 } while (0)
1338
1339#define SET_CLCALL_RETVAL(zztid, zzval, f) \
1340 do { CLREQ_RET(VG_(threads)[zztid].arch) = (zzval); \
1341 VG_TRACK( post_reg_write_clientcall_return, \
1342 zztid, O_CLREQ_RET, sizeof(UWord), f); \
1343 } while (0)
1344
sewardj0ec07f32006-01-12 12:32:32 +00001345
sewardje663cb92002-04-12 10:26:32 +00001346/* ---------------------------------------------------------------------
sewardj124ca2a2002-06-20 10:19:38 +00001347 Handle client requests.
sewardje663cb92002-04-12 10:26:32 +00001348 ------------------------------------------------------------------ */
1349
njn9cb54ac2005-06-12 04:19:17 +00001350// OS-specific(?) client requests
1351static Bool os_client_request(ThreadId tid, UWord *args)
1352{
1353 Bool handled = True;
1354
1355 vg_assert(VG_(is_running_thread)(tid));
1356
1357 switch(args[0]) {
1358 case VG_USERREQ__LIBC_FREERES_DONE:
1359 /* This is equivalent to an exit() syscall, but we don't set the
1360 exitcode (since it might already be set) */
1361 if (0 || VG_(clo_trace_syscalls) || VG_(clo_trace_sched))
sewardj738856f2009-07-15 14:48:32 +00001362 VG_(message)(Vg_DebugMsg,
1363 "__libc_freeres() done; really quitting!\n");
sewardjf54342a2006-10-17 01:51:24 +00001364 VG_(threads)[tid].exitreason = VgSrc_ExitThread;
njn9cb54ac2005-06-12 04:19:17 +00001365 break;
1366
1367 default:
1368 handled = False;
1369 break;
1370 }
1371
1372 return handled;
1373}
1374
1375
sewardj124ca2a2002-06-20 10:19:38 +00001376/* Do a client request for the thread tid. After the request, tid may
1377 or may not still be runnable; if not, the scheduler will have to
1378 choose a new thread to run.
1379*/
sewardje663cb92002-04-12 10:26:32 +00001380static
sewardjb5f6f512005-03-10 23:59:00 +00001381void do_client_request ( ThreadId tid )
sewardje663cb92002-04-12 10:26:32 +00001382{
sewardjb5f6f512005-03-10 23:59:00 +00001383 UWord* arg = (UWord*)(CLREQ_ARGS(VG_(threads)[tid].arch));
nethercoted1b64b22004-11-04 18:22:28 +00001384 UWord req_no = arg[0];
sewardj124ca2a2002-06-20 10:19:38 +00001385
fitzhardinge98abfc72003-12-16 02:05:15 +00001386 if (0)
nethercoted1b64b22004-11-04 18:22:28 +00001387 VG_(printf)("req no = 0x%llx, arg = %p\n", (ULong)req_no, arg);
sewardje663cb92002-04-12 10:26:32 +00001388 switch (req_no) {
1389
njn3e884182003-04-15 13:03:23 +00001390 case VG_USERREQ__CLIENT_CALL0: {
njn2ac95242005-03-13 23:07:30 +00001391 UWord (*f)(ThreadId) = (void*)arg[1];
fitzhardinge98abfc72003-12-16 02:05:15 +00001392 if (f == NULL)
sewardj738856f2009-07-15 14:48:32 +00001393 VG_(message)(Vg_DebugMsg, "VG_USERREQ__CLIENT_CALL0: func=%p\n", f);
fitzhardinge98abfc72003-12-16 02:05:15 +00001394 else
njn2ac95242005-03-13 23:07:30 +00001395 SET_CLCALL_RETVAL(tid, f ( tid ), (Addr)f);
njn3e884182003-04-15 13:03:23 +00001396 break;
1397 }
1398 case VG_USERREQ__CLIENT_CALL1: {
njn2ac95242005-03-13 23:07:30 +00001399 UWord (*f)(ThreadId, UWord) = (void*)arg[1];
fitzhardinge98abfc72003-12-16 02:05:15 +00001400 if (f == NULL)
sewardj738856f2009-07-15 14:48:32 +00001401 VG_(message)(Vg_DebugMsg, "VG_USERREQ__CLIENT_CALL1: func=%p\n", f);
fitzhardinge98abfc72003-12-16 02:05:15 +00001402 else
njn2ac95242005-03-13 23:07:30 +00001403 SET_CLCALL_RETVAL(tid, f ( tid, arg[2] ), (Addr)f );
njn3e884182003-04-15 13:03:23 +00001404 break;
1405 }
1406 case VG_USERREQ__CLIENT_CALL2: {
njn2ac95242005-03-13 23:07:30 +00001407 UWord (*f)(ThreadId, UWord, UWord) = (void*)arg[1];
fitzhardinge98abfc72003-12-16 02:05:15 +00001408 if (f == NULL)
sewardj738856f2009-07-15 14:48:32 +00001409 VG_(message)(Vg_DebugMsg, "VG_USERREQ__CLIENT_CALL2: func=%p\n", f);
fitzhardinge98abfc72003-12-16 02:05:15 +00001410 else
njn2ac95242005-03-13 23:07:30 +00001411 SET_CLCALL_RETVAL(tid, f ( tid, arg[2], arg[3] ), (Addr)f );
njn3e884182003-04-15 13:03:23 +00001412 break;
1413 }
1414 case VG_USERREQ__CLIENT_CALL3: {
njn2ac95242005-03-13 23:07:30 +00001415 UWord (*f)(ThreadId, UWord, UWord, UWord) = (void*)arg[1];
fitzhardinge98abfc72003-12-16 02:05:15 +00001416 if (f == NULL)
sewardj738856f2009-07-15 14:48:32 +00001417 VG_(message)(Vg_DebugMsg, "VG_USERREQ__CLIENT_CALL3: func=%p\n", f);
fitzhardinge98abfc72003-12-16 02:05:15 +00001418 else
njn2ac95242005-03-13 23:07:30 +00001419 SET_CLCALL_RETVAL(tid, f ( tid, arg[2], arg[3], arg[4] ), (Addr)f );
njn3e884182003-04-15 13:03:23 +00001420 break;
1421 }
1422
njnf09745a2005-05-10 03:01:23 +00001423 // Nb: this looks like a circular definition, because it kind of is.
1424 // See comment in valgrind.h to understand what's going on.
sewardj124ca2a2002-06-20 10:19:38 +00001425 case VG_USERREQ__RUNNING_ON_VALGRIND:
sewardjb5f6f512005-03-10 23:59:00 +00001426 SET_CLREQ_RETVAL(tid, RUNNING_ON_VALGRIND+1);
sewardj124ca2a2002-06-20 10:19:38 +00001427 break;
1428
fitzhardinge39de4b42003-10-31 07:12:21 +00001429 case VG_USERREQ__PRINTF: {
sewardjc560fb32010-01-28 15:23:54 +00001430 /* JRS 2010-Jan-28: this is DEPRECATED; use the
1431 _VALIST_BY_REF version instead */
1432 if (sizeof(va_list) != sizeof(UWord))
1433 goto va_list_casting_error_NORETURN;
sewardj05b07152010-01-04 01:01:02 +00001434 union {
1435 va_list vargs;
sewardjc560fb32010-01-28 15:23:54 +00001436 unsigned long uw;
1437 } u;
1438 u.uw = (unsigned long)arg[2];
1439 Int count =
1440 VG_(vmessage)( Vg_ClientMsg, (char *)arg[1], u.vargs );
1441 VG_(message_flush)();
1442 SET_CLREQ_RETVAL( tid, count );
1443 break;
1444 }
fitzhardinge39de4b42003-10-31 07:12:21 +00001445
sewardjc560fb32010-01-28 15:23:54 +00001446 case VG_USERREQ__PRINTF_BACKTRACE: {
1447 /* JRS 2010-Jan-28: this is DEPRECATED; use the
1448 _VALIST_BY_REF version instead */
1449 if (sizeof(va_list) != sizeof(UWord))
1450 goto va_list_casting_error_NORETURN;
sewardj05b07152010-01-04 01:01:02 +00001451 union {
1452 va_list vargs;
sewardjc560fb32010-01-28 15:23:54 +00001453 unsigned long uw;
1454 } u;
1455 u.uw = (unsigned long)arg[2];
1456 Int count =
1457 VG_(vmessage)( Vg_ClientMsg, (char *)arg[1], u.vargs );
1458 VG_(message_flush)();
1459 VG_(get_and_pp_StackTrace)( tid, VG_(clo_backtrace_size) );
1460 SET_CLREQ_RETVAL( tid, count );
1461 break;
1462 }
1463
1464 case VG_USERREQ__PRINTF_VALIST_BY_REF: {
1465 va_list* vargsp = (va_list*)arg[2];
1466 Int count =
1467 VG_(vmessage)( Vg_ClientMsg, (char *)arg[1], *vargsp );
1468 VG_(message_flush)();
1469 SET_CLREQ_RETVAL( tid, count );
1470 break;
1471 }
1472
1473 case VG_USERREQ__PRINTF_BACKTRACE_VALIST_BY_REF: {
1474 va_list* vargsp = (va_list*)arg[2];
1475 Int count =
1476 VG_(vmessage)( Vg_ClientMsg, (char *)arg[1], *vargsp );
1477 VG_(message_flush)();
1478 VG_(get_and_pp_StackTrace)( tid, VG_(clo_backtrace_size) );
1479 SET_CLREQ_RETVAL( tid, count );
1480 break;
1481 }
1482
1483 case VG_USERREQ__INTERNAL_PRINTF_VALIST_BY_REF: {
1484 va_list* vargsp = (va_list*)arg[2];
1485 Int count =
1486 VG_(vmessage)( Vg_DebugMsg, (char *)arg[1], *vargsp );
1487 VG_(message_flush)();
1488 SET_CLREQ_RETVAL( tid, count );
1489 break;
1490 }
fitzhardinge39de4b42003-10-31 07:12:21 +00001491
tomd2645142009-10-29 09:27:11 +00001492 case VG_USERREQ__ADD_IFUNC_TARGET: {
1493 VG_(redir_add_ifunc_target)( arg[1], arg[2] );
1494 SET_CLREQ_RETVAL( tid, 0);
1495 break; }
1496
rjwalsh0140af52005-06-04 20:42:33 +00001497 case VG_USERREQ__STACK_REGISTER: {
njn945ed2e2005-06-24 03:28:30 +00001498 UWord sid = VG_(register_stack)((Addr)arg[1], (Addr)arg[2]);
rjwalsh0140af52005-06-04 20:42:33 +00001499 SET_CLREQ_RETVAL( tid, sid );
1500 break; }
1501
1502 case VG_USERREQ__STACK_DEREGISTER: {
njn945ed2e2005-06-24 03:28:30 +00001503 VG_(deregister_stack)(arg[1]);
rjwalsh0140af52005-06-04 20:42:33 +00001504 SET_CLREQ_RETVAL( tid, 0 ); /* return value is meaningless */
1505 break; }
1506
1507 case VG_USERREQ__STACK_CHANGE: {
njn945ed2e2005-06-24 03:28:30 +00001508 VG_(change_stack)(arg[1], (Addr)arg[2], (Addr)arg[3]);
rjwalsh0140af52005-06-04 20:42:33 +00001509 SET_CLREQ_RETVAL( tid, 0 ); /* return value is meaningless */
1510 break; }
1511
fitzhardinge98abfc72003-12-16 02:05:15 +00001512 case VG_USERREQ__GET_MALLOCFUNCS: {
1513 struct vg_mallocfunc_info *info = (struct vg_mallocfunc_info *)arg[1];
1514
njnfc51f8d2005-06-21 03:20:17 +00001515 info->tl_malloc = VG_(tdict).tool_malloc;
1516 info->tl_calloc = VG_(tdict).tool_calloc;
1517 info->tl_realloc = VG_(tdict).tool_realloc;
1518 info->tl_memalign = VG_(tdict).tool_memalign;
1519 info->tl___builtin_new = VG_(tdict).tool___builtin_new;
1520 info->tl___builtin_vec_new = VG_(tdict).tool___builtin_vec_new;
1521 info->tl_free = VG_(tdict).tool_free;
1522 info->tl___builtin_delete = VG_(tdict).tool___builtin_delete;
1523 info->tl___builtin_vec_delete = VG_(tdict).tool___builtin_vec_delete;
njn8b140de2009-02-17 04:31:18 +00001524 info->tl_malloc_usable_size = VG_(tdict).tool_malloc_usable_size;
fitzhardinge98abfc72003-12-16 02:05:15 +00001525
njn088bfb42005-08-17 05:01:37 +00001526 info->mallinfo = VG_(mallinfo);
sewardjb5f6f512005-03-10 23:59:00 +00001527 info->clo_trace_malloc = VG_(clo_trace_malloc);
fitzhardinge98abfc72003-12-16 02:05:15 +00001528
1529 SET_CLREQ_RETVAL( tid, 0 ); /* return value is meaningless */
1530
1531 break;
1532 }
1533
njn25e49d8e72002-09-23 09:36:25 +00001534 /* Requests from the client program */
1535
1536 case VG_USERREQ__DISCARD_TRANSLATIONS:
1537 if (VG_(clo_verbosity) > 2)
1538 VG_(printf)( "client request: DISCARD_TRANSLATIONS,"
njn8a7b41b2007-09-23 00:51:24 +00001539 " addr %p, len %lu\n",
njn25e49d8e72002-09-23 09:36:25 +00001540 (void*)arg[1], arg[2] );
1541
sewardj45f4e7c2005-09-27 19:20:21 +00001542 VG_(discard_translations)(
1543 arg[1], arg[2], "scheduler(VG_USERREQ__DISCARD_TRANSLATIONS)"
1544 );
njn25e49d8e72002-09-23 09:36:25 +00001545
njnd3040452003-05-19 15:04:06 +00001546 SET_CLREQ_RETVAL( tid, 0 ); /* return value is meaningless */
njn25e49d8e72002-09-23 09:36:25 +00001547 break;
1548
njn47363ab2003-04-21 13:24:40 +00001549 case VG_USERREQ__COUNT_ERRORS:
nethercotef2b11482004-08-02 12:36:01 +00001550 SET_CLREQ_RETVAL( tid, VG_(get_n_errs_found)() );
njn47363ab2003-04-21 13:24:40 +00001551 break;
1552
sewardjc8259b82009-04-22 22:42:10 +00001553 case VG_USERREQ__LOAD_PDB_DEBUGINFO:
1554 VG_(di_notify_pdb_debuginfo)( arg[1], arg[2], arg[3], arg[4] );
1555 SET_CLREQ_RETVAL( tid, 0 ); /* return value is meaningless */
1556 break;
1557
sewardj5c659622010-08-20 18:22:07 +00001558 case VG_USERREQ__MAP_IP_TO_SRCLOC: {
1559 Addr ip = arg[1];
1560 UChar* buf64 = (UChar*)arg[2];
1561
1562 VG_(memset)(buf64, 0, 64);
1563 UInt linenum = 0;
1564 Bool ok = VG_(get_filename_linenum)(
1565 ip, &buf64[0], 50, NULL, 0, NULL, &linenum
1566 );
1567 if (ok) {
1568 /* Find the terminating zero in the first 50 bytes. */
1569 UInt i;
1570 for (i = 0; i < 50; i++) {
1571 if (buf64[i] == 0)
1572 break;
1573 }
1574 /* We must find a zero somewhere in 0 .. 49. Else
1575 VG_(get_filename_linenum) is not properly zero
1576 terminating. */
1577 vg_assert(i < 50);
1578 VG_(sprintf)(&buf64[i], ":%u", linenum);
1579 } else {
1580 buf64[0] = 0;
1581 }
1582
1583 SET_CLREQ_RETVAL( tid, 0 ); /* return value is meaningless */
1584 break;
1585 }
1586
njn32f8d8c2009-07-15 02:31:45 +00001587 case VG_USERREQ__MALLOCLIKE_BLOCK:
bart91347382011-03-25 20:07:25 +00001588 case VG_USERREQ__RESIZEINPLACE_BLOCK:
njn32f8d8c2009-07-15 02:31:45 +00001589 case VG_USERREQ__FREELIKE_BLOCK:
1590 // Ignore them if the addr is NULL; otherwise pass onto the tool.
1591 if (!arg[1]) {
1592 SET_CLREQ_RETVAL( tid, 0 ); /* return value is meaningless */
1593 break;
1594 } else {
1595 goto my_default;
1596 }
1597
sewardje663cb92002-04-12 10:26:32 +00001598 default:
njn32f8d8c2009-07-15 02:31:45 +00001599 my_default:
njn9cb54ac2005-06-12 04:19:17 +00001600 if (os_client_request(tid, arg)) {
1601 // do nothing, os_client_request() handled it
sewardjb5f6f512005-03-10 23:59:00 +00001602 } else if (VG_(needs).client_requests) {
nethercoted1b64b22004-11-04 18:22:28 +00001603 UWord ret;
sewardj34042512002-10-22 04:14:35 +00001604
njn25e49d8e72002-09-23 09:36:25 +00001605 if (VG_(clo_verbosity) > 2)
njn8a7b41b2007-09-23 00:51:24 +00001606 VG_(printf)("client request: code %lx, addr %p, len %lu\n",
njn25e49d8e72002-09-23 09:36:25 +00001607 arg[0], (void*)arg[1], arg[2] );
1608
njn51d827b2005-05-09 01:02:08 +00001609 if ( VG_TDICT_CALL(tool_handle_client_request, tid, arg, &ret) )
sewardjb5f6f512005-03-10 23:59:00 +00001610 SET_CLREQ_RETVAL(tid, ret);
njn25e49d8e72002-09-23 09:36:25 +00001611 } else {
sewardj34042512002-10-22 04:14:35 +00001612 static Bool whined = False;
1613
sewardjb5f6f512005-03-10 23:59:00 +00001614 if (!whined && VG_(clo_verbosity) > 2) {
nethercote7cc9c232004-01-21 15:08:04 +00001615 // Allow for requests in core, but defined by tools, which
njnd7994182003-10-02 13:44:04 +00001616 // have 0 and 0 in their two high bytes.
1617 Char c1 = (arg[0] >> 24) & 0xff;
1618 Char c2 = (arg[0] >> 16) & 0xff;
1619 if (c1 == 0) c1 = '_';
1620 if (c2 == 0) c2 = '_';
sewardj34042512002-10-22 04:14:35 +00001621 VG_(message)(Vg_UserMsg, "Warning:\n"
barta0b6b2c2008-07-07 06:49:24 +00001622 " unhandled client request: 0x%lx (%c%c+0x%lx). Perhaps\n"
sewardj738856f2009-07-15 14:48:32 +00001623 " VG_(needs).client_requests should be set?\n",
njnd7994182003-10-02 13:44:04 +00001624 arg[0], c1, c2, arg[0] & 0xffff);
sewardj34042512002-10-22 04:14:35 +00001625 whined = True;
1626 }
njn25e49d8e72002-09-23 09:36:25 +00001627 }
sewardje663cb92002-04-12 10:26:32 +00001628 break;
1629 }
sewardjc560fb32010-01-28 15:23:54 +00001630 return;
1631
1632 /*NOTREACHED*/
1633 va_list_casting_error_NORETURN:
1634 VG_(umsg)(
1635 "Valgrind: fatal error - cannot continue: use of the deprecated\n"
1636 "client requests VG_USERREQ__PRINTF or VG_USERREQ__PRINTF_BACKTRACE\n"
1637 "on a platform where they cannot be supported. Please use the\n"
1638 "equivalent _VALIST_BY_REF versions instead.\n"
1639 "\n"
1640 "This is a binary-incompatible change in Valgrind's client request\n"
1641 "mechanism. It is unfortunate, but difficult to avoid. End-users\n"
1642 "are expected to almost never see this message. The only case in\n"
1643 "which you might see this message is if your code uses the macros\n"
1644 "VALGRIND_PRINTF or VALGRIND_PRINTF_BACKTRACE. If so, you will need\n"
1645 "to recompile such code, using the header files from this version of\n"
1646 "Valgrind, and not any previous version.\n"
1647 "\n"
1648 "If you see this mesage in any other circumstances, it is probably\n"
1649 "a bug in Valgrind. In this case, please file a bug report at\n"
1650 "\n"
1651 " http://www.valgrind.org/support/bug_reports.html\n"
1652 "\n"
1653 "Will now abort.\n"
1654 );
1655 vg_assert(0);
sewardje663cb92002-04-12 10:26:32 +00001656}
1657
1658
sewardj6072c362002-04-19 14:40:57 +00001659/* ---------------------------------------------------------------------
njn6676d5b2005-06-19 18:49:19 +00001660 Sanity checking (permanently engaged)
sewardj6072c362002-04-19 14:40:57 +00001661 ------------------------------------------------------------------ */
1662
sewardjb5f6f512005-03-10 23:59:00 +00001663/* Internal consistency checks on the sched structures. */
sewardj6072c362002-04-19 14:40:57 +00001664static
sewardjb5f6f512005-03-10 23:59:00 +00001665void scheduler_sanity ( ThreadId tid )
sewardj6072c362002-04-19 14:40:57 +00001666{
sewardjb5f6f512005-03-10 23:59:00 +00001667 Bool bad = False;
sewardjf54342a2006-10-17 01:51:24 +00001668 static UInt lasttime = 0;
1669 UInt now;
1670 Int lwpid = VG_(gettid)();
jsgf855d93d2003-10-13 22:26:55 +00001671
sewardjb5f6f512005-03-10 23:59:00 +00001672 if (!VG_(is_running_thread)(tid)) {
1673 VG_(message)(Vg_DebugMsg,
sewardjf54342a2006-10-17 01:51:24 +00001674 "Thread %d is supposed to be running, "
sewardjad0a3a82006-12-17 18:58:55 +00001675 "but doesn't own the_BigLock (owned by %d)\n",
njnc7561b92005-06-19 01:24:32 +00001676 tid, VG_(running_tid));
sewardjb5f6f512005-03-10 23:59:00 +00001677 bad = True;
jsgf855d93d2003-10-13 22:26:55 +00001678 }
sewardj5f07b662002-04-23 16:52:51 +00001679
sewardjf54342a2006-10-17 01:51:24 +00001680 if (lwpid != VG_(threads)[tid].os_state.lwpid) {
sewardjb5f6f512005-03-10 23:59:00 +00001681 VG_(message)(Vg_DebugMsg,
njnd06ed472005-03-13 05:12:31 +00001682 "Thread %d supposed to be in LWP %d, but we're actually %d\n",
1683 tid, VG_(threads)[tid].os_state.lwpid, VG_(gettid)());
sewardjb5f6f512005-03-10 23:59:00 +00001684 bad = True;
sewardj5f07b662002-04-23 16:52:51 +00001685 }
sewardjf54342a2006-10-17 01:51:24 +00001686
njnf76d27a2009-05-28 01:53:07 +00001687#if !defined(VGO_darwin)
1688 // GrP fixme
sewardjad0a3a82006-12-17 18:58:55 +00001689 if (lwpid != the_BigLock.owner_lwpid) {
sewardjf54342a2006-10-17 01:51:24 +00001690 VG_(message)(Vg_DebugMsg,
sewardjad0a3a82006-12-17 18:58:55 +00001691 "Thread (LWPID) %d doesn't own the_BigLock\n",
sewardjf54342a2006-10-17 01:51:24 +00001692 tid);
1693 bad = True;
1694 }
njnf76d27a2009-05-28 01:53:07 +00001695#endif
sewardjf54342a2006-10-17 01:51:24 +00001696
1697 /* Periodically show the state of all threads, for debugging
1698 purposes. */
1699 now = VG_(read_millisecond_timer)();
1700 if (0 && (!bad) && (lasttime + 4000/*ms*/ <= now)) {
1701 lasttime = now;
1702 VG_(printf)("\n------------ Sched State at %d ms ------------\n",
1703 (Int)now);
1704 VG_(show_sched_status)();
1705 }
1706
1707 /* core_panic also shows the sched status, which is why we don't
1708 show it above if bad==True. */
1709 if (bad)
1710 VG_(core_panic)("scheduler_sanity: failed");
sewardj6072c362002-04-19 14:40:57 +00001711}
1712
njn6676d5b2005-06-19 18:49:19 +00001713void VG_(sanity_check_general) ( Bool force_expensive )
1714{
1715 ThreadId tid;
1716
sewardjf54342a2006-10-17 01:51:24 +00001717 static UInt next_slow_check_at = 1;
1718 static UInt slow_check_interval = 25;
1719
njn6676d5b2005-06-19 18:49:19 +00001720 if (VG_(clo_sanity_level) < 1) return;
1721
1722 /* --- First do all the tests that we can do quickly. ---*/
1723
1724 sanity_fast_count++;
1725
1726 /* Check stuff pertaining to the memory check system. */
1727
1728 /* Check that nobody has spuriously claimed that the first or
1729 last 16 pages of memory have become accessible [...] */
1730 if (VG_(needs).sanity_checks) {
njn6676d5b2005-06-19 18:49:19 +00001731 vg_assert(VG_TDICT_CALL(tool_cheap_sanity_check));
njn6676d5b2005-06-19 18:49:19 +00001732 }
1733
1734 /* --- Now some more expensive checks. ---*/
1735
sewardjf54342a2006-10-17 01:51:24 +00001736 /* Once every now and again, check some more expensive stuff.
1737 Gradually increase the interval between such checks so as not to
1738 burden long-running programs too much. */
njn6676d5b2005-06-19 18:49:19 +00001739 if ( force_expensive
sewardjf54342a2006-10-17 01:51:24 +00001740 || VG_(clo_sanity_level) > 1
1741 || (VG_(clo_sanity_level) == 1
1742 && sanity_fast_count == next_slow_check_at)) {
njn6676d5b2005-06-19 18:49:19 +00001743
sewardjf54342a2006-10-17 01:51:24 +00001744 if (0) VG_(printf)("SLOW at %d\n", sanity_fast_count-1);
1745
1746 next_slow_check_at = sanity_fast_count - 1 + slow_check_interval;
1747 slow_check_interval++;
njn6676d5b2005-06-19 18:49:19 +00001748 sanity_slow_count++;
1749
njn6676d5b2005-06-19 18:49:19 +00001750 if (VG_(needs).sanity_checks) {
njn6676d5b2005-06-19 18:49:19 +00001751 vg_assert(VG_TDICT_CALL(tool_expensive_sanity_check));
njn6676d5b2005-06-19 18:49:19 +00001752 }
1753
njn6676d5b2005-06-19 18:49:19 +00001754 /* Look for stack overruns. Visit all threads. */
njnd666ea72005-06-26 17:26:22 +00001755 for (tid = 1; tid < VG_N_THREADS; tid++) {
sewardj45f4e7c2005-09-27 19:20:21 +00001756 SizeT remains;
1757 VgStack* stack;
njn6676d5b2005-06-19 18:49:19 +00001758
1759 if (VG_(threads)[tid].status == VgTs_Empty ||
1760 VG_(threads)[tid].status == VgTs_Zombie)
1761 continue;
1762
sewardj45f4e7c2005-09-27 19:20:21 +00001763 stack
1764 = (VgStack*)
1765 VG_(get_ThreadState)(tid)->os_state.valgrind_stack_base;
sewardj46dbd3f2010-09-08 08:30:31 +00001766 SizeT limit
1767 = 4096; // Let's say. Checking more causes lots of L2 misses.
sewardj45f4e7c2005-09-27 19:20:21 +00001768 remains
sewardj46dbd3f2010-09-08 08:30:31 +00001769 = VG_(am_get_VgStack_unused_szB)(stack, limit);
1770 if (remains < limit)
njn6676d5b2005-06-19 18:49:19 +00001771 VG_(message)(Vg_DebugMsg,
barta0b6b2c2008-07-07 06:49:24 +00001772 "WARNING: Thread %d is within %ld bytes "
sewardj738856f2009-07-15 14:48:32 +00001773 "of running out of stack!\n",
njn6676d5b2005-06-19 18:49:19 +00001774 tid, remains);
1775 }
njn6676d5b2005-06-19 18:49:19 +00001776 }
1777
1778 if (VG_(clo_sanity_level) > 1) {
njn6676d5b2005-06-19 18:49:19 +00001779 /* Check sanity of the low-level memory manager. Note that bugs
1780 in the client's code can cause this to fail, so we don't do
1781 this check unless specially asked for. And because it's
1782 potentially very expensive. */
1783 VG_(sanity_check_malloc_all)();
njn6676d5b2005-06-19 18:49:19 +00001784 }
njn6676d5b2005-06-19 18:49:19 +00001785}
sewardj6072c362002-04-19 14:40:57 +00001786
sewardje663cb92002-04-12 10:26:32 +00001787/*--------------------------------------------------------------------*/
njn278b3d62005-05-30 23:20:51 +00001788/*--- end ---*/
sewardje663cb92002-04-12 10:26:32 +00001789/*--------------------------------------------------------------------*/