1 /* 2 This file is part of drd, a thread error detector. 3 4 Copyright (C) 2006-2015 Bart Van Assche <bvanassche (at) acm.org>. 5 6 This program is free software; you can redistribute it and/or 7 modify it under the terms of the GNU General Public License as 8 published by the Free Software Foundation; either version 2 of the 9 License, or (at your option) any later version. 10 11 This program is distributed in the hope that it will be useful, but 12 WITHOUT ANY WARRANTY; without even the implied warranty of 13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 General Public License for more details. 15 16 You should have received a copy of the GNU General Public License 17 along with this program; if not, write to the Free Software 18 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 19 02111-1307, USA. 20 21 The GNU General Public License is contained in the file COPYING. 22 */ 23 24 25 #ifndef __THREAD_H 26 #define __THREAD_H 27 28 29 /* Include directives. */ 30 31 #include "drd_basics.h" 32 #include "drd_segment.h" 33 #include "pub_drd_bitmap.h" 34 #include "pub_tool_libcassert.h" /* tl_assert() */ 35 #include "pub_tool_stacktrace.h" /* typedef StackTrace */ 36 #include "pub_tool_threadstate.h" /* VG_N_THREADS */ 37 38 39 /* Defines. */ 40 41 /** Maximum number of threads DRD keeps information about. */ 42 #define DRD_N_THREADS VG_N_THREADS 43 44 /** A number different from any valid DRD thread ID. */ 45 #define DRD_INVALID_THREADID 0 46 47 /** 48 * A number different from any valid POSIX thread ID. 49 * 50 * @note The PThreadId typedef and the INVALID_POSIX_THREADID depend on the 51 * operating system and threading library in use. PThreadId must contain at 52 * least as many bits as pthread_t, and INVALID_POSIX_THREADID 53 * must be a value that will never be returned by pthread_self(). 54 */ 55 #define INVALID_POSIX_THREADID ((PThreadId)0) 56 57 58 /* Type definitions. */ 59 60 /** 61 * POSIX thread ID. The type PThreadId must be at least as wide as 62 * pthread_t. 63 */ 64 typedef UWord PThreadId; 65 66 /** Per-thread information managed by DRD. */ 67 typedef struct 68 { 69 struct segment* sg_first;/**< Segment list. */ 70 struct segment* sg_last; 71 ThreadId vg_threadid; /**< Valgrind thread ID. */ 72 PThreadId pt_threadid; /**< POSIX thread ID. */ 73 Addr stack_min_min; /**< Lowest value stack pointer ever had. */ 74 Addr stack_min; /**< Current stack pointer. */ 75 Addr stack_startup; /**<Stack pointer after pthread_create() finished.*/ 76 Addr stack_max; /**< Top of stack. */ 77 SizeT stack_size; /**< Maximum size of stack. */ 78 HChar name[64]; /**< User-assigned thread name. */ 79 Bool on_alt_stack; 80 /** Whether this structure contains valid information. */ 81 Bool valid; 82 /** Indicates whether the Valgrind core knows about this thread. */ 83 Bool vg_thread_exists; 84 /** Indicates whether there is an associated POSIX thread ID. */ 85 Bool posix_thread_exists; 86 /** 87 * If true, indicates that there is a corresponding POSIX thread ID and 88 * a corresponding OS thread that is detached. 89 */ 90 Bool detached_posix_thread; 91 /** Wether recording of memory load accesses is currently enabled. */ 92 Bool is_recording_loads; 93 /** Wether recording of memory load accesses is currently enabled. */ 94 Bool is_recording_stores; 95 /** pthread_create() nesting level. */ 96 Int pthread_create_nesting_level; 97 /** Nesting level of synchronization functions called by the client. */ 98 Int synchr_nesting; 99 /** Delayed thread deletion sequence number. */ 100 unsigned deletion_seq; 101 /** 102 * ID of the creator thread. It can be safely accessed only until the 103 * thread is fully created. Then the creator thread lives its own life again. 104 */ 105 DrdThreadId creator_thread; 106 107 #if defined(VGO_solaris) 108 Int bind_guard_flag; /**< Bind flag from the runtime linker. */ 109 #endif /* VGO_solaris */ 110 } ThreadInfo; 111 112 113 /* 114 * Local variables of drd_thread.c that are declared here such that these 115 * can be accessed by inline functions. 116 */ 117 118 /** 119 * DRD thread ID of the currently running thread. It is crucial for correct 120 * operation of DRD that this number is always in sync with 121 * VG_(get_running_tid)(). 122 */ 123 extern DrdThreadId DRD_(g_drd_running_tid); 124 /** Per-thread information managed by DRD. */ 125 extern ThreadInfo* DRD_(g_threadinfo); 126 /** Conflict set for the currently running thread. */ 127 extern struct bitmap* DRD_(g_conflict_set); 128 extern Bool DRD_(verify_conflict_set); 129 /** Whether activities during thread creation should be ignored. */ 130 extern Bool DRD_(ignore_thread_creation); 131 132 133 /* Function declarations. */ 134 135 void DRD_(thread_trace_context_switches)(const Bool t); 136 void DRD_(thread_trace_conflict_set)(const Bool t); 137 void DRD_(thread_trace_conflict_set_bm)(const Bool t); 138 Bool DRD_(thread_get_trace_fork_join)(void); 139 void DRD_(thread_set_trace_fork_join)(const Bool t); 140 void DRD_(thread_set_segment_merging)(const Bool m); 141 int DRD_(thread_get_segment_merge_interval)(void); 142 void DRD_(thread_set_segment_merge_interval)(const int i); 143 void DRD_(thread_set_join_list_vol)(const int jlv); 144 145 void DRD_(thread_init)(void); 146 DrdThreadId DRD_(VgThreadIdToDrdThreadId)(const ThreadId tid); 147 DrdThreadId DRD_(NewVgThreadIdToDrdThreadId)(const ThreadId tid); 148 DrdThreadId DRD_(PtThreadIdToDrdThreadId)(const PThreadId tid); 149 ThreadId DRD_(DrdThreadIdToVgThreadId)(const DrdThreadId tid); 150 DrdThreadId DRD_(thread_pre_create)(const DrdThreadId creator, 151 const ThreadId vg_created); 152 DrdThreadId DRD_(thread_post_create)(const ThreadId vg_created); 153 void DRD_(thread_post_join)(DrdThreadId drd_joiner, DrdThreadId drd_joinee); 154 void DRD_(thread_delete)(const DrdThreadId tid, Bool detached); 155 void DRD_(thread_finished)(const DrdThreadId tid); 156 void DRD_(drd_thread_atfork_child)(const DrdThreadId tid); 157 void DRD_(thread_pre_cancel)(const DrdThreadId tid); 158 void DRD_(thread_set_stack_startup)(const DrdThreadId tid, 159 const Addr stack_startup); 160 Addr DRD_(thread_get_stack_min)(const DrdThreadId tid); 161 Addr DRD_(thread_get_stack_min_min)(const DrdThreadId tid); 162 Addr DRD_(thread_get_stack_max)(const DrdThreadId tid); 163 SizeT DRD_(thread_get_stack_size)(const DrdThreadId tid); 164 Bool DRD_(thread_get_on_alt_stack)(const DrdThreadId tid); 165 void DRD_(thread_set_on_alt_stack)(const DrdThreadId tid, 166 const Bool on_alt_stack); 167 Int DRD_(thread_get_threads_on_alt_stack)(void); 168 void DRD_(thread_set_pthreadid)(const DrdThreadId tid, const PThreadId ptid); 169 Bool DRD_(thread_get_joinable)(const DrdThreadId tid); 170 void DRD_(thread_set_joinable)(const DrdThreadId tid, const Bool joinable); 171 void DRD_(thread_entering_pthread_create)(const DrdThreadId tid); 172 void DRD_(thread_left_pthread_create)(const DrdThreadId tid); 173 #if defined(VGO_solaris) 174 void DRD_(thread_entering_rtld_bind_guard)(const DrdThreadId tid, int flags); 175 void DRD_(thread_leaving_rtld_bind_clear)(const DrdThreadId tid, int flags); 176 #endif /* VGO_solaris */ 177 const HChar* DRD_(thread_get_name)(const DrdThreadId tid); 178 void DRD_(thread_set_name)(const DrdThreadId tid, const HChar* const name); 179 void DRD_(thread_set_vg_running_tid)(const ThreadId vg_tid); 180 void DRD_(thread_set_running_tid)(const ThreadId vg_tid, 181 const DrdThreadId drd_tid); 182 int DRD_(thread_enter_synchr)(const DrdThreadId tid); 183 int DRD_(thread_leave_synchr)(const DrdThreadId tid); 184 int DRD_(thread_get_synchr_nesting_count)(const DrdThreadId tid); 185 void DRD_(thread_new_segment)(const DrdThreadId tid); 186 VectorClock* DRD_(thread_get_vc)(const DrdThreadId tid); 187 void DRD_(thread_get_latest_segment)(Segment** sg, const DrdThreadId tid); 188 void DRD_(thread_combine_vc_join)(const DrdThreadId joiner, 189 const DrdThreadId joinee); 190 void DRD_(thread_new_segment_and_combine_vc)(DrdThreadId tid, 191 const Segment* sg); 192 void DRD_(thread_update_conflict_set)(const DrdThreadId tid, 193 const VectorClock* const old_vc); 194 195 void DRD_(thread_stop_using_mem)(const Addr a1, const Addr a2); 196 void DRD_(thread_set_record_loads)(const DrdThreadId tid, const Bool enabled); 197 void DRD_(thread_set_record_stores)(const DrdThreadId tid, const Bool enabled); 198 void DRD_(thread_print_all)(void); 199 void DRD_(thread_report_races)(const DrdThreadId tid); 200 void DRD_(thread_report_races_segment)(const DrdThreadId tid, 201 const Segment* const p); 202 void DRD_(thread_report_all_races)(void); 203 void DRD_(thread_report_conflicting_segments)(const DrdThreadId tid, 204 const Addr addr, 205 const SizeT size, 206 const BmAccessTypeT access_type); 207 ULong DRD_(thread_get_context_switch_count)(void); 208 ULong DRD_(thread_get_report_races_count)(void); 209 ULong DRD_(thread_get_discard_ordered_segments_count)(void); 210 ULong DRD_(thread_get_compute_conflict_set_count)(void); 211 ULong DRD_(thread_get_update_conflict_set_count)(void); 212 ULong DRD_(thread_get_update_conflict_set_new_sg_count)(void); 213 ULong DRD_(thread_get_update_conflict_set_sync_count)(void); 214 ULong DRD_(thread_get_update_conflict_set_join_count)(void); 215 ULong DRD_(thread_get_conflict_set_bitmap_creation_count)(void); 216 ULong DRD_(thread_get_conflict_set_bitmap2_creation_count)(void); 217 218 219 /* Inline function definitions. */ 220 221 /** 222 * Whether or not the specified DRD thread ID is valid. 223 * 224 * A DRD thread ID is valid if and only if the following conditions are met: 225 * - The ID is a valid index of the DRD_(g_threadinfo)[] array. 226 * - The ID is not equal to DRD_INVALID_THREADID. 227 * - The ID refers either to a thread known by the Valgrind core, a joinable 228 * thread that has not yet been joined or a detached thread. 229 */ 230 static __inline__ 231 Bool DRD_(IsValidDrdThreadId)(const DrdThreadId tid) 232 { 233 return (0 <= (int)tid && tid < DRD_N_THREADS && tid != DRD_INVALID_THREADID 234 && (DRD_(g_threadinfo)[tid].valid)); 235 } 236 237 /** Returns the DRD thread ID of the currently running thread. */ 238 static __inline__ 239 DrdThreadId DRD_(thread_get_running_tid)(void) 240 { 241 #ifdef ENABLE_DRD_CONSISTENCY_CHECKS 242 tl_assert(DRD_(g_drd_running_tid) != DRD_INVALID_THREADID); 243 #endif 244 return DRD_(g_drd_running_tid); 245 } 246 247 /** Returns a pointer to the conflict set for the currently running thread. */ 248 static __inline__ 249 struct bitmap* DRD_(thread_get_conflict_set)(void) 250 { 251 return DRD_(g_conflict_set); 252 } 253 254 /** 255 * Reports whether or not the currently running client thread is executing code 256 * inside the pthread_create() function. 257 */ 258 static __inline__ 259 Bool DRD_(running_thread_inside_pthread_create)(void) 260 { 261 return (DRD_(g_threadinfo)[DRD_(g_drd_running_tid)] 262 .pthread_create_nesting_level > 0); 263 } 264 265 /** 266 * Reports whether or not recording of memory loads is enabled for the 267 * currently running client thread. 268 */ 269 static __inline__ 270 Bool DRD_(running_thread_is_recording_loads)(void) 271 { 272 #ifdef ENABLE_DRD_CONSISTENCY_CHECKS 273 tl_assert(0 <= (int)DRD_(g_drd_running_tid) 274 && DRD_(g_drd_running_tid) < DRD_N_THREADS 275 && DRD_(g_drd_running_tid) != DRD_INVALID_THREADID); 276 #endif 277 return (DRD_(g_threadinfo)[DRD_(g_drd_running_tid)].synchr_nesting == 0 278 && DRD_(g_threadinfo)[DRD_(g_drd_running_tid)].is_recording_loads); 279 } 280 281 /** 282 * Reports whether or not recording memory stores is enabled for the 283 * currently running client thread. 284 */ 285 static __inline__ 286 Bool DRD_(running_thread_is_recording_stores)(void) 287 { 288 #ifdef ENABLE_DRD_CONSISTENCY_CHECKS 289 tl_assert(0 <= (int)DRD_(g_drd_running_tid) 290 && DRD_(g_drd_running_tid) < DRD_N_THREADS 291 && DRD_(g_drd_running_tid) != DRD_INVALID_THREADID); 292 #endif 293 return (DRD_(g_threadinfo)[DRD_(g_drd_running_tid)].synchr_nesting == 0 294 && DRD_(g_threadinfo)[DRD_(g_drd_running_tid)].is_recording_stores); 295 } 296 297 /** 298 * Update the information about the lowest stack address that has ever been 299 * accessed by a thread. 300 */ 301 static __inline__ 302 void DRD_(thread_set_stack_min)(const DrdThreadId tid, const Addr stack_min) 303 { 304 #ifdef ENABLE_DRD_CONSISTENCY_CHECKS 305 tl_assert(0 <= (int)tid 306 && tid < DRD_N_THREADS 307 && tid != DRD_INVALID_THREADID); 308 #endif 309 DRD_(g_threadinfo)[tid].stack_min = stack_min; 310 #ifdef ENABLE_DRD_CONSISTENCY_CHECKS 311 /* This function can be called after the thread has been created but */ 312 /* before drd_post_thread_create() has filled in stack_max. */ 313 tl_assert(DRD_(g_threadinfo)[tid].stack_min 314 <= DRD_(g_threadinfo)[tid].stack_max 315 || DRD_(g_threadinfo)[tid].stack_max == 0); 316 #endif 317 if (UNLIKELY(stack_min < DRD_(g_threadinfo)[tid].stack_min_min)) 318 { 319 DRD_(g_threadinfo)[tid].stack_min_min = stack_min; 320 } 321 } 322 323 /** 324 * Return true if and only if the specified address is on the stack of the 325 * currently scheduled thread. 326 */ 327 static __inline__ 328 Bool DRD_(thread_address_on_stack)(const Addr a) 329 { 330 return (DRD_(g_threadinfo)[DRD_(g_drd_running_tid)].stack_min <= a 331 && a < DRD_(g_threadinfo)[DRD_(g_drd_running_tid)].stack_max); 332 } 333 334 /** 335 * Return true if and only if the specified address is on the stack of any 336 * thread. 337 */ 338 static __inline__ 339 Bool DRD_(thread_address_on_any_stack)(const Addr a) 340 { 341 UInt i; 342 343 for (i = 1; i < DRD_N_THREADS; i++) 344 { 345 if (DRD_(g_threadinfo)[i].vg_thread_exists 346 && DRD_(g_threadinfo)[i].stack_min <= a 347 && a < DRD_(g_threadinfo)[i].stack_max) 348 { 349 return True; 350 } 351 } 352 return False; 353 } 354 355 /** Return a pointer to the latest segment for the specified thread. */ 356 static __inline__ 357 Segment* DRD_(thread_get_segment)(const DrdThreadId tid) 358 { 359 #ifdef ENABLE_DRD_CONSISTENCY_CHECKS 360 tl_assert(0 <= (int)tid && tid < DRD_N_THREADS 361 && tid != DRD_INVALID_THREADID); 362 tl_assert(DRD_(g_threadinfo)[tid].sg_last); 363 #endif 364 return DRD_(g_threadinfo)[tid].sg_last; 365 } 366 367 /** Return a pointer to the latest segment for the running thread. */ 368 static __inline__ 369 Segment* DRD_(running_thread_get_segment)(void) 370 { 371 return DRD_(thread_get_segment)(DRD_(g_drd_running_tid)); 372 } 373 374 #endif /* __THREAD_H */ 375