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