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-2013 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             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