Home | History | Annotate | Download | only in coregrind
      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 (at) 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