1f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj 2f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj/*--------------------------------------------------------------------*/ 3f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj/*--- Error management for Helgrind. ---*/ 4f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj/*--- hg_errors.c ---*/ 5f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj/*--------------------------------------------------------------------*/ 6f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj 7f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj/* 8f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj This file is part of Helgrind, a Valgrind tool for detecting errors 9f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj in threaded programs. 10f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj 11ed39800a83baf5bffbe391f3974eb2af0f415f80Elliott Hughes Copyright (C) 2007-2017 OpenWorks Ltd 12f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj info@open-works.co.uk 13f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj 14f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj This program is free software; you can redistribute it and/or 15f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj modify it under the terms of the GNU General Public License as 16f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj published by the Free Software Foundation; either version 2 of the 17f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj License, or (at your option) any later version. 18f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj 19f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj This program is distributed in the hope that it will be useful, but 20f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj WITHOUT ANY WARRANTY; without even the implied warranty of 21f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 22f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj General Public License for more details. 23f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj 24f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj You should have received a copy of the GNU General Public License 25f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj along with this program; if not, write to the Free Software 26f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 27f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj 02111-1307, USA. 28f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj 29f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj The GNU General Public License is contained in the file COPYING. 30f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj*/ 31f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj 32f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj#include "pub_tool_basics.h" 33f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj#include "pub_tool_libcbase.h" 34f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj#include "pub_tool_libcassert.h" 35f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj#include "pub_tool_libcprint.h" 36328d6627c26471332610da3f5a0b9cc3cdd410c7philippe#include "pub_tool_stacktrace.h" 37f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj#include "pub_tool_execontext.h" 38f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj#include "pub_tool_errormgr.h" 39f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj#include "pub_tool_wordfm.h" 40f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj#include "pub_tool_xarray.h" 41f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj#include "pub_tool_debuginfo.h" 42f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj#include "pub_tool_threadstate.h" 4324118491f347852bc311069a273fce13608dd531sewardj#include "pub_tool_options.h" // VG_(clo_xml) 44f7ec77f53fd09a5682dbe6db049efe0746df7948philippe#include "pub_tool_aspacemgr.h" 4507c08527f05caeb0062b42ca9a58ee774ec5fba1philippe#include "pub_tool_addrinfo.h" 46f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj 47f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj#include "hg_basics.h" 48f57743408d27fedf60a7b48d25339d51b1f8a055philippe#include "hg_addrdescr.h" 49f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj#include "hg_wordset.h" 50f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj#include "hg_lock_n_thread.h" 51c5ea9961f9705b956742ae8c553c76caa2da8c29sewardj#include "libhb.h" 52f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj#include "hg_errors.h" /* self */ 53f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj 54f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj 55f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj/*----------------------------------------------------------------*/ 5624118491f347852bc311069a273fce13608dd531sewardj/*--- Error management -- storage ---*/ 57f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj/*----------------------------------------------------------------*/ 58f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj 59f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj/* maps (by value) strings to a copy of them in ARENA_TOOL */ 60f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj 61f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardjstatic WordFM* string_table = NULL; 62f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj 63f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardjULong HG_(stats__string_table_queries) = 0; 64f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj 65f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardjULong HG_(stats__string_table_get_map_size) ( void ) { 66f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj return string_table ? (ULong)VG_(sizeFM)(string_table) : 0; 67f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj} 68f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj 69f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardjstatic Word string_table_cmp ( UWord s1, UWord s2 ) { 70f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj return (Word)VG_(strcmp)( (HChar*)s1, (HChar*)s2 ); 71f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj} 72f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj 7319f91bbaedb4caef8a60ce94b0f507193cc0bc10florianstatic HChar* string_table_strdup ( const HChar* str ) { 74f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj HChar* copy = NULL; 75f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj HG_(stats__string_table_queries)++; 76f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj if (!str) 77f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj str = "(null)"; 78f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj if (!string_table) { 79f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj string_table = VG_(newFM)( HG_(zalloc), "hg.sts.1", 80f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj HG_(free), string_table_cmp ); 81f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj } 82f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj if (VG_(lookupFM)( string_table, 836bf3726ebf7a04ca48a5e6cb1ad7a3065054e54eflorian NULL, (UWord*)©, (UWord)str )) { 84f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj tl_assert(copy); 85f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj if (0) VG_(printf)("string_table_strdup: %p -> %p\n", str, copy ); 86f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj return copy; 87f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj } else { 88f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj copy = HG_(strdup)("hg.sts.2", str); 8919f91bbaedb4caef8a60ce94b0f507193cc0bc10florian VG_(addToFM)( string_table, (UWord)copy, (UWord)copy ); 90f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj return copy; 91f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj } 92f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj} 93f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj 94f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj/* maps from Lock .unique fields to LockP*s */ 95f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj 96f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardjstatic WordFM* map_LockN_to_P = NULL; 97f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj 98f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardjULong HG_(stats__LockN_to_P_queries) = 0; 99f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj 100f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardjULong HG_(stats__LockN_to_P_get_map_size) ( void ) { 101f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj return map_LockN_to_P ? (ULong)VG_(sizeFM)(map_LockN_to_P) : 0; 102f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj} 103f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj 104f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardjstatic Word lock_unique_cmp ( UWord lk1W, UWord lk2W ) 105f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj{ 106f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj Lock* lk1 = (Lock*)lk1W; 107f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj Lock* lk2 = (Lock*)lk2W; 108f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj tl_assert( HG_(is_sane_LockNorP)(lk1) ); 109f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj tl_assert( HG_(is_sane_LockNorP)(lk2) ); 110f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj if (lk1->unique < lk2->unique) return -1; 111f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj if (lk1->unique > lk2->unique) return 1; 112f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj return 0; 113f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj} 114f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj 115ffce8159a95134f0a2bc1cea3c3e6e265f096d9fsewardj/* Given a normal Lock (LockN), convert it to a persistent Lock 116ffce8159a95134f0a2bc1cea3c3e6e265f096d9fsewardj (LockP). In some cases the LockN could be invalid (if it's been 117ffce8159a95134f0a2bc1cea3c3e6e265f096d9fsewardj freed), so we enquire, in hg_main.c's admin_locks list, whether it 118ffce8159a95134f0a2bc1cea3c3e6e265f096d9fsewardj is in fact valid. If allowed_to_be_invalid is True, then it's OK 119ffce8159a95134f0a2bc1cea3c3e6e265f096d9fsewardj for the LockN to be invalid, in which case Lock_INVALID is 120ffce8159a95134f0a2bc1cea3c3e6e265f096d9fsewardj returned. In all other cases, we insist that the LockN is a valid 121ffce8159a95134f0a2bc1cea3c3e6e265f096d9fsewardj lock, and return its corresponding LockP. 122ffce8159a95134f0a2bc1cea3c3e6e265f096d9fsewardj 123ffce8159a95134f0a2bc1cea3c3e6e265f096d9fsewardj Why can LockNs sometimes be invalid? Because they are harvested 124ffce8159a95134f0a2bc1cea3c3e6e265f096d9fsewardj from locksets that are attached to the OldRef info for conflicting 125ffce8159a95134f0a2bc1cea3c3e6e265f096d9fsewardj threads. By the time we detect a race, the some of the elements of 126ffce8159a95134f0a2bc1cea3c3e6e265f096d9fsewardj the lockset may have been destroyed by the client, in which case 127ffce8159a95134f0a2bc1cea3c3e6e265f096d9fsewardj the corresponding Lock structures we maintain will have been freed. 128ffce8159a95134f0a2bc1cea3c3e6e265f096d9fsewardj 129ffce8159a95134f0a2bc1cea3c3e6e265f096d9fsewardj So we check that each LockN is a member of the admin_locks double 130ffce8159a95134f0a2bc1cea3c3e6e265f096d9fsewardj linked list of all Lock structures. That stops us prodding around 131ffce8159a95134f0a2bc1cea3c3e6e265f096d9fsewardj in potentially freed-up Lock structures. However, it's not quite a 132ffce8159a95134f0a2bc1cea3c3e6e265f096d9fsewardj proper check: if a new Lock has been reallocated at the same 133ffce8159a95134f0a2bc1cea3c3e6e265f096d9fsewardj address as one which was previously freed, we'll wind up copying 134ffce8159a95134f0a2bc1cea3c3e6e265f096d9fsewardj the new one as the basis for the LockP, which is completely bogus 135ffce8159a95134f0a2bc1cea3c3e6e265f096d9fsewardj because it is unrelated to the previous Lock that lived there. 136ffce8159a95134f0a2bc1cea3c3e6e265f096d9fsewardj Let's hope that doesn't happen too often. 137ffce8159a95134f0a2bc1cea3c3e6e265f096d9fsewardj*/ 138ffce8159a95134f0a2bc1cea3c3e6e265f096d9fsewardjstatic Lock* mk_LockP_from_LockN ( Lock* lkn, 139ffce8159a95134f0a2bc1cea3c3e6e265f096d9fsewardj Bool allowed_to_be_invalid ) 140f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj{ 141f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj Lock* lkp = NULL; 142f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj HG_(stats__LockN_to_P_queries)++; 143ffce8159a95134f0a2bc1cea3c3e6e265f096d9fsewardj 144ffce8159a95134f0a2bc1cea3c3e6e265f096d9fsewardj /* First off, let's do some sanity checks. If 145ffce8159a95134f0a2bc1cea3c3e6e265f096d9fsewardj allowed_to_be_invalid is False, we _must_ be able to find 'lkn' 146ffce8159a95134f0a2bc1cea3c3e6e265f096d9fsewardj in admin_locks; else we must assert. If it is True, it's OK for 147ffce8159a95134f0a2bc1cea3c3e6e265f096d9fsewardj it not to be findable, but in that case we must return 148ffce8159a95134f0a2bc1cea3c3e6e265f096d9fsewardj Lock_INVALID right away. */ 149ffce8159a95134f0a2bc1cea3c3e6e265f096d9fsewardj Lock* lock_list = HG_(get_admin_locks)(); 150ffce8159a95134f0a2bc1cea3c3e6e265f096d9fsewardj while (lock_list) { 151ffce8159a95134f0a2bc1cea3c3e6e265f096d9fsewardj if (lock_list == lkn) 152ffce8159a95134f0a2bc1cea3c3e6e265f096d9fsewardj break; 153ffce8159a95134f0a2bc1cea3c3e6e265f096d9fsewardj lock_list = lock_list->admin_next; 154ffce8159a95134f0a2bc1cea3c3e6e265f096d9fsewardj } 155ffce8159a95134f0a2bc1cea3c3e6e265f096d9fsewardj if (lock_list == NULL) { 156ffce8159a95134f0a2bc1cea3c3e6e265f096d9fsewardj /* We didn't find it. That possibility has to be OK'd by the 157ffce8159a95134f0a2bc1cea3c3e6e265f096d9fsewardj caller. */ 158ffce8159a95134f0a2bc1cea3c3e6e265f096d9fsewardj tl_assert(allowed_to_be_invalid); 159ffce8159a95134f0a2bc1cea3c3e6e265f096d9fsewardj return Lock_INVALID; 160ffce8159a95134f0a2bc1cea3c3e6e265f096d9fsewardj } 161ffce8159a95134f0a2bc1cea3c3e6e265f096d9fsewardj 162ffce8159a95134f0a2bc1cea3c3e6e265f096d9fsewardj /* So we must be looking at a valid LockN. */ 163f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj tl_assert( HG_(is_sane_LockN)(lkn) ); 164ffce8159a95134f0a2bc1cea3c3e6e265f096d9fsewardj 165f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj if (!map_LockN_to_P) { 166f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj map_LockN_to_P = VG_(newFM)( HG_(zalloc), "hg.mLPfLN.1", 167f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj HG_(free), lock_unique_cmp ); 168f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj } 1696bf3726ebf7a04ca48a5e6cb1ad7a3065054e54eflorian if (!VG_(lookupFM)( map_LockN_to_P, NULL, (UWord*)&lkp, (UWord)lkn)) { 170f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj lkp = HG_(zalloc)( "hg.mLPfLN.2", sizeof(Lock) ); 171f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj *lkp = *lkn; 1721d7c3322207f80d9a962a402a171a14e4d628a77sewardj lkp->admin_next = NULL; 1731d7c3322207f80d9a962a402a171a14e4d628a77sewardj lkp->admin_prev = NULL; 174f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj lkp->magic = LockP_MAGIC; 175f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj /* Forget about the bag of lock holders - don't copy that. 176f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj Also, acquired_at should be NULL whenever heldBy is, and vice 177f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj versa. Also forget about the associated libhb synch object. */ 178f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj lkp->heldW = False; 179f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj lkp->heldBy = NULL; 180f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj lkp->acquired_at = NULL; 181f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj lkp->hbso = NULL; 1826bf3726ebf7a04ca48a5e6cb1ad7a3065054e54eflorian VG_(addToFM)( map_LockN_to_P, (UWord)lkp, (UWord)lkp ); 183f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj } 184f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj tl_assert( HG_(is_sane_LockP)(lkp) ); 185f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj return lkp; 186f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj} 187f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj 188f631b021ceaf3a2fd3908a413255c3d82b88dea5florianstatic Int sort_by_guestaddr(const void* n1, const void* n2) 189f631b021ceaf3a2fd3908a413255c3d82b88dea5florian{ 190f631b021ceaf3a2fd3908a413255c3d82b88dea5florian const Lock* l1 = *(const Lock *const *)n1; 191f631b021ceaf3a2fd3908a413255c3d82b88dea5florian const Lock* l2 = *(const Lock *const *)n2; 192f631b021ceaf3a2fd3908a413255c3d82b88dea5florian 193f631b021ceaf3a2fd3908a413255c3d82b88dea5florian Addr a1 = l1 == Lock_INVALID ? 0 : l1->guestaddr; 194f631b021ceaf3a2fd3908a413255c3d82b88dea5florian Addr a2 = l2 == Lock_INVALID ? 0 : l2->guestaddr; 195f631b021ceaf3a2fd3908a413255c3d82b88dea5florian if (a1 < a2) return -1; 196f631b021ceaf3a2fd3908a413255c3d82b88dea5florian if (a1 > a2) return 1; 197f631b021ceaf3a2fd3908a413255c3d82b88dea5florian return 0; 198f631b021ceaf3a2fd3908a413255c3d82b88dea5florian} 199f631b021ceaf3a2fd3908a413255c3d82b88dea5florian 200ffce8159a95134f0a2bc1cea3c3e6e265f096d9fsewardj/* Expand a WordSet of LockN*'s into a NULL-terminated vector of 201ffce8159a95134f0a2bc1cea3c3e6e265f096d9fsewardj LockP*'s. Any LockN's that can't be converted into a LockP 202ffce8159a95134f0a2bc1cea3c3e6e265f096d9fsewardj (because they have been freed, see comment on mk_LockP_from_LockN) 203ffce8159a95134f0a2bc1cea3c3e6e265f096d9fsewardj are converted instead into the value Lock_INVALID. Hence the 204ffce8159a95134f0a2bc1cea3c3e6e265f096d9fsewardj returned vector is a sequence: zero or more (valid LockP* or 205ffce8159a95134f0a2bc1cea3c3e6e265f096d9fsewardj LockN_INVALID), terminated by a NULL. */ 206ffce8159a95134f0a2bc1cea3c3e6e265f096d9fsewardjstatic 207ffce8159a95134f0a2bc1cea3c3e6e265f096d9fsewardjLock** enumerate_WordSet_into_LockP_vector( WordSetU* univ_lsets, 208ffce8159a95134f0a2bc1cea3c3e6e265f096d9fsewardj WordSetID lockset, 209ffce8159a95134f0a2bc1cea3c3e6e265f096d9fsewardj Bool allowed_to_be_invalid ) 210ffce8159a95134f0a2bc1cea3c3e6e265f096d9fsewardj{ 211ffce8159a95134f0a2bc1cea3c3e6e265f096d9fsewardj tl_assert(univ_lsets); 212ffce8159a95134f0a2bc1cea3c3e6e265f096d9fsewardj tl_assert( HG_(plausibleWS)(univ_lsets, lockset) ); 213ffce8159a95134f0a2bc1cea3c3e6e265f096d9fsewardj UWord nLocks = HG_(cardinalityWS)(univ_lsets, lockset); 214ffce8159a95134f0a2bc1cea3c3e6e265f096d9fsewardj Lock** lockPs = HG_(zalloc)( "hg.eWSiLPa", 215ffce8159a95134f0a2bc1cea3c3e6e265f096d9fsewardj (nLocks+1) * sizeof(Lock*) ); 216ffce8159a95134f0a2bc1cea3c3e6e265f096d9fsewardj tl_assert(lockPs[nLocks] == NULL); /* pre-NULL terminated */ 217ffce8159a95134f0a2bc1cea3c3e6e265f096d9fsewardj UWord* lockNs = NULL; 218ffce8159a95134f0a2bc1cea3c3e6e265f096d9fsewardj UWord nLockNs = 0; 219ffce8159a95134f0a2bc1cea3c3e6e265f096d9fsewardj if (nLocks > 0) { 220ffce8159a95134f0a2bc1cea3c3e6e265f096d9fsewardj /* HG_(getPayloadWS) doesn't assign non-NULL to &lockNs if the 221ffce8159a95134f0a2bc1cea3c3e6e265f096d9fsewardj lockset is empty; hence the guarding "if". Sigh. */ 222ffce8159a95134f0a2bc1cea3c3e6e265f096d9fsewardj HG_(getPayloadWS)( &lockNs, &nLockNs, univ_lsets, lockset ); 223ffce8159a95134f0a2bc1cea3c3e6e265f096d9fsewardj tl_assert(lockNs); 224ffce8159a95134f0a2bc1cea3c3e6e265f096d9fsewardj } 225ffce8159a95134f0a2bc1cea3c3e6e265f096d9fsewardj UWord i; 226ffce8159a95134f0a2bc1cea3c3e6e265f096d9fsewardj /* Convert to LockPs. */ 227ffce8159a95134f0a2bc1cea3c3e6e265f096d9fsewardj for (i = 0; i < nLockNs; i++) { 228ffce8159a95134f0a2bc1cea3c3e6e265f096d9fsewardj lockPs[i] = mk_LockP_from_LockN( (Lock*)lockNs[i], 229ffce8159a95134f0a2bc1cea3c3e6e265f096d9fsewardj allowed_to_be_invalid ); 230ffce8159a95134f0a2bc1cea3c3e6e265f096d9fsewardj } 231f631b021ceaf3a2fd3908a413255c3d82b88dea5florian /* Sort the locks by increasing Lock::guestaddr to avoid jitters 232f631b021ceaf3a2fd3908a413255c3d82b88dea5florian in the output. */ 233f631b021ceaf3a2fd3908a413255c3d82b88dea5florian VG_(ssort)(lockPs, nLockNs, sizeof lockPs[0], sort_by_guestaddr); 234f631b021ceaf3a2fd3908a413255c3d82b88dea5florian 235ffce8159a95134f0a2bc1cea3c3e6e265f096d9fsewardj return lockPs; 236ffce8159a95134f0a2bc1cea3c3e6e265f096d9fsewardj} 237ffce8159a95134f0a2bc1cea3c3e6e265f096d9fsewardj 238ffce8159a95134f0a2bc1cea3c3e6e265f096d9fsewardj/* Get the number of useful elements in a vector created by 239ffce8159a95134f0a2bc1cea3c3e6e265f096d9fsewardj enumerate_WordSet_into_LockP_vector. Returns both the total number 240ffce8159a95134f0a2bc1cea3c3e6e265f096d9fsewardj of elements (not including the terminating NULL) and the number of 241ffce8159a95134f0a2bc1cea3c3e6e265f096d9fsewardj non-Lock_INVALID elements. */ 242ffce8159a95134f0a2bc1cea3c3e6e265f096d9fsewardjstatic void count_LockP_vector ( /*OUT*/UWord* nLocks, 243ffce8159a95134f0a2bc1cea3c3e6e265f096d9fsewardj /*OUT*/UWord* nLocksValid, 244ffce8159a95134f0a2bc1cea3c3e6e265f096d9fsewardj Lock** vec ) 245ffce8159a95134f0a2bc1cea3c3e6e265f096d9fsewardj{ 246ffce8159a95134f0a2bc1cea3c3e6e265f096d9fsewardj tl_assert(vec); 247ffce8159a95134f0a2bc1cea3c3e6e265f096d9fsewardj *nLocks = *nLocksValid = 0; 248ffce8159a95134f0a2bc1cea3c3e6e265f096d9fsewardj UWord n = 0; 249ffce8159a95134f0a2bc1cea3c3e6e265f096d9fsewardj while (vec[n]) { 250ffce8159a95134f0a2bc1cea3c3e6e265f096d9fsewardj (*nLocks)++; 251ffce8159a95134f0a2bc1cea3c3e6e265f096d9fsewardj if (vec[n] != Lock_INVALID) 252ffce8159a95134f0a2bc1cea3c3e6e265f096d9fsewardj (*nLocksValid)++; 253ffce8159a95134f0a2bc1cea3c3e6e265f096d9fsewardj n++; 254ffce8159a95134f0a2bc1cea3c3e6e265f096d9fsewardj } 255ffce8159a95134f0a2bc1cea3c3e6e265f096d9fsewardj} 256ffce8159a95134f0a2bc1cea3c3e6e265f096d9fsewardj 257ffce8159a95134f0a2bc1cea3c3e6e265f096d9fsewardj/* Find out whether 'lk' is in 'vec'. */ 258ffce8159a95134f0a2bc1cea3c3e6e265f096d9fsewardjstatic Bool elem_LockP_vector ( Lock** vec, Lock* lk ) 259ffce8159a95134f0a2bc1cea3c3e6e265f096d9fsewardj{ 260ffce8159a95134f0a2bc1cea3c3e6e265f096d9fsewardj tl_assert(vec); 261ffce8159a95134f0a2bc1cea3c3e6e265f096d9fsewardj tl_assert(lk); 262ffce8159a95134f0a2bc1cea3c3e6e265f096d9fsewardj UWord n = 0; 263ffce8159a95134f0a2bc1cea3c3e6e265f096d9fsewardj while (vec[n]) { 264ffce8159a95134f0a2bc1cea3c3e6e265f096d9fsewardj if (vec[n] == lk) 265ffce8159a95134f0a2bc1cea3c3e6e265f096d9fsewardj return True; 266ffce8159a95134f0a2bc1cea3c3e6e265f096d9fsewardj n++; 267ffce8159a95134f0a2bc1cea3c3e6e265f096d9fsewardj } 268ffce8159a95134f0a2bc1cea3c3e6e265f096d9fsewardj return False; 269ffce8159a95134f0a2bc1cea3c3e6e265f096d9fsewardj} 270ffce8159a95134f0a2bc1cea3c3e6e265f096d9fsewardj 271ffce8159a95134f0a2bc1cea3c3e6e265f096d9fsewardj 272f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj/* Errors: 273f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj 274f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj race: program counter 275f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj read or write 276f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj data size 277f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj previous state 278f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj current state 279f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj 280f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj FIXME: how does state printing interact with lockset gc? 281f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj Are the locksets in prev/curr state always valid? 282f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj Ditto question for the threadsets 283f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj ThreadSets - probably are always valid if Threads 284f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj are never thrown away. 285f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj LockSets - could at least print the lockset elements that 286f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj correspond to actual locks at the time of printing. Hmm. 287f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj*/ 288f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj 289f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj/* Error kinds */ 290f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardjtypedef 291f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj enum { 292f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj XE_Race=1101, // race 293f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj XE_UnlockUnlocked, // unlocking a not-locked lock 294f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj XE_UnlockForeign, // unlocking a lock held by some other thread 295f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj XE_UnlockBogus, // unlocking an address not known to be a lock 296f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj XE_PthAPIerror, // error from the POSIX pthreads API 297f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj XE_LockOrder, // lock order error 298f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj XE_Misc // misc other error (w/ string to describe it) 299f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj } 300f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj XErrorTag; 301f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj 302f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj/* Extra contexts for kinds */ 303f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardjtypedef 304f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj struct { 305f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj XErrorTag tag; 306f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj union { 307f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj struct { 30823f1200ba3aa3d8dbb484626ba1bdb7cfcf3b3a9sewardj Addr data_addr; 30923f1200ba3aa3d8dbb484626ba1bdb7cfcf3b3a9sewardj Int szB; 31007c08527f05caeb0062b42ca9a58ee774ec5fba1philippe AddrInfo data_addrinfo; 31123f1200ba3aa3d8dbb484626ba1bdb7cfcf3b3a9sewardj Bool isWrite; 31223f1200ba3aa3d8dbb484626ba1bdb7cfcf3b3a9sewardj Thread* thr; 313ffce8159a95134f0a2bc1cea3c3e6e265f096d9fsewardj Lock** locksHeldW; 314095d61eef541731e77e2c648983aee9ea2bf5e59sewardj /* h1_* and h2_* provide some description of a previously 315095d61eef541731e77e2c648983aee9ea2bf5e59sewardj observed access with which we are conflicting. */ 31623f1200ba3aa3d8dbb484626ba1bdb7cfcf3b3a9sewardj Thread* h1_ct; /* non-NULL means h1 info present */ 31723f1200ba3aa3d8dbb484626ba1bdb7cfcf3b3a9sewardj ExeContext* h1_ct_mbsegstartEC; 31823f1200ba3aa3d8dbb484626ba1bdb7cfcf3b3a9sewardj ExeContext* h1_ct_mbsegendEC; 31923f1200ba3aa3d8dbb484626ba1bdb7cfcf3b3a9sewardj Thread* h2_ct; /* non-NULL means h2 info present */ 32023f1200ba3aa3d8dbb484626ba1bdb7cfcf3b3a9sewardj ExeContext* h2_ct_accEC; 32123f1200ba3aa3d8dbb484626ba1bdb7cfcf3b3a9sewardj Int h2_ct_accSzB; 32223f1200ba3aa3d8dbb484626ba1bdb7cfcf3b3a9sewardj Bool h2_ct_accIsW; 323ffce8159a95134f0a2bc1cea3c3e6e265f096d9fsewardj Lock** h2_ct_locksHeldW; 324f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj } Race; 325f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj struct { 326f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj Thread* thr; /* doing the unlocking */ 327f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj Lock* lock; /* lock (that is already unlocked) */ 328f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj } UnlockUnlocked; 329f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj struct { 330f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj Thread* thr; /* doing the unlocking */ 331f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj Thread* owner; /* thread that actually holds the lock */ 332f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj Lock* lock; /* lock (that is held by 'owner') */ 333f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj } UnlockForeign; 334f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj struct { 335f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj Thread* thr; /* doing the unlocking */ 336f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj Addr lock_ga; /* purported address of the lock */ 337f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj } UnlockBogus; 338f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj struct { 339f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj Thread* thr; 340f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj HChar* fnname; /* persistent, in tool-arena */ 341f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj Word err; /* pth error code */ 342f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj HChar* errstr; /* persistent, in tool-arena */ 343f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj } PthAPIerror; 344f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj struct { 345f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj Thread* thr; 346ffce8159a95134f0a2bc1cea3c3e6e265f096d9fsewardj /* The first 4 fields describe the previously observed 347ffce8159a95134f0a2bc1cea3c3e6e265f096d9fsewardj (should-be) ordering. */ 34846daf0d598c38c9251964712d894f0fcd3cc4143philippe Lock* shouldbe_earlier_lk; 34946daf0d598c38c9251964712d894f0fcd3cc4143philippe Lock* shouldbe_later_lk; 350ffce8159a95134f0a2bc1cea3c3e6e265f096d9fsewardj ExeContext* shouldbe_earlier_ec; 351ffce8159a95134f0a2bc1cea3c3e6e265f096d9fsewardj ExeContext* shouldbe_later_ec; 352ffce8159a95134f0a2bc1cea3c3e6e265f096d9fsewardj /* In principle we need to record two more stacks, from 353ffce8159a95134f0a2bc1cea3c3e6e265f096d9fsewardj this thread, when acquiring the locks in the "wrong" 354ffce8159a95134f0a2bc1cea3c3e6e265f096d9fsewardj order. In fact the wallclock-later acquisition by this 355ffce8159a95134f0a2bc1cea3c3e6e265f096d9fsewardj thread is recorded in the main stack for this error. 356ffce8159a95134f0a2bc1cea3c3e6e265f096d9fsewardj So we only need a stack for the earlier acquisition by 357ffce8159a95134f0a2bc1cea3c3e6e265f096d9fsewardj this thread. */ 358ffce8159a95134f0a2bc1cea3c3e6e265f096d9fsewardj ExeContext* actual_earlier_ec; 359f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj } LockOrder; 360f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj struct { 3618fef62537fc0bcc0903d5be3080152f0e0b3979dsewardj Thread* thr; 3628fef62537fc0bcc0903d5be3080152f0e0b3979dsewardj HChar* errstr; /* persistent, in tool-arena */ 3638fef62537fc0bcc0903d5be3080152f0e0b3979dsewardj HChar* auxstr; /* optional, persistent, in tool-arena */ 3648fef62537fc0bcc0903d5be3080152f0e0b3979dsewardj ExeContext* auxctx; /* optional */ 365f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj } Misc; 366f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj } XE; 367f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj } 368f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj XError; 369f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj 370f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardjstatic void init_XError ( XError* xe ) { 371f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj VG_(memset)(xe, 0, sizeof(*xe) ); 372f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj xe->tag = XE_Race-1; /* bogus */ 373f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj} 374f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj 375f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj 376f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj/* Extensions of suppressions */ 377f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardjtypedef 378f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj enum { 379f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj XS_Race=1201, /* race */ 380f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj XS_FreeMemLock, 381f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj XS_UnlockUnlocked, 382f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj XS_UnlockForeign, 383f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj XS_UnlockBogus, 384f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj XS_PthAPIerror, 385f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj XS_LockOrder, 386f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj XS_Misc 387f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj } 388f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj XSuppTag; 389f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj 390f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj 391f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj/* Updates the copy with address info if necessary. */ 3928e3fbb5cd8276a7d07d5712bc05f9b3376d81a6aflorianUInt HG_(update_extra) ( const Error* err ) 393f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj{ 394f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj XError* xe = (XError*)VG_(get_error_extra)(err); 395f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj tl_assert(xe); 396f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj //if (extra != NULL && Undescribed == extra->addrinfo.akind) { 397f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj // describe_addr ( VG_(get_error_address)(err), &(extra->addrinfo) ); 398f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj //} 399f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj 400f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj if (xe->tag == XE_Race) { 40124118491f347852bc311069a273fce13608dd531sewardj 402ffce8159a95134f0a2bc1cea3c3e6e265f096d9fsewardj /* Note the set of locks that the thread is (w-)holding. 403ffce8159a95134f0a2bc1cea3c3e6e265f096d9fsewardj Convert the WordSetID of LockN*'s into a NULL-terminated 404ffce8159a95134f0a2bc1cea3c3e6e265f096d9fsewardj vector of LockP*'s. We don't expect to encounter any invalid 405ffce8159a95134f0a2bc1cea3c3e6e265f096d9fsewardj LockNs in this conversion. */ 406ffce8159a95134f0a2bc1cea3c3e6e265f096d9fsewardj tl_assert(xe->XE.Race.thr); 407ffce8159a95134f0a2bc1cea3c3e6e265f096d9fsewardj xe->XE.Race.locksHeldW 408ffce8159a95134f0a2bc1cea3c3e6e265f096d9fsewardj = enumerate_WordSet_into_LockP_vector( 409ffce8159a95134f0a2bc1cea3c3e6e265f096d9fsewardj HG_(get_univ_lsets)(), 410ffce8159a95134f0a2bc1cea3c3e6e265f096d9fsewardj xe->XE.Race.thr->locksetW, 411ffce8159a95134f0a2bc1cea3c3e6e265f096d9fsewardj False/*!allowed_to_be_invalid*/ 412ffce8159a95134f0a2bc1cea3c3e6e265f096d9fsewardj ); 413ffce8159a95134f0a2bc1cea3c3e6e265f096d9fsewardj 414f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj /* See if we can come up with a source level description of the 415f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj raced-upon address. This is potentially expensive, which is 416f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj why it's only done at the update_extra point, not when the 417f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj error is initially created. */ 418c5ea9961f9705b956742ae8c553c76caa2da8c29sewardj static Int xxx = 0; 419c5ea9961f9705b956742ae8c553c76caa2da8c29sewardj xxx++; 420c5ea9961f9705b956742ae8c553c76caa2da8c29sewardj if (0) 421c5ea9961f9705b956742ae8c553c76caa2da8c29sewardj VG_(printf)("HG_(update_extra): " 422c5ea9961f9705b956742ae8c553c76caa2da8c29sewardj "%d conflicting-event queries\n", xxx); 423095d61eef541731e77e2c648983aee9ea2bf5e59sewardj 42407c08527f05caeb0062b42ca9a58ee774ec5fba1philippe HG_(describe_addr) (xe->XE.Race.data_addr, &xe->XE.Race.data_addrinfo); 42524118491f347852bc311069a273fce13608dd531sewardj 42624118491f347852bc311069a273fce13608dd531sewardj /* And poke around in the conflicting-event map, to see if we 42724118491f347852bc311069a273fce13608dd531sewardj can rustle up a plausible-looking conflicting memory access 42824118491f347852bc311069a273fce13608dd531sewardj to show. */ 42923f1200ba3aa3d8dbb484626ba1bdb7cfcf3b3a9sewardj if (HG_(clo_history_level) >= 2) { 430ffce8159a95134f0a2bc1cea3c3e6e265f096d9fsewardj Thr* thrp = NULL; 431ffce8159a95134f0a2bc1cea3c3e6e265f096d9fsewardj ExeContext* wherep = NULL; 432ffce8159a95134f0a2bc1cea3c3e6e265f096d9fsewardj Addr acc_addr = xe->XE.Race.data_addr; 433ffce8159a95134f0a2bc1cea3c3e6e265f096d9fsewardj Int acc_szB = xe->XE.Race.szB; 434ffce8159a95134f0a2bc1cea3c3e6e265f096d9fsewardj Thr* acc_thr = xe->XE.Race.thr->hbthr; 435ffce8159a95134f0a2bc1cea3c3e6e265f096d9fsewardj Bool acc_isW = xe->XE.Race.isWrite; 436ffce8159a95134f0a2bc1cea3c3e6e265f096d9fsewardj SizeT conf_szB = 0; 437ffce8159a95134f0a2bc1cea3c3e6e265f096d9fsewardj Bool conf_isW = False; 438ffce8159a95134f0a2bc1cea3c3e6e265f096d9fsewardj WordSetID conf_locksHeldW = 0; 43923f1200ba3aa3d8dbb484626ba1bdb7cfcf3b3a9sewardj tl_assert(!xe->XE.Race.h2_ct_accEC); 44023f1200ba3aa3d8dbb484626ba1bdb7cfcf3b3a9sewardj tl_assert(!xe->XE.Race.h2_ct); 44123f1200ba3aa3d8dbb484626ba1bdb7cfcf3b3a9sewardj if (libhb_event_map_lookup( 442ffce8159a95134f0a2bc1cea3c3e6e265f096d9fsewardj &wherep, &thrp, &conf_szB, &conf_isW, &conf_locksHeldW, 44323f1200ba3aa3d8dbb484626ba1bdb7cfcf3b3a9sewardj acc_thr, acc_addr, acc_szB, acc_isW )) { 44423f1200ba3aa3d8dbb484626ba1bdb7cfcf3b3a9sewardj Thread* threadp; 44523f1200ba3aa3d8dbb484626ba1bdb7cfcf3b3a9sewardj tl_assert(wherep); 44623f1200ba3aa3d8dbb484626ba1bdb7cfcf3b3a9sewardj tl_assert(thrp); 44760626649e5fa6cd21af377fde5e83803fc136f61sewardj threadp = libhb_get_Thr_hgthread( thrp ); 44823f1200ba3aa3d8dbb484626ba1bdb7cfcf3b3a9sewardj tl_assert(threadp); 44923f1200ba3aa3d8dbb484626ba1bdb7cfcf3b3a9sewardj xe->XE.Race.h2_ct_accEC = wherep; 45023f1200ba3aa3d8dbb484626ba1bdb7cfcf3b3a9sewardj xe->XE.Race.h2_ct = threadp; 45123f1200ba3aa3d8dbb484626ba1bdb7cfcf3b3a9sewardj xe->XE.Race.h2_ct_accSzB = (Int)conf_szB; 45223f1200ba3aa3d8dbb484626ba1bdb7cfcf3b3a9sewardj xe->XE.Race.h2_ct_accIsW = conf_isW; 453ffce8159a95134f0a2bc1cea3c3e6e265f096d9fsewardj xe->XE.Race.h2_ct_locksHeldW 454ffce8159a95134f0a2bc1cea3c3e6e265f096d9fsewardj = enumerate_WordSet_into_LockP_vector( 455ffce8159a95134f0a2bc1cea3c3e6e265f096d9fsewardj HG_(get_univ_lsets)(), 456ffce8159a95134f0a2bc1cea3c3e6e265f096d9fsewardj conf_locksHeldW, 457ffce8159a95134f0a2bc1cea3c3e6e265f096d9fsewardj True/*allowed_to_be_invalid*/ 458ffce8159a95134f0a2bc1cea3c3e6e265f096d9fsewardj ); 459c5ea9961f9705b956742ae8c553c76caa2da8c29sewardj } 460c5ea9961f9705b956742ae8c553c76caa2da8c29sewardj } 46123f1200ba3aa3d8dbb484626ba1bdb7cfcf3b3a9sewardj 46223f1200ba3aa3d8dbb484626ba1bdb7cfcf3b3a9sewardj // both NULL or both non-NULL 46323f1200ba3aa3d8dbb484626ba1bdb7cfcf3b3a9sewardj tl_assert( (!!xe->XE.Race.h2_ct) == (!!xe->XE.Race.h2_ct_accEC) ); 464f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj } 465f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj 466f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj return sizeof(XError); 467f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj} 468f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj 469f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardjvoid HG_(record_error_Race) ( Thread* thr, 470a781be6728a28c94aec57f793f4d084456e93684sewardj Addr data_addr, Int szB, Bool isWrite, 47123f1200ba3aa3d8dbb484626ba1bdb7cfcf3b3a9sewardj Thread* h1_ct, 47223f1200ba3aa3d8dbb484626ba1bdb7cfcf3b3a9sewardj ExeContext* h1_ct_segstart, 47323f1200ba3aa3d8dbb484626ba1bdb7cfcf3b3a9sewardj ExeContext* h1_ct_mbsegendEC ) 474f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj{ 475f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj XError xe; 476f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj tl_assert( HG_(is_sane_Thread)(thr) ); 477f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj 478f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj# if defined(VGO_linux) 479f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj /* Skip any races on locations apparently in GOTPLT sections. This 480f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj is said to be caused by ld.so poking PLT table entries (or 481f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj whatever) when it writes the resolved address of a dynamically 482f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj linked routine, into the table (or whatever) when it is called 483f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj for the first time. */ 484f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj { 485e08950b4ce5a3f5d75a7279548f975cd6207dc74florian VgSectKind sect = VG_(DebugInfo_sect_kind)( NULL, data_addr ); 486f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj if (0) VG_(printf)("XXXXXXXXX RACE on %#lx %s\n", 487f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj data_addr, VG_(pp_SectKind)(sect)); 4885210413b79e93b660f5fd16dfb319237858835f5sewardj /* SectPLT is required on ???-linux */ 489f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj if (sect == Vg_SectGOTPLT) return; 4905210413b79e93b660f5fd16dfb319237858835f5sewardj /* SectPLT is required on ppc32/64-linux */ 4915210413b79e93b660f5fd16dfb319237858835f5sewardj if (sect == Vg_SectPLT) return; 4924fa71081858358c26ad182b82d2ddc305b2e72f1mjw /* SectGOT is required on arm-linux */ 4934fa71081858358c26ad182b82d2ddc305b2e72f1mjw if (sect == Vg_SectGOT) return; 494f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj } 495f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj# endif 496f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj 497f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj init_XError(&xe); 498f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj xe.tag = XE_Race; 499f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj xe.XE.Race.data_addr = data_addr; 500f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj xe.XE.Race.szB = szB; 501f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj xe.XE.Race.isWrite = isWrite; 502f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj xe.XE.Race.thr = thr; 503f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj tl_assert(isWrite == False || isWrite == True); 504a781be6728a28c94aec57f793f4d084456e93684sewardj tl_assert(szB == 8 || szB == 4 || szB == 2 || szB == 1); 50524118491f347852bc311069a273fce13608dd531sewardj /* Skip on the detailed description of the raced-on address at this 50624118491f347852bc311069a273fce13608dd531sewardj point; it's expensive. Leave it for the update_extra function 50724118491f347852bc311069a273fce13608dd531sewardj if we ever make it that far. */ 50807c08527f05caeb0062b42ca9a58ee774ec5fba1philippe xe.XE.Race.data_addrinfo.tag = Addr_Undescribed; 509f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj // FIXME: tid vs thr 510c5ea9961f9705b956742ae8c553c76caa2da8c29sewardj // Skip on any of the conflicting-access info at this point. 511c5ea9961f9705b956742ae8c553c76caa2da8c29sewardj // It's expensive to obtain, and this error is more likely than 512c5ea9961f9705b956742ae8c553c76caa2da8c29sewardj // not to be discarded. We'll fill these fields in in 513c5ea9961f9705b956742ae8c553c76caa2da8c29sewardj // HG_(update_extra) just above, assuming the error ever makes 514c5ea9961f9705b956742ae8c553c76caa2da8c29sewardj // it that far (unlikely). 51523f1200ba3aa3d8dbb484626ba1bdb7cfcf3b3a9sewardj xe.XE.Race.h2_ct_accSzB = 0; 51623f1200ba3aa3d8dbb484626ba1bdb7cfcf3b3a9sewardj xe.XE.Race.h2_ct_accIsW = False; 51723f1200ba3aa3d8dbb484626ba1bdb7cfcf3b3a9sewardj xe.XE.Race.h2_ct_accEC = NULL; 51823f1200ba3aa3d8dbb484626ba1bdb7cfcf3b3a9sewardj xe.XE.Race.h2_ct = NULL; 519f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj tl_assert( HG_(is_sane_ThreadId)(thr->coretid) ); 520f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj tl_assert( thr->coretid != VG_INVALID_THREADID ); 52123f1200ba3aa3d8dbb484626ba1bdb7cfcf3b3a9sewardj 52223f1200ba3aa3d8dbb484626ba1bdb7cfcf3b3a9sewardj xe.XE.Race.h1_ct = h1_ct; 52323f1200ba3aa3d8dbb484626ba1bdb7cfcf3b3a9sewardj xe.XE.Race.h1_ct_mbsegstartEC = h1_ct_segstart; 52423f1200ba3aa3d8dbb484626ba1bdb7cfcf3b3a9sewardj xe.XE.Race.h1_ct_mbsegendEC = h1_ct_mbsegendEC; 52523f1200ba3aa3d8dbb484626ba1bdb7cfcf3b3a9sewardj 526f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj VG_(maybe_record_error)( thr->coretid, 527f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj XE_Race, data_addr, NULL, &xe ); 528f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj} 529f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj 530f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardjvoid HG_(record_error_UnlockUnlocked) ( Thread* thr, Lock* lk ) 531f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj{ 532f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj XError xe; 533f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj tl_assert( HG_(is_sane_Thread)(thr) ); 534f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj tl_assert( HG_(is_sane_LockN)(lk) ); 535f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj init_XError(&xe); 536f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj xe.tag = XE_UnlockUnlocked; 537ffce8159a95134f0a2bc1cea3c3e6e265f096d9fsewardj xe.XE.UnlockUnlocked.thr 538ffce8159a95134f0a2bc1cea3c3e6e265f096d9fsewardj = thr; 539ffce8159a95134f0a2bc1cea3c3e6e265f096d9fsewardj xe.XE.UnlockUnlocked.lock 540ffce8159a95134f0a2bc1cea3c3e6e265f096d9fsewardj = mk_LockP_from_LockN(lk, False/*!allowed_to_be_invalid*/); 541f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj // FIXME: tid vs thr 542f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj tl_assert( HG_(is_sane_ThreadId)(thr->coretid) ); 543f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj tl_assert( thr->coretid != VG_INVALID_THREADID ); 544f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj VG_(maybe_record_error)( thr->coretid, 545f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj XE_UnlockUnlocked, 0, NULL, &xe ); 546f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj} 547f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj 548f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardjvoid HG_(record_error_UnlockForeign) ( Thread* thr, 549f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj Thread* owner, Lock* lk ) 550f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj{ 551f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj XError xe; 552f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj tl_assert( HG_(is_sane_Thread)(thr) ); 553f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj tl_assert( HG_(is_sane_Thread)(owner) ); 554f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj tl_assert( HG_(is_sane_LockN)(lk) ); 555f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj init_XError(&xe); 556f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj xe.tag = XE_UnlockForeign; 557f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj xe.XE.UnlockForeign.thr = thr; 558f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj xe.XE.UnlockForeign.owner = owner; 559ffce8159a95134f0a2bc1cea3c3e6e265f096d9fsewardj xe.XE.UnlockForeign.lock 560ffce8159a95134f0a2bc1cea3c3e6e265f096d9fsewardj = mk_LockP_from_LockN(lk, False/*!allowed_to_be_invalid*/); 561f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj // FIXME: tid vs thr 562f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj tl_assert( HG_(is_sane_ThreadId)(thr->coretid) ); 563f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj tl_assert( thr->coretid != VG_INVALID_THREADID ); 564f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj VG_(maybe_record_error)( thr->coretid, 565f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj XE_UnlockForeign, 0, NULL, &xe ); 566f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj} 567f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj 568f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardjvoid HG_(record_error_UnlockBogus) ( Thread* thr, Addr lock_ga ) 569f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj{ 570f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj XError xe; 571f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj tl_assert( HG_(is_sane_Thread)(thr) ); 572f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj init_XError(&xe); 573f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj xe.tag = XE_UnlockBogus; 574f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj xe.XE.UnlockBogus.thr = thr; 575f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj xe.XE.UnlockBogus.lock_ga = lock_ga; 576f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj // FIXME: tid vs thr 577f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj tl_assert( HG_(is_sane_ThreadId)(thr->coretid) ); 578f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj tl_assert( thr->coretid != VG_INVALID_THREADID ); 579f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj VG_(maybe_record_error)( thr->coretid, 580f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj XE_UnlockBogus, 0, NULL, &xe ); 581f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj} 582f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj 583f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardjvoid HG_(record_error_LockOrder)( 584ffce8159a95134f0a2bc1cea3c3e6e265f096d9fsewardj Thread* thr, 58546daf0d598c38c9251964712d894f0fcd3cc4143philippe Lock* shouldbe_earlier_lk, 58646daf0d598c38c9251964712d894f0fcd3cc4143philippe Lock* shouldbe_later_lk, 587ffce8159a95134f0a2bc1cea3c3e6e265f096d9fsewardj ExeContext* shouldbe_earlier_ec, 588ffce8159a95134f0a2bc1cea3c3e6e265f096d9fsewardj ExeContext* shouldbe_later_ec, 589ffce8159a95134f0a2bc1cea3c3e6e265f096d9fsewardj ExeContext* actual_earlier_ec 590f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj ) 591f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj{ 592f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj XError xe; 593f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj tl_assert( HG_(is_sane_Thread)(thr) ); 594c1fb9d265a0d64216d387684a425125af4aca557sewardj tl_assert(HG_(clo_track_lockorders)); 595f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj init_XError(&xe); 596f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj xe.tag = XE_LockOrder; 597f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj xe.XE.LockOrder.thr = thr; 59846daf0d598c38c9251964712d894f0fcd3cc4143philippe xe.XE.LockOrder.shouldbe_earlier_lk 59946daf0d598c38c9251964712d894f0fcd3cc4143philippe = mk_LockP_from_LockN(shouldbe_earlier_lk, 60046daf0d598c38c9251964712d894f0fcd3cc4143philippe False/*!allowed_to_be_invalid*/); 601ffce8159a95134f0a2bc1cea3c3e6e265f096d9fsewardj xe.XE.LockOrder.shouldbe_earlier_ec = shouldbe_earlier_ec; 60246daf0d598c38c9251964712d894f0fcd3cc4143philippe xe.XE.LockOrder.shouldbe_later_lk 60346daf0d598c38c9251964712d894f0fcd3cc4143philippe = mk_LockP_from_LockN(shouldbe_later_lk, 60446daf0d598c38c9251964712d894f0fcd3cc4143philippe False/*!allowed_to_be_invalid*/); 605ffce8159a95134f0a2bc1cea3c3e6e265f096d9fsewardj xe.XE.LockOrder.shouldbe_later_ec = shouldbe_later_ec; 606ffce8159a95134f0a2bc1cea3c3e6e265f096d9fsewardj xe.XE.LockOrder.actual_earlier_ec = actual_earlier_ec; 607f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj // FIXME: tid vs thr 608f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj tl_assert( HG_(is_sane_ThreadId)(thr->coretid) ); 609f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj tl_assert( thr->coretid != VG_INVALID_THREADID ); 610f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj VG_(maybe_record_error)( thr->coretid, 611f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj XE_LockOrder, 0, NULL, &xe ); 612f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj} 613f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj 6146bd9dc18c043927c1196caba20a327238a179c42florianvoid HG_(record_error_PthAPIerror) ( Thread* thr, const HChar* fnname, 6156bd9dc18c043927c1196caba20a327238a179c42florian Word err, const HChar* errstr ) 616f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj{ 617f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj XError xe; 618f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj tl_assert( HG_(is_sane_Thread)(thr) ); 619f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj tl_assert(fnname); 620f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj tl_assert(errstr); 621f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj init_XError(&xe); 622f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj xe.tag = XE_PthAPIerror; 623f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj xe.XE.PthAPIerror.thr = thr; 624f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj xe.XE.PthAPIerror.fnname = string_table_strdup(fnname); 625f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj xe.XE.PthAPIerror.err = err; 626f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj xe.XE.PthAPIerror.errstr = string_table_strdup(errstr); 627f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj // FIXME: tid vs thr 628f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj tl_assert( HG_(is_sane_ThreadId)(thr->coretid) ); 629f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj tl_assert( thr->coretid != VG_INVALID_THREADID ); 630f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj VG_(maybe_record_error)( thr->coretid, 631f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj XE_PthAPIerror, 0, NULL, &xe ); 632f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj} 633f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj 6346bd9dc18c043927c1196caba20a327238a179c42florianvoid HG_(record_error_Misc_w_aux) ( Thread* thr, const HChar* errstr, 6356bd9dc18c043927c1196caba20a327238a179c42florian const HChar* auxstr, ExeContext* auxctx ) 636f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj{ 637f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj XError xe; 638f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj tl_assert( HG_(is_sane_Thread)(thr) ); 639f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj tl_assert(errstr); 640f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj init_XError(&xe); 641f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj xe.tag = XE_Misc; 642f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj xe.XE.Misc.thr = thr; 643f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj xe.XE.Misc.errstr = string_table_strdup(errstr); 6448fef62537fc0bcc0903d5be3080152f0e0b3979dsewardj xe.XE.Misc.auxstr = auxstr ? string_table_strdup(auxstr) : NULL; 6458fef62537fc0bcc0903d5be3080152f0e0b3979dsewardj xe.XE.Misc.auxctx = auxctx; 646f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj // FIXME: tid vs thr 647f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj tl_assert( HG_(is_sane_ThreadId)(thr->coretid) ); 648f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj tl_assert( thr->coretid != VG_INVALID_THREADID ); 649f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj VG_(maybe_record_error)( thr->coretid, 650f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj XE_Misc, 0, NULL, &xe ); 651f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj} 652f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj 6536bd9dc18c043927c1196caba20a327238a179c42florianvoid HG_(record_error_Misc) ( Thread* thr, const HChar* errstr ) 6548fef62537fc0bcc0903d5be3080152f0e0b3979dsewardj{ 6558fef62537fc0bcc0903d5be3080152f0e0b3979dsewardj HG_(record_error_Misc_w_aux)(thr, errstr, NULL, NULL); 6568fef62537fc0bcc0903d5be3080152f0e0b3979dsewardj} 6578fef62537fc0bcc0903d5be3080152f0e0b3979dsewardj 6588e3fbb5cd8276a7d07d5712bc05f9b3376d81a6aflorianBool HG_(eq_Error) ( VgRes not_used, const Error* e1, const Error* e2 ) 659f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj{ 660f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj XError *xe1, *xe2; 661f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj 662f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj tl_assert(VG_(get_error_kind)(e1) == VG_(get_error_kind)(e2)); 663f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj 664f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj xe1 = (XError*)VG_(get_error_extra)(e1); 665f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj xe2 = (XError*)VG_(get_error_extra)(e2); 666f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj tl_assert(xe1); 667f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj tl_assert(xe2); 668f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj 669f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj switch (VG_(get_error_kind)(e1)) { 670f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj case XE_Race: 671f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj return xe1->XE.Race.szB == xe2->XE.Race.szB 672f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj && xe1->XE.Race.isWrite == xe2->XE.Race.isWrite 673f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj && (HG_(clo_cmp_race_err_addrs) 674f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj ? xe1->XE.Race.data_addr == xe2->XE.Race.data_addr 675f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj : True); 676f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj case XE_UnlockUnlocked: 677f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj return xe1->XE.UnlockUnlocked.thr == xe2->XE.UnlockUnlocked.thr 678f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj && xe1->XE.UnlockUnlocked.lock == xe2->XE.UnlockUnlocked.lock; 679f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj case XE_UnlockForeign: 680f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj return xe1->XE.UnlockForeign.thr == xe2->XE.UnlockForeign.thr 681f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj && xe1->XE.UnlockForeign.owner == xe2->XE.UnlockForeign.owner 682f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj && xe1->XE.UnlockForeign.lock == xe2->XE.UnlockForeign.lock; 683f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj case XE_UnlockBogus: 684f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj return xe1->XE.UnlockBogus.thr == xe2->XE.UnlockBogus.thr 685f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj && xe1->XE.UnlockBogus.lock_ga == xe2->XE.UnlockBogus.lock_ga; 686f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj case XE_PthAPIerror: 687f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj return xe1->XE.PthAPIerror.thr == xe2->XE.PthAPIerror.thr 688f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj && 0==VG_(strcmp)(xe1->XE.PthAPIerror.fnname, 689f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj xe2->XE.PthAPIerror.fnname) 690f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj && xe1->XE.PthAPIerror.err == xe2->XE.PthAPIerror.err; 691f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj case XE_LockOrder: 692f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj return xe1->XE.LockOrder.thr == xe2->XE.LockOrder.thr; 693f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj case XE_Misc: 694f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj return xe1->XE.Misc.thr == xe2->XE.Misc.thr 695f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj && 0==VG_(strcmp)(xe1->XE.Misc.errstr, xe2->XE.Misc.errstr); 696f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj default: 697f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj tl_assert(0); 698f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj } 699f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj 700f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj /*NOTREACHED*/ 701f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj tl_assert(0); 702f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj} 703f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj 704f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj 70524118491f347852bc311069a273fce13608dd531sewardj/*----------------------------------------------------------------*/ 70624118491f347852bc311069a273fce13608dd531sewardj/*--- Error management -- printing ---*/ 70724118491f347852bc311069a273fce13608dd531sewardj/*----------------------------------------------------------------*/ 70824118491f347852bc311069a273fce13608dd531sewardj 70924118491f347852bc311069a273fce13608dd531sewardj/* Do a printf-style operation on either the XML or normal output 71024118491f347852bc311069a273fce13608dd531sewardj channel, depending on the setting of VG_(clo_xml). 71124118491f347852bc311069a273fce13608dd531sewardj*/ 7126bf3726ebf7a04ca48a5e6cb1ad7a3065054e54eflorianstatic void emit_WRK ( const HChar* format, va_list vargs ) 71324118491f347852bc311069a273fce13608dd531sewardj{ 71424118491f347852bc311069a273fce13608dd531sewardj if (VG_(clo_xml)) { 71524118491f347852bc311069a273fce13608dd531sewardj VG_(vprintf_xml)(format, vargs); 71624118491f347852bc311069a273fce13608dd531sewardj } else { 71724118491f347852bc311069a273fce13608dd531sewardj VG_(vmessage)(Vg_UserMsg, format, vargs); 71824118491f347852bc311069a273fce13608dd531sewardj } 71924118491f347852bc311069a273fce13608dd531sewardj} 7206bf3726ebf7a04ca48a5e6cb1ad7a3065054e54eflorianstatic void emit ( const HChar* format, ... ) PRINTF_CHECK(1, 2); 7216bf3726ebf7a04ca48a5e6cb1ad7a3065054e54eflorianstatic void emit ( const HChar* format, ... ) 72224118491f347852bc311069a273fce13608dd531sewardj{ 72324118491f347852bc311069a273fce13608dd531sewardj va_list vargs; 72424118491f347852bc311069a273fce13608dd531sewardj va_start(vargs, format); 72524118491f347852bc311069a273fce13608dd531sewardj emit_WRK(format, vargs); 72624118491f347852bc311069a273fce13608dd531sewardj va_end(vargs); 72724118491f347852bc311069a273fce13608dd531sewardj} 72824118491f347852bc311069a273fce13608dd531sewardj 72924118491f347852bc311069a273fce13608dd531sewardj 730f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj/* Announce (that is, print the point-of-creation) of 'thr'. Only do 731f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj this once, as we only want to see these announcements once per 73224118491f347852bc311069a273fce13608dd531sewardj thread. Returned Bool indicates whether or not an announcement was 73324118491f347852bc311069a273fce13608dd531sewardj made. 73424118491f347852bc311069a273fce13608dd531sewardj*/ 73524118491f347852bc311069a273fce13608dd531sewardjstatic Bool announce_one_thread ( Thread* thr ) 736f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj{ 737f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj tl_assert(HG_(is_sane_Thread)(thr)); 738f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj tl_assert(thr->errmsg_index >= 1); 73924118491f347852bc311069a273fce13608dd531sewardj if (thr->announced) 74024118491f347852bc311069a273fce13608dd531sewardj return False; 74124118491f347852bc311069a273fce13608dd531sewardj 74224118491f347852bc311069a273fce13608dd531sewardj if (VG_(clo_xml)) { 74324118491f347852bc311069a273fce13608dd531sewardj 74424118491f347852bc311069a273fce13608dd531sewardj VG_(printf_xml)("<announcethread>\n"); 74511b5c6d24609d9b75aa15f0a6dfb2b207136de60sewardj VG_(printf_xml)(" <hthreadid>%d</hthreadid>\n", thr->errmsg_index); 746f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj if (thr->errmsg_index == 1) { 747f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj tl_assert(thr->created_at == NULL); 74824118491f347852bc311069a273fce13608dd531sewardj VG_(printf_xml)(" <isrootthread></isrootthread>\n"); 74924118491f347852bc311069a273fce13608dd531sewardj } else { 75024118491f347852bc311069a273fce13608dd531sewardj tl_assert(thr->created_at != NULL); 75124118491f347852bc311069a273fce13608dd531sewardj VG_(pp_ExeContext)( thr->created_at ); 75224118491f347852bc311069a273fce13608dd531sewardj } 75324118491f347852bc311069a273fce13608dd531sewardj VG_(printf_xml)("</announcethread>\n\n"); 75424118491f347852bc311069a273fce13608dd531sewardj 75524118491f347852bc311069a273fce13608dd531sewardj } else { 75624118491f347852bc311069a273fce13608dd531sewardj 757ffce8159a95134f0a2bc1cea3c3e6e265f096d9fsewardj VG_(umsg)("---Thread-Announcement----------" 758ffce8159a95134f0a2bc1cea3c3e6e265f096d9fsewardj "--------------------------------" "\n"); 759ffce8159a95134f0a2bc1cea3c3e6e265f096d9fsewardj VG_(umsg)("\n"); 760ffce8159a95134f0a2bc1cea3c3e6e265f096d9fsewardj 76124118491f347852bc311069a273fce13608dd531sewardj if (thr->errmsg_index == 1) { 76224118491f347852bc311069a273fce13608dd531sewardj tl_assert(thr->created_at == NULL); 76324118491f347852bc311069a273fce13608dd531sewardj VG_(message)(Vg_UserMsg, 76424118491f347852bc311069a273fce13608dd531sewardj "Thread #%d is the program's root thread\n", 76524118491f347852bc311069a273fce13608dd531sewardj thr->errmsg_index); 766f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj } else { 767f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj tl_assert(thr->created_at != NULL); 76824118491f347852bc311069a273fce13608dd531sewardj VG_(message)(Vg_UserMsg, "Thread #%d was created\n", 769f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj thr->errmsg_index); 770f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj VG_(pp_ExeContext)( thr->created_at ); 771f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj } 77224118491f347852bc311069a273fce13608dd531sewardj VG_(message)(Vg_UserMsg, "\n"); 77324118491f347852bc311069a273fce13608dd531sewardj 77424118491f347852bc311069a273fce13608dd531sewardj } 77524118491f347852bc311069a273fce13608dd531sewardj 77624118491f347852bc311069a273fce13608dd531sewardj thr->announced = True; 77724118491f347852bc311069a273fce13608dd531sewardj return True; 77824118491f347852bc311069a273fce13608dd531sewardj} 77924118491f347852bc311069a273fce13608dd531sewardj 780ffce8159a95134f0a2bc1cea3c3e6e265f096d9fsewardj/* Announce 'lk'. */ 781ffce8159a95134f0a2bc1cea3c3e6e265f096d9fsewardjstatic void announce_LockP ( Lock* lk ) 782ffce8159a95134f0a2bc1cea3c3e6e265f096d9fsewardj{ 783ffce8159a95134f0a2bc1cea3c3e6e265f096d9fsewardj tl_assert(lk); 784ffce8159a95134f0a2bc1cea3c3e6e265f096d9fsewardj if (lk == Lock_INVALID) 785ffce8159a95134f0a2bc1cea3c3e6e265f096d9fsewardj return; /* Can't be announced -- we know nothing about it. */ 786ffce8159a95134f0a2bc1cea3c3e6e265f096d9fsewardj tl_assert(lk->magic == LockP_MAGIC); 787ffce8159a95134f0a2bc1cea3c3e6e265f096d9fsewardj 788ffce8159a95134f0a2bc1cea3c3e6e265f096d9fsewardj if (VG_(clo_xml)) { 78946daf0d598c38c9251964712d894f0fcd3cc4143philippe if (lk->appeared_at) { 79046daf0d598c38c9251964712d894f0fcd3cc4143philippe emit( " <auxwhat>Lock at %p was first observed</auxwhat>\n", 79146daf0d598c38c9251964712d894f0fcd3cc4143philippe (void*)lk ); 79246daf0d598c38c9251964712d894f0fcd3cc4143philippe VG_(pp_ExeContext)( lk->appeared_at ); 79346daf0d598c38c9251964712d894f0fcd3cc4143philippe } 79446daf0d598c38c9251964712d894f0fcd3cc4143philippe 795ffce8159a95134f0a2bc1cea3c3e6e265f096d9fsewardj } else { 7968061201f9eaaf2fc6a672f631310662749a6527fphilippe if (lk->appeared_at) { 79746daf0d598c38c9251964712d894f0fcd3cc4143philippe VG_(umsg)( " Lock at %p was first observed\n", 7988061201f9eaaf2fc6a672f631310662749a6527fphilippe (void*)lk->guestaddr ); 7998061201f9eaaf2fc6a672f631310662749a6527fphilippe VG_(pp_ExeContext)( lk->appeared_at ); 8008061201f9eaaf2fc6a672f631310662749a6527fphilippe } else { 80146daf0d598c38c9251964712d894f0fcd3cc4143philippe VG_(umsg)( " Lock at %p : no stacktrace for first observation\n", 8028061201f9eaaf2fc6a672f631310662749a6527fphilippe (void*)lk->guestaddr ); 8038061201f9eaaf2fc6a672f631310662749a6527fphilippe } 8048061201f9eaaf2fc6a672f631310662749a6527fphilippe HG_(get_and_pp_addrdescr) (lk->guestaddr); 805ffce8159a95134f0a2bc1cea3c3e6e265f096d9fsewardj VG_(umsg)("\n"); 806ffce8159a95134f0a2bc1cea3c3e6e265f096d9fsewardj } 807ffce8159a95134f0a2bc1cea3c3e6e265f096d9fsewardj} 808ffce8159a95134f0a2bc1cea3c3e6e265f096d9fsewardj 809ffce8159a95134f0a2bc1cea3c3e6e265f096d9fsewardj/* Announce (that is, print point-of-first-observation) for the 810ffce8159a95134f0a2bc1cea3c3e6e265f096d9fsewardj locks in 'lockvec' and, if non-NULL, 'lockvec2'. */ 811ffce8159a95134f0a2bc1cea3c3e6e265f096d9fsewardjstatic void announce_combined_LockP_vecs ( Lock** lockvec, 812ffce8159a95134f0a2bc1cea3c3e6e265f096d9fsewardj Lock** lockvec2 ) 813ffce8159a95134f0a2bc1cea3c3e6e265f096d9fsewardj{ 814ffce8159a95134f0a2bc1cea3c3e6e265f096d9fsewardj UWord i; 815ffce8159a95134f0a2bc1cea3c3e6e265f096d9fsewardj tl_assert(lockvec); 816ffce8159a95134f0a2bc1cea3c3e6e265f096d9fsewardj for (i = 0; lockvec[i]; i++) { 817ffce8159a95134f0a2bc1cea3c3e6e265f096d9fsewardj announce_LockP(lockvec[i]); 818ffce8159a95134f0a2bc1cea3c3e6e265f096d9fsewardj } 819ffce8159a95134f0a2bc1cea3c3e6e265f096d9fsewardj if (lockvec2) { 820ffce8159a95134f0a2bc1cea3c3e6e265f096d9fsewardj for (i = 0; lockvec2[i]; i++) { 821ffce8159a95134f0a2bc1cea3c3e6e265f096d9fsewardj Lock* lk = lockvec2[i]; 822ffce8159a95134f0a2bc1cea3c3e6e265f096d9fsewardj if (!elem_LockP_vector(lockvec, lk)) 823ffce8159a95134f0a2bc1cea3c3e6e265f096d9fsewardj announce_LockP(lk); 824ffce8159a95134f0a2bc1cea3c3e6e265f096d9fsewardj } 825ffce8159a95134f0a2bc1cea3c3e6e265f096d9fsewardj } 826ffce8159a95134f0a2bc1cea3c3e6e265f096d9fsewardj} 827ffce8159a95134f0a2bc1cea3c3e6e265f096d9fsewardj 828ffce8159a95134f0a2bc1cea3c3e6e265f096d9fsewardj 8296bd9dc18c043927c1196caba20a327238a179c42florianstatic void show_LockP_summary_textmode ( Lock** locks, const HChar* pre ) 830ffce8159a95134f0a2bc1cea3c3e6e265f096d9fsewardj{ 831ffce8159a95134f0a2bc1cea3c3e6e265f096d9fsewardj tl_assert(locks); 832ffce8159a95134f0a2bc1cea3c3e6e265f096d9fsewardj UWord i; 833ffce8159a95134f0a2bc1cea3c3e6e265f096d9fsewardj UWord nLocks = 0, nLocksValid = 0; 834ffce8159a95134f0a2bc1cea3c3e6e265f096d9fsewardj count_LockP_vector(&nLocks, &nLocksValid, locks); 835ffce8159a95134f0a2bc1cea3c3e6e265f096d9fsewardj tl_assert(nLocksValid <= nLocks); 836ffce8159a95134f0a2bc1cea3c3e6e265f096d9fsewardj 837ffce8159a95134f0a2bc1cea3c3e6e265f096d9fsewardj if (nLocks == 0) { 838ffce8159a95134f0a2bc1cea3c3e6e265f096d9fsewardj VG_(umsg)( "%sLocks held: none", pre ); 839ffce8159a95134f0a2bc1cea3c3e6e265f096d9fsewardj } else { 840ffce8159a95134f0a2bc1cea3c3e6e265f096d9fsewardj VG_(umsg)( "%sLocks held: %lu, at address%s ", 841ffce8159a95134f0a2bc1cea3c3e6e265f096d9fsewardj pre, nLocks, nLocksValid == 1 ? "" : "es" ); 842ffce8159a95134f0a2bc1cea3c3e6e265f096d9fsewardj } 843ffce8159a95134f0a2bc1cea3c3e6e265f096d9fsewardj 844ffce8159a95134f0a2bc1cea3c3e6e265f096d9fsewardj if (nLocks > 0) { 845ffce8159a95134f0a2bc1cea3c3e6e265f096d9fsewardj for (i = 0; i < nLocks; i++) { 846ffce8159a95134f0a2bc1cea3c3e6e265f096d9fsewardj if (locks[i] == Lock_INVALID) 847ffce8159a95134f0a2bc1cea3c3e6e265f096d9fsewardj continue; 848ffce8159a95134f0a2bc1cea3c3e6e265f096d9fsewardj VG_(umsg)( "%p", (void*)locks[i]->guestaddr); 849ffce8159a95134f0a2bc1cea3c3e6e265f096d9fsewardj if (locks[i+1] != NULL) 850ffce8159a95134f0a2bc1cea3c3e6e265f096d9fsewardj VG_(umsg)(" "); 851ffce8159a95134f0a2bc1cea3c3e6e265f096d9fsewardj } 852ffce8159a95134f0a2bc1cea3c3e6e265f096d9fsewardj if (nLocksValid < nLocks) 853ffce8159a95134f0a2bc1cea3c3e6e265f096d9fsewardj VG_(umsg)(" (and %lu that can't be shown)", nLocks - nLocksValid); 854ffce8159a95134f0a2bc1cea3c3e6e265f096d9fsewardj } 855ffce8159a95134f0a2bc1cea3c3e6e265f096d9fsewardj VG_(umsg)("\n"); 856ffce8159a95134f0a2bc1cea3c3e6e265f096d9fsewardj} 857ffce8159a95134f0a2bc1cea3c3e6e265f096d9fsewardj 858ffce8159a95134f0a2bc1cea3c3e6e265f096d9fsewardj 85924118491f347852bc311069a273fce13608dd531sewardj/* This is the "this error is due to be printed shortly; so have a 86024118491f347852bc311069a273fce13608dd531sewardj look at it any print any preamble you want" function. We use it to 86124118491f347852bc311069a273fce13608dd531sewardj announce any previously un-announced threads in the upcoming error 86224118491f347852bc311069a273fce13608dd531sewardj message. 86324118491f347852bc311069a273fce13608dd531sewardj*/ 8648e3fbb5cd8276a7d07d5712bc05f9b3376d81a6aflorianvoid HG_(before_pp_Error) ( const Error* err ) 86524118491f347852bc311069a273fce13608dd531sewardj{ 86624118491f347852bc311069a273fce13608dd531sewardj XError* xe; 86724118491f347852bc311069a273fce13608dd531sewardj tl_assert(err); 86824118491f347852bc311069a273fce13608dd531sewardj xe = (XError*)VG_(get_error_extra)(err); 86924118491f347852bc311069a273fce13608dd531sewardj tl_assert(xe); 87024118491f347852bc311069a273fce13608dd531sewardj 87124118491f347852bc311069a273fce13608dd531sewardj switch (VG_(get_error_kind)(err)) { 87224118491f347852bc311069a273fce13608dd531sewardj case XE_Misc: 87324118491f347852bc311069a273fce13608dd531sewardj announce_one_thread( xe->XE.Misc.thr ); 87424118491f347852bc311069a273fce13608dd531sewardj break; 87524118491f347852bc311069a273fce13608dd531sewardj case XE_LockOrder: 87624118491f347852bc311069a273fce13608dd531sewardj announce_one_thread( xe->XE.LockOrder.thr ); 87724118491f347852bc311069a273fce13608dd531sewardj break; 87824118491f347852bc311069a273fce13608dd531sewardj case XE_PthAPIerror: 87924118491f347852bc311069a273fce13608dd531sewardj announce_one_thread( xe->XE.PthAPIerror.thr ); 88024118491f347852bc311069a273fce13608dd531sewardj break; 88124118491f347852bc311069a273fce13608dd531sewardj case XE_UnlockBogus: 88224118491f347852bc311069a273fce13608dd531sewardj announce_one_thread( xe->XE.UnlockBogus.thr ); 88324118491f347852bc311069a273fce13608dd531sewardj break; 88424118491f347852bc311069a273fce13608dd531sewardj case XE_UnlockForeign: 88524118491f347852bc311069a273fce13608dd531sewardj announce_one_thread( xe->XE.UnlockForeign.thr ); 88624118491f347852bc311069a273fce13608dd531sewardj announce_one_thread( xe->XE.UnlockForeign.owner ); 88724118491f347852bc311069a273fce13608dd531sewardj break; 88824118491f347852bc311069a273fce13608dd531sewardj case XE_UnlockUnlocked: 88924118491f347852bc311069a273fce13608dd531sewardj announce_one_thread( xe->XE.UnlockUnlocked.thr ); 89024118491f347852bc311069a273fce13608dd531sewardj break; 89124118491f347852bc311069a273fce13608dd531sewardj case XE_Race: 89224118491f347852bc311069a273fce13608dd531sewardj announce_one_thread( xe->XE.Race.thr ); 89323f1200ba3aa3d8dbb484626ba1bdb7cfcf3b3a9sewardj if (xe->XE.Race.h2_ct) 89423f1200ba3aa3d8dbb484626ba1bdb7cfcf3b3a9sewardj announce_one_thread( xe->XE.Race.h2_ct ); 89523f1200ba3aa3d8dbb484626ba1bdb7cfcf3b3a9sewardj if (xe->XE.Race.h1_ct) 89623f1200ba3aa3d8dbb484626ba1bdb7cfcf3b3a9sewardj announce_one_thread( xe->XE.Race.h1_ct ); 8970c9ac8d0deca2f2a552fb2b0cab24efe6191bac7philippe if (xe->XE.Race.data_addrinfo.Addr.Block.alloc_tinfo.tnr) { 8980c9ac8d0deca2f2a552fb2b0cab24efe6191bac7philippe Thread* thr = get_admin_threads(); 8990c9ac8d0deca2f2a552fb2b0cab24efe6191bac7philippe while (thr) { 9000c9ac8d0deca2f2a552fb2b0cab24efe6191bac7philippe if (thr->errmsg_index 9010c9ac8d0deca2f2a552fb2b0cab24efe6191bac7philippe == xe->XE.Race.data_addrinfo.Addr.Block.alloc_tinfo.tnr) { 9020c9ac8d0deca2f2a552fb2b0cab24efe6191bac7philippe announce_one_thread (thr); 9030c9ac8d0deca2f2a552fb2b0cab24efe6191bac7philippe break; 9040c9ac8d0deca2f2a552fb2b0cab24efe6191bac7philippe } 9050c9ac8d0deca2f2a552fb2b0cab24efe6191bac7philippe thr = thr->admin; 9060c9ac8d0deca2f2a552fb2b0cab24efe6191bac7philippe } 9070c9ac8d0deca2f2a552fb2b0cab24efe6191bac7philippe } 90824118491f347852bc311069a273fce13608dd531sewardj break; 90924118491f347852bc311069a273fce13608dd531sewardj default: 91024118491f347852bc311069a273fce13608dd531sewardj tl_assert(0); 911f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj } 912f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj} 913f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj 9148e3fbb5cd8276a7d07d5712bc05f9b3376d81a6aflorianvoid HG_(pp_Error) ( const Error* err ) 915f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj{ 91624118491f347852bc311069a273fce13608dd531sewardj const Bool xml = VG_(clo_xml); /* a shorthand, that's all */ 91724118491f347852bc311069a273fce13608dd531sewardj 918ffce8159a95134f0a2bc1cea3c3e6e265f096d9fsewardj if (!xml) { 919ffce8159a95134f0a2bc1cea3c3e6e265f096d9fsewardj VG_(umsg)("--------------------------------" 920ffce8159a95134f0a2bc1cea3c3e6e265f096d9fsewardj "--------------------------------" "\n"); 921ffce8159a95134f0a2bc1cea3c3e6e265f096d9fsewardj VG_(umsg)("\n"); 922ffce8159a95134f0a2bc1cea3c3e6e265f096d9fsewardj } 923ffce8159a95134f0a2bc1cea3c3e6e265f096d9fsewardj 924f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj XError *xe = (XError*)VG_(get_error_extra)(err); 92524118491f347852bc311069a273fce13608dd531sewardj tl_assert(xe); 926f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj 9272fa18d9ea5474392ec055e8e553a409ae36719cebart if (xml) 9282fa18d9ea5474392ec055e8e553a409ae36719cebart emit( " <kind>%s</kind>\n", HG_(get_error_name)(err)); 9292fa18d9ea5474392ec055e8e553a409ae36719cebart 930f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj switch (VG_(get_error_kind)(err)) { 931f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj 932f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj case XE_Misc: { 933f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj tl_assert( HG_(is_sane_Thread)( xe->XE.Misc.thr ) ); 93424118491f347852bc311069a273fce13608dd531sewardj 93524118491f347852bc311069a273fce13608dd531sewardj if (xml) { 93624118491f347852bc311069a273fce13608dd531sewardj 93724118491f347852bc311069a273fce13608dd531sewardj emit( " <xwhat>\n" ); 93824118491f347852bc311069a273fce13608dd531sewardj emit( " <text>Thread #%d: %s</text>\n", 93924118491f347852bc311069a273fce13608dd531sewardj (Int)xe->XE.Misc.thr->errmsg_index, 94024118491f347852bc311069a273fce13608dd531sewardj xe->XE.Misc.errstr ); 94124118491f347852bc311069a273fce13608dd531sewardj emit( " <hthreadid>%d</hthreadid>\n", 94224118491f347852bc311069a273fce13608dd531sewardj (Int)xe->XE.Misc.thr->errmsg_index ); 94324118491f347852bc311069a273fce13608dd531sewardj emit( " </xwhat>\n" ); 94424118491f347852bc311069a273fce13608dd531sewardj VG_(pp_ExeContext)( VG_(get_error_where)(err) ); 9458fef62537fc0bcc0903d5be3080152f0e0b3979dsewardj if (xe->XE.Misc.auxstr) { 9468fef62537fc0bcc0903d5be3080152f0e0b3979dsewardj emit(" <auxwhat>%s</auxwhat>\n", xe->XE.Misc.auxstr); 9478fef62537fc0bcc0903d5be3080152f0e0b3979dsewardj if (xe->XE.Misc.auxctx) 9488fef62537fc0bcc0903d5be3080152f0e0b3979dsewardj VG_(pp_ExeContext)( xe->XE.Misc.auxctx ); 9498fef62537fc0bcc0903d5be3080152f0e0b3979dsewardj } 95024118491f347852bc311069a273fce13608dd531sewardj 95124118491f347852bc311069a273fce13608dd531sewardj } else { 95224118491f347852bc311069a273fce13608dd531sewardj 95324118491f347852bc311069a273fce13608dd531sewardj emit( "Thread #%d: %s\n", 95424118491f347852bc311069a273fce13608dd531sewardj (Int)xe->XE.Misc.thr->errmsg_index, 95524118491f347852bc311069a273fce13608dd531sewardj xe->XE.Misc.errstr ); 95624118491f347852bc311069a273fce13608dd531sewardj VG_(pp_ExeContext)( VG_(get_error_where)(err) ); 9578fef62537fc0bcc0903d5be3080152f0e0b3979dsewardj if (xe->XE.Misc.auxstr) { 9588fef62537fc0bcc0903d5be3080152f0e0b3979dsewardj emit(" %s\n", xe->XE.Misc.auxstr); 9598fef62537fc0bcc0903d5be3080152f0e0b3979dsewardj if (xe->XE.Misc.auxctx) 9608fef62537fc0bcc0903d5be3080152f0e0b3979dsewardj VG_(pp_ExeContext)( xe->XE.Misc.auxctx ); 9618fef62537fc0bcc0903d5be3080152f0e0b3979dsewardj } 96224118491f347852bc311069a273fce13608dd531sewardj 96324118491f347852bc311069a273fce13608dd531sewardj } 964f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj break; 965f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj } 966f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj 967f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj case XE_LockOrder: { 968f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj tl_assert( HG_(is_sane_Thread)( xe->XE.LockOrder.thr ) ); 96924118491f347852bc311069a273fce13608dd531sewardj 97024118491f347852bc311069a273fce13608dd531sewardj if (xml) { 97124118491f347852bc311069a273fce13608dd531sewardj 97224118491f347852bc311069a273fce13608dd531sewardj emit( " <xwhat>\n" ); 97324118491f347852bc311069a273fce13608dd531sewardj emit( " <text>Thread #%d: lock order \"%p before %p\" " 97424118491f347852bc311069a273fce13608dd531sewardj "violated</text>\n", 97524118491f347852bc311069a273fce13608dd531sewardj (Int)xe->XE.LockOrder.thr->errmsg_index, 97646daf0d598c38c9251964712d894f0fcd3cc4143philippe (void*)xe->XE.LockOrder.shouldbe_earlier_lk->guestaddr, 97746daf0d598c38c9251964712d894f0fcd3cc4143philippe (void*)xe->XE.LockOrder.shouldbe_later_lk->guestaddr ); 97824118491f347852bc311069a273fce13608dd531sewardj emit( " <hthreadid>%d</hthreadid>\n", 97924118491f347852bc311069a273fce13608dd531sewardj (Int)xe->XE.LockOrder.thr->errmsg_index ); 98024118491f347852bc311069a273fce13608dd531sewardj emit( " </xwhat>\n" ); 98124118491f347852bc311069a273fce13608dd531sewardj VG_(pp_ExeContext)( VG_(get_error_where)(err) ); 982ffce8159a95134f0a2bc1cea3c3e6e265f096d9fsewardj if (xe->XE.LockOrder.shouldbe_earlier_ec 983ffce8159a95134f0a2bc1cea3c3e6e265f096d9fsewardj && xe->XE.LockOrder.shouldbe_later_ec) { 98424118491f347852bc311069a273fce13608dd531sewardj emit( " <auxwhat>Required order was established by " 98524118491f347852bc311069a273fce13608dd531sewardj "acquisition of lock at %p</auxwhat>\n", 98646daf0d598c38c9251964712d894f0fcd3cc4143philippe (void*)xe->XE.LockOrder.shouldbe_earlier_lk->guestaddr ); 987ffce8159a95134f0a2bc1cea3c3e6e265f096d9fsewardj VG_(pp_ExeContext)( xe->XE.LockOrder.shouldbe_earlier_ec ); 98824118491f347852bc311069a273fce13608dd531sewardj emit( " <auxwhat>followed by a later acquisition " 98924118491f347852bc311069a273fce13608dd531sewardj "of lock at %p</auxwhat>\n", 99046daf0d598c38c9251964712d894f0fcd3cc4143philippe (void*)xe->XE.LockOrder.shouldbe_later_lk->guestaddr ); 991ffce8159a95134f0a2bc1cea3c3e6e265f096d9fsewardj VG_(pp_ExeContext)( xe->XE.LockOrder.shouldbe_later_ec ); 99224118491f347852bc311069a273fce13608dd531sewardj } 99346daf0d598c38c9251964712d894f0fcd3cc4143philippe announce_LockP ( xe->XE.LockOrder.shouldbe_earlier_lk ); 99446daf0d598c38c9251964712d894f0fcd3cc4143philippe announce_LockP ( xe->XE.LockOrder.shouldbe_later_lk ); 99524118491f347852bc311069a273fce13608dd531sewardj 99624118491f347852bc311069a273fce13608dd531sewardj } else { 99724118491f347852bc311069a273fce13608dd531sewardj 99824118491f347852bc311069a273fce13608dd531sewardj emit( "Thread #%d: lock order \"%p before %p\" violated\n", 99924118491f347852bc311069a273fce13608dd531sewardj (Int)xe->XE.LockOrder.thr->errmsg_index, 100046daf0d598c38c9251964712d894f0fcd3cc4143philippe (void*)xe->XE.LockOrder.shouldbe_earlier_lk->guestaddr, 100146daf0d598c38c9251964712d894f0fcd3cc4143philippe (void*)xe->XE.LockOrder.shouldbe_later_lk->guestaddr ); 1002ffce8159a95134f0a2bc1cea3c3e6e265f096d9fsewardj emit( "\n" ); 1003ffce8159a95134f0a2bc1cea3c3e6e265f096d9fsewardj emit( "Observed (incorrect) order is: " 1004ffce8159a95134f0a2bc1cea3c3e6e265f096d9fsewardj "acquisition of lock at %p\n", 100546daf0d598c38c9251964712d894f0fcd3cc4143philippe (void*)xe->XE.LockOrder.shouldbe_later_lk->guestaddr); 1006ffce8159a95134f0a2bc1cea3c3e6e265f096d9fsewardj if (xe->XE.LockOrder.actual_earlier_ec) { 1007ffce8159a95134f0a2bc1cea3c3e6e265f096d9fsewardj VG_(pp_ExeContext)(xe->XE.LockOrder.actual_earlier_ec); 1008ffce8159a95134f0a2bc1cea3c3e6e265f096d9fsewardj } else { 1009ffce8159a95134f0a2bc1cea3c3e6e265f096d9fsewardj emit(" (stack unavailable)\n"); 1010ffce8159a95134f0a2bc1cea3c3e6e265f096d9fsewardj } 1011ffce8159a95134f0a2bc1cea3c3e6e265f096d9fsewardj emit( "\n" ); 1012ffce8159a95134f0a2bc1cea3c3e6e265f096d9fsewardj emit(" followed by a later acquisition of lock at %p\n", 101346daf0d598c38c9251964712d894f0fcd3cc4143philippe (void*)xe->XE.LockOrder.shouldbe_earlier_lk->guestaddr); 101424118491f347852bc311069a273fce13608dd531sewardj VG_(pp_ExeContext)( VG_(get_error_where)(err) ); 1015ffce8159a95134f0a2bc1cea3c3e6e265f096d9fsewardj if (xe->XE.LockOrder.shouldbe_earlier_ec 1016ffce8159a95134f0a2bc1cea3c3e6e265f096d9fsewardj && xe->XE.LockOrder.shouldbe_later_ec) { 1017ffce8159a95134f0a2bc1cea3c3e6e265f096d9fsewardj emit("\n"); 1018ffce8159a95134f0a2bc1cea3c3e6e265f096d9fsewardj emit( "Required order was established by " 101924118491f347852bc311069a273fce13608dd531sewardj "acquisition of lock at %p\n", 102046daf0d598c38c9251964712d894f0fcd3cc4143philippe (void*)xe->XE.LockOrder.shouldbe_earlier_lk->guestaddr ); 1021ffce8159a95134f0a2bc1cea3c3e6e265f096d9fsewardj VG_(pp_ExeContext)( xe->XE.LockOrder.shouldbe_earlier_ec ); 1022ffce8159a95134f0a2bc1cea3c3e6e265f096d9fsewardj emit( "\n" ); 1023ffce8159a95134f0a2bc1cea3c3e6e265f096d9fsewardj emit( " followed by a later acquisition of lock at %p\n", 102446daf0d598c38c9251964712d894f0fcd3cc4143philippe (void*)xe->XE.LockOrder.shouldbe_later_lk->guestaddr ); 1025ffce8159a95134f0a2bc1cea3c3e6e265f096d9fsewardj VG_(pp_ExeContext)( xe->XE.LockOrder.shouldbe_later_ec ); 102624118491f347852bc311069a273fce13608dd531sewardj } 102746daf0d598c38c9251964712d894f0fcd3cc4143philippe emit("\n"); 102846daf0d598c38c9251964712d894f0fcd3cc4143philippe announce_LockP ( xe->XE.LockOrder.shouldbe_earlier_lk ); 102946daf0d598c38c9251964712d894f0fcd3cc4143philippe announce_LockP ( xe->XE.LockOrder.shouldbe_later_lk ); 103024118491f347852bc311069a273fce13608dd531sewardj 1031f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj } 103224118491f347852bc311069a273fce13608dd531sewardj 1033f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj break; 1034f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj } 1035f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj 1036f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj case XE_PthAPIerror: { 1037f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj tl_assert( HG_(is_sane_Thread)( xe->XE.PthAPIerror.thr ) ); 103824118491f347852bc311069a273fce13608dd531sewardj 103924118491f347852bc311069a273fce13608dd531sewardj if (xml) { 104024118491f347852bc311069a273fce13608dd531sewardj 104124118491f347852bc311069a273fce13608dd531sewardj emit( " <xwhat>\n" ); 1042b3af9cf0b234d0d188347d92944e04ac9c8fbcd0bart emit( 1043b3af9cf0b234d0d188347d92944e04ac9c8fbcd0bart " <text>Thread #%d's call to %pS failed</text>\n", 104424118491f347852bc311069a273fce13608dd531sewardj (Int)xe->XE.PthAPIerror.thr->errmsg_index, 104524118491f347852bc311069a273fce13608dd531sewardj xe->XE.PthAPIerror.fnname ); 104624118491f347852bc311069a273fce13608dd531sewardj emit( " <hthreadid>%d</hthreadid>\n", 104724118491f347852bc311069a273fce13608dd531sewardj (Int)xe->XE.PthAPIerror.thr->errmsg_index ); 104824118491f347852bc311069a273fce13608dd531sewardj emit( " </xwhat>\n" ); 104924118491f347852bc311069a273fce13608dd531sewardj emit( " <what>with error code %ld (%s)</what>\n", 105024118491f347852bc311069a273fce13608dd531sewardj xe->XE.PthAPIerror.err, xe->XE.PthAPIerror.errstr ); 105124118491f347852bc311069a273fce13608dd531sewardj VG_(pp_ExeContext)( VG_(get_error_where)(err) ); 105224118491f347852bc311069a273fce13608dd531sewardj 105324118491f347852bc311069a273fce13608dd531sewardj } else { 105424118491f347852bc311069a273fce13608dd531sewardj 1055b3af9cf0b234d0d188347d92944e04ac9c8fbcd0bart emit( "Thread #%d's call to %pS failed\n", 105624118491f347852bc311069a273fce13608dd531sewardj (Int)xe->XE.PthAPIerror.thr->errmsg_index, 105724118491f347852bc311069a273fce13608dd531sewardj xe->XE.PthAPIerror.fnname ); 105824118491f347852bc311069a273fce13608dd531sewardj emit( " with error code %ld (%s)\n", 105924118491f347852bc311069a273fce13608dd531sewardj xe->XE.PthAPIerror.err, xe->XE.PthAPIerror.errstr ); 106024118491f347852bc311069a273fce13608dd531sewardj VG_(pp_ExeContext)( VG_(get_error_where)(err) ); 106124118491f347852bc311069a273fce13608dd531sewardj 106224118491f347852bc311069a273fce13608dd531sewardj } 106324118491f347852bc311069a273fce13608dd531sewardj 1064f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj break; 1065f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj } 1066f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj 1067f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj case XE_UnlockBogus: { 1068f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj tl_assert( HG_(is_sane_Thread)( xe->XE.UnlockBogus.thr ) ); 106924118491f347852bc311069a273fce13608dd531sewardj 107024118491f347852bc311069a273fce13608dd531sewardj if (xml) { 107124118491f347852bc311069a273fce13608dd531sewardj 107224118491f347852bc311069a273fce13608dd531sewardj emit( " <xwhat>\n" ); 107324118491f347852bc311069a273fce13608dd531sewardj emit( " <text>Thread #%d unlocked an invalid " 107424118491f347852bc311069a273fce13608dd531sewardj "lock at %p</text>\n", 107524118491f347852bc311069a273fce13608dd531sewardj (Int)xe->XE.UnlockBogus.thr->errmsg_index, 107624118491f347852bc311069a273fce13608dd531sewardj (void*)xe->XE.UnlockBogus.lock_ga ); 107724118491f347852bc311069a273fce13608dd531sewardj emit( " <hthreadid>%d</hthreadid>\n", 107824118491f347852bc311069a273fce13608dd531sewardj (Int)xe->XE.UnlockBogus.thr->errmsg_index ); 107924118491f347852bc311069a273fce13608dd531sewardj emit( " </xwhat>\n" ); 108024118491f347852bc311069a273fce13608dd531sewardj VG_(pp_ExeContext)( VG_(get_error_where)(err) ); 108124118491f347852bc311069a273fce13608dd531sewardj 108224118491f347852bc311069a273fce13608dd531sewardj } else { 108324118491f347852bc311069a273fce13608dd531sewardj 108424118491f347852bc311069a273fce13608dd531sewardj emit( "Thread #%d unlocked an invalid lock at %p\n", 108524118491f347852bc311069a273fce13608dd531sewardj (Int)xe->XE.UnlockBogus.thr->errmsg_index, 108624118491f347852bc311069a273fce13608dd531sewardj (void*)xe->XE.UnlockBogus.lock_ga ); 108724118491f347852bc311069a273fce13608dd531sewardj VG_(pp_ExeContext)( VG_(get_error_where)(err) ); 108824118491f347852bc311069a273fce13608dd531sewardj 108924118491f347852bc311069a273fce13608dd531sewardj } 109024118491f347852bc311069a273fce13608dd531sewardj 1091f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj break; 1092f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj } 1093f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj 1094f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj case XE_UnlockForeign: { 1095f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj tl_assert( HG_(is_sane_LockP)( xe->XE.UnlockForeign.lock ) ); 1096f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj tl_assert( HG_(is_sane_Thread)( xe->XE.UnlockForeign.owner ) ); 1097f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj tl_assert( HG_(is_sane_Thread)( xe->XE.UnlockForeign.thr ) ); 109824118491f347852bc311069a273fce13608dd531sewardj 109924118491f347852bc311069a273fce13608dd531sewardj if (xml) { 110024118491f347852bc311069a273fce13608dd531sewardj 110124118491f347852bc311069a273fce13608dd531sewardj emit( " <xwhat>\n" ); 110224118491f347852bc311069a273fce13608dd531sewardj emit( " <text>Thread #%d unlocked lock at %p " 110324118491f347852bc311069a273fce13608dd531sewardj "currently held by thread #%d</text>\n", 110424118491f347852bc311069a273fce13608dd531sewardj (Int)xe->XE.UnlockForeign.thr->errmsg_index, 110524118491f347852bc311069a273fce13608dd531sewardj (void*)xe->XE.UnlockForeign.lock->guestaddr, 110624118491f347852bc311069a273fce13608dd531sewardj (Int)xe->XE.UnlockForeign.owner->errmsg_index ); 110724118491f347852bc311069a273fce13608dd531sewardj emit( " <hthreadid>%d</hthreadid>\n", 110824118491f347852bc311069a273fce13608dd531sewardj (Int)xe->XE.UnlockForeign.thr->errmsg_index ); 110924118491f347852bc311069a273fce13608dd531sewardj emit( " <hthreadid>%d</hthreadid>\n", 111024118491f347852bc311069a273fce13608dd531sewardj (Int)xe->XE.UnlockForeign.owner->errmsg_index ); 111124118491f347852bc311069a273fce13608dd531sewardj emit( " </xwhat>\n" ); 111224118491f347852bc311069a273fce13608dd531sewardj VG_(pp_ExeContext)( VG_(get_error_where)(err) ); 111346daf0d598c38c9251964712d894f0fcd3cc4143philippe announce_LockP ( xe->XE.UnlockForeign.lock ); 111424118491f347852bc311069a273fce13608dd531sewardj 111524118491f347852bc311069a273fce13608dd531sewardj } else { 111624118491f347852bc311069a273fce13608dd531sewardj 111724118491f347852bc311069a273fce13608dd531sewardj emit( "Thread #%d unlocked lock at %p " 111824118491f347852bc311069a273fce13608dd531sewardj "currently held by thread #%d\n", 111924118491f347852bc311069a273fce13608dd531sewardj (Int)xe->XE.UnlockForeign.thr->errmsg_index, 112024118491f347852bc311069a273fce13608dd531sewardj (void*)xe->XE.UnlockForeign.lock->guestaddr, 112124118491f347852bc311069a273fce13608dd531sewardj (Int)xe->XE.UnlockForeign.owner->errmsg_index ); 112224118491f347852bc311069a273fce13608dd531sewardj VG_(pp_ExeContext)( VG_(get_error_where)(err) ); 112346daf0d598c38c9251964712d894f0fcd3cc4143philippe announce_LockP ( xe->XE.UnlockForeign.lock ); 112424118491f347852bc311069a273fce13608dd531sewardj 1125f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj } 112624118491f347852bc311069a273fce13608dd531sewardj 1127f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj break; 1128f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj } 1129f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj 1130f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj case XE_UnlockUnlocked: { 1131f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj tl_assert( HG_(is_sane_LockP)( xe->XE.UnlockUnlocked.lock ) ); 1132f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj tl_assert( HG_(is_sane_Thread)( xe->XE.UnlockUnlocked.thr ) ); 1133f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj 113424118491f347852bc311069a273fce13608dd531sewardj if (xml) { 113524118491f347852bc311069a273fce13608dd531sewardj 113624118491f347852bc311069a273fce13608dd531sewardj emit( " <xwhat>\n" ); 113724118491f347852bc311069a273fce13608dd531sewardj emit( " <text>Thread #%d unlocked a " 113824118491f347852bc311069a273fce13608dd531sewardj "not-locked lock at %p</text>\n", 113924118491f347852bc311069a273fce13608dd531sewardj (Int)xe->XE.UnlockUnlocked.thr->errmsg_index, 114024118491f347852bc311069a273fce13608dd531sewardj (void*)xe->XE.UnlockUnlocked.lock->guestaddr ); 114124118491f347852bc311069a273fce13608dd531sewardj emit( " <hthreadid>%d</hthreadid>\n", 114224118491f347852bc311069a273fce13608dd531sewardj (Int)xe->XE.UnlockUnlocked.thr->errmsg_index ); 114324118491f347852bc311069a273fce13608dd531sewardj emit( " </xwhat>\n" ); 114424118491f347852bc311069a273fce13608dd531sewardj VG_(pp_ExeContext)( VG_(get_error_where)(err) ); 114546daf0d598c38c9251964712d894f0fcd3cc4143philippe announce_LockP ( xe->XE.UnlockUnlocked.lock); 114624118491f347852bc311069a273fce13608dd531sewardj 114724118491f347852bc311069a273fce13608dd531sewardj } else { 114824118491f347852bc311069a273fce13608dd531sewardj 114924118491f347852bc311069a273fce13608dd531sewardj emit( "Thread #%d unlocked a not-locked lock at %p\n", 115024118491f347852bc311069a273fce13608dd531sewardj (Int)xe->XE.UnlockUnlocked.thr->errmsg_index, 115124118491f347852bc311069a273fce13608dd531sewardj (void*)xe->XE.UnlockUnlocked.lock->guestaddr ); 115224118491f347852bc311069a273fce13608dd531sewardj VG_(pp_ExeContext)( VG_(get_error_where)(err) ); 115346daf0d598c38c9251964712d894f0fcd3cc4143philippe announce_LockP ( xe->XE.UnlockUnlocked.lock); 115424118491f347852bc311069a273fce13608dd531sewardj 1155f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj } 115624118491f347852bc311069a273fce13608dd531sewardj 1157f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj break; 1158f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj } 1159f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj 1160f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj case XE_Race: { 1161f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj Addr err_ga; 11626bf3726ebf7a04ca48a5e6cb1ad7a3065054e54eflorian const HChar* what; 1163f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj Int szB; 1164f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj what = xe->XE.Race.isWrite ? "write" : "read"; 1165f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj szB = xe->XE.Race.szB; 1166f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj err_ga = VG_(get_error_address)(err); 1167f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj 116824118491f347852bc311069a273fce13608dd531sewardj tl_assert( HG_(is_sane_Thread)( xe->XE.Race.thr )); 116923f1200ba3aa3d8dbb484626ba1bdb7cfcf3b3a9sewardj if (xe->XE.Race.h2_ct) 117023f1200ba3aa3d8dbb484626ba1bdb7cfcf3b3a9sewardj tl_assert( HG_(is_sane_Thread)( xe->XE.Race.h2_ct )); 117124118491f347852bc311069a273fce13608dd531sewardj 117224118491f347852bc311069a273fce13608dd531sewardj if (xml) { 117324118491f347852bc311069a273fce13608dd531sewardj 117424118491f347852bc311069a273fce13608dd531sewardj /* ------ XML ------ */ 117524118491f347852bc311069a273fce13608dd531sewardj emit( " <xwhat>\n" ); 117624118491f347852bc311069a273fce13608dd531sewardj emit( " <text>Possible data race during %s of size %d " 1177ffce8159a95134f0a2bc1cea3c3e6e265f096d9fsewardj "at %p by thread #%d</text>\n", 1178ffce8159a95134f0a2bc1cea3c3e6e265f096d9fsewardj what, szB, (void*)err_ga, (Int)xe->XE.Race.thr->errmsg_index ); 117924118491f347852bc311069a273fce13608dd531sewardj emit( " <hthreadid>%d</hthreadid>\n", 118024118491f347852bc311069a273fce13608dd531sewardj (Int)xe->XE.Race.thr->errmsg_index ); 118124118491f347852bc311069a273fce13608dd531sewardj emit( " </xwhat>\n" ); 118224118491f347852bc311069a273fce13608dd531sewardj VG_(pp_ExeContext)( VG_(get_error_where)(err) ); 118324118491f347852bc311069a273fce13608dd531sewardj 118423f1200ba3aa3d8dbb484626ba1bdb7cfcf3b3a9sewardj if (xe->XE.Race.h2_ct) { 118523f1200ba3aa3d8dbb484626ba1bdb7cfcf3b3a9sewardj tl_assert(xe->XE.Race.h2_ct_accEC); // assured by update_extra 118623f1200ba3aa3d8dbb484626ba1bdb7cfcf3b3a9sewardj emit( " <xauxwhat>\n"); 118723f1200ba3aa3d8dbb484626ba1bdb7cfcf3b3a9sewardj emit( " <text>This conflicts with a previous %s of size %d " 118823f1200ba3aa3d8dbb484626ba1bdb7cfcf3b3a9sewardj "by thread #%d</text>\n", 118923f1200ba3aa3d8dbb484626ba1bdb7cfcf3b3a9sewardj xe->XE.Race.h2_ct_accIsW ? "write" : "read", 119023f1200ba3aa3d8dbb484626ba1bdb7cfcf3b3a9sewardj xe->XE.Race.h2_ct_accSzB, 119123f1200ba3aa3d8dbb484626ba1bdb7cfcf3b3a9sewardj xe->XE.Race.h2_ct->errmsg_index ); 119223f1200ba3aa3d8dbb484626ba1bdb7cfcf3b3a9sewardj emit( " <hthreadid>%d</hthreadid>\n", 119323f1200ba3aa3d8dbb484626ba1bdb7cfcf3b3a9sewardj xe->XE.Race.h2_ct->errmsg_index); 119423f1200ba3aa3d8dbb484626ba1bdb7cfcf3b3a9sewardj emit(" </xauxwhat>\n"); 119523f1200ba3aa3d8dbb484626ba1bdb7cfcf3b3a9sewardj VG_(pp_ExeContext)( xe->XE.Race.h2_ct_accEC ); 119623f1200ba3aa3d8dbb484626ba1bdb7cfcf3b3a9sewardj } 119723f1200ba3aa3d8dbb484626ba1bdb7cfcf3b3a9sewardj 119823f1200ba3aa3d8dbb484626ba1bdb7cfcf3b3a9sewardj if (xe->XE.Race.h1_ct) { 119923f1200ba3aa3d8dbb484626ba1bdb7cfcf3b3a9sewardj emit( " <xauxwhat>\n"); 120023f1200ba3aa3d8dbb484626ba1bdb7cfcf3b3a9sewardj emit( " <text>This conflicts with a previous access " 120123f1200ba3aa3d8dbb484626ba1bdb7cfcf3b3a9sewardj "by thread #%d, after</text>\n", 120223f1200ba3aa3d8dbb484626ba1bdb7cfcf3b3a9sewardj xe->XE.Race.h1_ct->errmsg_index ); 120323f1200ba3aa3d8dbb484626ba1bdb7cfcf3b3a9sewardj emit( " <hthreadid>%d</hthreadid>\n", 120423f1200ba3aa3d8dbb484626ba1bdb7cfcf3b3a9sewardj xe->XE.Race.h1_ct->errmsg_index ); 120523f1200ba3aa3d8dbb484626ba1bdb7cfcf3b3a9sewardj emit(" </xauxwhat>\n"); 120623f1200ba3aa3d8dbb484626ba1bdb7cfcf3b3a9sewardj if (xe->XE.Race.h1_ct_mbsegstartEC) { 120723f1200ba3aa3d8dbb484626ba1bdb7cfcf3b3a9sewardj VG_(pp_ExeContext)( xe->XE.Race.h1_ct_mbsegstartEC ); 120824118491f347852bc311069a273fce13608dd531sewardj } else { 120923f1200ba3aa3d8dbb484626ba1bdb7cfcf3b3a9sewardj emit( " <auxwhat>(the start of the thread)</auxwhat>\n" ); 121023f1200ba3aa3d8dbb484626ba1bdb7cfcf3b3a9sewardj } 121123f1200ba3aa3d8dbb484626ba1bdb7cfcf3b3a9sewardj emit( " <auxwhat>but before</auxwhat>\n" ); 121223f1200ba3aa3d8dbb484626ba1bdb7cfcf3b3a9sewardj if (xe->XE.Race.h1_ct_mbsegendEC) { 121323f1200ba3aa3d8dbb484626ba1bdb7cfcf3b3a9sewardj VG_(pp_ExeContext)( xe->XE.Race.h1_ct_mbsegendEC ); 121423f1200ba3aa3d8dbb484626ba1bdb7cfcf3b3a9sewardj } else { 1215ad4e979f408239dabbaae955d8ffcb84a51a5c85florian emit( " <auxwhat>(the end of the thread)</auxwhat>\n" ); 121624118491f347852bc311069a273fce13608dd531sewardj } 1217f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj } 1218f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj 121924118491f347852bc311069a273fce13608dd531sewardj } else { 122024118491f347852bc311069a273fce13608dd531sewardj 122124118491f347852bc311069a273fce13608dd531sewardj /* ------ Text ------ */ 1222ffce8159a95134f0a2bc1cea3c3e6e265f096d9fsewardj announce_combined_LockP_vecs( xe->XE.Race.locksHeldW, 1223ffce8159a95134f0a2bc1cea3c3e6e265f096d9fsewardj xe->XE.Race.h2_ct_locksHeldW ); 1224ffce8159a95134f0a2bc1cea3c3e6e265f096d9fsewardj 122524118491f347852bc311069a273fce13608dd531sewardj emit( "Possible data race during %s of size %d " 1226ffce8159a95134f0a2bc1cea3c3e6e265f096d9fsewardj "at %p by thread #%d\n", 1227ffce8159a95134f0a2bc1cea3c3e6e265f096d9fsewardj what, szB, (void*)err_ga, (Int)xe->XE.Race.thr->errmsg_index ); 1228ffce8159a95134f0a2bc1cea3c3e6e265f096d9fsewardj 1229ffce8159a95134f0a2bc1cea3c3e6e265f096d9fsewardj tl_assert(xe->XE.Race.locksHeldW); 1230ffce8159a95134f0a2bc1cea3c3e6e265f096d9fsewardj show_LockP_summary_textmode( xe->XE.Race.locksHeldW, "" ); 123124118491f347852bc311069a273fce13608dd531sewardj VG_(pp_ExeContext)( VG_(get_error_where)(err) ); 123223f1200ba3aa3d8dbb484626ba1bdb7cfcf3b3a9sewardj 123323f1200ba3aa3d8dbb484626ba1bdb7cfcf3b3a9sewardj if (xe->XE.Race.h2_ct) { 123423f1200ba3aa3d8dbb484626ba1bdb7cfcf3b3a9sewardj tl_assert(xe->XE.Race.h2_ct_accEC); // assured by update_extra 1235ffce8159a95134f0a2bc1cea3c3e6e265f096d9fsewardj tl_assert(xe->XE.Race.h2_ct_locksHeldW); 1236ffce8159a95134f0a2bc1cea3c3e6e265f096d9fsewardj emit( "\n" ); 1237ffce8159a95134f0a2bc1cea3c3e6e265f096d9fsewardj emit( "This conflicts with a previous %s of size %d " 123823f1200ba3aa3d8dbb484626ba1bdb7cfcf3b3a9sewardj "by thread #%d\n", 123923f1200ba3aa3d8dbb484626ba1bdb7cfcf3b3a9sewardj xe->XE.Race.h2_ct_accIsW ? "write" : "read", 124023f1200ba3aa3d8dbb484626ba1bdb7cfcf3b3a9sewardj xe->XE.Race.h2_ct_accSzB, 124123f1200ba3aa3d8dbb484626ba1bdb7cfcf3b3a9sewardj xe->XE.Race.h2_ct->errmsg_index ); 1242ffce8159a95134f0a2bc1cea3c3e6e265f096d9fsewardj show_LockP_summary_textmode( xe->XE.Race.h2_ct_locksHeldW, "" ); 124323f1200ba3aa3d8dbb484626ba1bdb7cfcf3b3a9sewardj VG_(pp_ExeContext)( xe->XE.Race.h2_ct_accEC ); 124423f1200ba3aa3d8dbb484626ba1bdb7cfcf3b3a9sewardj } 124523f1200ba3aa3d8dbb484626ba1bdb7cfcf3b3a9sewardj 124623f1200ba3aa3d8dbb484626ba1bdb7cfcf3b3a9sewardj if (xe->XE.Race.h1_ct) { 124723f1200ba3aa3d8dbb484626ba1bdb7cfcf3b3a9sewardj emit( " This conflicts with a previous access by thread #%d, " 124823f1200ba3aa3d8dbb484626ba1bdb7cfcf3b3a9sewardj "after\n", 124923f1200ba3aa3d8dbb484626ba1bdb7cfcf3b3a9sewardj xe->XE.Race.h1_ct->errmsg_index ); 125023f1200ba3aa3d8dbb484626ba1bdb7cfcf3b3a9sewardj if (xe->XE.Race.h1_ct_mbsegstartEC) { 125123f1200ba3aa3d8dbb484626ba1bdb7cfcf3b3a9sewardj VG_(pp_ExeContext)( xe->XE.Race.h1_ct_mbsegstartEC ); 125223f1200ba3aa3d8dbb484626ba1bdb7cfcf3b3a9sewardj } else { 125323f1200ba3aa3d8dbb484626ba1bdb7cfcf3b3a9sewardj emit( " (the start of the thread)\n" ); 125423f1200ba3aa3d8dbb484626ba1bdb7cfcf3b3a9sewardj } 125523f1200ba3aa3d8dbb484626ba1bdb7cfcf3b3a9sewardj emit( " but before\n" ); 125623f1200ba3aa3d8dbb484626ba1bdb7cfcf3b3a9sewardj if (xe->XE.Race.h1_ct_mbsegendEC) { 125723f1200ba3aa3d8dbb484626ba1bdb7cfcf3b3a9sewardj VG_(pp_ExeContext)( xe->XE.Race.h1_ct_mbsegendEC ); 125824118491f347852bc311069a273fce13608dd531sewardj } else { 1259ad4e979f408239dabbaae955d8ffcb84a51a5c85florian emit( " (the end of the thread)\n" ); 126024118491f347852bc311069a273fce13608dd531sewardj } 126124118491f347852bc311069a273fce13608dd531sewardj } 126224118491f347852bc311069a273fce13608dd531sewardj 126324118491f347852bc311069a273fce13608dd531sewardj } 126407c08527f05caeb0062b42ca9a58ee774ec5fba1philippe VG_(pp_addrinfo) (err_ga, &xe->XE.Race.data_addrinfo); 1265f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj break; /* case XE_Race */ 1266f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj } /* case XE_Race */ 1267f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj 1268f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj default: 1269f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj tl_assert(0); 1270f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj } /* switch (VG_(get_error_kind)(err)) */ 1271f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj} 1272f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj 1273328d6627c26471332610da3f5a0b9cc3cdd410c7philippevoid HG_(print_access) (StackTrace ips, UInt n_ips, 1274328d6627c26471332610da3f5a0b9cc3cdd410c7philippe Thr* thr_a, 1275328d6627c26471332610da3f5a0b9cc3cdd410c7philippe Addr ga, 1276328d6627c26471332610da3f5a0b9cc3cdd410c7philippe SizeT SzB, 1277328d6627c26471332610da3f5a0b9cc3cdd410c7philippe Bool isW, 1278328d6627c26471332610da3f5a0b9cc3cdd410c7philippe WordSetID locksHeldW ) 1279328d6627c26471332610da3f5a0b9cc3cdd410c7philippe{ 1280328d6627c26471332610da3f5a0b9cc3cdd410c7philippe Thread* threadp; 1281328d6627c26471332610da3f5a0b9cc3cdd410c7philippe 1282328d6627c26471332610da3f5a0b9cc3cdd410c7philippe threadp = libhb_get_Thr_hgthread( thr_a ); 1283328d6627c26471332610da3f5a0b9cc3cdd410c7philippe tl_assert(threadp); 1284328d6627c26471332610da3f5a0b9cc3cdd410c7philippe if (!threadp->announced) { 1285328d6627c26471332610da3f5a0b9cc3cdd410c7philippe /* This is for interactive use. We announce the thread if needed, 1286328d6627c26471332610da3f5a0b9cc3cdd410c7philippe but reset it to not announced afterwards, because we want 1287328d6627c26471332610da3f5a0b9cc3cdd410c7philippe the thread to be announced on the error output/log if needed. */ 1288328d6627c26471332610da3f5a0b9cc3cdd410c7philippe announce_one_thread (threadp); 1289328d6627c26471332610da3f5a0b9cc3cdd410c7philippe threadp->announced = False; 1290328d6627c26471332610da3f5a0b9cc3cdd410c7philippe } 1291328d6627c26471332610da3f5a0b9cc3cdd410c7philippe 1292328d6627c26471332610da3f5a0b9cc3cdd410c7philippe announce_one_thread (threadp); 1293328d6627c26471332610da3f5a0b9cc3cdd410c7philippe VG_(printf) ("%s of size %d at %p by thread #%d", 1294328d6627c26471332610da3f5a0b9cc3cdd410c7philippe isW ? "write" : "read", 1295328d6627c26471332610da3f5a0b9cc3cdd410c7philippe (int)SzB, (void*)ga, threadp->errmsg_index); 1296328d6627c26471332610da3f5a0b9cc3cdd410c7philippe if (threadp->coretid == VG_INVALID_THREADID) 1297328d6627c26471332610da3f5a0b9cc3cdd410c7philippe VG_(printf)(" tid (exited)\n"); 1298328d6627c26471332610da3f5a0b9cc3cdd410c7philippe else 12995e5cb009574352880f1bc530e1a73ddaae5003fcflorian VG_(printf)(" tid %u\n", threadp->coretid); 1300328d6627c26471332610da3f5a0b9cc3cdd410c7philippe { 1301328d6627c26471332610da3f5a0b9cc3cdd410c7philippe Lock** locksHeldW_P; 1302328d6627c26471332610da3f5a0b9cc3cdd410c7philippe locksHeldW_P = enumerate_WordSet_into_LockP_vector( 1303328d6627c26471332610da3f5a0b9cc3cdd410c7philippe HG_(get_univ_lsets)(), 1304328d6627c26471332610da3f5a0b9cc3cdd410c7philippe locksHeldW, 1305328d6627c26471332610da3f5a0b9cc3cdd410c7philippe True/*allowed_to_be_invalid*/ 1306328d6627c26471332610da3f5a0b9cc3cdd410c7philippe ); 1307328d6627c26471332610da3f5a0b9cc3cdd410c7philippe show_LockP_summary_textmode( locksHeldW_P, "" ); 1308328d6627c26471332610da3f5a0b9cc3cdd410c7philippe HG_(free) (locksHeldW_P); 1309328d6627c26471332610da3f5a0b9cc3cdd410c7philippe } 1310328d6627c26471332610da3f5a0b9cc3cdd410c7philippe VG_(pp_StackTrace) (ips, n_ips); 1311328d6627c26471332610da3f5a0b9cc3cdd410c7philippe VG_(printf) ("\n"); 1312328d6627c26471332610da3f5a0b9cc3cdd410c7philippe} 1313328d6627c26471332610da3f5a0b9cc3cdd410c7philippe 13148e3fbb5cd8276a7d07d5712bc05f9b3376d81a6aflorianconst HChar* HG_(get_error_name) ( const Error* err ) 1315f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj{ 1316f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj switch (VG_(get_error_kind)(err)) { 1317f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj case XE_Race: return "Race"; 1318f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj case XE_UnlockUnlocked: return "UnlockUnlocked"; 1319f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj case XE_UnlockForeign: return "UnlockForeign"; 1320f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj case XE_UnlockBogus: return "UnlockBogus"; 1321f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj case XE_PthAPIerror: return "PthAPIerror"; 1322f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj case XE_LockOrder: return "LockOrder"; 1323f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj case XE_Misc: return "Misc"; 1324f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj default: tl_assert(0); /* fill in missing case */ 1325f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj } 1326f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj} 1327f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj 132819f91bbaedb4caef8a60ce94b0f507193cc0bc10florianBool HG_(recognised_suppression) ( const HChar* name, Supp *su ) 1329f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj{ 1330f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj# define TRY(_name,_xskind) \ 1331f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj if (0 == VG_(strcmp)(name, (_name))) { \ 1332f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj VG_(set_supp_kind)(su, (_xskind)); \ 1333f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj return True; \ 1334f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj } 1335f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj TRY("Race", XS_Race); 1336f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj TRY("FreeMemLock", XS_FreeMemLock); 1337f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj TRY("UnlockUnlocked", XS_UnlockUnlocked); 1338f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj TRY("UnlockForeign", XS_UnlockForeign); 1339f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj TRY("UnlockBogus", XS_UnlockBogus); 1340f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj TRY("PthAPIerror", XS_PthAPIerror); 1341f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj TRY("LockOrder", XS_LockOrder); 1342f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj TRY("Misc", XS_Misc); 1343f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj return False; 1344f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj# undef TRY 1345f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj} 1346f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj 134719f91bbaedb4caef8a60ce94b0f507193cc0bc10florianBool HG_(read_extra_suppression_info) ( Int fd, HChar** bufpp, SizeT* nBufp, 1348362441db825242200142a91bb07c4a0300b36a3ephilippe Int* lineno, Supp* su ) 1349f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj{ 1350f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj /* do nothing -- no extra suppression info present. Return True to 1351f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj indicate nothing bad happened. */ 1352f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj return True; 1353f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj} 1354f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj 13558e3fbb5cd8276a7d07d5712bc05f9b3376d81a6aflorianBool HG_(error_matches_suppression) ( const Error* err, const Supp* su ) 1356f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj{ 1357f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj switch (VG_(get_supp_kind)(su)) { 1358f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj case XS_Race: return VG_(get_error_kind)(err) == XE_Race; 1359f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj case XS_UnlockUnlocked: return VG_(get_error_kind)(err) == XE_UnlockUnlocked; 1360f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj case XS_UnlockForeign: return VG_(get_error_kind)(err) == XE_UnlockForeign; 1361f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj case XS_UnlockBogus: return VG_(get_error_kind)(err) == XE_UnlockBogus; 1362f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj case XS_PthAPIerror: return VG_(get_error_kind)(err) == XE_PthAPIerror; 1363f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj case XS_LockOrder: return VG_(get_error_kind)(err) == XE_LockOrder; 1364f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj case XS_Misc: return VG_(get_error_kind)(err) == XE_Misc; 1365f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj //case XS_: return VG_(get_error_kind)(err) == XE_; 1366f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj default: tl_assert(0); /* fill in missing cases */ 1367f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj } 1368f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj} 1369f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj 13708e3fbb5cd8276a7d07d5712bc05f9b3376d81a6aflorianSizeT HG_(get_extra_suppression_info) ( const Error* err, 1371dbb3584f591710a15a437918c0fc27e300993566florian /*OUT*/HChar* buf, Int nBuf ) 1372f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj{ 13733e81b8bed1f7ab6848a83f5507487131a6f9d778florian tl_assert(nBuf >= 1); 1374f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj /* Do nothing */ 13753e81b8bed1f7ab6848a83f5507487131a6f9d778florian buf[0] = '\0'; 13763e81b8bed1f7ab6848a83f5507487131a6f9d778florian return 0; 1377f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj} 1378f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj 13798e3fbb5cd8276a7d07d5712bc05f9b3376d81a6aflorianSizeT HG_(print_extra_suppression_use) ( const Supp* su, 13804e32d67a5b880bf1d871c5141822078d4dcdc3acphilippe /*OUT*/HChar* buf, Int nBuf ) 13814e32d67a5b880bf1d871c5141822078d4dcdc3acphilippe{ 13823e81b8bed1f7ab6848a83f5507487131a6f9d778florian tl_assert(nBuf >= 1); 13834e32d67a5b880bf1d871c5141822078d4dcdc3acphilippe /* Do nothing */ 13843e81b8bed1f7ab6848a83f5507487131a6f9d778florian buf[0] = '\0'; 13853e81b8bed1f7ab6848a83f5507487131a6f9d778florian return 0; 13864e32d67a5b880bf1d871c5141822078d4dcdc3acphilippe} 13874e32d67a5b880bf1d871c5141822078d4dcdc3acphilippe 13888e3fbb5cd8276a7d07d5712bc05f9b3376d81a6aflorianvoid HG_(update_extra_suppression_use) ( const Error* err, const Supp* su ) 13894e32d67a5b880bf1d871c5141822078d4dcdc3acphilippe{ 13904e32d67a5b880bf1d871c5141822078d4dcdc3acphilippe /* Do nothing */ 13914e32d67a5b880bf1d871c5141822078d4dcdc3acphilippe return; 13924e32d67a5b880bf1d871c5141822078d4dcdc3acphilippe} 13934e32d67a5b880bf1d871c5141822078d4dcdc3acphilippe 1394f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj 1395f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj/*--------------------------------------------------------------------*/ 1396f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj/*--- end hg_errors.c ---*/ 1397f98e1c03ce4bea1fb092cdea5571c41f29f6df9bsewardj/*--------------------------------------------------------------------*/ 1398