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