1 2 /*--------------------------------------------------------------------*/ 3 /*--- The thread state. pub_core_threadstate.h ---*/ 4 /*--------------------------------------------------------------------*/ 5 6 /* 7 This file is part of Valgrind, a dynamic binary instrumentation 8 framework. 9 10 Copyright (C) 2000-2012 Julian Seward 11 jseward (at) 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 #ifndef __PUB_CORE_THREADSTATE_H 32 #define __PUB_CORE_THREADSTATE_H 33 34 //-------------------------------------------------------------------- 35 // PURPOSE: This module defines the ThreadState type and the 36 // VG_(threads)[] data structure which holds all the important thread 37 // state. It also defines some simple operations on the data structure 38 // that don't require any external help. (m_scheduler does the complex 39 // stuff). 40 //-------------------------------------------------------------------- 41 42 #include "pub_tool_threadstate.h" 43 44 /*------------------------------------------------------------*/ 45 /*--- Types ---*/ 46 /*------------------------------------------------------------*/ 47 48 /* 49 Thread state machine: 50 51 Empty -> Init -> Runnable <=> WaitSys/Yielding 52 ^ | 53 \---- Zombie -----/ 54 */ 55 typedef 56 enum ThreadStatus { 57 VgTs_Empty, /* this slot is not in use */ 58 VgTs_Init, /* just allocated */ 59 VgTs_Runnable, /* ready to run */ 60 VgTs_WaitSys, /* waiting for a syscall to complete */ 61 VgTs_Yielding, /* temporarily yielding the CPU */ 62 VgTs_Zombie, /* transient state just before exiting */ 63 } 64 ThreadStatus; 65 66 /* Return codes from the scheduler. */ 67 typedef 68 enum { 69 VgSrc_None, /* not exiting yet */ 70 VgSrc_ExitThread, /* just this thread is exiting */ 71 VgSrc_ExitProcess, /* entire process is exiting */ 72 VgSrc_FatalSig /* Killed by the default action of a fatal 73 signal */ 74 } 75 VgSchedReturnCode; 76 77 78 #if defined(VGA_x86) 79 typedef VexGuestX86State VexGuestArchState; 80 #elif defined(VGA_amd64) 81 typedef VexGuestAMD64State VexGuestArchState; 82 #elif defined(VGA_ppc32) 83 typedef VexGuestPPC32State VexGuestArchState; 84 #elif defined(VGA_ppc64) 85 typedef VexGuestPPC64State VexGuestArchState; 86 #elif defined(VGA_arm) 87 typedef VexGuestARMState VexGuestArchState; 88 #elif defined(VGA_s390x) 89 typedef VexGuestS390XState VexGuestArchState; 90 #elif defined(VGA_mips32) 91 typedef VexGuestMIPS32State VexGuestArchState; 92 #else 93 # error Unknown architecture 94 #endif 95 96 /* Forward declarations */ 97 struct SyscallStatus; 98 struct SyscallArgs; 99 100 /* Architecture-specific thread state */ 101 typedef 102 struct { 103 /* --- BEGIN vex-mandated guest state --- */ 104 105 /* Note that for code generation reasons, we require that the 106 guest state area, its two shadows, and the spill area, are 107 16-aligned and have 16-aligned sizes, and there are no holes 108 in between. This is checked by do_pre_run_checks() in 109 scheduler.c. */ 110 111 /* Saved machine context. */ 112 VexGuestArchState vex __attribute__((aligned(16))); 113 114 /* Saved shadow context (2 copies). */ 115 VexGuestArchState vex_shadow1 __attribute__((aligned(16))); 116 VexGuestArchState vex_shadow2 __attribute__((aligned(16))); 117 118 /* Spill area. */ 119 UChar vex_spill[LibVEX_N_SPILL_BYTES] __attribute__((aligned(16))); 120 121 /* --- END vex-mandated guest state --- */ 122 } 123 ThreadArchState; 124 125 126 /* OS-specific thread state. IMPORTANT: if you add fields to this, 127 you _must_ add code to os_state_clear() to initialise those 128 fields. */ 129 typedef 130 struct { 131 /* who we are */ 132 Int lwpid; // PID of kernel task (Darwin: Mach thread) 133 Int threadgroup; // thread group id 134 135 ThreadId parent; // parent tid (if any) 136 137 /* runtime details */ 138 Addr valgrind_stack_base; // Valgrind's stack (VgStack*) 139 Addr valgrind_stack_init_SP; // starting value for SP 140 141 /* exit details */ 142 Word exitcode; // in the case of exitgroup, set by someone else 143 Int fatalsig; // fatal signal 144 145 # if defined(VGO_darwin) 146 // Mach trap POST handler as chosen by PRE 147 void (*post_mach_trap_fn)(ThreadId tid, 148 struct SyscallArgs *, struct SyscallStatus *); 149 150 // This thread's pthread 151 Addr pthread; 152 153 // Argument passed when thread started 154 Addr func_arg; 155 156 // Synchronization between child thread and parent thread's POST wrapper 157 semaphore_t child_go; 158 semaphore_t child_done; 159 160 // Workqueue re-entry 161 // (setjmp in PRE(workq_ops), longjmp in wqthread_hijack) 162 // DDD: JRS fixme: this comment is no longer correct; wq_jmpbuf is 163 // never used, and there is no such setjmp or longjmp pair. 164 // I guess we could leave wq_jmpbuf_valid in place though, since 165 // it does allow for an assertion in ML_(wqthread_continue_NORETURN). 166 Bool wq_jmpbuf_valid; 167 //jmp_buf wq_jmpbuf; 168 169 // Values saved from transient Mach RPC messages 170 Addr remote_port; // destination for original message 171 Int msgh_id; // outgoing message id 172 union { 173 struct { 174 Addr port; 175 } mach_port; 176 struct { 177 Int right; 178 } mach_port_allocate; 179 struct { 180 Addr port; 181 Int right; 182 Int delta; 183 } mach_port_mod_refs; 184 struct { 185 Addr task; 186 Addr name; 187 Int disposition; 188 } mach_port_insert_right; 189 struct { 190 Addr size; 191 int flags; 192 } vm_allocate; 193 struct { 194 Addr address; 195 Addr size; 196 } vm_deallocate; 197 struct { 198 Addr src; 199 Addr dst; 200 Addr size; 201 } vm_copy; 202 struct { 203 Addr address; 204 Addr size; 205 int set_maximum; 206 UWord new_protection; 207 } vm_protect; 208 struct { 209 Addr addr; 210 SizeT size; 211 } vm_read; 212 struct { 213 ULong addr; 214 ULong size; 215 } mach_vm_read; 216 struct { 217 Addr addr; 218 SizeT size; 219 Addr data; 220 } vm_read_overwrite; 221 struct { 222 Addr size; 223 int copy; 224 UWord protection; 225 } vm_map; 226 struct { 227 Addr size; 228 } vm_remap; 229 struct { 230 ULong size; 231 int flags; 232 } mach_vm_allocate; 233 struct { 234 ULong address; 235 ULong size; 236 } mach_vm_deallocate; 237 struct { 238 ULong address; 239 ULong size; 240 int set_maximum; 241 unsigned int new_protection; 242 } mach_vm_protect; 243 struct { 244 ULong size; 245 int copy; 246 UWord protection; 247 } mach_vm_map; 248 struct { 249 Addr thread; 250 UWord flavor; 251 } thread_get_state; 252 struct { 253 Addr address; 254 } io_connect_unmap_memory; 255 struct { 256 int which_port; 257 } task_get_special_port; 258 struct { 259 char *service_name; 260 } bootstrap_look_up; 261 struct { 262 vki_size_t size; 263 } WindowServer_29828; 264 struct { 265 Int access_rights; 266 } WindowServer_29831; 267 struct { 268 char *path; 269 } io_registry_entry_from_path; 270 } mach_args; 271 # endif 272 273 } 274 ThreadOSstate; 275 276 277 /* Overall thread state */ 278 typedef struct { 279 /* ThreadId == 0 (and hence vg_threads[0]) is NEVER USED. 280 The thread identity is simply the index in vg_threads[]. 281 ThreadId == 1 is the root thread and has the special property 282 that we don't try and allocate or deallocate its stack. For 283 convenience of generating error message, we also put the 284 ThreadId in this tid field, but be aware that it should 285 ALWAYS == the index in vg_threads[]. */ 286 ThreadId tid; 287 288 /* Current scheduling status. */ 289 ThreadStatus status; 290 291 /* This is set if the thread is in the process of exiting for any 292 reason. The precise details of the exit are in the OS-specific 293 state. */ 294 VgSchedReturnCode exitreason; 295 296 /* Architecture-specific thread state. */ 297 ThreadArchState arch; 298 299 /* This thread's blocked-signals mask. Semantics is that for a 300 signal to be delivered to this thread, the signal must not be 301 blocked by this signal mask. If more than one thread accepts a 302 signal, then it will be delivered to one at random. If all 303 threads block the signal, it will remain pending until either a 304 thread unblocks it or someone uses sigwaitsig/sigtimedwait. */ 305 vki_sigset_t sig_mask; 306 307 /* tmp_sig_mask is usually the same as sig_mask, and is kept in 308 sync whenever sig_mask is changed. The only time they have 309 different values is during the execution of a sigsuspend, where 310 tmp_sig_mask is the temporary mask which sigsuspend installs. 311 It is only consulted to compute the signal mask applied to a 312 signal handler. */ 313 vki_sigset_t tmp_sig_mask; 314 315 /* A little signal queue for signals we can't get the kernel to 316 queue for us. This is only allocated as needed, since it should 317 be rare. */ 318 struct SigQueue *sig_queue; 319 320 /* Client stacks. When a thread slot is freed, we don't deallocate its 321 stack; we just leave it lying around for the next use of the 322 slot. If the next use of the slot requires a larger stack, 323 only then is the old one deallocated and a new one 324 allocated. 325 326 For the main thread (threadid == 1), this mechanism doesn't 327 apply. We don't know the size of the stack since we didn't 328 allocate it, and furthermore we never reallocate it. */ 329 330 /* The allocated size of this thread's stack */ 331 SizeT client_stack_szB; 332 333 /* Address of the highest legitimate word in this stack. This is 334 used for error messages only -- not critical for execution 335 correctness. Is is set for all stacks, specifically including 336 ThreadId == 1 (the main thread). */ 337 Addr client_stack_highest_word; 338 339 /* Alternate signal stack */ 340 vki_stack_t altstack; 341 342 /* OS-specific thread state */ 343 ThreadOSstate os_state; 344 345 /* Error disablement level. A counter which allows selectively 346 disabling error reporting in threads. When zero, reporting is 347 enabled. When nonzero, it is disabled. This is controlled by 348 the client request 'VG_USERREQ__CHANGE_ERR_DISABLEMENT'. New 349 threads are always created with this as zero (errors 350 enabled). */ 351 UInt err_disablement_level; 352 353 /* Per-thread jmp_buf to resume scheduler after a signal */ 354 Bool sched_jmpbuf_valid; 355 VG_MINIMAL_JMP_BUF(sched_jmpbuf); 356 } 357 ThreadState; 358 359 360 /*------------------------------------------------------------*/ 361 /*--- The thread table. ---*/ 362 /*------------------------------------------------------------*/ 363 364 /* A statically allocated array of threads. NOTE: [0] is 365 never used, to simplify the simulation of initialisers for 366 LinuxThreads. */ 367 extern ThreadState VG_(threads)[VG_N_THREADS]; 368 369 // The running thread. m_scheduler should be the only other module 370 // to write to this. 371 extern ThreadId VG_(running_tid); 372 373 374 /*------------------------------------------------------------*/ 375 /*--- Basic operations on the thread table. ---*/ 376 /*------------------------------------------------------------*/ 377 378 /* Initialize the m_threadstate module. */ 379 void VG_(init_Threads)(void); 380 381 // Convert a ThreadStatus to a string. 382 const HChar* VG_(name_of_ThreadStatus) ( ThreadStatus status ); 383 384 /* Get the ThreadState for a particular thread */ 385 extern ThreadState *VG_(get_ThreadState) ( ThreadId tid ); 386 387 /* Check that tid is in range and denotes a non-Empty thread. */ 388 extern Bool VG_(is_valid_tid) ( ThreadId tid ); 389 390 /* Returns true if a thread is currently running (ie, has the CPU lock) */ 391 extern Bool VG_(is_running_thread)(ThreadId tid); 392 393 /* Returns true if the thread is in the process of exiting */ 394 extern Bool VG_(is_exiting)(ThreadId tid); 395 396 /* Return the number of non-dead Threads */ 397 extern Int VG_(count_living_threads)(void); 398 399 /* Return the number of threads in VgTs_Runnable state */ 400 extern Int VG_(count_runnable_threads)(void); 401 402 /* Given an LWP id (ie, real kernel thread id), find the corresponding 403 ThreadId */ 404 extern ThreadId VG_(lwpid_to_vgtid)(Int lwpid); 405 406 #endif // __PUB_CORE_THREADSTATE_H 407 408 /*--------------------------------------------------------------------*/ 409 /*--- end ---*/ 410 /*--------------------------------------------------------------------*/ 411