blob: 19a998246c2c933c21ec3887189016021d2dbc24 [file] [log] [blame]
njnc7561b92005-06-19 01:24:32 +00001
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
Elliott Hughesed398002017-06-21 14:41:24 -070010 Copyright (C) 2000-2017 Julian Seward
njnc7561b92005-06-19 01:24:32 +000011 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"
florianc91f5842013-09-15 10:42:26 +000043#include "pub_core_libcsetjmp.h" // VG_MINIMAL_JMP_BUF
florian535fb1b2013-09-15 13:54:34 +000044#include "pub_core_vki.h" // vki_sigset_t
florian5b5ca272015-04-18 17:41:31 +000045#include "pub_core_guest.h" // VexGuestArchState
floriande6ffbd2014-10-06 16:41:14 +000046#include "libvex.h" // LibVEX_N_SPILL_BYTES
47
njnc7561b92005-06-19 01:24:32 +000048
49/*------------------------------------------------------------*/
50/*--- Types ---*/
51/*------------------------------------------------------------*/
52
53/*
54 Thread state machine:
55
56 Empty -> Init -> Runnable <=> WaitSys/Yielding
57 ^ |
58 \---- Zombie -----/
59 */
60typedef
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. */
72typedef
73 enum {
74 VgSrc_None, /* not exiting yet */
sewardjd8a725e2006-10-17 02:01:12 +000075 VgSrc_ExitThread, /* just this thread is exiting */
philippeb8ba0312013-10-21 19:57:08 +000076 VgSrc_ExitProcess, /* this thread is exiting due to another thread
77 calling exit() */
njnc7561b92005-06-19 01:24:32 +000078 VgSrc_FatalSig /* Killed by the default action of a fatal
79 signal */
80 }
81 VgSchedReturnCode;
82
83
njnf76d27a2009-05-28 01:53:07 +000084/* Forward declarations */
85struct SyscallStatus;
86struct SyscallArgs;
njnc7561b92005-06-19 01:24:32 +000087
sewardja4068de2006-04-05 23:06:31 +000088/* Architecture-specific thread state */
njnc7561b92005-06-19 01:24:32 +000089typedef
90 struct {
91 /* --- BEGIN vex-mandated guest state --- */
92
sewardj7cf4e6b2008-05-01 20:24:26 +000093 /* Note that for code generation reasons, we require that the
94 guest state area, its two shadows, and the spill area, are
florian5fdb28c2015-02-13 17:05:57 +000095 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. */
njnc7561b92005-06-19 01:24:32 +000098
sewardj7cf4e6b2008-05-01 20:24:26 +000099 /* Saved machine context. */
florian51854532015-02-13 16:26:44 +0000100 VexGuestArchState vex __attribute__((aligned(LibVEX_GUEST_STATE_ALIGN)));
sewardj7cf4e6b2008-05-01 20:24:26 +0000101
102 /* Saved shadow context (2 copies). */
florian51854532015-02-13 16:26:44 +0000103 VexGuestArchState vex_shadow1
104 __attribute__((aligned(LibVEX_GUEST_STATE_ALIGN)));
105 VexGuestArchState vex_shadow2
106 __attribute__((aligned(LibVEX_GUEST_STATE_ALIGN)));
njnc7561b92005-06-19 01:24:32 +0000107
108 /* Spill area. */
florian51854532015-02-13 16:26:44 +0000109 UChar vex_spill[LibVEX_N_SPILL_BYTES]
110 __attribute__((aligned(LibVEX_GUEST_STATE_ALIGN)));
njnc7561b92005-06-19 01:24:32 +0000111
112 /* --- END vex-mandated guest state --- */
113 }
114 ThreadArchState;
115
sewardja4068de2006-04-05 23:06:31 +0000116
Elliott Hughesed398002017-06-21 14:41:24 -0700117#define NULL_STK_ID (~(UWord)0)
118
njn99778ee2009-05-19 05:01:27 +0000119/* OS-specific thread state. IMPORTANT: if you add fields to this,
120 you _must_ add code to os_state_clear() to initialise those
121 fields. */
sewardja4068de2006-04-05 23:06:31 +0000122typedef
123 struct {
124 /* who we are */
njnf76d27a2009-05-28 01:53:07 +0000125 Int lwpid; // PID of kernel task (Darwin: Mach thread)
sewardja4068de2006-04-05 23:06:31 +0000126 Int threadgroup; // thread group id
njnc7561b92005-06-19 01:24:32 +0000127
sewardja4068de2006-04-05 23:06:31 +0000128 ThreadId parent; // parent tid (if any)
njnc7561b92005-06-19 01:24:32 +0000129
sewardja4068de2006-04-05 23:06:31 +0000130 /* runtime details */
131 Addr valgrind_stack_base; // Valgrind's stack (VgStack*)
132 Addr valgrind_stack_init_SP; // starting value for SP
njnc7561b92005-06-19 01:24:32 +0000133
Elliott Hughesed398002017-06-21 14:41:24 -0700134 /* Client stack is registered as stk_id (on linux/darwin, by
135 ML_(guess_and_register_stack)).
136 Stack id NULL_STK_ID means that the user stack is not (yet)
137 registered. */
138 UWord stk_id;
139
sewardja4068de2006-04-05 23:06:31 +0000140 /* exit details */
sewardjd8a725e2006-10-17 02:01:12 +0000141 Word exitcode; // in the case of exitgroup, set by someone else
142 Int fatalsig; // fatal signal
143
njnf76d27a2009-05-28 01:53:07 +0000144# if defined(VGO_darwin)
145 // Mach trap POST handler as chosen by PRE
146 void (*post_mach_trap_fn)(ThreadId tid,
147 struct SyscallArgs *, struct SyscallStatus *);
148
149 // This thread's pthread
150 Addr pthread;
151
152 // Argument passed when thread started
153 Addr func_arg;
154
155 // Synchronization between child thread and parent thread's POST wrapper
156 semaphore_t child_go;
157 semaphore_t child_done;
158
159 // Workqueue re-entry
160 // (setjmp in PRE(workq_ops), longjmp in wqthread_hijack)
161 // DDD: JRS fixme: this comment is no longer correct; wq_jmpbuf is
162 // never used, and there is no such setjmp or longjmp pair.
163 // I guess we could leave wq_jmpbuf_valid in place though, since
164 // it does allow for an assertion in ML_(wqthread_continue_NORETURN).
165 Bool wq_jmpbuf_valid;
166 //jmp_buf wq_jmpbuf;
167
168 // Values saved from transient Mach RPC messages
169 Addr remote_port; // destination for original message
170 Int msgh_id; // outgoing message id
171 union {
172 struct {
173 Addr port;
174 } mach_port;
175 struct {
176 Int right;
177 } mach_port_allocate;
178 struct {
179 Addr port;
180 Int right;
181 Int delta;
182 } mach_port_mod_refs;
183 struct {
184 Addr task;
185 Addr name;
186 Int disposition;
187 } mach_port_insert_right;
188 struct {
189 Addr size;
190 int flags;
191 } vm_allocate;
192 struct {
193 Addr address;
194 Addr size;
195 } vm_deallocate;
196 struct {
197 Addr src;
198 Addr dst;
199 Addr size;
200 } vm_copy;
201 struct {
202 Addr address;
203 Addr size;
204 int set_maximum;
205 UWord new_protection;
206 } vm_protect;
207 struct {
208 Addr addr;
209 SizeT size;
210 } vm_read;
211 struct {
212 ULong addr;
213 ULong size;
214 } mach_vm_read;
215 struct {
216 Addr addr;
217 SizeT size;
218 Addr data;
219 } vm_read_overwrite;
220 struct {
221 Addr size;
222 int copy;
223 UWord protection;
224 } vm_map;
225 struct {
226 Addr size;
227 } vm_remap;
228 struct {
229 ULong size;
230 int flags;
231 } mach_vm_allocate;
232 struct {
233 ULong address;
234 ULong size;
235 } mach_vm_deallocate;
236 struct {
237 ULong address;
238 ULong size;
239 int set_maximum;
240 unsigned int new_protection;
241 } mach_vm_protect;
242 struct {
243 ULong size;
244 int copy;
245 UWord protection;
246 } mach_vm_map;
247 struct {
sewardj5d75d532014-06-20 12:35:00 +0000248 ULong size;
249 int copy;
250 } mach_vm_remap;
251 struct {
njnf76d27a2009-05-28 01:53:07 +0000252 Addr thread;
253 UWord flavor;
254 } thread_get_state;
255 struct {
256 Addr address;
257 } io_connect_unmap_memory;
258 struct {
259 int which_port;
260 } task_get_special_port;
261 struct {
rhyskiddb6d764a2015-05-31 01:58:57 +0000262 int which;
263 } host_get_special_port;
264 struct {
njnf76d27a2009-05-28 01:53:07 +0000265 char *service_name;
266 } bootstrap_look_up;
267 struct {
268 vki_size_t size;
269 } WindowServer_29828;
270 struct {
271 Int access_rights;
272 } WindowServer_29831;
273 struct {
274 char *path;
275 } io_registry_entry_from_path;
276 } mach_args;
sewardj8eb8bab2015-07-21 14:44:28 +0000277
278# elif defined(VGO_solaris)
279# if defined(VGP_x86_solaris)
280 /* A pointer to thread related data. The pointer is used to set up
281 a segment descriptor (GDT[VKI_GDT_LWPGS]) when the thread is about to
282 be run. A client program sets this value explicitly by calling the
283 lwp_private syscall or it can be passed as a part of ucontext_t when
284 a new thread is created (the lwp_create syscall). */
285 Addr thrptr;
286# elif defined(VGP_amd64_solaris)
287 /* GDT is not fully simulated by AMD64/Solaris. The %fs segment
288 register is assumed to be always zero and vex->guest_FS_CONST holds
289 the 64-bit offset associated with a %fs value of zero. */
290# endif
291
sewardj8eb8bab2015-07-21 14:44:28 +0000292 /* Simulation of the kernel's lwp->lwp_ustack. Set in the PRE wrapper
293 of the getsetcontext syscall, for SETUSTACK. Used in
294 VG_(save_context)(), VG_(restore_context)() and
295 VG_(sigframe_create)(). */
296 vki_stack_t *ustack;
297
298 /* Flag saying if the current call is in the door_return() variant of
299 the door() syscall. */
300 Bool in_door_return;
301
302 /* Address of the door server procedure corresponding to the current
303 thread. Used to keep track which door call the current thread
304 services. Valid only between subsequent door_return() invocations. */
305 Addr door_return_procedure;
306
307 /* Simulation of the kernel's lwp->lwp_oldcontext. Set in
308 VG_(restore_context)() and VG_(sigframe_create)(). Used in
309 VG_(save_context)(). */
310 vki_ucontext_t *oldcontext;
311
312 /* Address of sc_shared_t struct shared between kernel and libc.
313 Set in POST(sys_schedctl). Every thread gets its own address
314 but typically many are squeezed on a singled mapped page.
315 Cleaned in the child atfork handler. */
316 Addr schedctl_data;
317
318 /* True if this is daemon thread. */
319 Bool daemon_thread;
njnf76d27a2009-05-28 01:53:07 +0000320# endif
321
sewardja4068de2006-04-05 23:06:31 +0000322 }
323 ThreadOSstate;
njnc7561b92005-06-19 01:24:32 +0000324
325
sewardja4068de2006-04-05 23:06:31 +0000326/* Overall thread state */
njnc7561b92005-06-19 01:24:32 +0000327typedef struct {
328 /* ThreadId == 0 (and hence vg_threads[0]) is NEVER USED.
329 The thread identity is simply the index in vg_threads[].
330 ThreadId == 1 is the root thread and has the special property
331 that we don't try and allocate or deallocate its stack. For
332 convenience of generating error message, we also put the
333 ThreadId in this tid field, but be aware that it should
334 ALWAYS == the index in vg_threads[]. */
335 ThreadId tid;
336
337 /* Current scheduling status. */
338 ThreadStatus status;
339
340 /* This is set if the thread is in the process of exiting for any
341 reason. The precise details of the exit are in the OS-specific
342 state. */
343 VgSchedReturnCode exitreason;
344
345 /* Architecture-specific thread state. */
346 ThreadArchState arch;
347
348 /* This thread's blocked-signals mask. Semantics is that for a
349 signal to be delivered to this thread, the signal must not be
350 blocked by this signal mask. If more than one thread accepts a
351 signal, then it will be delivered to one at random. If all
352 threads block the signal, it will remain pending until either a
353 thread unblocks it or someone uses sigwaitsig/sigtimedwait. */
354 vki_sigset_t sig_mask;
355
356 /* tmp_sig_mask is usually the same as sig_mask, and is kept in
357 sync whenever sig_mask is changed. The only time they have
358 different values is during the execution of a sigsuspend, where
359 tmp_sig_mask is the temporary mask which sigsuspend installs.
360 It is only consulted to compute the signal mask applied to a
Elliott Hughesed398002017-06-21 14:41:24 -0700361 signal handler.
362 PW Nov 2016 : it is not clear if and where this tmp_sig_mask
363 is set when an handler runs "inside" a sigsuspend. */
njnc7561b92005-06-19 01:24:32 +0000364 vki_sigset_t tmp_sig_mask;
365
366 /* A little signal queue for signals we can't get the kernel to
367 queue for us. This is only allocated as needed, since it should
368 be rare. */
369 struct SigQueue *sig_queue;
370
371 /* Client stacks. When a thread slot is freed, we don't deallocate its
372 stack; we just leave it lying around for the next use of the
373 slot. If the next use of the slot requires a larger stack,
374 only then is the old one deallocated and a new one
375 allocated.
376
sewardja4068de2006-04-05 23:06:31 +0000377 For the main thread (threadid == 1), this mechanism doesn't
njnc7561b92005-06-19 01:24:32 +0000378 apply. We don't know the size of the stack since we didn't
379 allocate it, and furthermore we never reallocate it. */
380
bart96a0de32008-03-29 09:25:11 +0000381 /* The allocated size of this thread's stack */
njnc7561b92005-06-19 01:24:32 +0000382 SizeT client_stack_szB;
383
philippe38a74d22014-08-29 22:53:19 +0000384 /* Address of the highest legitimate byte in this stack. This is
njnc7561b92005-06-19 01:24:32 +0000385 used for error messages only -- not critical for execution
386 correctness. Is is set for all stacks, specifically including
sewardja4068de2006-04-05 23:06:31 +0000387 ThreadId == 1 (the main thread). */
philippe38a74d22014-08-29 22:53:19 +0000388 Addr client_stack_highest_byte;
njnc7561b92005-06-19 01:24:32 +0000389
390 /* Alternate signal stack */
391 vki_stack_t altstack;
392
393 /* OS-specific thread state */
sewardja4068de2006-04-05 23:06:31 +0000394 ThreadOSstate os_state;
njnc7561b92005-06-19 01:24:32 +0000395
sewardjdc873c02011-07-24 16:02:33 +0000396 /* Error disablement level. A counter which allows selectively
397 disabling error reporting in threads. When zero, reporting is
398 enabled. When nonzero, it is disabled. This is controlled by
399 the client request 'VG_USERREQ__CHANGE_ERR_DISABLEMENT'. New
400 threads are always created with this as zero (errors
401 enabled). */
402 UInt err_disablement_level;
403
njnc7561b92005-06-19 01:24:32 +0000404 /* Per-thread jmp_buf to resume scheduler after a signal */
sewardj6c591e12011-04-11 16:17:51 +0000405 Bool sched_jmpbuf_valid;
sewardj97d3ebb2011-04-11 18:36:34 +0000406 VG_MINIMAL_JMP_BUF(sched_jmpbuf);
florian49789512013-09-16 17:08:50 +0000407
408 /* This thread's name. NULL, if no name. */
409 HChar *thread_name;
Elliott Hughesed398002017-06-21 14:41:24 -0700410 UInt ptrace;
njnc7561b92005-06-19 01:24:32 +0000411}
412ThreadState;
413
414
415/*------------------------------------------------------------*/
416/*--- The thread table. ---*/
417/*------------------------------------------------------------*/
418
Elliott Hughesed398002017-06-21 14:41:24 -0700419/* An array of threads, dynamically allocated by VG_(init_Threads).
420 NOTE: [0] is never used, to simplify the simulation of initialisers
421 for LinuxThreads. */
florian1e802b62015-02-13 19:08:26 +0000422extern ThreadState *VG_(threads);
njnc7561b92005-06-19 01:24:32 +0000423
Elliott Hughesed398002017-06-21 14:41:24 -0700424/* In an outer valgrind, VG_(inner_threads) stores the address of
425 the inner VG_(threads) array, as reported by the inner using
426 the client request INNER_THREADS. */
427extern ThreadState *VG_(inner_threads);
428
njnc7561b92005-06-19 01:24:32 +0000429// The running thread. m_scheduler should be the only other module
430// to write to this.
431extern ThreadId VG_(running_tid);
432
njnf76d27a2009-05-28 01:53:07 +0000433
njnc7561b92005-06-19 01:24:32 +0000434/*------------------------------------------------------------*/
435/*--- Basic operations on the thread table. ---*/
436/*------------------------------------------------------------*/
437
bart27233e92012-03-08 14:59:25 +0000438/* Initialize the m_threadstate module. */
439void VG_(init_Threads)(void);
440
njnc7561b92005-06-19 01:24:32 +0000441// Convert a ThreadStatus to a string.
442const HChar* VG_(name_of_ThreadStatus) ( ThreadStatus status );
443
philippeb8ba0312013-10-21 19:57:08 +0000444// Convert a VgSchedReturnCode to a string.
445const HChar* VG_(name_of_VgSchedReturnCode) ( VgSchedReturnCode retcode );
446
njnc7561b92005-06-19 01:24:32 +0000447/* Get the ThreadState for a particular thread */
448extern ThreadState *VG_(get_ThreadState) ( ThreadId tid );
449
450/* Check that tid is in range and denotes a non-Empty thread. */
451extern Bool VG_(is_valid_tid) ( ThreadId tid );
452
453/* Returns true if a thread is currently running (ie, has the CPU lock) */
454extern Bool VG_(is_running_thread)(ThreadId tid);
455
456/* Returns true if the thread is in the process of exiting */
457extern Bool VG_(is_exiting)(ThreadId tid);
458
459/* Return the number of non-dead Threads */
460extern Int VG_(count_living_threads)(void);
461
sewardjd8a725e2006-10-17 02:01:12 +0000462/* Return the number of threads in VgTs_Runnable state */
463extern Int VG_(count_runnable_threads)(void);
464
njnc7561b92005-06-19 01:24:32 +0000465/* Given an LWP id (ie, real kernel thread id), find the corresponding
466 ThreadId */
sewardj42781722006-12-17 19:36:06 +0000467extern ThreadId VG_(lwpid_to_vgtid)(Int lwpid);
njnc7561b92005-06-19 01:24:32 +0000468
469#endif // __PUB_CORE_THREADSTATE_H
470
471/*--------------------------------------------------------------------*/
472/*--- end ---*/
473/*--------------------------------------------------------------------*/