1ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* 2ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown This file is part of drd, a thread error detector. 3ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 4436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov Copyright (C) 2006-2013 Bart Van Assche <bvanassche@acm.org>. 5ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 6ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown This program is free software; you can redistribute it and/or 7ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown modify it under the terms of the GNU General Public License as 8ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown published by the Free Software Foundation; either version 2 of the 9ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown License, or (at your option) any later version. 10ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 11ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown This program is distributed in the hope that it will be useful, but 12ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown WITHOUT ANY WARRANTY; without even the implied warranty of 13ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown General Public License for more details. 15ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 16ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown You should have received a copy of the GNU General Public License 17ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown along with this program; if not, write to the Free Software 18ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 19ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 02111-1307, USA. 20ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 21ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown The GNU General Public License is contained in the file COPYING. 22ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown*/ 23ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 24ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 25ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#include "drd_barrier.h" 26ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#include "drd_clientobj.h" 27ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#include "drd_clientreq.h" 28ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#include "drd_cond.h" 29ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#include "drd_error.h" 30b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#include "drd_hb.h" 31ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#include "drd_load_store.h" 32ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#include "drd_malloc_wrappers.h" 33ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#include "drd_mutex.h" 34ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#include "drd_rwlock.h" 35ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#include "drd_segment.h" 36ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#include "drd_semaphore.h" 37ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#include "drd_suppression.h" 38ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#include "drd_thread.h" 39ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#include "libvex_guest_offsets.h" 40ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#include "pub_drd_bitmap.h" 41ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#include "pub_tool_vki.h" // Must be included before pub_tool_libcproc 42ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#include "pub_tool_basics.h" 43ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#include "pub_tool_debuginfo.h" // VG_(describe_IP)() 44ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#include "pub_tool_libcassert.h" // tl_assert() 45ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#include "pub_tool_libcbase.h" // VG_(strcmp) 46ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#include "pub_tool_libcprint.h" // VG_(printf) 47ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#include "pub_tool_libcproc.h" 48ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#include "pub_tool_machine.h" 49ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#include "pub_tool_mallocfree.h" // VG_(malloc)(), VG_(free)() 50ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#include "pub_tool_options.h" // command line options 51ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#include "pub_tool_replacemalloc.h" 52ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#include "pub_tool_threadstate.h" // VG_(get_running_tid)() 53ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#include "pub_tool_tooliface.h" 54f673d1bf8bfb172f0eccbe4d3a908b3c65b55b33Kenny Root#include "pub_tool_aspacemgr.h" // VG_(am_is_valid_for_client) 55ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 56ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 57ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* Local variables. */ 58ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 59b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanovstatic Bool s_print_stats; 60b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanovstatic Bool s_var_info; 61b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanovstatic Bool s_show_stack_usage; 62b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanovstatic Bool s_trace_alloc; 63436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanovstatic Bool trace_sectsuppr; 64ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 65ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 66ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/** 67ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown * Implement the needs_command_line_options for drd. 68ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown */ 69436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanovstatic Bool DRD_(process_cmd_line_option)(const HChar* arg) 70ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{ 71ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown int check_stack_accesses = -1; 72b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov int join_list_vol = -1; 73ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown int exclusive_threshold_ms = -1; 74ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown int first_race_only = -1; 75ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown int report_signal_unlocked = -1; 76ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown int segment_merging = -1; 77ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown int segment_merge_interval = -1; 78ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown int shared_threshold_ms = -1; 79ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown int show_confl_seg = -1; 80ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown int trace_barrier = -1; 81ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown int trace_clientobj = -1; 82ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown int trace_cond = -1; 83ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown int trace_csw = -1; 84ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown int trace_fork_join = -1; 85b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov int trace_hb = -1; 86ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown int trace_conflict_set = -1; 87ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown int trace_conflict_set_bm = -1; 88ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown int trace_mutex = -1; 89ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown int trace_rwlock = -1; 90ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown int trace_segment = -1; 91ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown int trace_semaphore = -1; 92ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown int trace_suppression = -1; 93436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov const HChar* trace_address = 0; 94436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov const HChar* ptrace_address= 0; 95ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 96ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if VG_BOOL_CLO(arg, "--check-stack-var", check_stack_accesses) {} 97b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov else if VG_INT_CLO (arg, "--join-list-vol", join_list_vol) {} 98ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown else if VG_BOOL_CLO(arg, "--drd-stats", s_print_stats) {} 99ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown else if VG_BOOL_CLO(arg, "--first-race-only", first_race_only) {} 100b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov else if VG_BOOL_CLO(arg, "--free-is-write", DRD_(g_free_is_write)) {} 101ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown else if VG_BOOL_CLO(arg,"--report-signal-unlocked",report_signal_unlocked) 102ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown {} 103ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown else if VG_BOOL_CLO(arg, "--segment-merging", segment_merging) {} 104ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown else if VG_INT_CLO (arg, "--segment-merging-interval", segment_merge_interval) 105ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown {} 106ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown else if VG_BOOL_CLO(arg, "--show-confl-seg", show_confl_seg) {} 107ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown else if VG_BOOL_CLO(arg, "--show-stack-usage", s_show_stack_usage) {} 108ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown else if VG_BOOL_CLO(arg, "--trace-alloc", s_trace_alloc) {} 109ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown else if VG_BOOL_CLO(arg, "--trace-barrier", trace_barrier) {} 110ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown else if VG_BOOL_CLO(arg, "--trace-clientobj", trace_clientobj) {} 111ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown else if VG_BOOL_CLO(arg, "--trace-cond", trace_cond) {} 112ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown else if VG_BOOL_CLO(arg, "--trace-conflict-set", trace_conflict_set) {} 113ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown else if VG_BOOL_CLO(arg, "--trace-conflict-set-bm", trace_conflict_set_bm){} 114ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown else if VG_BOOL_CLO(arg, "--trace-csw", trace_csw) {} 115ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown else if VG_BOOL_CLO(arg, "--trace-fork-join", trace_fork_join) {} 116b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov else if VG_BOOL_CLO(arg, "--trace-hb", trace_hb) {} 117ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown else if VG_BOOL_CLO(arg, "--trace-mutex", trace_mutex) {} 118ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown else if VG_BOOL_CLO(arg, "--trace-rwlock", trace_rwlock) {} 119436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov else if VG_BOOL_CLO(arg, "--trace-sectsuppr", trace_sectsuppr) {} 120ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown else if VG_BOOL_CLO(arg, "--trace-segment", trace_segment) {} 121ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown else if VG_BOOL_CLO(arg, "--trace-semaphore", trace_semaphore) {} 122ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown else if VG_BOOL_CLO(arg, "--trace-suppr", trace_suppression) {} 123ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown else if VG_BOOL_CLO(arg, "--var-info", s_var_info) {} 124ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown else if VG_INT_CLO (arg, "--exclusive-threshold", exclusive_threshold_ms) {} 125663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng else if VG_STR_CLO (arg, "--ptrace-addr", ptrace_address) {} 126ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown else if VG_INT_CLO (arg, "--shared-threshold", shared_threshold_ms) {} 127ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown else if VG_STR_CLO (arg, "--trace-addr", trace_address) {} 128ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown else 129ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return VG_(replacement_malloc_process_cmd_line_option)(arg); 130ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 131ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (check_stack_accesses != -1) 132ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown DRD_(set_check_stack_accesses)(check_stack_accesses); 133ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (exclusive_threshold_ms != -1) 134ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown { 135ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown DRD_(mutex_set_lock_threshold)(exclusive_threshold_ms); 136ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown DRD_(rwlock_set_exclusive_threshold)(exclusive_threshold_ms); 137ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 138ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (first_race_only != -1) 139ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown { 140ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown DRD_(set_first_race_only)(first_race_only); 141ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 142b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov if (join_list_vol != -1) 143b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov DRD_(thread_set_join_list_vol)(join_list_vol); 144ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (report_signal_unlocked != -1) 145ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown { 146ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown DRD_(cond_set_report_signal_unlocked)(report_signal_unlocked); 147ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 148ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (shared_threshold_ms != -1) 149ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown { 150ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown DRD_(rwlock_set_shared_threshold)(shared_threshold_ms); 151ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 152ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (segment_merging != -1) 153ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown DRD_(thread_set_segment_merging)(segment_merging); 154ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (segment_merge_interval != -1) 155ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown DRD_(thread_set_segment_merge_interval)(segment_merge_interval); 156ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (show_confl_seg != -1) 157ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown DRD_(set_show_conflicting_segments)(show_confl_seg); 158663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng if (trace_address) { 159ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown const Addr addr = VG_(strtoll16)(trace_address, 0); 160663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng DRD_(start_tracing_address_range)(addr, addr + 1, False); 161663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng } 162663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng if (ptrace_address) { 163436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov char *plus = VG_(strchr)(ptrace_address, '+'); 164436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov Addr addr, length; 165436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov if (plus) 166436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov *plus = '\0'; 167436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov addr = VG_(strtoll16)(ptrace_address, 0); 168436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov length = plus ? VG_(strtoll16)(plus + 1, 0) : 1; 169436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov DRD_(start_tracing_address_range)(addr, addr + length, True); 170ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 171ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (trace_barrier != -1) 172ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown DRD_(barrier_set_trace)(trace_barrier); 173ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (trace_clientobj != -1) 174ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown DRD_(clientobj_set_trace)(trace_clientobj); 175ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (trace_cond != -1) 176ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown DRD_(cond_set_trace)(trace_cond); 177ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (trace_csw != -1) 178ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown DRD_(thread_trace_context_switches)(trace_csw); 179ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (trace_fork_join != -1) 180ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown DRD_(thread_set_trace_fork_join)(trace_fork_join); 181b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov if (trace_hb != -1) 182b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov DRD_(hb_set_trace)(trace_hb); 183ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (trace_conflict_set != -1) 184ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown DRD_(thread_trace_conflict_set)(trace_conflict_set); 185ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (trace_conflict_set_bm != -1) 186ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown DRD_(thread_trace_conflict_set_bm)(trace_conflict_set_bm); 187ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (trace_mutex != -1) 188ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown DRD_(mutex_set_trace)(trace_mutex); 189ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (trace_rwlock != -1) 190ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown DRD_(rwlock_set_trace)(trace_rwlock); 191ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (trace_segment != -1) 192ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown DRD_(sg_set_trace)(trace_segment); 193ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (trace_semaphore != -1) 194ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown DRD_(semaphore_set_trace)(trace_semaphore); 195ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (trace_suppression != -1) 196ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown DRD_(suppression_set_trace)(trace_suppression); 197ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 198ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return True; 199ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown} 200ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 201ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic void DRD_(print_usage)(void) 202ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{ 203ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown VG_(printf)( 204ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown" --check-stack-var=yes|no Whether or not to report data races on\n" 205ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown" stack variables [no].\n" 206ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown" --exclusive-threshold=<n> Print an error message if any mutex or\n" 207b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov" writer lock is held longer than the specified\n" 208b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov" time (in milliseconds) [off].\n" 209ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown" --first-race-only=yes|no Only report the first data race that occurs on\n" 210ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown" a memory location instead of all races [no].\n" 211ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown" --free-is-write=yes|no Whether to report races between freeing memory\n" 212ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown" and subsequent accesses of that memory[no].\n" 213b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov" --join-list-vol=<n> Number of threads to delay cleanup for [10].\n" 214ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown" --report-signal-unlocked=yes|no Whether to report calls to\n" 215ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown" pthread_cond_signal() where the mutex associated\n" 216ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown" with the signal via pthread_cond_wait() is not\n" 217ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown" locked at the time the signal is sent [yes].\n" 218ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown" --segment-merging=yes|no Controls segment merging [yes].\n" 219ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown" Segment merging is an algorithm to limit memory usage of the\n" 220ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown" data race detection algorithm. Disabling segment merging may\n" 221ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown" improve the accuracy of the so-called 'other segments' displayed\n" 222ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown" in race reports but can also trigger an out of memory error.\n" 223ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown" --segment-merging-interval=<n> Perform segment merging every time n new\n" 224ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown" segments have been created. Default: %d.\n" 225ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown" --shared-threshold=<n> Print an error message if a reader lock\n" 226b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov" is held longer than the specified time (in\n" 227b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov" milliseconds) [off]\n" 228ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown" --show-confl-seg=yes|no Show conflicting segments in race reports [yes].\n" 229ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown" --show-stack-usage=yes|no Print stack usage at thread exit time [no].\n" 230ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown"\n" 231ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown" drd options for monitoring process behavior:\n" 232436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov" --ptrace-addr=<address>[+<length>] Trace all load and store activity for\n" 233436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov" the specified address range and keep doing that\n" 234436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov" even after the memory at that address has been\n" 235436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov" freed and reallocated [off].\n" 236663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng" --trace-addr=<address> Trace all load and store activity for the\n" 237ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown" specified address [off].\n" 238436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov" --trace-alloc=yes|no Trace all memory allocations and deallocations\n" 239436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov" [no].\n" 240ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown" --trace-barrier=yes|no Trace all barrier activity [no].\n" 241ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown" --trace-cond=yes|no Trace all condition variable activity [no].\n" 242ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown" --trace-fork-join=yes|no Trace all thread fork/join activity [no].\n" 243b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov" --trace-hb=yes|no Trace ANNOTATE_HAPPENS_BEFORE() etc. [no].\n" 244ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown" --trace-mutex=yes|no Trace all mutex activity [no].\n" 245ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown" --trace-rwlock=yes|no Trace all reader-writer lock activity[no].\n" 246ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown" --trace-semaphore=yes|no Trace all semaphore activity [no].\n", 247ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownDRD_(thread_get_segment_merge_interval)() 248ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown); 249ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown} 250ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 251ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic void DRD_(print_debug_usage)(void) 252ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{ 253ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown VG_(printf)( 254ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown" --drd-stats=yes|no Print statistics about DRD activity [no].\n" 255ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown" --trace-clientobj=yes|no Trace all client object activity [no].\n" 256ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown" --trace-csw=yes|no Trace all scheduler context switches [no].\n" 257ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown" --trace-conflict-set=yes|no Trace all conflict set updates [no].\n" 258ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown" --trace-conflict-set-bm=yes|no Trace all conflict set bitmap\n" 259ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown" updates [no]. Note: enabling this option\n" 260ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown" will generate a lot of output !\n" 261436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov" --trace-sectsuppr=yes|no Trace which the dynamic library sections on\n" 262436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov" which data race detection is suppressed.\n" 263ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown" --trace-segment=yes|no Trace segment actions [no].\n" 264ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown" --trace-suppr=yes|no Trace all address suppression actions [no].\n" 265ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown); 266ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown} 267ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 268ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 269ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown// 270ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown// Implements the thread-related core callbacks. 271ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown// 272ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 273ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic void drd_pre_mem_read(const CorePart part, 274ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown const ThreadId tid, 275436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov const HChar* const s, 276ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown const Addr a, 277ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown const SizeT size) 278ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{ 2792ca80a6a6fc069acdb73186e8e578dbf8f46af80Dmitriy Ivanov DRD_(thread_set_vg_running_tid)(VG_(get_running_tid)()); 280ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (size > 0) 281ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown { 282ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown DRD_(trace_load)(a, size); 283ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 284ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown} 285ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 286ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic void drd_pre_mem_read_asciiz(const CorePart part, 287ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown const ThreadId tid, 288436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov const HChar* const s, 289ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown const Addr a) 290ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{ 291436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov const HChar* p = (void*)a; 292ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown SizeT size = 0; 293ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 294f673d1bf8bfb172f0eccbe4d3a908b3c65b55b33Kenny Root // Don't segfault if the string starts in an obviously stupid 295f673d1bf8bfb172f0eccbe4d3a908b3c65b55b33Kenny Root // place. Actually we should check the whole string, not just 296f673d1bf8bfb172f0eccbe4d3a908b3c65b55b33Kenny Root // the start address, but that's too much trouble. At least 297f673d1bf8bfb172f0eccbe4d3a908b3c65b55b33Kenny Root // checking the first byte is better than nothing. See #255009. 298f673d1bf8bfb172f0eccbe4d3a908b3c65b55b33Kenny Root if (!VG_(am_is_valid_for_client) (a, 1, VKI_PROT_READ)) 299f673d1bf8bfb172f0eccbe4d3a908b3c65b55b33Kenny Root return; 300f673d1bf8bfb172f0eccbe4d3a908b3c65b55b33Kenny Root 301ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* Note: the expression '*p' reads client memory and may crash if the */ 302ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* client provided an invalid pointer ! */ 303ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown while (*p) 304ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown { 305ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown p++; 306ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown size++; 307ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 308ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (size > 0) 309ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown { 310ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown DRD_(trace_load)(a, size); 311ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 312ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown} 313ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 314ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic void drd_post_mem_write(const CorePart part, 315ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown const ThreadId tid, 316ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown const Addr a, 317ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown const SizeT size) 318ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{ 319ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown DRD_(thread_set_vg_running_tid)(VG_(get_running_tid)()); 320ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (size > 0) 321ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown { 322ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown DRD_(trace_store)(a, size); 323ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 324ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown} 325ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 326ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic __inline__ 327ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownvoid drd_start_using_mem(const Addr a1, const SizeT len, 328ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown const Bool is_stack_mem) 329ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{ 330b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov const Addr a2 = a1 + len; 331b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 332b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov tl_assert(a1 <= a2); 333ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 334ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (!is_stack_mem && s_trace_alloc) 335b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov DRD_(trace_msg)("Started using memory range 0x%lx + %ld%s", 336b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov a1, len, DRD_(running_thread_inside_pthread_create)() 337b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov ? " (inside pthread_create())" : ""); 338b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 339b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov if (!is_stack_mem && DRD_(g_free_is_write)) 340b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov DRD_(thread_stop_using_mem)(a1, a2); 341ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 342ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (UNLIKELY(DRD_(any_address_is_traced)())) 343ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown { 344663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng DRD_(trace_mem_access)(a1, len, eStart, 0, 0); 345ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 346ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 347ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (UNLIKELY(DRD_(running_thread_inside_pthread_create)())) 348ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown { 349b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov DRD_(start_suppression)(a1, a2, "pthread_create()"); 350ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 351ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown} 352ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 353ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic void drd_start_using_mem_w_ecu(const Addr a1, 354ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown const SizeT len, 355ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown UInt ec_uniq) 356ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{ 357ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown drd_start_using_mem(a1, len, False); 358ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown} 359ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 360ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic void drd_start_using_mem_w_tid(const Addr a1, 361ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown const SizeT len, 362ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ThreadId tid) 363ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{ 364ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown drd_start_using_mem(a1, len, False); 365ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown} 366ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 367ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic __inline__ 368ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownvoid drd_stop_using_mem(const Addr a1, const SizeT len, 369ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown const Bool is_stack_mem) 370ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{ 371ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown const Addr a2 = a1 + len; 372ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 373ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown tl_assert(a1 <= a2); 374ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 375ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (UNLIKELY(DRD_(any_address_is_traced)())) 376663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng DRD_(trace_mem_access)(a1, len, eEnd, 0, 0); 377ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 378ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (!is_stack_mem && s_trace_alloc) 379b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov DRD_(trace_msg)("Stopped using memory range 0x%lx + %ld", 380b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov a1, len); 381ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 382ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (!is_stack_mem || DRD_(get_check_stack_accesses)()) 383ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown { 384b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov if (is_stack_mem || !DRD_(g_free_is_write)) 385b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov DRD_(thread_stop_using_mem)(a1, a2); 386b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov else if (DRD_(g_free_is_write)) 387b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov DRD_(trace_store)(a1, len); 388ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown DRD_(clientobj_stop_using_mem)(a1, a2); 389ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown DRD_(suppression_stop_using_mem)(a1, a2); 390ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 391ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown} 392ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 393ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic __inline__ 394ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownvoid drd_stop_using_nonstack_mem(const Addr a1, const SizeT len) 395ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{ 396ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown drd_stop_using_mem(a1, len, False); 397ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown} 398ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 399ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/** 400ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown * Discard all information DRD has about memory accesses and client objects 401ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown * in the specified address range. 402ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown */ 403ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownvoid DRD_(clean_memory)(const Addr a1, const SizeT len) 404ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{ 405ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown const Bool is_stack_memory = DRD_(thread_address_on_any_stack)(a1); 406ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown drd_stop_using_mem(a1, len, is_stack_memory); 407ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown drd_start_using_mem(a1, len, is_stack_memory); 408ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown} 409ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 410ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/** 411436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov * Suppress data race reports on all addresses contained in .plt, .got and 412ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown * .got.plt sections inside the address range [ a, a + len [. The data in 413ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown * these sections is modified by _dl_relocate_object() every time a function 414ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown * in a shared library is called for the first time. Since the first call 415ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown * to a function in a shared library can happen from a multithreaded context, 416ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown * such calls can cause conflicting accesses. See also Ulrich Drepper's 417ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown * paper "How to Write Shared Libraries" for more information about relocation 418ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown * (http://people.redhat.com/drepper/dsohowto.pdf). 419436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov * Note: the contents of the .got section is only modified by the MIPS resolver. 420ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown */ 421ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic void DRD_(suppress_relocation_conflicts)(const Addr a, const SizeT len) 422ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{ 423ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown const DebugInfo* di; 424ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 425663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng if (trace_sectsuppr) 426663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng VG_(dmsg)("Evaluating range @ 0x%lx size %ld\n", a, len); 427ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 428663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng for (di = VG_(next_DebugInfo)(0); di; di = VG_(next_DebugInfo)(di)) { 429ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Addr avma; 430ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown SizeT size; 431ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 432663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng if (trace_sectsuppr) 433663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng VG_(dmsg)("Examining %s / %s\n", VG_(DebugInfo_get_filename)(di), 434663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng VG_(DebugInfo_get_soname)(di)); 435663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 436436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov /* 437436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov * Suppress the race report on the libpthread global variable 438436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov * __pthread_multiple_threads. See also 439436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov * http://bugs.kde.org/show_bug.cgi?id=323905. 440436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov */ 441436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov avma = VG_(DebugInfo_get_bss_avma)(di); 442436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov size = VG_(DebugInfo_get_bss_size)(di); 443436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov tl_assert((avma && size) || (avma == 0 && size == 0)); 444436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov if (size > 0 && 445436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov VG_(strcmp)(VG_(DebugInfo_get_soname)(di), "libpthread.so.0") == 0) { 446436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov if (trace_sectsuppr) 447436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov VG_(dmsg)("Suppressing .bss @ 0x%lx size %ld\n", avma, size); 448436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov tl_assert(VG_(DebugInfo_sect_kind)(NULL, 0, avma) == Vg_SectBSS); 449436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov DRD_(start_suppression)(avma, avma + size, ".bss"); 450436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov } 451436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov 452ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown avma = VG_(DebugInfo_get_plt_avma)(di); 453ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown size = VG_(DebugInfo_get_plt_size)(di); 454ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown tl_assert((avma && size) || (avma == 0 && size == 0)); 455663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng if (size > 0) { 456663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng if (trace_sectsuppr) 457663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng VG_(dmsg)("Suppressing .plt @ 0x%lx size %ld\n", avma, size); 458ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown tl_assert(VG_(DebugInfo_sect_kind)(NULL, 0, avma) == Vg_SectPLT); 459ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown DRD_(start_suppression)(avma, avma + size, ".plt"); 460ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 461ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 462ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown avma = VG_(DebugInfo_get_gotplt_avma)(di); 463ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown size = VG_(DebugInfo_get_gotplt_size)(di); 464ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown tl_assert((avma && size) || (avma == 0 && size == 0)); 465663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng if (size > 0) { 466663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng if (trace_sectsuppr) 467663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng VG_(dmsg)("Suppressing .got.plt @ 0x%lx size %ld\n", avma, size); 468ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown tl_assert(VG_(DebugInfo_sect_kind)(NULL, 0, avma) == Vg_SectGOTPLT); 469ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown DRD_(start_suppression)(avma, avma + size, ".gotplt"); 470ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 471436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov 472436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov avma = VG_(DebugInfo_get_got_avma)(di); 473436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov size = VG_(DebugInfo_get_got_size)(di); 474436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov tl_assert((avma && size) || (avma == 0 && size == 0)); 475436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov if (size > 0) { 476436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov if (trace_sectsuppr) 477436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov VG_(dmsg)("Suppressing .got @ 0x%lx size %ld\n", avma, size); 478436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov tl_assert(VG_(DebugInfo_sect_kind)(NULL, 0, avma) == Vg_SectGOT); 479436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov DRD_(start_suppression)(avma, avma + size, ".got"); 480436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov } 481ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 482ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown} 483ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 484ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic 485ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownvoid drd_start_using_mem_w_perms(const Addr a, const SizeT len, 486ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown const Bool rr, const Bool ww, const Bool xx, 487ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ULong di_handle) 488ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{ 489ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown DRD_(thread_set_vg_running_tid)(VG_(get_running_tid)()); 490ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 491ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown drd_start_using_mem(a, len, False); 492ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 493ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown DRD_(suppress_relocation_conflicts)(a, len); 494ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown} 495ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 496663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng/** 497663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng * Called by the core when the stack of a thread grows, to indicate that 498663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng * the addresses in range [ a, a + len [ may now be used by the client. 499663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng * Assumption: stacks grow downward. 500663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng */ 501ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic __inline__ 502663860b1408516d02ebfcb3a9999a134e6cfb223Ben Chengvoid drd_start_using_mem_stack2(const DrdThreadId tid, const Addr a, 503663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng const SizeT len) 504ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{ 505663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng DRD_(thread_set_stack_min)(tid, a - VG_STACK_REDZONE_SZB); 506663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng drd_start_using_mem(a - VG_STACK_REDZONE_SZB, len + VG_STACK_REDZONE_SZB, 507ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown True); 508ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown} 509ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 510ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic __inline__ 511663860b1408516d02ebfcb3a9999a134e6cfb223Ben Chengvoid drd_start_using_mem_stack(const Addr a, const SizeT len) 512ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{ 513663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng drd_start_using_mem_stack2(DRD_(thread_get_running_tid)(), a, len); 514663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng} 515663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 516663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng/** 517663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng * Called by the core when the stack of a thread shrinks, to indicate that 518663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng * the addresses [ a, a + len [ are no longer accessible for the client. 519663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng * Assumption: stacks grow downward. 520663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng */ 521663860b1408516d02ebfcb3a9999a134e6cfb223Ben Chengstatic __inline__ 522663860b1408516d02ebfcb3a9999a134e6cfb223Ben Chengvoid drd_stop_using_mem_stack2(const DrdThreadId tid, const Addr a, 523663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng const SizeT len) 524663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng{ 525663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng DRD_(thread_set_stack_min)(tid, a + len - VG_STACK_REDZONE_SZB); 526ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown drd_stop_using_mem(a - VG_STACK_REDZONE_SZB, len + VG_STACK_REDZONE_SZB, 527ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown True); 528ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown} 529ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 530663860b1408516d02ebfcb3a9999a134e6cfb223Ben Chengstatic __inline__ 531663860b1408516d02ebfcb3a9999a134e6cfb223Ben Chengvoid drd_stop_using_mem_stack(const Addr a, const SizeT len) 532663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng{ 533663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng drd_stop_using_mem_stack2(DRD_(thread_get_running_tid)(), a, len); 534663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng} 535663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 536ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic 537ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownBool on_alt_stack(const Addr a) 538ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{ 539ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ThreadId vg_tid; 540ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Addr alt_min; 541ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown SizeT alt_size; 542ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 543ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown vg_tid = VG_(get_running_tid)(); 544ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown alt_min = VG_(thread_get_altstack_min)(vg_tid); 545ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown alt_size = VG_(thread_get_altstack_size)(vg_tid); 546ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return (SizeT)(a - alt_min) < alt_size; 547ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown} 548ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 549ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic 550ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownvoid drd_start_using_mem_alt_stack(const Addr a, const SizeT len) 551ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{ 552ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (!on_alt_stack(a)) 553ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown drd_start_using_mem_stack(a, len); 554ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown} 555ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 556ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic 557ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownvoid drd_stop_using_mem_alt_stack(const Addr a, const SizeT len) 558ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{ 559ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (!on_alt_stack(a)) 560ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown drd_stop_using_mem_stack(a, len); 561ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown} 562ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 563ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/** 564ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown * Callback function invoked by the Valgrind core before a signal is delivered. 565ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown */ 566ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic 567ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownvoid drd_pre_deliver_signal(const ThreadId vg_tid, const Int sigNo, 568ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown const Bool alt_stack) 569ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{ 570ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown DrdThreadId drd_tid; 571ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 572ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown drd_tid = DRD_(VgThreadIdToDrdThreadId)(vg_tid); 573ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown DRD_(thread_set_on_alt_stack)(drd_tid, alt_stack); 574ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (alt_stack) 575ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown { 576ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* 577ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown * As soon a signal handler has been invoked on the alternate stack, 578ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown * switch to stack memory handling functions that can handle the 579ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown * alternate stack. 580ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown */ 581ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown VG_(track_new_mem_stack)(drd_start_using_mem_alt_stack); 582ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown VG_(track_die_mem_stack)(drd_stop_using_mem_alt_stack); 583ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 584ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown} 585ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 586ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/** 587ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown * Callback function invoked by the Valgrind core after a signal is delivered, 588ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown * at least if the signal handler did not longjmp(). 589ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown */ 590ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic 591ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownvoid drd_post_deliver_signal(const ThreadId vg_tid, const Int sigNo) 592ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{ 593ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown DrdThreadId drd_tid; 594ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 595ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown drd_tid = DRD_(VgThreadIdToDrdThreadId)(vg_tid); 596ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown DRD_(thread_set_on_alt_stack)(drd_tid, False); 597ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (DRD_(thread_get_threads_on_alt_stack)() == 0) 598ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown { 599ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown VG_(track_new_mem_stack)(drd_start_using_mem_stack); 600ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown VG_(track_die_mem_stack)(drd_stop_using_mem_stack); 601ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 602ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown} 603ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 604ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/** 605ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown * Callback function called by the Valgrind core before a stack area is 606ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown * being used by a signal handler. 607ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown * 608436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov * @param[in] a Start of address range - VG_STACK_REDZONE_SZB. 609436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov * @param[in] len Address range length + VG_STACK_REDZONE_SZB. 610ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown * @param[in] tid Valgrind thread ID for whom the signal frame is being 611ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown * constructed. 612ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown */ 613ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic void drd_start_using_mem_stack_signal(const Addr a, const SizeT len, 614ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ThreadId tid) 615ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{ 616ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown DRD_(thread_set_vg_running_tid)(VG_(get_running_tid)()); 617436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov drd_start_using_mem(a + VG_STACK_REDZONE_SZB, len - VG_STACK_REDZONE_SZB, 618436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov True); 619ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown} 620ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 621ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic void drd_stop_using_mem_stack_signal(Addr a, SizeT len) 622ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{ 623436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov drd_stop_using_mem(a + VG_STACK_REDZONE_SZB, len - VG_STACK_REDZONE_SZB, 624436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov True); 625ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown} 626ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 627ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic 628ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownvoid drd_pre_thread_create(const ThreadId creator, const ThreadId created) 629ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{ 630ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown const DrdThreadId drd_creator = DRD_(VgThreadIdToDrdThreadId)(creator); 631ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown tl_assert(created != VG_INVALID_THREADID); 632ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown DRD_(thread_pre_create)(drd_creator, created); 633ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (DRD_(IsValidDrdThreadId)(drd_creator)) 634ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown { 635ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown DRD_(thread_new_segment)(drd_creator); 636ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 637ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (DRD_(thread_get_trace_fork_join)()) 638ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown { 639b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov DRD_(trace_msg)("drd_pre_thread_create creator = %d, created = %d", 640b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov drd_creator, created); 641ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 642ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown} 643ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 644663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng/** 645663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng * Called by Valgrind's core before any loads or stores are performed on 646663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng * the context of thread "created". 647663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng */ 648ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic 649ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownvoid drd_post_thread_create(const ThreadId vg_created) 650ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{ 651ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown DrdThreadId drd_created; 652663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng Addr stack_max; 653ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 654ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown tl_assert(vg_created != VG_INVALID_THREADID); 655ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 656ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown drd_created = DRD_(thread_post_create)(vg_created); 657663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 658663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng /* Set up red zone before the code in glibc's clone.S is run. */ 659663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng stack_max = DRD_(thread_get_stack_max)(drd_created); 660663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng drd_start_using_mem_stack2(drd_created, stack_max, 0); 661663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 662ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (DRD_(thread_get_trace_fork_join)()) 663ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown { 664b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov DRD_(trace_msg)("drd_post_thread_create created = %d", drd_created); 665ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 666ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (! DRD_(get_check_stack_accesses)()) 667ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown { 668ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown DRD_(start_suppression)(DRD_(thread_get_stack_max)(drd_created) 669ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown - DRD_(thread_get_stack_size)(drd_created), 670ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown DRD_(thread_get_stack_max)(drd_created), 671ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "stack"); 672ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 673ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown} 674ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 675ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* Called after a thread has performed its last memory access. */ 676ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic void drd_thread_finished(ThreadId vg_tid) 677ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{ 678ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown DrdThreadId drd_tid; 679ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 680663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng /* 681663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng * Ignore if invoked because thread creation failed. See e.g. 682663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng * coregrind/m_syswrap/syswrap-amd64-linux.c 683663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng */ 684663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng if (VG_(get_running_tid)() != vg_tid) 685663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng return; 686ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 687ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown drd_tid = DRD_(VgThreadIdToDrdThreadId)(vg_tid); 688663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng tl_assert(drd_tid != DRD_INVALID_THREADID); 689ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (DRD_(thread_get_trace_fork_join)()) 690ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown { 691b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov DRD_(trace_msg)("drd_thread_finished tid = %d%s", drd_tid, 692b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov DRD_(thread_get_joinable)(drd_tid) 693b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov ? "" : " (which is a detached thread)"); 694ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 695b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov if (s_show_stack_usage && !VG_(clo_xml)) { 696ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown const SizeT stack_size = DRD_(thread_get_stack_size)(drd_tid); 697ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown const SizeT used_stack 698ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown = (DRD_(thread_get_stack_max)(drd_tid) 699ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown - DRD_(thread_get_stack_min_min)(drd_tid)); 700ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown VG_(message)(Vg_UserMsg, 701ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "thread %d%s finished and used %ld bytes out of %ld" 702ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown " on its stack. Margin: %ld bytes.\n", 703ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown drd_tid, 704ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown DRD_(thread_get_joinable)(drd_tid) 705b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov ? "" : " (which is a detached thread)", 706b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov used_stack, stack_size, stack_size - used_stack); 707ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 708ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 709ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown drd_stop_using_mem(DRD_(thread_get_stack_min)(drd_tid), 710ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown DRD_(thread_get_stack_max)(drd_tid) 711ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown - DRD_(thread_get_stack_min)(drd_tid), 712ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown True); 713ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown DRD_(thread_set_record_loads)(drd_tid, False); 714ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown DRD_(thread_set_record_stores)(drd_tid, False); 715ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown DRD_(thread_finished)(drd_tid); 716ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown} 717ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 718f673d1bf8bfb172f0eccbe4d3a908b3c65b55b33Kenny Root/* 719f673d1bf8bfb172f0eccbe4d3a908b3c65b55b33Kenny Root * Called immediately after fork for the child process only. 'tid' is the 720f673d1bf8bfb172f0eccbe4d3a908b3c65b55b33Kenny Root * only surviving thread in the child process. Cleans up thread state. 721f673d1bf8bfb172f0eccbe4d3a908b3c65b55b33Kenny Root * See also http://pubs.opengroup.org/onlinepubs/9699919799/functions/pthread_atfork.html for a detailed discussion of using fork() in combination with mutexes. 722f673d1bf8bfb172f0eccbe4d3a908b3c65b55b33Kenny Root */ 723f673d1bf8bfb172f0eccbe4d3a908b3c65b55b33Kenny Rootstatic 724f673d1bf8bfb172f0eccbe4d3a908b3c65b55b33Kenny Rootvoid drd__atfork_child(ThreadId tid) 725f673d1bf8bfb172f0eccbe4d3a908b3c65b55b33Kenny Root{ 726f673d1bf8bfb172f0eccbe4d3a908b3c65b55b33Kenny Root DRD_(drd_thread_atfork_child)(tid); 727f673d1bf8bfb172f0eccbe4d3a908b3c65b55b33Kenny Root} 728f673d1bf8bfb172f0eccbe4d3a908b3c65b55b33Kenny Root 729f673d1bf8bfb172f0eccbe4d3a908b3c65b55b33Kenny Root 730ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown// 731ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown// Implementation of the tool interface. 732ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown// 733ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 734ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic void DRD_(post_clo_init)(void) 735ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{ 736ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#if defined(VGO_linux) || defined(VGO_darwin) 737ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* fine */ 738ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#else 739ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown VG_(printf)("\nWARNING: DRD has not yet been tested on this operating system.\n\n"); 740ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown# endif 741ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 742ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (s_var_info) 743ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown { 744ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown VG_(needs_var_info)(); 745ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 746ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown} 747ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 748ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic void drd_start_client_code(const ThreadId tid, const ULong bbs_done) 749ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{ 750ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown tl_assert(tid == VG_(get_running_tid)()); 751ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown DRD_(thread_set_vg_running_tid)(tid); 752ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown} 753ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 754ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic void DRD_(fini)(Int exitcode) 755ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{ 756ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown // thread_print_all(); 757ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (VG_(clo_verbosity) == 1 && !VG_(clo_xml)) { 758b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov VG_(message)(Vg_UserMsg, "For counts of detected and suppressed errors, " 759ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "rerun with: -v\n"); 760ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 761ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 762b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov if ((VG_(clo_stats) || s_print_stats) && !VG_(clo_xml)) 763ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown { 764ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ULong pu = DRD_(thread_get_update_conflict_set_count)(); 765ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ULong pu_seg_cr = DRD_(thread_get_update_conflict_set_new_sg_count)(); 766ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ULong pu_mtx_cv = DRD_(thread_get_update_conflict_set_sync_count)(); 767ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ULong pu_join = DRD_(thread_get_update_conflict_set_join_count)(); 768ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 769ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown VG_(message)(Vg_UserMsg, 770ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown " thread: %lld context switches.\n", 771ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown DRD_(thread_get_context_switch_count)()); 772ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown VG_(message)(Vg_UserMsg, 773ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "confl set: %lld full updates and %lld partial updates;\n", 774b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov DRD_(thread_get_compute_conflict_set_count)(), 775b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov pu); 776ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown VG_(message)(Vg_UserMsg, 777ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown " %lld partial updates during segment creation,\n", 778b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov pu_seg_cr); 779ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown VG_(message)(Vg_UserMsg, 780ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown " %lld because of mutex/sema/cond.var. operations,\n", 781b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov pu_mtx_cv); 782ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown VG_(message)(Vg_UserMsg, 783ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown " %lld because of barrier/rwlock operations and\n", 784ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown pu - pu_seg_cr - pu_mtx_cv - pu_join); 785ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown VG_(message)(Vg_UserMsg, 786ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown " %lld partial updates because of thread join" 787b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov " operations.\n", 788b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov pu_join); 789ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown VG_(message)(Vg_UserMsg, 790ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown " segments: created %lld segments, max %lld alive,\n", 791ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown DRD_(sg_get_segments_created_count)(), 792ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown DRD_(sg_get_max_segments_alive_count)()); 793ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown VG_(message)(Vg_UserMsg, 794ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown " %lld discard points and %lld merges.\n", 795ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown DRD_(thread_get_discard_ordered_segments_count)(), 796ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown DRD_(sg_get_segment_merge_count)()); 797ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown VG_(message)(Vg_UserMsg, 798ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "segmnt cr: %lld mutex, %lld rwlock, %lld semaphore and" 799ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown " %lld barrier.\n", 800ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown DRD_(get_mutex_segment_creation_count)(), 801ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown DRD_(get_rwlock_segment_creation_count)(), 802ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown DRD_(get_semaphore_segment_creation_count)(), 803ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown DRD_(get_barrier_segment_creation_count)()); 804ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown VG_(message)(Vg_UserMsg, 805ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown " bitmaps: %lld level one" 806ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown " and %lld level two bitmaps were allocated.\n", 807ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown DRD_(bm_get_bitmap_creation_count)(), 808ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown DRD_(bm_get_bitmap2_creation_count)()); 809ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown VG_(message)(Vg_UserMsg, 810ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown " mutex: %lld non-recursive lock/unlock events.\n", 811ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown DRD_(get_mutex_lock_count)()); 812ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown DRD_(print_malloc_stats)(); 813ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 814663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 815663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng DRD_(bm_module_cleanup)(); 816ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown} 817ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 818ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic 819ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownvoid drd_pre_clo_init(void) 820ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{ 821ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown // Basic tool stuff. 822ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown VG_(details_name) ("drd"); 823ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown VG_(details_version) (NULL); 824ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown VG_(details_description) ("a thread error detector"); 825436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov VG_(details_copyright_author)("Copyright (C) 2006-2013, and GNU GPL'd," 826ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown " by Bart Van Assche."); 827ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown VG_(details_bug_reports_to) (VG_BUGS_TO); 828ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 829ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown VG_(basic_tool_funcs) (DRD_(post_clo_init), 830ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown DRD_(instrument), 831ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown DRD_(fini)); 832ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 833ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown // Command line stuff. 834ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown VG_(needs_command_line_options)(DRD_(process_cmd_line_option), 835ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown DRD_(print_usage), 836ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown DRD_(print_debug_usage)); 837b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov VG_(needs_xml_output) (); 838ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 839ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown // Error handling. 840ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown DRD_(register_error_handlers)(); 841ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 842ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown // Core event tracking. 843ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown VG_(track_pre_mem_read) (drd_pre_mem_read); 844ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown VG_(track_pre_mem_read_asciiz) (drd_pre_mem_read_asciiz); 845ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown VG_(track_post_mem_write) (drd_post_mem_write); 846ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown VG_(track_new_mem_brk) (drd_start_using_mem_w_tid); 847ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown VG_(track_new_mem_mmap) (drd_start_using_mem_w_perms); 848ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown VG_(track_new_mem_stack) (drd_start_using_mem_stack); 849ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown VG_(track_new_mem_stack_signal) (drd_start_using_mem_stack_signal); 850ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown VG_(track_new_mem_startup) (drd_start_using_mem_w_perms); 851ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown VG_(track_die_mem_brk) (drd_stop_using_nonstack_mem); 852ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown VG_(track_die_mem_munmap) (drd_stop_using_nonstack_mem); 853ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown VG_(track_die_mem_stack) (drd_stop_using_mem_stack); 854ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown VG_(track_die_mem_stack_signal) (drd_stop_using_mem_stack_signal); 855ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown VG_(track_pre_deliver_signal) (drd_pre_deliver_signal); 856ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown VG_(track_post_deliver_signal) (drd_post_deliver_signal); 857ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown VG_(track_start_client_code) (drd_start_client_code); 858ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown VG_(track_pre_thread_ll_create) (drd_pre_thread_create); 859ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown VG_(track_pre_thread_first_insn)(drd_post_thread_create); 860ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown VG_(track_pre_thread_ll_exit) (drd_thread_finished); 861f673d1bf8bfb172f0eccbe4d3a908b3c65b55b33Kenny Root VG_(atfork) (NULL/*pre*/, NULL/*parent*/, 862f673d1bf8bfb172f0eccbe4d3a908b3c65b55b33Kenny Root drd__atfork_child/*child*/); 863ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 864ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown // Other stuff. 865ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown DRD_(register_malloc_wrappers)(drd_start_using_mem_w_ecu, 866ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown drd_stop_using_nonstack_mem); 867ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 868663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng DRD_(bm_module_init)(); 869663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 870ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown DRD_(clientreq_init)(); 871ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 872ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown DRD_(suppression_init)(); 873ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 874ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown DRD_(clientobj_init)(); 875ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 876663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng DRD_(thread_init)(); 877663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 878ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown { 879436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov HChar* const smi = VG_(getenv)("DRD_SEGMENT_MERGING_INTERVAL"); 880ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (smi) 881ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown DRD_(thread_set_segment_merge_interval)(VG_(strtoll10)(smi, NULL)); 882ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 883ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown} 884ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 885ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 886ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownVG_DETERMINE_INTERFACE_VERSION(drd_pre_clo_init) 887