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 */
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 */
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 */
85struct SyscallStatus;
86struct SyscallArgs;
87
88/* Architecture-specific thread state */
89typedef
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. */
120typedef
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 */
273typedef 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}
355ThreadState;
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. */
365extern ThreadState *VG_(threads);
366
367// The running thread.  m_scheduler should be the only other module
368// to write to this.
369extern ThreadId VG_(running_tid);
370
371
372/*------------------------------------------------------------*/
373/*--- Basic operations on the thread table.                ---*/
374/*------------------------------------------------------------*/
375
376/* Initialize the m_threadstate module. */
377void VG_(init_Threads)(void);
378
379// Convert a ThreadStatus to a string.
380const HChar* VG_(name_of_ThreadStatus) ( ThreadStatus status );
381
382// Convert a VgSchedReturnCode to a string.
383const HChar* VG_(name_of_VgSchedReturnCode) ( VgSchedReturnCode retcode );
384
385/* Get the ThreadState for a particular thread */
386extern ThreadState *VG_(get_ThreadState) ( ThreadId tid );
387
388/* Check that tid is in range and denotes a non-Empty thread. */
389extern Bool VG_(is_valid_tid) ( ThreadId tid );
390
391/* Returns true if a thread is currently running (ie, has the CPU lock) */
392extern Bool VG_(is_running_thread)(ThreadId tid);
393
394/* Returns true if the thread is in the process of exiting */
395extern Bool VG_(is_exiting)(ThreadId tid);
396
397/* Return the number of non-dead Threads */
398extern Int VG_(count_living_threads)(void);
399
400/* Return the number of threads in VgTs_Runnable state */
401extern Int VG_(count_runnable_threads)(void);
402
403/* Given an LWP id (ie, real kernel thread id), find the corresponding
404   ThreadId */
405extern ThreadId VG_(lwpid_to_vgtid)(Int lwpid);
406
407#endif   // __PUB_CORE_THREADSTATE_H
408
409/*--------------------------------------------------------------------*/
410/*--- end                                                          ---*/
411/*--------------------------------------------------------------------*/
412