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