1
2/*--------------------------------------------------------------------*/
3/*--- Thread scheduling.                               scheduler.c ---*/
4/*--------------------------------------------------------------------*/
5
6/*
7   This file is part of Valgrind, a dynamic binary instrumentation
8   framework.
9
10   Copyright (C) 2000-2010 Julian Seward
11      jseward@acm.org
12
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
28   The GNU General Public License is contained in the file COPYING.
29*/
30
31/*
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
41   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
43   manipulate any shared state (which is anything other than its own
44   ThreadState entry), it must hold the_BigLock.
45
46   When a thread is about to block in a blocking syscall, it releases
47   the_BigLock, and re-takes it when it becomes runnable again (either
48   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
56   implemented elsewhere.  [Some of the functions have worked their
57   way back for the moment, until we do an OS port in earnest...]
58 */
59
60#include "pub_core_basics.h"
61#include "pub_core_debuglog.h"
62#include "pub_core_vki.h"
63#include "pub_core_vkiscnums.h"    // __NR_sched_yield
64#include "pub_core_threadstate.h"
65#include "pub_core_aspacemgr.h"
66#include "pub_core_clreq.h"         // for VG_USERREQ__*
67#include "pub_core_dispatch.h"
68#include "pub_core_errormgr.h"      // For VG_(get_n_errs_found)()
69#include "pub_core_libcbase.h"
70#include "pub_core_libcassert.h"
71#include "pub_core_libcprint.h"
72#include "pub_core_libcproc.h"
73#include "pub_core_libcsignal.h"
74#if defined(VGO_darwin)
75#include "pub_core_mach.h"
76#endif
77#include "pub_core_machine.h"
78#include "pub_core_mallocfree.h"
79#include "pub_core_options.h"
80#include "pub_core_replacemalloc.h"
81#include "pub_core_signals.h"
82#include "pub_core_stacks.h"
83#include "pub_core_stacktrace.h"    // For VG_(get_and_pp_StackTrace)()
84#include "pub_core_syscall.h"
85#include "pub_core_syswrap.h"
86#include "pub_core_tooliface.h"
87#include "pub_core_translate.h"     // For VG_(translate)()
88#include "pub_core_transtab.h"
89#include "pub_core_debuginfo.h"     // VG_(di_notify_pdb_debuginfo)
90#include "priv_sema.h"
91#include "pub_core_scheduler.h"     // self
92#include "pub_core_redir.h"
93
94
95/* ---------------------------------------------------------------------
96   Types and globals for the scheduler.
97   ------------------------------------------------------------------ */
98
99/* ThreadId and ThreadState are defined elsewhere*/
100
101/* Defines the thread-scheduling timeslice, in terms of the number of
102   basic blocks we attempt to run each thread for.  Smaller values
103   give finer interleaving but much increased scheduling overheads. */
104#define SCHEDULING_QUANTUM   100000
105
106/* If False, a fault is Valgrind-internal (ie, a bug) */
107Bool VG_(in_generated_code) = False;
108
109/* Counts downwards in VG_(run_innerloop). */
110UInt VG_(dispatch_ctr);
111
112/* 64-bit counter for the number of basic blocks done. */
113static ULong bbs_done = 0;
114
115/* Forwards */
116static void do_client_request ( ThreadId tid );
117static void scheduler_sanity ( ThreadId tid );
118static void mostly_clear_thread_record ( ThreadId tid );
119
120/* Stats. */
121static ULong n_scheduling_events_MINOR = 0;
122static ULong n_scheduling_events_MAJOR = 0;
123
124/* Sanity checking counts. */
125static UInt sanity_fast_count = 0;
126static UInt sanity_slow_count = 0;
127
128void VG_(print_scheduler_stats)(void)
129{
130   VG_(message)(Vg_DebugMsg,
131      "scheduler: %'llu jumps (bb entries).\n", bbs_done );
132   VG_(message)(Vg_DebugMsg,
133      "scheduler: %'llu/%'llu major/minor sched events.\n",
134      n_scheduling_events_MAJOR, n_scheduling_events_MINOR);
135   VG_(message)(Vg_DebugMsg,
136                "   sanity: %d cheap, %d expensive checks.\n",
137                sanity_fast_count, sanity_slow_count );
138}
139
140/* CPU semaphore, so that threads can run exclusively */
141static vg_sema_t the_BigLock;
142
143
144/* ---------------------------------------------------------------------
145   Helper functions for the scheduler.
146   ------------------------------------------------------------------ */
147
148static
149void print_sched_event ( ThreadId tid, Char* what )
150{
151   VG_(message)(Vg_DebugMsg, "  SCHED[%d]: %s\n", tid, what );
152}
153
154static
155HChar* name_of_sched_event ( UInt event )
156{
157   switch (event) {
158      case VEX_TRC_JMP_SYS_SYSCALL:   return "SYSCALL";
159      case VEX_TRC_JMP_SYS_INT32:     return "INT32";
160      case VEX_TRC_JMP_SYS_INT128:    return "INT128";
161      case VEX_TRC_JMP_SYS_INT129:    return "INT129";
162      case VEX_TRC_JMP_SYS_INT130:    return "INT130";
163      case VEX_TRC_JMP_SYS_SYSENTER:  return "SYSENTER";
164      case VEX_TRC_JMP_CLIENTREQ:     return "CLIENTREQ";
165      case VEX_TRC_JMP_YIELD:         return "YIELD";
166      case VEX_TRC_JMP_YIELD_NOREDIR: return "YIELD_NOREDIR";
167      case VEX_TRC_JMP_NODECODE:      return "NODECODE";
168      case VEX_TRC_JMP_MAPFAIL:       return "MAPFAIL";
169      case VEX_TRC_JMP_NOREDIR:       return "NOREDIR";
170      case VEX_TRC_JMP_EMWARN:        return "EMWARN";
171      case VEX_TRC_JMP_TINVAL:        return "TINVAL";
172      case VG_TRC_INVARIANT_FAILED:   return "INVFAILED";
173      case VG_TRC_INNER_COUNTERZERO:  return "COUNTERZERO";
174      case VG_TRC_INNER_FASTMISS:     return "FASTMISS";
175      case VG_TRC_FAULT_SIGNAL:       return "FAULTSIGNAL";
176      default:                        return "??UNKNOWN??";
177  }
178}
179
180/* Allocate a completely empty ThreadState record. */
181ThreadId VG_(alloc_ThreadState) ( void )
182{
183   Int i;
184   for (i = 1; i < VG_N_THREADS; i++) {
185      if (VG_(threads)[i].status == VgTs_Empty) {
186	 VG_(threads)[i].status = VgTs_Init;
187	 VG_(threads)[i].exitreason = VgSrc_None;
188         return i;
189      }
190   }
191   VG_(printf)("vg_alloc_ThreadState: no free slots available\n");
192   VG_(printf)("Increase VG_N_THREADS, rebuild and try again.\n");
193   VG_(core_panic)("VG_N_THREADS is too low");
194   /*NOTREACHED*/
195}
196
197/*
198   Mark a thread as Runnable.  This will block until the_BigLock is
199   available, so that we get exclusive access to all the shared
200   structures and the CPU.  Up until we get the_BigLock, we must not
201   touch any shared state.
202
203   When this returns, we'll actually be running.
204 */
205void VG_(acquire_BigLock)(ThreadId tid, HChar* who)
206{
207   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
218   /* 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. */
221   ML_(sema_down)(&the_BigLock, False/*not LL*/);
222
223   tst = VG_(get_ThreadState)(tid);
224
225   vg_assert(tst->status != VgTs_Runnable);
226
227   tst->status = VgTs_Runnable;
228
229   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;
233
234   { Addr gsp = VG_(get_SP)(tid);
235     VG_(unknown_SP_update)(gsp, gsp, 0/*unknown origin*/);
236   }
237
238   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   }
244}
245
246/*
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 */
253void VG_(release_BigLock)(ThreadId tid, ThreadStatus sleepstate, HChar* who)
254{
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
264   vg_assert(VG_(running_tid) == tid);
265   VG_(running_tid) = VG_INVALID_THREADID;
266
267   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
275   /* Release the_BigLock; this will reschedule any runnable
276      thread. */
277   ML_(sema_up)(&the_BigLock, False/*not LL*/);
278}
279
280/* 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
293/* 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
302   mostly_clear_thread_record(tid);
303   VG_(running_tid) = VG_INVALID_THREADID;
304
305   /* There should still be a valid exitreason for this thread */
306   vg_assert(VG_(threads)[tid].exitreason != VgSrc_None);
307
308   if (VG_(clo_trace_sched))
309      print_sched_event(tid, "release lock in VG_(exit_thread)");
310
311   ML_(sema_up)(&the_BigLock, False/*not LL*/);
312}
313
314/* 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)
318{
319   vg_assert(VG_(is_valid_tid)(tid));
320   vg_assert(!VG_(is_running_thread)(tid));
321
322   if (VG_(threads)[tid].status == VgTs_WaitSys) {
323      if (VG_(clo_trace_signals)) {
324	 VG_(message)(Vg_DebugMsg,
325                      "get_thread_out_of_syscall zaps tid %d lwp %d\n",
326		      tid, VG_(threads)[tid].os_state.lwpid);
327      }
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
356   }
357}
358
359/*
360   Yield the CPU for a short time to let some other thread run.
361 */
362void VG_(vg_yield)(void)
363{
364   ThreadId tid = VG_(running_tid);
365
366   vg_assert(tid != VG_INVALID_THREADID);
367   vg_assert(VG_(threads)[tid].os_state.lwpid == VG_(gettid)());
368
369   VG_(release_BigLock)(tid, VgTs_Yielding, "VG_(vg_yield)");
370
371   /*
372      Tell the kernel we're yielding.
373    */
374   VG_(do_syscall0)(__NR_sched_yield);
375
376   VG_(acquire_BigLock)(tid, "VG_(vg_yield)");
377}
378
379
380/* Set the standard set of blocked signals, used whenever we're not
381   running a client syscall. */
382static void block_signals(void)
383{
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
399   VG_(sigprocmask)(VKI_SIG_SETMASK, &mask, NULL);
400}
401
402static void os_state_clear(ThreadState *tst)
403{
404   tst->os_state.lwpid       = 0;
405   tst->os_state.threadgroup = 0;
406#  if defined(VGO_linux)
407   /* no other fields to clear */
408#  elif defined(VGO_aix5)
409   tst->os_state.cancel_async    = False;
410   tst->os_state.cancel_disabled = False;
411   tst->os_state.cancel_progress = Canc_NoRequest;
412#  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"
424#  endif
425}
426
427static void os_state_init(ThreadState *tst)
428{
429   tst->os_state.valgrind_stack_base    = 0;
430   tst->os_state.valgrind_stack_init_SP = 0;
431   os_state_clear(tst);
432}
433
434static
435void mostly_clear_thread_record ( ThreadId tid )
436{
437   vki_sigset_t savedmask;
438
439   vg_assert(tid >= 0 && tid < VG_N_THREADS);
440   VG_(cleanup_thread)(&VG_(threads)[tid].arch);
441   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
447   VG_(sigemptyset)(&VG_(threads)[tid].sig_mask);
448   VG_(sigemptyset)(&VG_(threads)[tid].tmp_sig_mask);
449
450   os_state_clear(&VG_(threads)[tid]);
451
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;
456
457   VG_(clear_out_queued_signals)(tid, &savedmask);
458
459   VG_(threads)[tid].sched_jmpbuf_valid = False;
460}
461
462/*
463   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.
468
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
475   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.
478*/
479static void sched_fork_cleanup(ThreadId me)
480{
481   ThreadId tid;
482   vg_assert(VG_(running_tid) == me);
483
484#  if defined(VGO_darwin)
485   // GrP fixme hack reset Mach ports
486   VG_(mach_init)();
487#  endif
488
489   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++) {
494      if (tid != me) {
495         mostly_clear_thread_record(tid);
496	 VG_(threads)[tid].status = VgTs_Empty;
497         VG_(clear_syscallInfo)(tid);
498      }
499   }
500
501   /* re-init and take the sema */
502   ML_(sema_deinit)(&the_BigLock);
503   ML_(sema_init)(&the_BigLock);
504   ML_(sema_down)(&the_BigLock, False/*not LL*/);
505}
506
507
508/* 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.
511*/
512ThreadId VG_(scheduler_init_phase1) ( void )
513{
514   Int i;
515   ThreadId tid_main;
516
517   VG_(debugLog)(1,"sched","sched_init_phase1\n");
518
519   ML_(sema_init)(&the_BigLock);
520
521   for (i = 0 /* NB; not 1 */; i < VG_N_THREADS; i++) {
522      /* Paranoia .. completely zero it out. */
523      VG_(memset)( & VG_(threads)[i], 0, sizeof( VG_(threads)[i] ) );
524
525      VG_(threads)[i].sig_queue = NULL;
526
527      os_state_init(&VG_(threads)[i]);
528      mostly_clear_thread_record(i);
529
530      VG_(threads)[i].status                    = VgTs_Empty;
531      VG_(threads)[i].client_stack_szB          = 0;
532      VG_(threads)[i].client_stack_highest_word = (Addr)NULL;
533   }
534
535   tid_main = VG_(alloc_ThreadState)();
536
537   /* 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
545   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));
565
566   VG_(threads)[tid_main].client_stack_highest_word
567      = clstack_end + 1 - sizeof(UWord);
568   VG_(threads)[tid_main].client_stack_szB
569      = clstack_size;
570
571   VG_(atfork)(NULL, NULL, sched_fork_cleanup);
572}
573
574
575/* ---------------------------------------------------------------------
576   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									\
585      (jumped) = __builtin_setjmp(_qq_tst->sched_jmpbuf);               \
586      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
600   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 )
606{
607   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;
615
616   if (0)
617   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,
622               (void*)a_spill, sz_spill );
623
624   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));
627   vg_assert(VG_IS_16_ALIGNED(sz_spill));
628
629   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));
633
634   /* 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. */
645   vg_assert(sz_spill == LibVEX_N_SPILL_BYTES);
646   vg_assert(a_vex + 3 * sz_vex == a_spill);
647
648#  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
658#  if defined(VGA_ppc32) || defined(VGA_ppc64)
659   /* ppc guest_state vector regs must be 16 byte aligned for
660      loads/stores.  This is important! */
661   vg_assert(VG_IS_16_ALIGNED(& tst->arch.vex.guest_VR0));
662   vg_assert(VG_IS_16_ALIGNED(& tst->arch.vex_shadow1.guest_VR0));
663   vg_assert(VG_IS_16_ALIGNED(& tst->arch.vex_shadow2.guest_VR0));
664   /* be extra paranoid .. */
665   vg_assert(VG_IS_16_ALIGNED(& tst->arch.vex.guest_VR1));
666   vg_assert(VG_IS_16_ALIGNED(& tst->arch.vex_shadow1.guest_VR1));
667   vg_assert(VG_IS_16_ALIGNED(& tst->arch.vex_shadow2.guest_VR1));
668#  endif
669
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
681}
682
683
684/* Run the thread tid for a while, and return a VG_TRC_* value
685   indicating why VG_(run_innerloop) stopped. */
686static UInt run_thread_for_a_while ( ThreadId tid )
687{
688   volatile Int          jumped;
689   volatile ThreadState* tst = NULL; /* stop gcc complaining */
690   volatile UInt         trc;
691   volatile Int          dispatch_ctr_SAVED;
692   volatile Int          done_this_time;
693
694   /* Paranoia */
695   vg_assert(VG_(is_valid_tid)(tid));
696   vg_assert(VG_(is_running_thread)(tid));
697   vg_assert(!VG_(is_exiting)(tid));
698
699   tst = VG_(get_ThreadState)(tid);
700   do_pre_run_checks( (ThreadState*)tst );
701   /* end Paranoia */
702
703   trc = 0;
704   dispatch_ctr_SAVED = VG_(dispatch_ctr);
705
706#  if defined(VGP_ppc32_aix5) || defined(VGP_ppc64_aix5)
707   /* On AIX, we need to get a plausible value for SPRG3 for this
708      thread, since it's used I think as a thread-state pointer.  It
709      is presumably set by the kernel for each dispatched thread and
710      cannot be changed by user space.  It therefore seems safe enough
711      to copy the host's value of it into the guest state at the point
712      the thread is dispatched.
713      (Later): Hmm, looks like SPRG3 is only used in 32-bit mode.
714      Oh well. */
715   { UWord host_sprg3;
716     __asm__ __volatile__( "mfspr %0,259\n" : "=b"(host_sprg3) );
717    VG_(threads)[tid].arch.vex.guest_SPRG3_RO = host_sprg3;
718    vg_assert(sizeof(VG_(threads)[tid].arch.vex.guest_SPRG3_RO) == sizeof(void*));
719   }
720#  endif
721
722   /* there should be no undealt-with signals */
723   //vg_assert(VG_(threads)[tid].siginfo.si_signo == 0);
724
725   if (0) {
726      vki_sigset_t m;
727      Int i, err = VG_(sigprocmask)(VKI_SIG_SETMASK, NULL, &m);
728      vg_assert(err == 0);
729      VG_(printf)("tid %d: entering code with unblocked signals: ", tid);
730      for (i = 1; i <= _VKI_NSIG; i++)
731         if (!VG_(sigismember)(&m, i))
732            VG_(printf)("%d ", i);
733      VG_(printf)("\n");
734   }
735
736   // Tell the tool this thread is about to run client code
737   VG_TRACK( start_client_code, tid, bbs_done );
738
739   vg_assert(VG_(in_generated_code) == False);
740   VG_(in_generated_code) = True;
741
742   SCHEDSETJMP(
743      tid,
744      jumped,
745      trc = (UInt)VG_(run_innerloop)( (void*)&tst->arch.vex,
746                                      VG_(clo_profile_flags) > 0 ? 1 : 0 )
747   );
748
749   vg_assert(VG_(in_generated_code) == True);
750   VG_(in_generated_code) = False;
751
752   if (jumped) {
753      /* We get here if the client took a fault that caused our signal
754         handler to longjmp. */
755      vg_assert(trc == 0);
756      trc = VG_TRC_FAULT_SIGNAL;
757      block_signals();
758   }
759
760   done_this_time = (Int)dispatch_ctr_SAVED - (Int)VG_(dispatch_ctr) - 0;
761
762   vg_assert(done_this_time >= 0);
763   bbs_done += (ULong)done_this_time;
764
765   // Tell the tool this thread has stopped running client code
766   VG_TRACK( stop_client_code, tid, bbs_done );
767
768   return trc;
769}
770
771
772/* Run a no-redir translation just once, and return the resulting
773   VG_TRC_* value. */
774static UInt run_noredir_translation ( Addr hcode, ThreadId tid )
775{
776   volatile Int          jumped;
777   volatile ThreadState* tst;
778   volatile UWord        argblock[4];
779   volatile UInt         retval;
780
781   /* Paranoia */
782   vg_assert(VG_(is_valid_tid)(tid));
783   vg_assert(VG_(is_running_thread)(tid));
784   vg_assert(!VG_(is_exiting)(tid));
785
786   tst = VG_(get_ThreadState)(tid);
787   do_pre_run_checks( (ThreadState*)tst );
788   /* end Paranoia */
789
790#  if defined(VGA_ppc32) || defined(VGA_ppc64)
791   /* I don't think we need to clear this thread's guest_RESVN here,
792      because we can only get here if run_thread_for_a_while() has
793      been used immediately before, on this same thread. */
794#  endif
795
796   /* There can be 3 outcomes from VG_(run_a_noredir_translation):
797
798      - a signal occurred and the sighandler longjmp'd.  Then both [2]
799        and [3] are unchanged - hence zero.
800
801      - translation ran normally, set [2] (next guest IP) and set [3]
802        to whatever [1] was beforehand, indicating a normal (boring)
803        jump to the next block.
804
805      - translation ran normally, set [2] (next guest IP) and set [3]
806        to something different from [1] beforehand, which indicates a
807        TRC_ value.
808   */
809   argblock[0] = (UWord)hcode;
810   argblock[1] = (UWord)&VG_(threads)[tid].arch.vex;
811   argblock[2] = 0; /* next guest IP is written here */
812   argblock[3] = 0; /* guest state ptr afterwards is written here */
813
814   // Tell the tool this thread is about to run client code
815   VG_TRACK( start_client_code, tid, bbs_done );
816
817   vg_assert(VG_(in_generated_code) == False);
818   VG_(in_generated_code) = True;
819
820   SCHEDSETJMP(
821      tid,
822      jumped,
823      VG_(run_a_noredir_translation)( &argblock[0] )
824   );
825
826   VG_(in_generated_code) = False;
827
828   if (jumped) {
829      /* We get here if the client took a fault that caused our signal
830         handler to longjmp. */
831      vg_assert(argblock[2] == 0); /* next guest IP was not written */
832      vg_assert(argblock[3] == 0); /* trc was not written */
833      block_signals();
834      retval = VG_TRC_FAULT_SIGNAL;
835   } else {
836      /* store away the guest program counter */
837      VG_(set_IP)( tid, argblock[2] );
838      if (argblock[3] == argblock[1])
839         /* the guest state pointer afterwards was unchanged */
840         retval = VG_TRC_BORING;
841      else
842         retval = (UInt)argblock[3];
843   }
844
845   bbs_done++;
846
847   // Tell the tool this thread has stopped running client code
848   VG_TRACK( stop_client_code, tid, bbs_done );
849
850   return retval;
851}
852
853
854/* ---------------------------------------------------------------------
855   The scheduler proper.
856   ------------------------------------------------------------------ */
857
858static void handle_tt_miss ( ThreadId tid )
859{
860   Bool found;
861   Addr ip = VG_(get_IP)(tid);
862
863   /* Trivial event.  Miss in the fast-cache.  Do a full
864      lookup for it. */
865   found = VG_(search_transtab)( NULL, ip, True/*upd_fast_cache*/ );
866   if (UNLIKELY(!found)) {
867      /* Not found; we need to request a translation. */
868      if (VG_(translate)( tid, ip, /*debug*/False, 0/*not verbose*/,
869                          bbs_done, True/*allow redirection*/ )) {
870	 found = VG_(search_transtab)( NULL, ip, True );
871         vg_assert2(found, "VG_TRC_INNER_FASTMISS: missing tt_fast entry");
872
873      } else {
874	 // If VG_(translate)() fails, it's because it had to throw a
875	 // signal because the client jumped to a bad address.  That
876	 // means that either a signal has been set up for delivery,
877	 // or the thread has been marked for termination.  Either
878	 // way, we just need to go back into the scheduler loop.
879      }
880   }
881}
882
883static void handle_syscall(ThreadId tid, UInt trc)
884{
885   ThreadState * volatile tst = VG_(get_ThreadState)(tid);
886   Bool jumped;
887
888   /* Syscall may or may not block; either way, it will be
889      complete by the time this call returns, and we'll be
890      runnable again.  We could take a signal while the
891      syscall runs. */
892
893   if (VG_(clo_sanity_level >= 3))
894      VG_(am_do_sync_check)("(BEFORE SYSCALL)",__FILE__,__LINE__);
895
896   SCHEDSETJMP(tid, jumped, VG_(client_syscall)(tid, trc));
897
898   if (VG_(clo_sanity_level >= 3))
899      VG_(am_do_sync_check)("(AFTER SYSCALL)",__FILE__,__LINE__);
900
901   if (!VG_(is_running_thread)(tid))
902      VG_(printf)("tid %d not running; VG_(running_tid)=%d, tid %d status %d\n",
903		  tid, VG_(running_tid), tid, tst->status);
904   vg_assert(VG_(is_running_thread)(tid));
905
906   if (jumped) {
907      block_signals();
908      VG_(poll_signals)(tid);
909   }
910}
911
912/* tid just requested a jump to the noredir version of its current
913   program counter.  So make up that translation if needed, run it,
914   and return the resulting thread return code. */
915static UInt/*trc*/ handle_noredir_jump ( ThreadId tid )
916{
917   AddrH hcode = 0;
918   Addr  ip    = VG_(get_IP)(tid);
919
920   Bool  found = VG_(search_unredir_transtab)( &hcode, ip );
921   if (!found) {
922      /* Not found; we need to request a translation. */
923      if (VG_(translate)( tid, ip, /*debug*/False, 0/*not verbose*/, bbs_done,
924                          False/*NO REDIRECTION*/ )) {
925
926         found = VG_(search_unredir_transtab)( &hcode, ip );
927         vg_assert2(found, "unredir translation missing after creation?!");
928
929      } else {
930	 // If VG_(translate)() fails, it's because it had to throw a
931	 // signal because the client jumped to a bad address.  That
932	 // means that either a signal has been set up for delivery,
933	 // or the thread has been marked for termination.  Either
934	 // way, we just need to go back into the scheduler loop.
935         return VG_TRC_BORING;
936      }
937
938   }
939
940   vg_assert(found);
941   vg_assert(hcode != 0);
942
943   /* Otherwise run it and return the resulting VG_TRC_* value. */
944   return run_noredir_translation( hcode, tid );
945}
946
947
948/*
949   Run a thread until it wants to exit.
950
951   We assume that the caller has already called VG_(acquire_BigLock) for
952   us, so we own the VCPU.  Also, all signals are blocked.
953 */
954VgSchedReturnCode VG_(scheduler) ( ThreadId tid )
955{
956   UInt     trc;
957   ThreadState *tst = VG_(get_ThreadState)(tid);
958
959   if (VG_(clo_trace_sched))
960      print_sched_event(tid, "entering VG_(scheduler)");
961
962   /* set the proper running signal mask */
963   block_signals();
964
965   vg_assert(VG_(is_running_thread)(tid));
966
967   VG_(dispatch_ctr) = SCHEDULING_QUANTUM + 1;
968
969   while (!VG_(is_exiting)(tid)) {
970
971      if (VG_(dispatch_ctr) == 1) {
972
973#        if defined(VGP_ppc32_aix5) || defined(VGP_ppc64_aix5)
974         /* Note: count runnable threads before dropping The Lock. */
975         Int rt = VG_(count_runnable_threads)();
976#        endif
977
978	 /* Our slice is done, so yield the CPU to another thread.  On
979            Linux, this doesn't sleep between sleeping and running,
980            since that would take too much time.  On AIX, we have to
981            prod the scheduler to get it consider other threads; not
982            doing so appears to cause very long delays before other
983            runnable threads get rescheduled. */
984
985	 /* 4 July 06: it seems that a zero-length nsleep is needed to
986            cause async thread cancellation (canceller.c) to terminate
987            in finite time; else it is in some kind of race/starvation
988            situation and completion is arbitrarily delayed (although
989            this is not a deadlock).
990
991            Unfortunately these sleeps cause MPI jobs not to terminate
992            sometimes (some kind of livelock).  So sleeping once
993            every N opportunities appears to work. */
994
995	 /* 3 Aug 06: doing sys__nsleep works but crashes some apps.
996            sys_yield also helps the problem, whilst not crashing apps. */
997
998	 VG_(release_BigLock)(tid, VgTs_Yielding,
999                                   "VG_(scheduler):timeslice");
1000	 /* ------------ now we don't have The Lock ------------ */
1001
1002#        if defined(VGP_ppc32_aix5) || defined(VGP_ppc64_aix5)
1003         { static Int ctr=0;
1004           vg_assert(__NR_AIX5__nsleep != __NR_AIX5_UNKNOWN);
1005           vg_assert(__NR_AIX5_yield   != __NR_AIX5_UNKNOWN);
1006           if (1 && rt > 0 && ((++ctr % 3) == 0)) {
1007              //struct vki_timespec ts;
1008              //ts.tv_sec = 0;
1009              //ts.tv_nsec = 0*1000*1000;
1010              //VG_(do_syscall2)(__NR_AIX5__nsleep, (UWord)&ts, (UWord)NULL);
1011	      VG_(do_syscall0)(__NR_AIX5_yield);
1012           }
1013         }
1014#        endif
1015
1016         VG_(do_syscall0)(__NR_sched_yield);
1017
1018	 VG_(acquire_BigLock)(tid, "VG_(scheduler):timeslice");
1019	 /* ------------ now we do have The Lock ------------ */
1020
1021	 /* OK, do some relatively expensive housekeeping stuff */
1022	 scheduler_sanity(tid);
1023	 VG_(sanity_check_general)(False);
1024
1025	 /* Look for any pending signals for this thread, and set them up
1026	    for delivery */
1027	 VG_(poll_signals)(tid);
1028
1029	 if (VG_(is_exiting)(tid))
1030	    break;		/* poll_signals picked up a fatal signal */
1031
1032	 /* For stats purposes only. */
1033	 n_scheduling_events_MAJOR++;
1034
1035	 /* Figure out how many bbs to ask vg_run_innerloop to do.  Note
1036	    that it decrements the counter before testing it for zero, so
1037	    that if tst->dispatch_ctr is set to N you get at most N-1
1038	    iterations.  Also this means that tst->dispatch_ctr must
1039	    exceed zero before entering the innerloop.  Also also, the
1040	    decrement is done before the bb is actually run, so you
1041	    always get at least one decrement even if nothing happens. */
1042         VG_(dispatch_ctr) = SCHEDULING_QUANTUM + 1;
1043
1044	 /* paranoia ... */
1045	 vg_assert(tst->tid == tid);
1046	 vg_assert(tst->os_state.lwpid == VG_(gettid)());
1047      }
1048
1049      /* For stats purposes only. */
1050      n_scheduling_events_MINOR++;
1051
1052      if (0)
1053         VG_(message)(Vg_DebugMsg, "thread %d: running for %d bbs\n",
1054                                   tid, VG_(dispatch_ctr) - 1 );
1055
1056      if (trc == VEX_TRC_JMP_YIELD_NOREDIR) {
1057        trc = handle_noredir_jump(tid);
1058      } else {
1059        trc = run_thread_for_a_while ( tid );
1060      }
1061
1062      if (VG_(clo_trace_sched) && VG_(clo_verbosity) > 2) {
1063	 Char buf[50];
1064	 VG_(sprintf)(buf, "TRC: %s", name_of_sched_event(trc));
1065	 print_sched_event(tid, buf);
1066      }
1067
1068      if (trc == VEX_TRC_JMP_NOREDIR) {
1069         /* If we got a request to run a no-redir version of
1070            something, do so now -- handle_noredir_jump just (creates
1071            and) runs that one translation.  The flip side is that the
1072            noredir translation can't itself return another noredir
1073            request -- that would be nonsensical.  It can, however,
1074            return VG_TRC_BORING, which just means keep going as
1075            normal. */
1076         trc = handle_noredir_jump(tid);
1077         vg_assert(trc != VEX_TRC_JMP_NOREDIR);
1078      }
1079
1080      switch (trc) {
1081      case VG_TRC_BORING:
1082         /* no special event, just keep going. */
1083         break;
1084
1085      case VG_TRC_INNER_FASTMISS:
1086	 vg_assert(VG_(dispatch_ctr) > 1);
1087	 handle_tt_miss(tid);
1088	 break;
1089
1090      case VEX_TRC_JMP_CLIENTREQ:
1091	 do_client_request(tid);
1092	 break;
1093
1094      case VEX_TRC_JMP_SYS_INT128:  /* x86-linux */
1095      case VEX_TRC_JMP_SYS_INT129:  /* x86-darwin */
1096      case VEX_TRC_JMP_SYS_INT130:  /* x86-darwin */
1097      case VEX_TRC_JMP_SYS_SYSCALL: /* amd64-linux, ppc32-linux, amd64-darwin */
1098	 handle_syscall(tid, trc);
1099	 if (VG_(clo_sanity_level) > 2)
1100	    VG_(sanity_check_general)(True); /* sanity-check every syscall */
1101	 break;
1102
1103      case VEX_TRC_JMP_YIELD:
1104	 /* Explicit yield, because this thread is in a spin-lock
1105	    or something.  Only let the thread run for a short while
1106            longer.  Because swapping to another thread is expensive,
1107            we're prepared to let this thread eat a little more CPU
1108            before swapping to another.  That means that short term
1109            spins waiting for hardware to poke memory won't cause a
1110            thread swap. */
1111	 if (VG_(dispatch_ctr) > 2000)
1112            VG_(dispatch_ctr) = 2000;
1113	 break;
1114
1115      case VEX_TRC_JMP_YIELD_NOREDIR:
1116         VG_(dispatch_ctr) = 1;
1117         break;
1118
1119      case VG_TRC_INNER_COUNTERZERO:
1120	 /* Timeslice is out.  Let a new thread be scheduled. */
1121	 vg_assert(VG_(dispatch_ctr) == 1);
1122	 break;
1123
1124      case VG_TRC_FAULT_SIGNAL:
1125	 /* Everything should be set up (either we're exiting, or
1126	    about to start in a signal handler). */
1127	 break;
1128
1129      case VEX_TRC_JMP_MAPFAIL:
1130         /* Failure of arch-specific address translation (x86/amd64
1131            segment override use) */
1132         /* jrs 2005 03 11: is this correct? */
1133         VG_(synth_fault)(tid);
1134         break;
1135
1136      case VEX_TRC_JMP_EMWARN: {
1137         static Int  counts[EmWarn_NUMBER];
1138         static Bool counts_initted = False;
1139         VexEmWarn ew;
1140         HChar*    what;
1141         Bool      show;
1142         Int       q;
1143         if (!counts_initted) {
1144            counts_initted = True;
1145            for (q = 0; q < EmWarn_NUMBER; q++)
1146               counts[q] = 0;
1147         }
1148         ew   = (VexEmWarn)VG_(threads)[tid].arch.vex.guest_EMWARN;
1149         what = (ew < 0 || ew >= EmWarn_NUMBER)
1150                   ? "unknown (?!)"
1151                   : LibVEX_EmWarn_string(ew);
1152         show = (ew < 0 || ew >= EmWarn_NUMBER)
1153                   ? True
1154                   : counts[ew]++ < 3;
1155         if (show && VG_(clo_show_emwarns) && !VG_(clo_xml)) {
1156            VG_(message)( Vg_UserMsg,
1157                          "Emulation warning: unsupported action:\n");
1158            VG_(message)( Vg_UserMsg, "  %s\n", what);
1159            VG_(get_and_pp_StackTrace)( tid, VG_(clo_backtrace_size) );
1160         }
1161         break;
1162      }
1163
1164      case VEX_TRC_JMP_EMFAIL: {
1165         VexEmWarn ew;
1166         HChar*    what;
1167         ew   = (VexEmWarn)VG_(threads)[tid].arch.vex.guest_EMWARN;
1168         what = (ew < 0 || ew >= EmWarn_NUMBER)
1169                   ? "unknown (?!)"
1170                   : LibVEX_EmWarn_string(ew);
1171         VG_(message)( Vg_UserMsg,
1172                       "Emulation fatal error -- Valgrind cannot continue:\n");
1173         VG_(message)( Vg_UserMsg, "  %s\n", what);
1174         VG_(get_and_pp_StackTrace)( tid, VG_(clo_backtrace_size) );
1175         VG_(message)(Vg_UserMsg, "\n");
1176         VG_(message)(Vg_UserMsg, "Valgrind has to exit now.  Sorry.\n");
1177         VG_(message)(Vg_UserMsg, "\n");
1178         VG_(exit)(1);
1179         break;
1180      }
1181
1182      case VEX_TRC_JMP_SIGTRAP:
1183         VG_(synth_sigtrap)(tid);
1184         break;
1185
1186      case VEX_TRC_JMP_SIGSEGV:
1187         VG_(synth_fault)(tid);
1188         break;
1189
1190      case VEX_TRC_JMP_SIGBUS:
1191         VG_(synth_sigbus)(tid);
1192         break;
1193
1194      case VEX_TRC_JMP_NODECODE:
1195         VG_(umsg)(
1196            "valgrind: Unrecognised instruction at address %#lx.\n",
1197            VG_(get_IP)(tid));
1198#define M(a) VG_(umsg)(a "\n");
1199   M("Your program just tried to execute an instruction that Valgrind" );
1200   M("did not recognise.  There are two possible reasons for this."    );
1201   M("1. Your program has a bug and erroneously jumped to a non-code"  );
1202   M("   location.  If you are running Memcheck and you just saw a"    );
1203   M("   warning about a bad jump, it's probably your program's fault.");
1204   M("2. The instruction is legitimate but Valgrind doesn't handle it,");
1205   M("   i.e. it's Valgrind's fault.  If you think this is the case or");
1206   M("   you are not sure, please let us know and we'll try to fix it.");
1207   M("Either way, Valgrind will now raise a SIGILL signal which will"  );
1208   M("probably kill your program."                                     );
1209#undef M
1210         VG_(synth_sigill)(tid, VG_(get_IP)(tid));
1211         break;
1212
1213      case VEX_TRC_JMP_TINVAL:
1214         VG_(discard_translations)(
1215            (Addr64)VG_(threads)[tid].arch.vex.guest_TISTART,
1216            VG_(threads)[tid].arch.vex.guest_TILEN,
1217            "scheduler(VEX_TRC_JMP_TINVAL)"
1218         );
1219         if (0)
1220            VG_(printf)("dump translations done.\n");
1221         break;
1222
1223      case VG_TRC_INVARIANT_FAILED:
1224         /* This typically happens if, after running generated code,
1225            it is detected that host CPU settings (eg, FPU/Vector
1226            control words) are not as they should be.  Vex's code
1227            generation specifies the state such control words should
1228            be in on entry to Vex-generated code, and they should be
1229            unchanged on exit from it.  Failure of this assertion
1230            usually means a bug in Vex's code generation. */
1231         //{ UInt xx;
1232         //  __asm__ __volatile__ (
1233         //     "\t.word 0xEEF12A10\n"  // fmrx r2,fpscr
1234         //     "\tmov %0, r2" : "=r"(xx) : : "r2" );
1235         //  VG_(printf)("QQQQ new fpscr = %08x\n", xx);
1236         //}
1237         vg_assert2(0, "VG_(scheduler), phase 3: "
1238                       "run_innerloop detected host "
1239                       "state invariant failure", trc);
1240
1241      case VEX_TRC_JMP_SYS_SYSENTER:
1242         /* Do whatever simulation is appropriate for an x86 sysenter
1243            instruction.  Note that it is critical to set this thread's
1244            guest_EIP to point at the code to execute after the
1245            sysenter, since Vex-generated code will not have set it --
1246            vex does not know what it should be.  Vex sets the next
1247            address to zero, so if you don't set guest_EIP, the thread
1248            will jump to zero afterwards and probably die as a result. */
1249#        if defined(VGP_x86_linux)
1250         vg_assert2(0, "VG_(scheduler), phase 3: "
1251                       "sysenter_x86 on x86-linux is not supported");
1252#        elif defined(VGP_x86_darwin)
1253         /* return address in client edx */
1254         VG_(threads)[tid].arch.vex.guest_EIP
1255            = VG_(threads)[tid].arch.vex.guest_EDX;
1256         handle_syscall(tid, trc);
1257#        else
1258         vg_assert2(0, "VG_(scheduler), phase 3: "
1259                       "sysenter_x86 on non-x86 platform?!?!");
1260#        endif
1261         break;
1262
1263      default:
1264	 vg_assert2(0, "VG_(scheduler), phase 3: "
1265                       "unexpected thread return code (%u)", trc);
1266	 /* NOTREACHED */
1267	 break;
1268
1269      } /* switch (trc) */
1270   }
1271
1272   if (VG_(clo_trace_sched))
1273      print_sched_event(tid, "exiting VG_(scheduler)");
1274
1275   vg_assert(VG_(is_exiting)(tid));
1276
1277   return tst->exitreason;
1278}
1279
1280
1281/*
1282   This causes all threads to forceably exit.  They aren't actually
1283   dead by the time this returns; you need to call
1284   VG_(reap_threads)() to wait for them.
1285 */
1286void VG_(nuke_all_threads_except) ( ThreadId me, VgSchedReturnCode src )
1287{
1288   ThreadId tid;
1289
1290   vg_assert(VG_(is_running_thread)(me));
1291
1292   for (tid = 1; tid < VG_N_THREADS; tid++) {
1293      if (tid == me
1294          || VG_(threads)[tid].status == VgTs_Empty)
1295         continue;
1296      if (0)
1297         VG_(printf)(
1298            "VG_(nuke_all_threads_except): nuking tid %d\n", tid);
1299
1300      VG_(threads)[tid].exitreason = src;
1301      if (src == VgSrc_FatalSig)
1302         VG_(threads)[tid].os_state.fatalsig = VKI_SIGKILL;
1303      VG_(get_thread_out_of_syscall)(tid);
1304   }
1305}
1306
1307
1308/* ---------------------------------------------------------------------
1309   Specifying shadow register values
1310   ------------------------------------------------------------------ */
1311
1312#if defined(VGA_x86)
1313#  define VG_CLREQ_ARGS       guest_EAX
1314#  define VG_CLREQ_RET        guest_EDX
1315#elif defined(VGA_amd64)
1316#  define VG_CLREQ_ARGS       guest_RAX
1317#  define VG_CLREQ_RET        guest_RDX
1318#elif defined(VGA_ppc32) || defined(VGA_ppc64)
1319#  define VG_CLREQ_ARGS       guest_GPR4
1320#  define VG_CLREQ_RET        guest_GPR3
1321#elif defined(VGA_arm)
1322#  define VG_CLREQ_ARGS       guest_R4
1323#  define VG_CLREQ_RET        guest_R3
1324#else
1325#  error Unknown arch
1326#endif
1327
1328#define CLREQ_ARGS(regs)   ((regs).vex.VG_CLREQ_ARGS)
1329#define CLREQ_RET(regs)    ((regs).vex.VG_CLREQ_RET)
1330#define O_CLREQ_RET        (offsetof(VexGuestArchState, VG_CLREQ_RET))
1331
1332// These macros write a value to a client's thread register, and tell the
1333// tool that it's happened (if necessary).
1334
1335#define SET_CLREQ_RETVAL(zztid, zzval) \
1336   do { CLREQ_RET(VG_(threads)[zztid].arch) = (zzval); \
1337        VG_TRACK( post_reg_write, \
1338                  Vg_CoreClientReq, zztid, O_CLREQ_RET, sizeof(UWord)); \
1339   } while (0)
1340
1341#define SET_CLCALL_RETVAL(zztid, zzval, f) \
1342   do { CLREQ_RET(VG_(threads)[zztid].arch) = (zzval); \
1343        VG_TRACK( post_reg_write_clientcall_return, \
1344                  zztid, O_CLREQ_RET, sizeof(UWord), f); \
1345   } while (0)
1346
1347
1348/* ---------------------------------------------------------------------
1349   Handle client requests.
1350   ------------------------------------------------------------------ */
1351
1352// OS-specific(?) client requests
1353static Bool os_client_request(ThreadId tid, UWord *args)
1354{
1355   Bool handled = True;
1356
1357   vg_assert(VG_(is_running_thread)(tid));
1358
1359   switch(args[0]) {
1360   case VG_USERREQ__LIBC_FREERES_DONE:
1361      /* This is equivalent to an exit() syscall, but we don't set the
1362	 exitcode (since it might already be set) */
1363      if (0 || VG_(clo_trace_syscalls) || VG_(clo_trace_sched))
1364         VG_(message)(Vg_DebugMsg,
1365                      "__libc_freeres() done; really quitting!\n");
1366      VG_(threads)[tid].exitreason = VgSrc_ExitThread;
1367      break;
1368
1369   default:
1370      handled = False;
1371      break;
1372   }
1373
1374   return handled;
1375}
1376
1377
1378/* Do a client request for the thread tid.  After the request, tid may
1379   or may not still be runnable; if not, the scheduler will have to
1380   choose a new thread to run.
1381*/
1382static
1383void do_client_request ( ThreadId tid )
1384{
1385   UWord* arg = (UWord*)(CLREQ_ARGS(VG_(threads)[tid].arch));
1386   UWord req_no = arg[0];
1387
1388   if (0)
1389      VG_(printf)("req no = 0x%llx, arg = %p\n", (ULong)req_no, arg);
1390   switch (req_no) {
1391
1392      case VG_USERREQ__CLIENT_CALL0: {
1393         UWord (*f)(ThreadId) = (void*)arg[1];
1394	 if (f == NULL)
1395	    VG_(message)(Vg_DebugMsg, "VG_USERREQ__CLIENT_CALL0: func=%p\n", f);
1396	 else
1397	    SET_CLCALL_RETVAL(tid, f ( tid ), (Addr)f);
1398         break;
1399      }
1400      case VG_USERREQ__CLIENT_CALL1: {
1401         UWord (*f)(ThreadId, UWord) = (void*)arg[1];
1402	 if (f == NULL)
1403	    VG_(message)(Vg_DebugMsg, "VG_USERREQ__CLIENT_CALL1: func=%p\n", f);
1404	 else
1405	    SET_CLCALL_RETVAL(tid, f ( tid, arg[2] ), (Addr)f );
1406         break;
1407      }
1408      case VG_USERREQ__CLIENT_CALL2: {
1409         UWord (*f)(ThreadId, UWord, UWord) = (void*)arg[1];
1410	 if (f == NULL)
1411	    VG_(message)(Vg_DebugMsg, "VG_USERREQ__CLIENT_CALL2: func=%p\n", f);
1412	 else
1413	    SET_CLCALL_RETVAL(tid, f ( tid, arg[2], arg[3] ), (Addr)f );
1414         break;
1415      }
1416      case VG_USERREQ__CLIENT_CALL3: {
1417         UWord (*f)(ThreadId, UWord, UWord, UWord) = (void*)arg[1];
1418	 if (f == NULL)
1419	    VG_(message)(Vg_DebugMsg, "VG_USERREQ__CLIENT_CALL3: func=%p\n", f);
1420	 else
1421	    SET_CLCALL_RETVAL(tid, f ( tid, arg[2], arg[3], arg[4] ), (Addr)f );
1422         break;
1423      }
1424
1425      // Nb: this looks like a circular definition, because it kind of is.
1426      // See comment in valgrind.h to understand what's going on.
1427      case VG_USERREQ__RUNNING_ON_VALGRIND:
1428         SET_CLREQ_RETVAL(tid, RUNNING_ON_VALGRIND+1);
1429         break;
1430
1431      case VG_USERREQ__PRINTF: {
1432         /* JRS 2010-Jan-28: this is DEPRECATED; use the
1433            _VALIST_BY_REF version instead */
1434         if (sizeof(va_list) != sizeof(UWord))
1435            goto va_list_casting_error_NORETURN;
1436         union {
1437            va_list vargs;
1438            unsigned long uw;
1439         } u;
1440         u.uw = (unsigned long)arg[2];
1441         Int count =
1442            VG_(vmessage)( Vg_ClientMsg, (char *)arg[1], u.vargs );
1443         VG_(message_flush)();
1444         SET_CLREQ_RETVAL( tid, count );
1445         break;
1446      }
1447
1448      case VG_USERREQ__PRINTF_BACKTRACE: {
1449         /* JRS 2010-Jan-28: this is DEPRECATED; use the
1450            _VALIST_BY_REF version instead */
1451         if (sizeof(va_list) != sizeof(UWord))
1452            goto va_list_casting_error_NORETURN;
1453         union {
1454            va_list vargs;
1455            unsigned long uw;
1456         } u;
1457         u.uw = (unsigned long)arg[2];
1458         Int count =
1459            VG_(vmessage)( Vg_ClientMsg, (char *)arg[1], u.vargs );
1460         VG_(message_flush)();
1461         VG_(get_and_pp_StackTrace)( tid, VG_(clo_backtrace_size) );
1462         SET_CLREQ_RETVAL( tid, count );
1463         break;
1464      }
1465
1466      case VG_USERREQ__PRINTF_VALIST_BY_REF: {
1467         va_list* vargsp = (va_list*)arg[2];
1468         Int count =
1469            VG_(vmessage)( Vg_ClientMsg, (char *)arg[1], *vargsp );
1470         VG_(message_flush)();
1471         SET_CLREQ_RETVAL( tid, count );
1472         break;
1473      }
1474
1475      case VG_USERREQ__PRINTF_BACKTRACE_VALIST_BY_REF: {
1476         va_list* vargsp = (va_list*)arg[2];
1477         Int count =
1478            VG_(vmessage)( Vg_ClientMsg, (char *)arg[1], *vargsp );
1479         VG_(message_flush)();
1480         VG_(get_and_pp_StackTrace)( tid, VG_(clo_backtrace_size) );
1481         SET_CLREQ_RETVAL( tid, count );
1482         break;
1483      }
1484
1485      case VG_USERREQ__INTERNAL_PRINTF_VALIST_BY_REF: {
1486         va_list* vargsp = (va_list*)arg[2];
1487         Int count =
1488            VG_(vmessage)( Vg_DebugMsg, (char *)arg[1], *vargsp );
1489         VG_(message_flush)();
1490         SET_CLREQ_RETVAL( tid, count );
1491         break;
1492      }
1493
1494      case VG_USERREQ__ADD_IFUNC_TARGET: {
1495         VG_(redir_add_ifunc_target)( arg[1], arg[2] );
1496         SET_CLREQ_RETVAL( tid, 0);
1497         break; }
1498
1499      case VG_USERREQ__STACK_REGISTER: {
1500         UWord sid = VG_(register_stack)((Addr)arg[1], (Addr)arg[2]);
1501         SET_CLREQ_RETVAL( tid, sid );
1502         break; }
1503
1504      case VG_USERREQ__STACK_DEREGISTER: {
1505         VG_(deregister_stack)(arg[1]);
1506         SET_CLREQ_RETVAL( tid, 0 );     /* return value is meaningless */
1507         break; }
1508
1509      case VG_USERREQ__STACK_CHANGE: {
1510         VG_(change_stack)(arg[1], (Addr)arg[2], (Addr)arg[3]);
1511         SET_CLREQ_RETVAL( tid, 0 );     /* return value is meaningless */
1512         break; }
1513
1514      case VG_USERREQ__GET_MALLOCFUNCS: {
1515	 struct vg_mallocfunc_info *info = (struct vg_mallocfunc_info *)arg[1];
1516
1517	 info->tl_malloc               = VG_(tdict).tool_malloc;
1518	 info->tl_calloc               = VG_(tdict).tool_calloc;
1519	 info->tl_realloc              = VG_(tdict).tool_realloc;
1520	 info->tl_memalign             = VG_(tdict).tool_memalign;
1521	 info->tl___builtin_new        = VG_(tdict).tool___builtin_new;
1522	 info->tl___builtin_vec_new    = VG_(tdict).tool___builtin_vec_new;
1523	 info->tl_free                 = VG_(tdict).tool_free;
1524	 info->tl___builtin_delete     = VG_(tdict).tool___builtin_delete;
1525	 info->tl___builtin_vec_delete = VG_(tdict).tool___builtin_vec_delete;
1526         info->tl_malloc_usable_size   = VG_(tdict).tool_malloc_usable_size;
1527
1528	 info->mallinfo                = VG_(mallinfo);
1529	 info->clo_trace_malloc        = VG_(clo_trace_malloc);
1530
1531         SET_CLREQ_RETVAL( tid, 0 );     /* return value is meaningless */
1532
1533	 break;
1534      }
1535
1536      /* Requests from the client program */
1537
1538      case VG_USERREQ__DISCARD_TRANSLATIONS:
1539         if (VG_(clo_verbosity) > 2)
1540            VG_(printf)( "client request: DISCARD_TRANSLATIONS,"
1541                         " addr %p,  len %lu\n",
1542                         (void*)arg[1], arg[2] );
1543
1544         VG_(discard_translations)(
1545            arg[1], arg[2], "scheduler(VG_USERREQ__DISCARD_TRANSLATIONS)"
1546         );
1547
1548         SET_CLREQ_RETVAL( tid, 0 );     /* return value is meaningless */
1549	 break;
1550
1551      case VG_USERREQ__COUNT_ERRORS:
1552         SET_CLREQ_RETVAL( tid, VG_(get_n_errs_found)() );
1553         break;
1554
1555      case VG_USERREQ__LOAD_PDB_DEBUGINFO:
1556         VG_(di_notify_pdb_debuginfo)( arg[1], arg[2], arg[3], arg[4] );
1557         SET_CLREQ_RETVAL( tid, 0 );     /* return value is meaningless */
1558         break;
1559
1560      case VG_USERREQ__MAP_IP_TO_SRCLOC: {
1561         Addr   ip    = arg[1];
1562         UChar* buf64 = (UChar*)arg[2];
1563
1564         VG_(memset)(buf64, 0, 64);
1565         UInt linenum = 0;
1566         Bool ok = VG_(get_filename_linenum)(
1567                      ip, &buf64[0], 50, NULL, 0, NULL, &linenum
1568                   );
1569         if (ok) {
1570            /* Find the terminating zero in the first 50 bytes. */
1571            UInt i;
1572            for (i = 0; i < 50; i++) {
1573               if (buf64[i] == 0)
1574                  break;
1575            }
1576            /* We must find a zero somewhere in 0 .. 49.  Else
1577               VG_(get_filename_linenum) is not properly zero
1578               terminating. */
1579            vg_assert(i < 50);
1580            VG_(sprintf)(&buf64[i], ":%u", linenum);
1581         } else {
1582            buf64[0] = 0;
1583         }
1584
1585         SET_CLREQ_RETVAL( tid, 0 ); /* return value is meaningless */
1586         break;
1587      }
1588
1589      case VG_USERREQ__MALLOCLIKE_BLOCK:
1590      case VG_USERREQ__FREELIKE_BLOCK:
1591         // Ignore them if the addr is NULL;  otherwise pass onto the tool.
1592         if (!arg[1]) {
1593            SET_CLREQ_RETVAL( tid, 0 );     /* return value is meaningless */
1594            break;
1595         } else {
1596            goto my_default;
1597         }
1598
1599      case VG_USERREQ__NACL_MEM_START: {
1600         extern void LoadNaClDebugInfo(Addr a);
1601         VG_(printf)("*********************** NaCl mem_start: %p\n", (void*)arg[1]);
1602         if (arg[1])
1603           LoadNaClDebugInfo(arg[1]);
1604         goto my_default;
1605      }
1606
1607      case VG_USERREQ__NACL_FILE: {
1608         extern char *nacl_file;
1609         VG_(printf)("*********************** NaCl nacl_file: %s\n", (void*)arg[1]);
1610         nacl_file = (char*) arg[1];
1611         goto my_default;
1612      }
1613
1614
1615      default:
1616       my_default:
1617	 if (os_client_request(tid, arg)) {
1618	    // do nothing, os_client_request() handled it
1619         } else if (VG_(needs).client_requests) {
1620	    UWord ret;
1621
1622            if (VG_(clo_verbosity) > 2)
1623               VG_(printf)("client request: code %lx,  addr %p,  len %lu\n",
1624                           arg[0], (void*)arg[1], arg[2] );
1625
1626	    if ( VG_TDICT_CALL(tool_handle_client_request, tid, arg, &ret) )
1627	       SET_CLREQ_RETVAL(tid, ret);
1628         } else {
1629	    static Bool whined = False;
1630
1631	    if (!whined && VG_(clo_verbosity) > 2) {
1632               // Allow for requests in core, but defined by tools, which
1633               // have 0 and 0 in their two high bytes.
1634               Char c1 = (arg[0] >> 24) & 0xff;
1635               Char c2 = (arg[0] >> 16) & 0xff;
1636               if (c1 == 0) c1 = '_';
1637               if (c2 == 0) c2 = '_';
1638	       VG_(message)(Vg_UserMsg, "Warning:\n"
1639                   "  unhandled client request: 0x%lx (%c%c+0x%lx).  Perhaps\n"
1640		   "  VG_(needs).client_requests should be set?\n",
1641			    arg[0], c1, c2, arg[0] & 0xffff);
1642	       whined = True;
1643	    }
1644         }
1645         break;
1646   }
1647   return;
1648
1649   /*NOTREACHED*/
1650  va_list_casting_error_NORETURN:
1651   VG_(umsg)(
1652      "Valgrind: fatal error - cannot continue: use of the deprecated\n"
1653      "client requests VG_USERREQ__PRINTF or VG_USERREQ__PRINTF_BACKTRACE\n"
1654      "on a platform where they cannot be supported.  Please use the\n"
1655      "equivalent _VALIST_BY_REF versions instead.\n"
1656      "\n"
1657      "This is a binary-incompatible change in Valgrind's client request\n"
1658      "mechanism.  It is unfortunate, but difficult to avoid.  End-users\n"
1659      "are expected to almost never see this message.  The only case in\n"
1660      "which you might see this message is if your code uses the macros\n"
1661      "VALGRIND_PRINTF or VALGRIND_PRINTF_BACKTRACE.  If so, you will need\n"
1662      "to recompile such code, using the header files from this version of\n"
1663      "Valgrind, and not any previous version.\n"
1664      "\n"
1665      "If you see this mesage in any other circumstances, it is probably\n"
1666      "a bug in Valgrind.  In this case, please file a bug report at\n"
1667      "\n"
1668      "   http://www.valgrind.org/support/bug_reports.html\n"
1669      "\n"
1670      "Will now abort.\n"
1671   );
1672   vg_assert(0);
1673}
1674
1675
1676/* ---------------------------------------------------------------------
1677   Sanity checking (permanently engaged)
1678   ------------------------------------------------------------------ */
1679
1680/* Internal consistency checks on the sched structures. */
1681static
1682void scheduler_sanity ( ThreadId tid )
1683{
1684   Bool bad = False;
1685   static UInt lasttime = 0;
1686   UInt now;
1687   Int lwpid = VG_(gettid)();
1688
1689   if (!VG_(is_running_thread)(tid)) {
1690      VG_(message)(Vg_DebugMsg,
1691		   "Thread %d is supposed to be running, "
1692                   "but doesn't own the_BigLock (owned by %d)\n",
1693		   tid, VG_(running_tid));
1694      bad = True;
1695   }
1696
1697   if (lwpid != VG_(threads)[tid].os_state.lwpid) {
1698      VG_(message)(Vg_DebugMsg,
1699                   "Thread %d supposed to be in LWP %d, but we're actually %d\n",
1700                   tid, VG_(threads)[tid].os_state.lwpid, VG_(gettid)());
1701      bad = True;
1702   }
1703
1704#if !defined(VGO_darwin)
1705   // GrP fixme
1706   if (lwpid != the_BigLock.owner_lwpid) {
1707      VG_(message)(Vg_DebugMsg,
1708                   "Thread (LWPID) %d doesn't own the_BigLock\n",
1709                   tid);
1710      bad = True;
1711   }
1712#endif
1713
1714   /* Periodically show the state of all threads, for debugging
1715      purposes. */
1716   now = VG_(read_millisecond_timer)();
1717   if (0 && (!bad) && (lasttime + 4000/*ms*/ <= now)) {
1718      lasttime = now;
1719      VG_(printf)("\n------------ Sched State at %d ms ------------\n",
1720                  (Int)now);
1721      VG_(show_sched_status)();
1722   }
1723
1724   /* core_panic also shows the sched status, which is why we don't
1725      show it above if bad==True. */
1726   if (bad)
1727      VG_(core_panic)("scheduler_sanity: failed");
1728}
1729
1730void VG_(sanity_check_general) ( Bool force_expensive )
1731{
1732   ThreadId tid;
1733
1734   static UInt next_slow_check_at = 1;
1735   static UInt slow_check_interval = 25;
1736
1737   if (VG_(clo_sanity_level) < 1) return;
1738
1739   /* --- First do all the tests that we can do quickly. ---*/
1740
1741   sanity_fast_count++;
1742
1743   /* Check stuff pertaining to the memory check system. */
1744
1745   /* Check that nobody has spuriously claimed that the first or
1746      last 16 pages of memory have become accessible [...] */
1747   if (VG_(needs).sanity_checks) {
1748      vg_assert(VG_TDICT_CALL(tool_cheap_sanity_check));
1749   }
1750
1751   /* --- Now some more expensive checks. ---*/
1752
1753   /* Once every now and again, check some more expensive stuff.
1754      Gradually increase the interval between such checks so as not to
1755      burden long-running programs too much. */
1756   if ( force_expensive
1757        || VG_(clo_sanity_level) > 1
1758        || (VG_(clo_sanity_level) == 1
1759            && sanity_fast_count == next_slow_check_at)) {
1760
1761      if (0) VG_(printf)("SLOW at %d\n", sanity_fast_count-1);
1762
1763      next_slow_check_at = sanity_fast_count - 1 + slow_check_interval;
1764      slow_check_interval++;
1765      sanity_slow_count++;
1766
1767      if (VG_(needs).sanity_checks) {
1768          vg_assert(VG_TDICT_CALL(tool_expensive_sanity_check));
1769      }
1770
1771      /* Look for stack overruns.  Visit all threads. */
1772      for (tid = 1; tid < VG_N_THREADS; tid++) {
1773	 SizeT    remains;
1774         VgStack* stack;
1775
1776	 if (VG_(threads)[tid].status == VgTs_Empty ||
1777	     VG_(threads)[tid].status == VgTs_Zombie)
1778	    continue;
1779
1780         stack
1781            = (VgStack*)
1782              VG_(get_ThreadState)(tid)->os_state.valgrind_stack_base;
1783         SizeT limit
1784            = 4096; // Let's say.  Checking more causes lots of L2 misses.
1785	 remains
1786            = VG_(am_get_VgStack_unused_szB)(stack, limit);
1787	 if (remains < limit)
1788	    VG_(message)(Vg_DebugMsg,
1789                         "WARNING: Thread %d is within %ld bytes "
1790                         "of running out of stack!\n",
1791		         tid, remains);
1792      }
1793   }
1794
1795   if (VG_(clo_sanity_level) > 1) {
1796      /* Check sanity of the low-level memory manager.  Note that bugs
1797         in the client's code can cause this to fail, so we don't do
1798         this check unless specially asked for.  And because it's
1799         potentially very expensive. */
1800      VG_(sanity_check_malloc_all)();
1801   }
1802}
1803
1804/*--------------------------------------------------------------------*/
1805/*--- end                                                          ---*/
1806/*--------------------------------------------------------------------*/
1807