• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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-2015 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             int which;
255          } host_get_special_port;
256          struct {
257             char *service_name;
258          } bootstrap_look_up;
259          struct {
260             vki_size_t size;
261          } WindowServer_29828;
262          struct {
263             Int access_rights;
264          } WindowServer_29831;
265          struct {
266             char *path;
267          } io_registry_entry_from_path;
268       } mach_args;
269 
270 #     elif defined(VGO_solaris)
271 #     if defined(VGP_x86_solaris)
272       /* A pointer to thread related data. The pointer is used to set up
273          a segment descriptor (GDT[VKI_GDT_LWPGS]) when the thread is about to
274          be run. A client program sets this value explicitly by calling the
275          lwp_private syscall or it can be passed as a part of ucontext_t when
276          a new thread is created (the lwp_create syscall). */
277       Addr thrptr;
278 #     elif defined(VGP_amd64_solaris)
279       /* GDT is not fully simulated by AMD64/Solaris. The %fs segment
280          register is assumed to be always zero and vex->guest_FS_CONST holds
281          the 64-bit offset associated with a %fs value of zero. */
282 #     endif
283 
284       /* Stack id (value (UWord)(-1) means that there is no stack). This
285          tracks a stack that is set in restore_stack(). */
286       UWord stk_id;
287 
288       /* Simulation of the kernel's lwp->lwp_ustack. Set in the PRE wrapper
289          of the getsetcontext syscall, for SETUSTACK. Used in
290          VG_(save_context)(), VG_(restore_context)() and
291          VG_(sigframe_create)(). */
292       vki_stack_t *ustack;
293 
294       /* Flag saying if the current call is in the door_return() variant of
295          the door() syscall. */
296       Bool in_door_return;
297 
298       /* Address of the door server procedure corresponding to the current
299          thread. Used to keep track which door call the current thread
300          services. Valid only between subsequent door_return() invocations. */
301       Addr door_return_procedure;
302 
303       /* Simulation of the kernel's lwp->lwp_oldcontext. Set in
304          VG_(restore_context)() and VG_(sigframe_create)(). Used in
305          VG_(save_context)(). */
306       vki_ucontext_t *oldcontext;
307 
308       /* Address of sc_shared_t struct shared between kernel and libc.
309          Set in POST(sys_schedctl). Every thread gets its own address
310          but typically many are squeezed on a singled mapped page.
311          Cleaned in the child atfork handler. */
312       Addr schedctl_data;
313 
314       /* True if this is daemon thread. */
315       Bool daemon_thread;
316 #     endif
317 
318    }
319    ThreadOSstate;
320 
321 
322 /* Overall thread state */
323 typedef struct {
324    /* ThreadId == 0 (and hence vg_threads[0]) is NEVER USED.
325       The thread identity is simply the index in vg_threads[].
326       ThreadId == 1 is the root thread and has the special property
327       that we don't try and allocate or deallocate its stack.  For
328       convenience of generating error message, we also put the
329       ThreadId in this tid field, but be aware that it should
330       ALWAYS == the index in vg_threads[]. */
331    ThreadId tid;
332 
333    /* Current scheduling status. */
334    ThreadStatus status;
335 
336    /* This is set if the thread is in the process of exiting for any
337       reason.  The precise details of the exit are in the OS-specific
338       state. */
339    VgSchedReturnCode exitreason;
340 
341    /* Architecture-specific thread state. */
342    ThreadArchState arch;
343 
344    /* This thread's blocked-signals mask.  Semantics is that for a
345       signal to be delivered to this thread, the signal must not be
346       blocked by this signal mask.  If more than one thread accepts a
347       signal, then it will be delivered to one at random.  If all
348       threads block the signal, it will remain pending until either a
349       thread unblocks it or someone uses sigwaitsig/sigtimedwait. */
350    vki_sigset_t sig_mask;
351 
352    /* tmp_sig_mask is usually the same as sig_mask, and is kept in
353       sync whenever sig_mask is changed.  The only time they have
354       different values is during the execution of a sigsuspend, where
355       tmp_sig_mask is the temporary mask which sigsuspend installs.
356       It is only consulted to compute the signal mask applied to a
357       signal handler. */
358    vki_sigset_t tmp_sig_mask;
359 
360    /* A little signal queue for signals we can't get the kernel to
361       queue for us.  This is only allocated as needed, since it should
362       be rare. */
363    struct SigQueue *sig_queue;
364 
365    /* Client stacks.  When a thread slot is freed, we don't deallocate its
366       stack; we just leave it lying around for the next use of the
367       slot.  If the next use of the slot requires a larger stack,
368       only then is the old one deallocated and a new one
369       allocated.
370 
371       For the main thread (threadid == 1), this mechanism doesn't
372       apply.  We don't know the size of the stack since we didn't
373       allocate it, and furthermore we never reallocate it. */
374 
375    /* The allocated size of this thread's stack */
376    SizeT client_stack_szB;
377 
378    /* Address of the highest legitimate byte in this stack.  This is
379       used for error messages only -- not critical for execution
380       correctness.  Is is set for all stacks, specifically including
381       ThreadId == 1 (the main thread). */
382    Addr client_stack_highest_byte;
383 
384    /* Alternate signal stack */
385    vki_stack_t altstack;
386 
387    /* OS-specific thread state */
388    ThreadOSstate os_state;
389 
390    /* Error disablement level.  A counter which allows selectively
391       disabling error reporting in threads.  When zero, reporting is
392       enabled.  When nonzero, it is disabled.  This is controlled by
393       the client request 'VG_USERREQ__CHANGE_ERR_DISABLEMENT'.  New
394       threads are always created with this as zero (errors
395       enabled). */
396    UInt err_disablement_level;
397 
398    /* Per-thread jmp_buf to resume scheduler after a signal */
399    Bool               sched_jmpbuf_valid;
400    VG_MINIMAL_JMP_BUF(sched_jmpbuf);
401 
402    /* This thread's name. NULL, if no name. */
403    HChar *thread_name;
404 }
405 ThreadState;
406 
407 
408 /*------------------------------------------------------------*/
409 /*--- The thread table.                                    ---*/
410 /*------------------------------------------------------------*/
411 
412 /* A statically allocated array of threads.  NOTE: [0] is
413    never used, to simplify the simulation of initialisers for
414    LinuxThreads. */
415 extern ThreadState *VG_(threads);
416 
417 // The running thread.  m_scheduler should be the only other module
418 // to write to this.
419 extern ThreadId VG_(running_tid);
420 
421 
422 /*------------------------------------------------------------*/
423 /*--- Basic operations on the thread table.                ---*/
424 /*------------------------------------------------------------*/
425 
426 /* Initialize the m_threadstate module. */
427 void VG_(init_Threads)(void);
428 
429 // Convert a ThreadStatus to a string.
430 const HChar* VG_(name_of_ThreadStatus) ( ThreadStatus status );
431 
432 // Convert a VgSchedReturnCode to a string.
433 const HChar* VG_(name_of_VgSchedReturnCode) ( VgSchedReturnCode retcode );
434 
435 /* Get the ThreadState for a particular thread */
436 extern ThreadState *VG_(get_ThreadState) ( ThreadId tid );
437 
438 /* Check that tid is in range and denotes a non-Empty thread. */
439 extern Bool VG_(is_valid_tid) ( ThreadId tid );
440 
441 /* Returns true if a thread is currently running (ie, has the CPU lock) */
442 extern Bool VG_(is_running_thread)(ThreadId tid);
443 
444 /* Returns true if the thread is in the process of exiting */
445 extern Bool VG_(is_exiting)(ThreadId tid);
446 
447 /* Return the number of non-dead Threads */
448 extern Int VG_(count_living_threads)(void);
449 
450 /* Return the number of threads in VgTs_Runnable state */
451 extern Int VG_(count_runnable_threads)(void);
452 
453 /* Given an LWP id (ie, real kernel thread id), find the corresponding
454    ThreadId */
455 extern ThreadId VG_(lwpid_to_vgtid)(Int lwpid);
456 
457 #endif   // __PUB_CORE_THREADSTATE_H
458 
459 /*--------------------------------------------------------------------*/
460 /*--- end                                                          ---*/
461 /*--------------------------------------------------------------------*/
462