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 
     46 /*------------------------------------------------------------*/
     47 /*--- Types                                                ---*/
     48 /*------------------------------------------------------------*/
     49 
     50 /*
     51    Thread state machine:
     52 
     53    Empty -> Init -> Runnable <=> WaitSys/Yielding
     54      ^                 |
     55      \---- Zombie -----/
     56  */
     57 typedef
     58    enum ThreadStatus {
     59       VgTs_Empty,      /* this slot is not in use */
     60       VgTs_Init,       /* just allocated */
     61       VgTs_Runnable,   /* ready to run */
     62       VgTs_WaitSys,    /* waiting for a syscall to complete */
     63       VgTs_Yielding,   /* temporarily yielding the CPU */
     64       VgTs_Zombie,     /* transient state just before exiting */
     65    }
     66    ThreadStatus;
     67 
     68 /* Return codes from the scheduler. */
     69 typedef
     70    enum {
     71       VgSrc_None,	 /* not exiting yet */
     72       VgSrc_ExitThread,  /* just this thread is exiting */
     73       VgSrc_ExitProcess, /* this thread is exiting due to another thread
     74                             calling exit() */
     75       VgSrc_FatalSig	 /* Killed by the default action of a fatal
     76 			    signal */
     77    }
     78    VgSchedReturnCode;
     79 
     80 
     81 #if defined(VGA_x86)
     82    typedef VexGuestX86State   VexGuestArchState;
     83 #elif defined(VGA_amd64)
     84    typedef VexGuestAMD64State VexGuestArchState;
     85 #elif defined(VGA_ppc32)
     86    typedef VexGuestPPC32State VexGuestArchState;
     87 #elif defined(VGA_ppc64)
     88    typedef VexGuestPPC64State VexGuestArchState;
     89 #elif defined(VGA_arm)
     90    typedef VexGuestARMState   VexGuestArchState;
     91 #elif defined(VGA_arm64)
     92    typedef VexGuestARM64State VexGuestArchState;
     93 #elif defined(VGA_s390x)
     94    typedef VexGuestS390XState VexGuestArchState;
     95 #elif defined(VGA_mips32)
     96    typedef VexGuestMIPS32State VexGuestArchState;
     97 #elif defined(VGA_mips64)
     98    typedef VexGuestMIPS64State VexGuestArchState;
     99 #else
    100 #  error Unknown architecture
    101 #endif
    102 
    103 /* Forward declarations */
    104 struct SyscallStatus;
    105 struct SyscallArgs;
    106 
    107 /* Architecture-specific thread state */
    108 typedef
    109    struct {
    110       /* --- BEGIN vex-mandated guest state --- */
    111 
    112       /* Note that for code generation reasons, we require that the
    113          guest state area, its two shadows, and the spill area, are
    114          16-aligned and have 16-aligned sizes, and there are no holes
    115          in between.  This is checked by do_pre_run_checks() in
    116          scheduler.c. */
    117 
    118       /* Saved machine context. */
    119       VexGuestArchState vex __attribute__((aligned(16)));
    120 
    121       /* Saved shadow context (2 copies). */
    122       VexGuestArchState vex_shadow1 __attribute__((aligned(16)));
    123       VexGuestArchState vex_shadow2 __attribute__((aligned(16)));
    124 
    125       /* Spill area. */
    126       UChar vex_spill[LibVEX_N_SPILL_BYTES] __attribute__((aligned(16)));
    127 
    128       /* --- END vex-mandated guest state --- */
    129    }
    130    ThreadArchState;
    131 
    132 
    133 /* OS-specific thread state.  IMPORTANT: if you add fields to this,
    134    you _must_ add code to os_state_clear() to initialise those
    135    fields. */
    136 typedef
    137    struct {
    138       /* who we are */
    139       Int lwpid;        // PID of kernel task  (Darwin: Mach thread)
    140       Int threadgroup;  // thread group id
    141 
    142       ThreadId parent;  // parent tid (if any)
    143 
    144       /* runtime details */
    145       Addr valgrind_stack_base;    // Valgrind's stack (VgStack*)
    146       Addr valgrind_stack_init_SP; // starting value for SP
    147 
    148       /* exit details */
    149       Word exitcode; // in the case of exitgroup, set by someone else
    150       Int  fatalsig; // fatal signal
    151 
    152 #     if defined(VGO_darwin)
    153       // Mach trap POST handler as chosen by PRE
    154       void (*post_mach_trap_fn)(ThreadId tid,
    155                                 struct SyscallArgs *, struct SyscallStatus *);
    156 
    157       // This thread's pthread
    158       Addr pthread;
    159 
    160       // Argument passed when thread started
    161       Addr func_arg;
    162 
    163       // Synchronization between child thread and parent thread's POST wrapper
    164       semaphore_t child_go;
    165       semaphore_t child_done;
    166 
    167       // Workqueue re-entry
    168       // (setjmp in PRE(workq_ops), longjmp in wqthread_hijack)
    169       // DDD: JRS fixme: this comment is no longer correct; wq_jmpbuf is
    170       // never used, and there is no such setjmp or longjmp pair.
    171       // I guess we could leave wq_jmpbuf_valid in place though, since
    172       // it does allow for an assertion in ML_(wqthread_continue_NORETURN).
    173       Bool wq_jmpbuf_valid;
    174       //jmp_buf wq_jmpbuf;
    175 
    176       // Values saved from transient Mach RPC messages
    177       Addr remote_port;  // destination for original message
    178       Int msgh_id;       // outgoing message id
    179       union {
    180          struct {
    181             Addr port;
    182          } mach_port;
    183          struct {
    184             Int right;
    185          } mach_port_allocate;
    186          struct {
    187             Addr port;
    188             Int right;
    189             Int delta;
    190          } mach_port_mod_refs;
    191          struct {
    192             Addr task;
    193             Addr name;
    194             Int disposition;
    195          } mach_port_insert_right;
    196          struct {
    197             Addr size;
    198             int flags;
    199          } vm_allocate;
    200          struct {
    201             Addr address;
    202             Addr size;
    203          } vm_deallocate;
    204          struct {
    205             Addr src;
    206             Addr dst;
    207             Addr size;
    208          } vm_copy;
    209          struct {
    210             Addr address;
    211             Addr size;
    212             int set_maximum;
    213             UWord new_protection;
    214          } vm_protect;
    215          struct {
    216             Addr addr;
    217             SizeT size;
    218          } vm_read;
    219          struct {
    220             ULong addr;
    221             ULong size;
    222          } mach_vm_read;
    223          struct {
    224             Addr addr;
    225             SizeT size;
    226             Addr data;
    227          } vm_read_overwrite;
    228          struct {
    229             Addr size;
    230             int copy;
    231             UWord protection;
    232          } vm_map;
    233          struct {
    234             Addr size;
    235          } vm_remap;
    236          struct {
    237             ULong size;
    238             int flags;
    239          } mach_vm_allocate;
    240          struct {
    241             ULong address;
    242             ULong size;
    243          } mach_vm_deallocate;
    244          struct {
    245             ULong address;
    246             ULong size;
    247             int set_maximum;
    248             unsigned int new_protection;
    249          } mach_vm_protect;
    250          struct {
    251             ULong size;
    252             int copy;
    253             UWord protection;
    254          } mach_vm_map;
    255          struct {
    256             Addr thread;
    257             UWord flavor;
    258          } thread_get_state;
    259          struct {
    260             Addr address;
    261          } io_connect_unmap_memory;
    262          struct {
    263             int which_port;
    264          } task_get_special_port;
    265          struct {
    266             char *service_name;
    267          } bootstrap_look_up;
    268          struct {
    269             vki_size_t size;
    270          } WindowServer_29828;
    271          struct {
    272             Int access_rights;
    273          } WindowServer_29831;
    274          struct {
    275             char *path;
    276          } io_registry_entry_from_path;
    277       } mach_args;
    278 #     endif
    279 
    280    }
    281    ThreadOSstate;
    282 
    283 
    284 /* Overall thread state */
    285 typedef struct {
    286    /* ThreadId == 0 (and hence vg_threads[0]) is NEVER USED.
    287       The thread identity is simply the index in vg_threads[].
    288       ThreadId == 1 is the root thread and has the special property
    289       that we don't try and allocate or deallocate its stack.  For
    290       convenience of generating error message, we also put the
    291       ThreadId in this tid field, but be aware that it should
    292       ALWAYS == the index in vg_threads[]. */
    293    ThreadId tid;
    294 
    295    /* Current scheduling status. */
    296    ThreadStatus status;
    297 
    298    /* This is set if the thread is in the process of exiting for any
    299       reason.  The precise details of the exit are in the OS-specific
    300       state. */
    301    VgSchedReturnCode exitreason;
    302 
    303    /* Architecture-specific thread state. */
    304    ThreadArchState arch;
    305 
    306    /* This thread's blocked-signals mask.  Semantics is that for a
    307       signal to be delivered to this thread, the signal must not be
    308       blocked by this signal mask.  If more than one thread accepts a
    309       signal, then it will be delivered to one at random.  If all
    310       threads block the signal, it will remain pending until either a
    311       thread unblocks it or someone uses sigwaitsig/sigtimedwait. */
    312    vki_sigset_t sig_mask;
    313 
    314    /* tmp_sig_mask is usually the same as sig_mask, and is kept in
    315       sync whenever sig_mask is changed.  The only time they have
    316       different values is during the execution of a sigsuspend, where
    317       tmp_sig_mask is the temporary mask which sigsuspend installs.
    318       It is only consulted to compute the signal mask applied to a
    319       signal handler. */
    320    vki_sigset_t tmp_sig_mask;
    321 
    322    /* A little signal queue for signals we can't get the kernel to
    323       queue for us.  This is only allocated as needed, since it should
    324       be rare. */
    325    struct SigQueue *sig_queue;
    326 
    327    /* Client stacks.  When a thread slot is freed, we don't deallocate its
    328       stack; we just leave it lying around for the next use of the
    329       slot.  If the next use of the slot requires a larger stack,
    330       only then is the old one deallocated and a new one
    331       allocated.
    332 
    333       For the main thread (threadid == 1), this mechanism doesn't
    334       apply.  We don't know the size of the stack since we didn't
    335       allocate it, and furthermore we never reallocate it. */
    336 
    337    /* The allocated size of this thread's stack */
    338    SizeT client_stack_szB;
    339 
    340    /* Address of the highest legitimate word in this stack.  This is
    341       used for error messages only -- not critical for execution
    342       correctness.  Is is set for all stacks, specifically including
    343       ThreadId == 1 (the main thread). */
    344    Addr client_stack_highest_word;
    345 
    346    /* Alternate signal stack */
    347    vki_stack_t altstack;
    348 
    349    /* OS-specific thread state */
    350    ThreadOSstate os_state;
    351 
    352    /* Error disablement level.  A counter which allows selectively
    353       disabling error reporting in threads.  When zero, reporting is
    354       enabled.  When nonzero, it is disabled.  This is controlled by
    355       the client request 'VG_USERREQ__CHANGE_ERR_DISABLEMENT'.  New
    356       threads are always created with this as zero (errors
    357       enabled). */
    358    UInt err_disablement_level;
    359 
    360    /* Per-thread jmp_buf to resume scheduler after a signal */
    361    Bool               sched_jmpbuf_valid;
    362    VG_MINIMAL_JMP_BUF(sched_jmpbuf);
    363 
    364    /* This thread's name. NULL, if no name. */
    365    HChar *thread_name;
    366 }
    367 ThreadState;
    368 
    369 
    370 /*------------------------------------------------------------*/
    371 /*--- The thread table.                                    ---*/
    372 /*------------------------------------------------------------*/
    373 
    374 /* A statically allocated array of threads.  NOTE: [0] is
    375    never used, to simplify the simulation of initialisers for
    376    LinuxThreads. */
    377 extern ThreadState VG_(threads)[VG_N_THREADS];
    378 
    379 // The running thread.  m_scheduler should be the only other module
    380 // to write to this.
    381 extern ThreadId VG_(running_tid);
    382 
    383 
    384 /*------------------------------------------------------------*/
    385 /*--- Basic operations on the thread table.                ---*/
    386 /*------------------------------------------------------------*/
    387 
    388 /* Initialize the m_threadstate module. */
    389 void VG_(init_Threads)(void);
    390 
    391 // Convert a ThreadStatus to a string.
    392 const HChar* VG_(name_of_ThreadStatus) ( ThreadStatus status );
    393 
    394 // Convert a VgSchedReturnCode to a string.
    395 const HChar* VG_(name_of_VgSchedReturnCode) ( VgSchedReturnCode retcode );
    396 
    397 /* Get the ThreadState for a particular thread */
    398 extern ThreadState *VG_(get_ThreadState) ( ThreadId tid );
    399 
    400 /* Check that tid is in range and denotes a non-Empty thread. */
    401 extern Bool VG_(is_valid_tid) ( ThreadId tid );
    402 
    403 /* Returns true if a thread is currently running (ie, has the CPU lock) */
    404 extern Bool VG_(is_running_thread)(ThreadId tid);
    405 
    406 /* Returns true if the thread is in the process of exiting */
    407 extern Bool VG_(is_exiting)(ThreadId tid);
    408 
    409 /* Return the number of non-dead Threads */
    410 extern Int VG_(count_living_threads)(void);
    411 
    412 /* Return the number of threads in VgTs_Runnable state */
    413 extern Int VG_(count_runnable_threads)(void);
    414 
    415 /* Given an LWP id (ie, real kernel thread id), find the corresponding
    416    ThreadId */
    417 extern ThreadId VG_(lwpid_to_vgtid)(Int lwpid);
    418 
    419 #endif   // __PUB_CORE_THREADSTATE_H
    420 
    421 /*--------------------------------------------------------------------*/
    422 /*--- end                                                          ---*/
    423 /*--------------------------------------------------------------------*/
    424