1ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 2ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/*--------------------------------------------------------------------*/ 3ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/*--- Management, printing, etc, of errors and suppressions. ---*/ 4ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/*--- mc_errors.c ---*/ 5ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/*--------------------------------------------------------------------*/ 6ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 7ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* 8ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown This file is part of MemCheck, a heavyweight Valgrind tool for 9ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown detecting memory errors. 10ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 11ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Copyright (C) 2000-2010 Julian Seward 12ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown jseward@acm.org 13ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 14ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown This program is free software; you can redistribute it and/or 15ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown modify it under the terms of the GNU General Public License as 16ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown published by the Free Software Foundation; either version 2 of the 17ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown License, or (at your option) any later version. 18ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 19ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown This program is distributed in the hope that it will be useful, but 20ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown WITHOUT ANY WARRANTY; without even the implied warranty of 21ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 22ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown General Public License for more details. 23ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 24ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown You should have received a copy of the GNU General Public License 25ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown along with this program; if not, write to the Free Software 26ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 27ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 02111-1307, USA. 28ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 29ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown The GNU General Public License is contained in the file COPYING. 30ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown*/ 31ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 32ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#include "pub_tool_basics.h" 33ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#include "pub_tool_hashtable.h" // For mc_include.h 34ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#include "pub_tool_libcbase.h" 35ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#include "pub_tool_libcassert.h" 36ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#include "pub_tool_libcprint.h" 37ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#include "pub_tool_machine.h" 38ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#include "pub_tool_mallocfree.h" 39ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#include "pub_tool_options.h" 40ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#include "pub_tool_replacemalloc.h" 41ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#include "pub_tool_tooliface.h" 42ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#include "pub_tool_threadstate.h" 43ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#include "pub_tool_debuginfo.h" // VG_(get_dataname_and_offset) 44ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#include "pub_tool_xarray.h" 45f0cb39bc6abe181a0abdd1f6c778521ae8497277Evgeniy Stepanov#include "pub_tool_vki.h" 46f0cb39bc6abe181a0abdd1f6c778521ae8497277Evgeniy Stepanov#include "pub_tool_libcfile.h" 47ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 48ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#include "mc_include.h" 49ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 50ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 51ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/*------------------------------------------------------------*/ 52ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/*--- Error types ---*/ 53ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/*------------------------------------------------------------*/ 54ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 55ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* See comment in mc_include.h */ 56ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownBool MC_(any_value_errors) = False; 57ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 58ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 59ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown// Different kinds of blocks. 60ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Browntypedef enum { 61ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Block_Mallocd = 111, 62ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Block_Freed, 63ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Block_Mempool, 64ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Block_MempoolChunk, 65ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Block_UserG 66ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown} BlockKind; 67ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 68ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* ------------------ Addresses -------------------- */ 69ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 70ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* The classification of a faulting address. */ 71ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Browntypedef 72ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown enum { 73ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Addr_Undescribed, // as-yet unclassified 74ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Addr_Unknown, // classification yielded nothing useful 75ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Addr_Block, // in malloc'd/free'd block 76ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Addr_Stack, // on a thread's stack 77ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Addr_DataSym, // in a global data sym 78ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Addr_Variable, // variable described by the debug info 79ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Addr_SectKind // last-ditch classification attempt 80ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 81ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown AddrTag; 82ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 83ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Browntypedef 84ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown struct _AddrInfo 85ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown AddrInfo; 86ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 87ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstruct _AddrInfo { 88ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown AddrTag tag; 89ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown union { 90ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown // As-yet unclassified. 91ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown struct { } Undescribed; 92ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 93ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown // On a stack. 94ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown struct { 95ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ThreadId tid; // Which thread's stack? 96ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } Stack; 97ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 98ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown // This covers heap blocks (normal and from mempools) and user-defined 99ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown // blocks. 100ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown struct { 101ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown BlockKind block_kind; 102ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Char* block_desc; // "block", "mempool" or user-defined 103ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown SizeT block_szB; 104ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown PtrdiffT rwoffset; 105ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ExeContext* lastchange; 106ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } Block; 107ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 108ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown // In a global .data symbol. This holds the first 127 chars of 109ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown // the variable's name (zero terminated), plus a (memory) offset. 110ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown struct { 111ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Char name[128]; 112ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown PtrdiffT offset; 113ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } DataSym; 114ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 115ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown // Is described by Dwarf debug info. XArray*s of HChar. 116ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown struct { 117ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown XArray* /* of HChar */ descr1; 118ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown XArray* /* of HChar */ descr2; 119ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } Variable; 120ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 121ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown // Could only narrow it down to be the PLT/GOT/etc of a given 122ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown // object. Better than nothing, perhaps. 123ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown struct { 124ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Char objname[128]; 125ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown VgSectKind kind; 126ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } SectKind; 127ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 128ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown // Classification yielded nothing useful. 129ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown struct { } Unknown; 130ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 131ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } Addr; 132ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}; 133ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 134ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* ------------------ Errors ----------------------- */ 135ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 136ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* What kind of error it is. */ 137ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Browntypedef 138ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown enum { 139ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Err_Value, 140ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Err_Cond, 141ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Err_CoreMem, 142ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Err_Addr, 143ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Err_Jump, 144ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Err_RegParam, 145ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Err_MemParam, 146ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Err_User, 147ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Err_Free, 148ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Err_FreeMismatch, 149ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Err_Overlap, 150ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Err_Leak, 151ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Err_IllegalMempool, 152ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 153ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown MC_ErrorTag; 154ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 155ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 156ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Browntypedef struct _MC_Error MC_Error; 157ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 158ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstruct _MC_Error { 159ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown // Nb: we don't need the tag here, as it's stored in the Error type! Yuk. 160ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown //MC_ErrorTag tag; 161ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 162ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown union { 163ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown // Use of an undefined value: 164ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown // - as a pointer in a load or store 165ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown // - as a jump target 166ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown struct { 167ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown SizeT szB; // size of value in bytes 168ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown // Origin info 169ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown UInt otag; // origin tag 170ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ExeContext* origin_ec; // filled in later 171ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } Value; 172ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 173ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown // Use of an undefined value in a conditional branch or move. 174ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown struct { 175ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown // Origin info 176ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown UInt otag; // origin tag 177ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ExeContext* origin_ec; // filled in later 178ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } Cond; 179ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 180ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown // Addressability error in core (signal-handling) operation. 181ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown // It would be good to get rid of this error kind, merge it with 182ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown // another one somehow. 183ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown struct { 184ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } CoreMem; 185ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 186ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown // Use of an unaddressable memory location in a load or store. 187ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown struct { 188ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Bool isWrite; // read or write? 189ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown SizeT szB; // not used for exec (jump) errors 190ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Bool maybe_gcc; // True if just below %esp -- could be a gcc bug 191ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown AddrInfo ai; 192ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } Addr; 193ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 194ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown // Jump to an unaddressable memory location. 195ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown struct { 196ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown AddrInfo ai; 197ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } Jump; 198ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 199ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown // System call register input contains undefined bytes. 200ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown struct { 201ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown // Origin info 202ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown UInt otag; // origin tag 203ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ExeContext* origin_ec; // filled in later 204ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } RegParam; 205ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 206ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown // System call memory input contains undefined/unaddressable bytes 207ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown struct { 208ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Bool isAddrErr; // Addressability or definedness error? 209ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown AddrInfo ai; 210ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown // Origin info 211ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown UInt otag; // origin tag 212ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ExeContext* origin_ec; // filled in later 213ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } MemParam; 214ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 215ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown // Problem found from a client request like CHECK_MEM_IS_ADDRESSABLE. 216ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown struct { 217ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Bool isAddrErr; // Addressability or definedness error? 218ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown AddrInfo ai; 219ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown // Origin info 220ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown UInt otag; // origin tag 221ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ExeContext* origin_ec; // filled in later 222ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } User; 223ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 224ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown // Program tried to free() something that's not a heap block (this 225ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown // covers double-frees). */ 226ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown struct { 227ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown AddrInfo ai; 228ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } Free; 229ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 230ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown // Program allocates heap block with one function 231ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown // (malloc/new/new[]/custom) and deallocates with not the matching one. 232ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown struct { 233ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown AddrInfo ai; 234ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } FreeMismatch; 235ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 236ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown // Call to strcpy, memcpy, etc, with overlapping blocks. 237ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown struct { 238ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Addr src; // Source block 239ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Addr dst; // Destination block 240ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Int szB; // Size in bytes; 0 if unused. 241ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } Overlap; 242ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 243ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown // A memory leak. 244ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown struct { 245ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown UInt n_this_record; 246ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown UInt n_total_records; 247ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown LossRecord* lr; 248ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } Leak; 249ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 250ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown // A memory pool error. 251ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown struct { 252ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown AddrInfo ai; 253ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } IllegalMempool; 254ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 255ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } Err; 256ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}; 257ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 258ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 259ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/*------------------------------------------------------------*/ 260ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/*--- Printing errors ---*/ 261ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/*------------------------------------------------------------*/ 262ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 263ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* This is the "this error is due to be printed shortly; so have a 264ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown look at it any print any preamble you want" function. Which, in 265ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Memcheck, we don't use. Hence a no-op. 266ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown*/ 267ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownvoid MC_(before_pp_Error) ( Error* err ) { 268ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown} 269ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 270ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* Do a printf-style operation on either the XML or normal output 271ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown channel, depending on the setting of VG_(clo_xml). 272ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown*/ 273ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic void emit_WRK ( HChar* format, va_list vargs ) 274ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{ 275ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (VG_(clo_xml)) { 276ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown VG_(vprintf_xml)(format, vargs); 277ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } else { 278ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown VG_(vmessage)(Vg_UserMsg, format, vargs); 279ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 280ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown} 281ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic void emit ( HChar* format, ... ) PRINTF_CHECK(1, 2); 282ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic void emit ( HChar* format, ... ) 283ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{ 284ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown va_list vargs; 285ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown va_start(vargs, format); 286ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown emit_WRK(format, vargs); 287ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown va_end(vargs); 288ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown} 289ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic void emiN ( HChar* format, ... ) /* NO FORMAT CHECK */ 290ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{ 291ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown va_list vargs; 292ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown va_start(vargs, format); 293ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown emit_WRK(format, vargs); 294ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown va_end(vargs); 295ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown} 296ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 297ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 298ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic void mc_pp_AddrInfo ( Addr a, AddrInfo* ai, Bool maybe_gcc ) 299ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{ 300ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown HChar* xpre = VG_(clo_xml) ? " <auxwhat>" : " "; 301ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown HChar* xpost = VG_(clo_xml) ? "</auxwhat>" : ""; 302ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 303ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown switch (ai->tag) { 304ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case Addr_Unknown: 305ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (maybe_gcc) { 306ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown emit( "%sAddress 0x%llx is just below the stack ptr. " 307ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "To suppress, use: --workaround-gcc296-bugs=yes%s\n", 308ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown xpre, (ULong)a, xpost ); 309ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } else { 310ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown emit( "%sAddress 0x%llx " 311ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "is not stack'd, malloc'd or (recently) free'd%s\n", 312ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown xpre, (ULong)a, xpost ); 313ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 314ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown break; 315ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 316ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case Addr_Stack: 317ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown emit( "%sAddress 0x%llx is on thread %d's stack%s\n", 318ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown xpre, (ULong)a, ai->Addr.Stack.tid, xpost ); 319ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown break; 320ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 321ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case Addr_Block: { 322ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown SizeT block_szB = ai->Addr.Block.block_szB; 323ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown PtrdiffT rwoffset = ai->Addr.Block.rwoffset; 324ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown SizeT delta; 325ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown const Char* relative; 326ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 327ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (rwoffset < 0) { 328ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown delta = (SizeT)(-rwoffset); 329ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown relative = "before"; 330ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } else if (rwoffset >= block_szB) { 331ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown delta = rwoffset - block_szB; 332ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown relative = "after"; 333ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } else { 334ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown delta = rwoffset; 335ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown relative = "inside"; 336ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 337ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown emit( 338ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "%sAddress 0x%lx is %'lu bytes %s a %s of size %'lu %s%s\n", 339ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown xpre, 340ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown a, delta, relative, ai->Addr.Block.block_desc, 341ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown block_szB, 342ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ai->Addr.Block.block_kind==Block_Mallocd ? "alloc'd" 343ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown : ai->Addr.Block.block_kind==Block_Freed ? "free'd" 344ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown : "client-defined", 345ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown xpost 346ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ); 347ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown VG_(pp_ExeContext)(ai->Addr.Block.lastchange); 348ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown break; 349ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 350ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 351ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case Addr_DataSym: 352ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown emiN( "%sAddress 0x%llx is %llu bytes " 353ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "inside data symbol \"%t\"%s\n", 354ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown xpre, 355ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown (ULong)a, 356ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown (ULong)ai->Addr.DataSym.offset, 357ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ai->Addr.DataSym.name, 358ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown xpost ); 359ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown break; 360ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 361ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case Addr_Variable: 362ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* Note, no need for XML tags here, because descr1/2 will 363ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown already have <auxwhat> or <xauxwhat>s on them, in XML 364ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown mode. */ 365ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (ai->Addr.Variable.descr1) 366ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown emit( "%s%s\n", 367ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown VG_(clo_xml) ? " " : " ", 368ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown (HChar*)VG_(indexXA)(ai->Addr.Variable.descr1, 0) ); 369ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (ai->Addr.Variable.descr2) 370ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown emit( "%s%s\n", 371ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown VG_(clo_xml) ? " " : " ", 372ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown (HChar*)VG_(indexXA)(ai->Addr.Variable.descr2, 0) ); 373ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown break; 374ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 375ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case Addr_SectKind: 376ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown emiN( "%sAddress 0x%llx is in the %t segment of %t%s\n", 377ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown xpre, 378ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown (ULong)a, 379ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown VG_(pp_SectKind)(ai->Addr.SectKind.kind), 380ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ai->Addr.SectKind.objname, 381ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown xpost ); 382ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown break; 383ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 384ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown default: 385ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown VG_(tool_panic)("mc_pp_AddrInfo"); 386ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 387ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown} 388ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 389ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic const HChar* str_leak_lossmode ( Reachedness lossmode ) 390ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{ 391ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown const HChar *loss = "?"; 392ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown switch (lossmode) { 393ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case Unreached: loss = "definitely lost"; break; 394ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case IndirectLeak: loss = "indirectly lost"; break; 395ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case Possible: loss = "possibly lost"; break; 396ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case Reachable: loss = "still reachable"; break; 397ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 398ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return loss; 399ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown} 400ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 401ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic const HChar* xml_leak_kind ( Reachedness lossmode ) 402ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{ 403ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown const HChar *loss = "?"; 404ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown switch (lossmode) { 405ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case Unreached: loss = "Leak_DefinitelyLost"; break; 406ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case IndirectLeak: loss = "Leak_IndirectlyLost"; break; 407ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case Possible: loss = "Leak_PossiblyLost"; break; 408ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case Reachable: loss = "Leak_StillReachable"; break; 409ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 410ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return loss; 411ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown} 412ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 413ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic void mc_pp_origin ( ExeContext* ec, UInt okind ) 414ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{ 415ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown HChar* src = NULL; 416ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown tl_assert(ec); 417ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 418ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown switch (okind) { 419ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case MC_OKIND_STACK: src = " by a stack allocation"; break; 420ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case MC_OKIND_HEAP: src = " by a heap allocation"; break; 421ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case MC_OKIND_USER: src = " by a client request"; break; 422ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case MC_OKIND_UNKNOWN: src = ""; break; 423ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 424ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown tl_assert(src); /* guards against invalid 'okind' */ 425ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 426ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (VG_(clo_xml)) { 427ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown emit( " <auxwhat>Uninitialised value was created%s</auxwhat>\n", 428ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown src); 429ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown VG_(pp_ExeContext)( ec ); 430ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } else { 431ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown emit( " Uninitialised value was created%s\n", src); 432ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown VG_(pp_ExeContext)( ec ); 433ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 434ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown} 435ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 436ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownvoid MC_(pp_Error) ( Error* err ) 437ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{ 438ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown const Bool xml = VG_(clo_xml); /* a shorthand */ 439ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown MC_Error* extra = VG_(get_error_extra)(err); 440ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 441ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown switch (VG_(get_error_kind)(err)) { 442ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case Err_CoreMem: 443ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* What the hell *is* a CoreMemError? jrs 2005-May-18 */ 444ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* As of 2006-Dec-14, it's caused by unaddressable bytes in a 445ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown signal handler frame. --njn */ 446ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown // JRS 17 May 09: None of our regtests exercise this; hence AFAIK 447ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown // the following code is untested. Bad. 448ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (xml) { 449ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown emit( " <kind>CoreMemError</kind>\n" ); 450ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown emiN( " <what>%t contains unaddressable byte(s)</what>\n", 451ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown VG_(get_error_string)(err)); 452ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown VG_(pp_ExeContext)( VG_(get_error_where)(err) ); 453ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } else { 454ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown emit( "%s contains unaddressable byte(s)\n", 455ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown VG_(get_error_string)(err)); 456ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown VG_(pp_ExeContext)( VG_(get_error_where)(err) ); 457ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 458ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown break; 459ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 460ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case Err_Value: 461ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown MC_(any_value_errors) = True; 462ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (xml) { 463ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown emit( " <kind>UninitValue</kind>\n" ); 464ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown emit( " <what>Use of uninitialised value of size %ld</what>\n", 465ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown extra->Err.Value.szB ); 466ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown VG_(pp_ExeContext)( VG_(get_error_where)(err) ); 467ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (extra->Err.Value.origin_ec) 468ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown mc_pp_origin( extra->Err.Value.origin_ec, 469ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown extra->Err.Value.otag & 3 ); 470ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } else { 471ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* Could also show extra->Err.Cond.otag if debugging origin 472ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown tracking */ 473ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown emit( "Use of uninitialised value of size %ld\n", 474ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown extra->Err.Value.szB ); 475ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown VG_(pp_ExeContext)( VG_(get_error_where)(err) ); 476ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (extra->Err.Value.origin_ec) 477ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown mc_pp_origin( extra->Err.Value.origin_ec, 478ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown extra->Err.Value.otag & 3 ); 479ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 480ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown break; 481ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 482ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case Err_Cond: 483ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown MC_(any_value_errors) = True; 484ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (xml) { 485ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown emit( " <kind>UninitCondition</kind>\n" ); 486ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown emit( " <what>Conditional jump or move depends" 487ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown " on uninitialised value(s)</what>\n" ); 488ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown VG_(pp_ExeContext)( VG_(get_error_where)(err) ); 489ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (extra->Err.Cond.origin_ec) 490ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown mc_pp_origin( extra->Err.Cond.origin_ec, 491ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown extra->Err.Cond.otag & 3 ); 492ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } else { 493ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* Could also show extra->Err.Cond.otag if debugging origin 494ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown tracking */ 495ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown emit( "Conditional jump or move depends" 496ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown " on uninitialised value(s)\n" ); 497ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown VG_(pp_ExeContext)( VG_(get_error_where)(err) ); 498ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (extra->Err.Cond.origin_ec) 499ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown mc_pp_origin( extra->Err.Cond.origin_ec, 500ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown extra->Err.Cond.otag & 3 ); 501ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 502ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown break; 503ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 504ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case Err_RegParam: 505ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown MC_(any_value_errors) = True; 506ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (xml) { 507ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown emit( " <kind>SyscallParam</kind>\n" ); 508ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown emiN( " <what>Syscall param %t contains " 509ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "uninitialised byte(s)</what>\n", 510ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown VG_(get_error_string)(err) ); 511ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown VG_(pp_ExeContext)( VG_(get_error_where)(err) ); 512ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (extra->Err.RegParam.origin_ec) 513ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown mc_pp_origin( extra->Err.RegParam.origin_ec, 514ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown extra->Err.RegParam.otag & 3 ); 515ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } else { 516ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown emit( "Syscall param %s contains uninitialised byte(s)\n", 517ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown VG_(get_error_string)(err) ); 518ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown VG_(pp_ExeContext)( VG_(get_error_where)(err) ); 519ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (extra->Err.RegParam.origin_ec) 520ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown mc_pp_origin( extra->Err.RegParam.origin_ec, 521ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown extra->Err.RegParam.otag & 3 ); 522ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 523ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown break; 524ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 525ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case Err_MemParam: 526ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (!extra->Err.MemParam.isAddrErr) 527ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown MC_(any_value_errors) = True; 528ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (xml) { 529ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown emit( " <kind>SyscallParam</kind>\n" ); 530ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown emiN( " <what>Syscall param %t points to %s byte(s)</what>\n", 531ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown VG_(get_error_string)(err), 532ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown extra->Err.MemParam.isAddrErr 533ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ? "unaddressable" : "uninitialised" ); 534ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown VG_(pp_ExeContext)( VG_(get_error_where)(err) ); 535ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown mc_pp_AddrInfo(VG_(get_error_address)(err), 536ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown &extra->Err.MemParam.ai, False); 537ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (extra->Err.MemParam.origin_ec 538ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown && !extra->Err.MemParam.isAddrErr) 539ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown mc_pp_origin( extra->Err.MemParam.origin_ec, 540ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown extra->Err.MemParam.otag & 3 ); 541ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } else { 542ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown emit( "Syscall param %s points to %s byte(s)\n", 543ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown VG_(get_error_string)(err), 544ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown extra->Err.MemParam.isAddrErr 545ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ? "unaddressable" : "uninitialised" ); 546ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown VG_(pp_ExeContext)( VG_(get_error_where)(err) ); 547ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown mc_pp_AddrInfo(VG_(get_error_address)(err), 548ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown &extra->Err.MemParam.ai, False); 549ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (extra->Err.MemParam.origin_ec 550ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown && !extra->Err.MemParam.isAddrErr) 551ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown mc_pp_origin( extra->Err.MemParam.origin_ec, 552ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown extra->Err.MemParam.otag & 3 ); 553ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 554ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown break; 555ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 556ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case Err_User: 557ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (!extra->Err.User.isAddrErr) 558ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown MC_(any_value_errors) = True; 559ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (xml) { 560ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown emit( " <kind>ClientCheck</kind>\n" ); 561ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown emit( " <what>%s byte(s) found " 562ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "during client check request</what>\n", 563ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown extra->Err.User.isAddrErr 564ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ? "Unaddressable" : "Uninitialised" ); 565ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown VG_(pp_ExeContext)( VG_(get_error_where)(err) ); 566ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown mc_pp_AddrInfo(VG_(get_error_address)(err), &extra->Err.User.ai, 567ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown False); 568ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (extra->Err.User.origin_ec && !extra->Err.User.isAddrErr) 569ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown mc_pp_origin( extra->Err.User.origin_ec, 570ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown extra->Err.User.otag & 3 ); 571ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } else { 572ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown emit( "%s byte(s) found during client check request\n", 573ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown extra->Err.User.isAddrErr 574ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ? "Unaddressable" : "Uninitialised" ); 575ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown VG_(pp_ExeContext)( VG_(get_error_where)(err) ); 576ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown mc_pp_AddrInfo(VG_(get_error_address)(err), &extra->Err.User.ai, 577ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown False); 578ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (extra->Err.User.origin_ec && !extra->Err.User.isAddrErr) 579ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown mc_pp_origin( extra->Err.User.origin_ec, 580ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown extra->Err.User.otag & 3 ); 581ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 582ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown break; 583ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 584ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case Err_Free: 585ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (xml) { 586ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown emit( " <kind>InvalidFree</kind>\n" ); 587ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown emit( " <what>Invalid free() / delete / delete[]</what>\n" ); 588ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown VG_(pp_ExeContext)( VG_(get_error_where)(err) ); 589ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown mc_pp_AddrInfo( VG_(get_error_address)(err), 590ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown &extra->Err.Free.ai, False ); 591ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } else { 592ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown emit( "Invalid free() / delete / delete[]\n" ); 593ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown VG_(pp_ExeContext)( VG_(get_error_where)(err) ); 594ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown mc_pp_AddrInfo( VG_(get_error_address)(err), 595ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown &extra->Err.Free.ai, False ); 596ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 597ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown break; 598ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 599ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case Err_FreeMismatch: 600ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (xml) { 601ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown emit( " <kind>MismatchedFree</kind>\n" ); 602ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown emit( " <what>Mismatched free() / delete / delete []</what>\n" ); 603ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown VG_(pp_ExeContext)( VG_(get_error_where)(err) ); 604ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown mc_pp_AddrInfo(VG_(get_error_address)(err), 605ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown &extra->Err.FreeMismatch.ai, False); 606ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } else { 607ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown emit( "Mismatched free() / delete / delete []\n" ); 608ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown VG_(pp_ExeContext)( VG_(get_error_where)(err) ); 609ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown mc_pp_AddrInfo(VG_(get_error_address)(err), 610ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown &extra->Err.FreeMismatch.ai, False); 611ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 612ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown break; 613ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 614ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case Err_Addr: 615ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (xml) { 616ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown emit( " <kind>Invalid%s</kind>\n", 617ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown extra->Err.Addr.isWrite ? "Write" : "Read" ); 618ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown emit( " <what>Invalid %s of size %ld</what>\n", 619ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown extra->Err.Addr.isWrite ? "write" : "read", 620ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown extra->Err.Addr.szB ); 621ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown VG_(pp_ExeContext)( VG_(get_error_where)(err) ); 622ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown mc_pp_AddrInfo( VG_(get_error_address)(err), 623ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown &extra->Err.Addr.ai, 624ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown extra->Err.Addr.maybe_gcc ); 625ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } else { 626ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown emit( "Invalid %s of size %ld\n", 627ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown extra->Err.Addr.isWrite ? "write" : "read", 628ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown extra->Err.Addr.szB ); 629ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown VG_(pp_ExeContext)( VG_(get_error_where)(err) ); 630ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 631ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown mc_pp_AddrInfo( VG_(get_error_address)(err), 632ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown &extra->Err.Addr.ai, 633ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown extra->Err.Addr.maybe_gcc ); 634ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 635ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown break; 636ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 637ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case Err_Jump: 638ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (xml) { 639ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown emit( " <kind>InvalidJump</kind>\n" ); 640ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown emit( " <what>Jump to the invalid address stated " 641ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "on the next line</what>\n" ); 642ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown VG_(pp_ExeContext)( VG_(get_error_where)(err) ); 643ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown mc_pp_AddrInfo( VG_(get_error_address)(err), &extra->Err.Jump.ai, 644ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown False ); 645ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } else { 646ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown emit( "Jump to the invalid address stated on the next line\n" ); 647ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown VG_(pp_ExeContext)( VG_(get_error_where)(err) ); 648ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown mc_pp_AddrInfo( VG_(get_error_address)(err), &extra->Err.Jump.ai, 649ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown False ); 650ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 651ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown break; 652ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 653ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case Err_Overlap: 654ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (xml) { 655ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown emit( " <kind>Overlap</kind>\n" ); 656ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (extra->Err.Overlap.szB == 0) { 657ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown emiN( " <what>Source and destination overlap " 658ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "in %t(%#lx, %#lx)\n</what>\n", 659ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown VG_(get_error_string)(err), 660ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown extra->Err.Overlap.dst, extra->Err.Overlap.src ); 661ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } else { 662ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown emit( " <what>Source and destination overlap " 663ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "in %s(%#lx, %#lx, %d)</what>\n", 664ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown VG_(get_error_string)(err), 665ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown extra->Err.Overlap.dst, extra->Err.Overlap.src, 666ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown extra->Err.Overlap.szB ); 667ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 668ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown VG_(pp_ExeContext)( VG_(get_error_where)(err) ); 669ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } else { 670ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (extra->Err.Overlap.szB == 0) { 671ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown emiN( "Source and destination overlap in %t(%#lx, %#lx)\n", 672ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown VG_(get_error_string)(err), 673ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown extra->Err.Overlap.dst, extra->Err.Overlap.src ); 674ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } else { 675ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown emit( "Source and destination overlap in %s(%#lx, %#lx, %d)\n", 676ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown VG_(get_error_string)(err), 677ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown extra->Err.Overlap.dst, extra->Err.Overlap.src, 678ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown extra->Err.Overlap.szB ); 679ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 680ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown VG_(pp_ExeContext)( VG_(get_error_where)(err) ); 681ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 682ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown break; 683ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 684ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case Err_IllegalMempool: 685ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown // JRS 17 May 09: None of our regtests exercise this; hence AFAIK 686ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown // the following code is untested. Bad. 687ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (xml) { 688ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown emit( " <kind>InvalidMemPool</kind>\n" ); 689ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown emit( " <what>Illegal memory pool address</what>\n" ); 690ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown VG_(pp_ExeContext)( VG_(get_error_where)(err) ); 691ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown mc_pp_AddrInfo( VG_(get_error_address)(err), 692ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown &extra->Err.IllegalMempool.ai, False ); 693ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } else { 694ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown emit( "Illegal memory pool address\n" ); 695ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown VG_(pp_ExeContext)( VG_(get_error_where)(err) ); 696ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown mc_pp_AddrInfo( VG_(get_error_address)(err), 697ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown &extra->Err.IllegalMempool.ai, False ); 698ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 699ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown break; 700ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 701ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case Err_Leak: { 702ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown UInt n_this_record = extra->Err.Leak.n_this_record; 703ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown UInt n_total_records = extra->Err.Leak.n_total_records; 704ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown LossRecord* lr = extra->Err.Leak.lr; 705ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (xml) { 706ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown emit(" <kind>%s</kind>\n", xml_leak_kind(lr->key.state)); 707ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (lr->indirect_szB > 0) { 708ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown emit( " <xwhat>\n" ); 709ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown emit( " <text>%'lu (%'lu direct, %'lu indirect) bytes " 710ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "in %'u blocks" 711ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown " are %s in loss record %'u of %'u</text>\n", 712ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown lr->szB + lr->indirect_szB, lr->szB, lr->indirect_szB, 713ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown lr->num_blocks, 714ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown str_leak_lossmode(lr->key.state), 715ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown n_this_record, n_total_records ); 716ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown // Nb: don't put commas in these XML numbers 717ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown emit( " <leakedbytes>%lu</leakedbytes>\n", 718ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown lr->szB + lr->indirect_szB ); 719ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown emit( " <leakedblocks>%u</leakedblocks>\n", lr->num_blocks ); 720ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown emit( " </xwhat>\n" ); 721ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } else { 722ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown emit( " <xwhat>\n" ); 723ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown emit( " <text>%'lu bytes in %'u blocks" 724ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown " are %s in loss record %'u of %'u</text>\n", 725ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown lr->szB, lr->num_blocks, 726ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown str_leak_lossmode(lr->key.state), 727ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown n_this_record, n_total_records ); 728ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown emit( " <leakedbytes>%ld</leakedbytes>\n", lr->szB); 729ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown emit( " <leakedblocks>%d</leakedblocks>\n", lr->num_blocks); 730ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown emit( " </xwhat>\n" ); 731ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 732ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown VG_(pp_ExeContext)(lr->key.allocated_at); 733ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } else { /* ! if (xml) */ 734ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (lr->indirect_szB > 0) { 735ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown emit( 736ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "%'lu (%'lu direct, %'lu indirect) bytes in %'u blocks" 737ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown " are %s in loss record %'u of %'u\n", 738ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown lr->szB + lr->indirect_szB, lr->szB, lr->indirect_szB, 739ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown lr->num_blocks, str_leak_lossmode(lr->key.state), 740ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown n_this_record, n_total_records 741ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ); 742ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } else { 743ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown emit( 744ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "%'lu bytes in %'u blocks are %s in loss record %'u of %'u\n", 745ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown lr->szB, lr->num_blocks, str_leak_lossmode(lr->key.state), 746ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown n_this_record, n_total_records 747ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ); 748ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 749ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown VG_(pp_ExeContext)(lr->key.allocated_at); 750ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } /* if (xml) */ 751ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown break; 752ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 753ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 754ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown default: 755ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown VG_(printf)("Error:\n unknown Memcheck error code %d\n", 756ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown VG_(get_error_kind)(err)); 757ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown VG_(tool_panic)("unknown error code in mc_pp_Error)"); 758ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 759f0cb39bc6abe181a0abdd1f6c778521ae8497277Evgeniy Stepanov 760f0cb39bc6abe181a0abdd1f6c778521ae8497277Evgeniy Stepanov if (MC_(clo_summary_file)) { 761f0cb39bc6abe181a0abdd1f6c778521ae8497277Evgeniy Stepanov /* Each time we report a warning, we replace the contents of the summary 762f0cb39bc6abe181a0abdd1f6c778521ae8497277Evgeniy Stepanov * file with one line indicating the number of reported warnings. 763f0cb39bc6abe181a0abdd1f6c778521ae8497277Evgeniy Stepanov * This way, at the end of memcheck execution we will have a file with 764f0cb39bc6abe181a0abdd1f6c778521ae8497277Evgeniy Stepanov * one line saying 765f0cb39bc6abe181a0abdd1f6c778521ae8497277Evgeniy Stepanov * Memcheck: XX warnings reported 766f0cb39bc6abe181a0abdd1f6c778521ae8497277Evgeniy Stepanov * If there were no warnings, the file will not be changed. 767f0cb39bc6abe181a0abdd1f6c778521ae8497277Evgeniy Stepanov * If memcheck crashes, the file will still contain the last summary. 768f0cb39bc6abe181a0abdd1f6c778521ae8497277Evgeniy Stepanov * */ 769f0cb39bc6abe181a0abdd1f6c778521ae8497277Evgeniy Stepanov static int n_warnings = 0; 770f0cb39bc6abe181a0abdd1f6c778521ae8497277Evgeniy Stepanov char buf[100]; 771f0cb39bc6abe181a0abdd1f6c778521ae8497277Evgeniy Stepanov SysRes sres = VG_(open)(MC_(clo_summary_file), 772f0cb39bc6abe181a0abdd1f6c778521ae8497277Evgeniy Stepanov VKI_O_WRONLY|VKI_O_CREAT|VKI_O_TRUNC, 773f0cb39bc6abe181a0abdd1f6c778521ae8497277Evgeniy Stepanov VKI_S_IRUSR|VKI_S_IWUSR); 774f0cb39bc6abe181a0abdd1f6c778521ae8497277Evgeniy Stepanov if (sr_isError(sres)) { 775f0cb39bc6abe181a0abdd1f6c778521ae8497277Evgeniy Stepanov VG_(tool_panic)("can not open the summary file"); 776f0cb39bc6abe181a0abdd1f6c778521ae8497277Evgeniy Stepanov } 777f0cb39bc6abe181a0abdd1f6c778521ae8497277Evgeniy Stepanov n_warnings++; 778f0cb39bc6abe181a0abdd1f6c778521ae8497277Evgeniy Stepanov VG_(snprintf)(buf, sizeof(buf), "Memcheck: %d warning(s) reported\n", 779f0cb39bc6abe181a0abdd1f6c778521ae8497277Evgeniy Stepanov n_warnings); 780f0cb39bc6abe181a0abdd1f6c778521ae8497277Evgeniy Stepanov VG_(write)(sr_Res(sres), buf, VG_(strlen)(buf)); 781f0cb39bc6abe181a0abdd1f6c778521ae8497277Evgeniy Stepanov VG_(close)(sr_Res(sres)); 782f0cb39bc6abe181a0abdd1f6c778521ae8497277Evgeniy Stepanov } 783ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown} 784ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 785ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/*------------------------------------------------------------*/ 786ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/*--- Recording errors ---*/ 787ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/*------------------------------------------------------------*/ 788ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 789ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* These many bytes below %ESP are considered addressible if we're 790ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown doing the --workaround-gcc296-bugs hack. */ 791ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#define VG_GCC296_BUG_STACK_SLOP 1024 792ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 793ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* Is this address within some small distance below %ESP? Used only 794ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown for the --workaround-gcc296-bugs kludge. */ 795ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic Bool is_just_below_ESP( Addr esp, Addr aa ) 796ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{ 797ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown esp -= VG_STACK_REDZONE_SZB; 798ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (esp > aa && (esp - aa) <= VG_GCC296_BUG_STACK_SLOP) 799ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return True; 800ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown else 801ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return False; 802ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown} 803ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 804ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* --- Called from generated and non-generated code --- */ 805ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 806ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownvoid MC_(record_address_error) ( ThreadId tid, Addr a, Int szB, 807ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Bool isWrite ) 808ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{ 809ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown MC_Error extra; 810ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Bool just_below_esp; 811ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 812ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (MC_(in_ignored_range)(a)) 813ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return; 814ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 815ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown# if defined(VGP_ppc32_aix5) || defined(VGP_ppc64_aix5) 816ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* AIX zero-page handling. On AIX, reads from page zero are, 817ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown bizarrely enough, legitimate. Writes to page zero aren't, 818ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown though. Since memcheck can't distinguish reads from writes, the 819ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown best we can do is to 'act normal' and mark the A bits in the 820ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown normal way as noaccess, but then hide any reads from that page 821ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown that get reported here. */ 822ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if ((!isWrite) && a >= 0 && a < 4096 && a+szB <= 4096) 823ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return; 824ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 825ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* Appalling AIX hack. It suppresses reads done by glink 826ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown fragments. Getting rid of this would require figuring out 827ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown somehow where the referenced data areas are (and their 828ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown sizes). */ 829ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if ((!isWrite) && szB == sizeof(Word)) { 830ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown UInt i1, i2; 831ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown UInt* pc = (UInt*)VG_(get_IP)(tid); 832ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (sizeof(Word) == 4) { 833ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown i1 = 0x800c0000; /* lwz r0,0(r12) */ 834ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown i2 = 0x804c0004; /* lwz r2,4(r12) */ 835ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } else { 836ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown i1 = 0xe80c0000; /* ld r0,0(r12) */ 837ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown i2 = 0xe84c0008; /* ld r2,8(r12) */ 838ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 839ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (pc[0] == i1 && pc[1] == i2) return; 840ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (pc[0] == i2 && pc[-1] == i1) return; 841ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 842ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown# endif 843ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 844ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown just_below_esp = is_just_below_ESP( VG_(get_SP)(tid), a ); 845ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 846ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* If this is caused by an access immediately below %ESP, and the 847ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown user asks nicely, we just ignore it. */ 848ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (MC_(clo_workaround_gcc296_bugs) && just_below_esp) 849ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return; 850ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 851ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown extra.Err.Addr.isWrite = isWrite; 852ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown extra.Err.Addr.szB = szB; 853ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown extra.Err.Addr.maybe_gcc = just_below_esp; 854ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown extra.Err.Addr.ai.tag = Addr_Undescribed; 855ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown VG_(maybe_record_error)( tid, Err_Addr, a, /*s*/NULL, &extra ); 856ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown} 857ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 858ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownvoid MC_(record_value_error) ( ThreadId tid, Int szB, UInt otag ) 859ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{ 860ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown MC_Error extra; 861ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown tl_assert( MC_(clo_mc_level) >= 2 ); 862ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (otag > 0) 863ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown tl_assert( MC_(clo_mc_level) == 3 ); 864ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown extra.Err.Value.szB = szB; 865ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown extra.Err.Value.otag = otag; 866ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown extra.Err.Value.origin_ec = NULL; /* Filled in later */ 867ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown VG_(maybe_record_error)( tid, Err_Value, /*addr*/0, /*s*/NULL, &extra ); 868ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown} 869ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 870ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownvoid MC_(record_cond_error) ( ThreadId tid, UInt otag ) 871ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{ 872ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown MC_Error extra; 873ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown tl_assert( MC_(clo_mc_level) >= 2 ); 874ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (otag > 0) 875ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown tl_assert( MC_(clo_mc_level) == 3 ); 876ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown extra.Err.Cond.otag = otag; 877ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown extra.Err.Cond.origin_ec = NULL; /* Filled in later */ 878ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown VG_(maybe_record_error)( tid, Err_Cond, /*addr*/0, /*s*/NULL, &extra ); 879ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown} 880ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 881ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* --- Called from non-generated code --- */ 882ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 883ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* This is for memory errors in signal-related memory. */ 884ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownvoid MC_(record_core_mem_error) ( ThreadId tid, Char* msg ) 885ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{ 886ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown VG_(maybe_record_error)( tid, Err_CoreMem, /*addr*/0, msg, /*extra*/NULL ); 887ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown} 888ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 889ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownvoid MC_(record_regparam_error) ( ThreadId tid, Char* msg, UInt otag ) 890ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{ 891ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown MC_Error extra; 892ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown tl_assert(VG_INVALID_THREADID != tid); 893ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (otag > 0) 894ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown tl_assert( MC_(clo_mc_level) == 3 ); 895ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown extra.Err.RegParam.otag = otag; 896ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown extra.Err.RegParam.origin_ec = NULL; /* Filled in later */ 897ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown VG_(maybe_record_error)( tid, Err_RegParam, /*addr*/0, msg, &extra ); 898ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown} 899ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 900ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownvoid MC_(record_memparam_error) ( ThreadId tid, Addr a, 901ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Bool isAddrErr, Char* msg, UInt otag ) 902ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{ 903ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown MC_Error extra; 904ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown tl_assert(VG_INVALID_THREADID != tid); 905ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (!isAddrErr) 906ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown tl_assert( MC_(clo_mc_level) >= 2 ); 907ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (otag != 0) { 908ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown tl_assert( MC_(clo_mc_level) == 3 ); 909ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown tl_assert( !isAddrErr ); 910ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 911ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown extra.Err.MemParam.isAddrErr = isAddrErr; 912ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown extra.Err.MemParam.ai.tag = Addr_Undescribed; 913ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown extra.Err.MemParam.otag = otag; 914ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown extra.Err.MemParam.origin_ec = NULL; /* Filled in later */ 915ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown VG_(maybe_record_error)( tid, Err_MemParam, a, msg, &extra ); 916ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown} 917ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 918ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownvoid MC_(record_jump_error) ( ThreadId tid, Addr a ) 919ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{ 920ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown MC_Error extra; 921ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown tl_assert(VG_INVALID_THREADID != tid); 922ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown extra.Err.Jump.ai.tag = Addr_Undescribed; 923ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown VG_(maybe_record_error)( tid, Err_Jump, a, /*s*/NULL, &extra ); 924ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown} 925ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 926ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownvoid MC_(record_free_error) ( ThreadId tid, Addr a ) 927ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{ 928ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown MC_Error extra; 929ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown tl_assert(VG_INVALID_THREADID != tid); 930ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown extra.Err.Free.ai.tag = Addr_Undescribed; 931ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown VG_(maybe_record_error)( tid, Err_Free, a, /*s*/NULL, &extra ); 932ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown} 933ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 934ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownvoid MC_(record_freemismatch_error) ( ThreadId tid, MC_Chunk* mc ) 935ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{ 936ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown MC_Error extra; 937ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown AddrInfo* ai = &extra.Err.FreeMismatch.ai; 938ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown tl_assert(VG_INVALID_THREADID != tid); 939ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ai->tag = Addr_Block; 940ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ai->Addr.Block.block_kind = Block_Mallocd; // Nb: Not 'Block_Freed' 941ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ai->Addr.Block.block_desc = "block"; 942ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ai->Addr.Block.block_szB = mc->szB; 943ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ai->Addr.Block.rwoffset = 0; 944ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ai->Addr.Block.lastchange = mc->where; 945ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown VG_(maybe_record_error)( tid, Err_FreeMismatch, mc->data, /*s*/NULL, 946ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown &extra ); 947ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown} 948ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 949ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownvoid MC_(record_illegal_mempool_error) ( ThreadId tid, Addr a ) 950ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{ 951ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown MC_Error extra; 952ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown tl_assert(VG_INVALID_THREADID != tid); 953ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown extra.Err.IllegalMempool.ai.tag = Addr_Undescribed; 954ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown VG_(maybe_record_error)( tid, Err_IllegalMempool, a, /*s*/NULL, &extra ); 955ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown} 956ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 957ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownvoid MC_(record_overlap_error) ( ThreadId tid, Char* function, 958ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Addr src, Addr dst, SizeT szB ) 959ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{ 960ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown MC_Error extra; 961ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown tl_assert(VG_INVALID_THREADID != tid); 962ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown extra.Err.Overlap.src = src; 963ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown extra.Err.Overlap.dst = dst; 964ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown extra.Err.Overlap.szB = szB; 965ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown VG_(maybe_record_error)( 966ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown tid, Err_Overlap, /*addr*/0, /*s*/function, &extra ); 967ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown} 968ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 969ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownBool MC_(record_leak_error) ( ThreadId tid, UInt n_this_record, 970ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown UInt n_total_records, LossRecord* lr, 971ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Bool print_record, Bool count_error ) 972ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{ 973ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown MC_Error extra; 974ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown extra.Err.Leak.n_this_record = n_this_record; 975ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown extra.Err.Leak.n_total_records = n_total_records; 976ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown extra.Err.Leak.lr = lr; 977ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return 978ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown VG_(unique_error) ( tid, Err_Leak, /*Addr*/0, /*s*/NULL, &extra, 979ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown lr->key.allocated_at, print_record, 980ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /*allow_GDB_attach*/False, count_error ); 981ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown} 982ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 983ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownvoid MC_(record_user_error) ( ThreadId tid, Addr a, 984ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Bool isAddrErr, UInt otag ) 985ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{ 986ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown MC_Error extra; 987ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (otag != 0) { 988ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown tl_assert(!isAddrErr); 989ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown tl_assert( MC_(clo_mc_level) == 3 ); 990ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 991ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (!isAddrErr) { 992ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown tl_assert( MC_(clo_mc_level) >= 2 ); 993ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 994ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown tl_assert(VG_INVALID_THREADID != tid); 995ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown extra.Err.User.isAddrErr = isAddrErr; 996ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown extra.Err.User.ai.tag = Addr_Undescribed; 997ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown extra.Err.User.otag = otag; 998ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown extra.Err.User.origin_ec = NULL; /* Filled in later */ 999ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown VG_(maybe_record_error)( tid, Err_User, a, /*s*/NULL, &extra ); 1000ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown} 1001ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 1002ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/*------------------------------------------------------------*/ 1003ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/*--- Other error operations ---*/ 1004ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/*------------------------------------------------------------*/ 1005ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 1006ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* Compare error contexts, to detect duplicates. Note that if they 1007ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown are otherwise the same, the faulting addrs and associated rwoffsets 1008ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown are allowed to be different. */ 1009ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownBool MC_(eq_Error) ( VgRes res, Error* e1, Error* e2 ) 1010ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{ 1011ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown MC_Error* extra1 = VG_(get_error_extra)(e1); 1012ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown MC_Error* extra2 = VG_(get_error_extra)(e2); 1013ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 1014ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* Guaranteed by calling function */ 1015ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown tl_assert(VG_(get_error_kind)(e1) == VG_(get_error_kind)(e2)); 1016ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 1017ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown switch (VG_(get_error_kind)(e1)) { 1018ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case Err_CoreMem: { 1019ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Char *e1s, *e2s; 1020ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown e1s = VG_(get_error_string)(e1); 1021ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown e2s = VG_(get_error_string)(e2); 1022ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (e1s == e2s) return True; 1023ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (VG_STREQ(e1s, e2s)) return True; 1024ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return False; 1025ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 1026ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 1027ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case Err_RegParam: 1028ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return VG_STREQ(VG_(get_error_string)(e1), VG_(get_error_string)(e2)); 1029ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 1030ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown // Perhaps we should also check the addrinfo.akinds for equality. 1031ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown // That would result in more error reports, but only in cases where 1032ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown // a register contains uninitialised bytes and points to memory 1033ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown // containing uninitialised bytes. Currently, the 2nd of those to be 1034ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown // detected won't be reported. That is (nearly?) always the memory 1035ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown // error, which is good. 1036ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case Err_MemParam: 1037ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (!VG_STREQ(VG_(get_error_string)(e1), 1038ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown VG_(get_error_string)(e2))) return False; 1039ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown // fall through 1040ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case Err_User: 1041ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return ( extra1->Err.User.isAddrErr == extra2->Err.User.isAddrErr 1042ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ? True : False ); 1043ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 1044ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case Err_Free: 1045ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case Err_FreeMismatch: 1046ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case Err_Jump: 1047ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case Err_IllegalMempool: 1048ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case Err_Overlap: 1049ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case Err_Cond: 1050ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return True; 1051ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 1052ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case Err_Addr: 1053ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return ( extra1->Err.Addr.szB == extra2->Err.Addr.szB 1054ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ? True : False ); 1055ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 1056ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case Err_Value: 1057ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return ( extra1->Err.Value.szB == extra2->Err.Value.szB 1058ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ? True : False ); 1059ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 1060ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case Err_Leak: 1061ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown VG_(tool_panic)("Shouldn't get Err_Leak in mc_eq_Error,\n" 1062ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "since it's handled with VG_(unique_error)()!"); 1063ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 1064ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown default: 1065ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown VG_(printf)("Error:\n unknown error code %d\n", 1066ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown VG_(get_error_kind)(e1)); 1067ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown VG_(tool_panic)("unknown error code in mc_eq_Error"); 1068ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 1069ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown} 1070ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 1071f673d1bf8bfb172f0eccbe4d3a908b3c65b55b33Kenny Root/* Functions used when searching MC_Chunk lists */ 1072f673d1bf8bfb172f0eccbe4d3a908b3c65b55b33Kenny Rootstatic 1073f673d1bf8bfb172f0eccbe4d3a908b3c65b55b33Kenny RootBool addr_is_in_MC_Chunk_default_REDZONE_SZB(MC_Chunk* mc, Addr a) 1074ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{ 1075ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return VG_(addr_is_in_block)( a, mc->data, mc->szB, 1076ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown MC_MALLOC_REDZONE_SZB ); 1077ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown} 1078f673d1bf8bfb172f0eccbe4d3a908b3c65b55b33Kenny Rootstatic 1079f673d1bf8bfb172f0eccbe4d3a908b3c65b55b33Kenny RootBool addr_is_in_MC_Chunk_with_REDZONE_SZB(MC_Chunk* mc, Addr a, SizeT rzB) 1080f673d1bf8bfb172f0eccbe4d3a908b3c65b55b33Kenny Root{ 1081f673d1bf8bfb172f0eccbe4d3a908b3c65b55b33Kenny Root return VG_(addr_is_in_block)( a, mc->data, mc->szB, 1082f673d1bf8bfb172f0eccbe4d3a908b3c65b55b33Kenny Root rzB ); 1083f673d1bf8bfb172f0eccbe4d3a908b3c65b55b33Kenny Root} 1084ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 1085f673d1bf8bfb172f0eccbe4d3a908b3c65b55b33Kenny Root// Forward declarations 1086ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic Bool client_block_maybe_describe( Addr a, AddrInfo* ai ); 1087f673d1bf8bfb172f0eccbe4d3a908b3c65b55b33Kenny Rootstatic Bool mempool_block_maybe_describe( Addr a, AddrInfo* ai ); 1088ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 1089ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 1090ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* Describe an address as best you can, for error messages, 1091ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown putting the result in ai. */ 1092ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic void describe_addr ( Addr a, /*OUT*/AddrInfo* ai ) 1093ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{ 1094ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown MC_Chunk* mc; 1095ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ThreadId tid; 1096ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Addr stack_min, stack_max; 1097ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown VgSectKind sect; 1098ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 1099ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown tl_assert(Addr_Undescribed == ai->tag); 1100ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 1101f673d1bf8bfb172f0eccbe4d3a908b3c65b55b33Kenny Root /* -- Perhaps it's a user-named block? -- */ 1102ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (client_block_maybe_describe( a, ai )) { 1103ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return; 1104ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 1105f673d1bf8bfb172f0eccbe4d3a908b3c65b55b33Kenny Root /* -- Perhaps it's in mempool block? -- */ 1106f673d1bf8bfb172f0eccbe4d3a908b3c65b55b33Kenny Root if (mempool_block_maybe_describe( a, ai )) { 1107f673d1bf8bfb172f0eccbe4d3a908b3c65b55b33Kenny Root return; 1108f673d1bf8bfb172f0eccbe4d3a908b3c65b55b33Kenny Root } 1109ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* -- Search for a recently freed block which might bracket it. -- */ 1110ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown mc = MC_(get_freed_list_head)(); 1111ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown while (mc) { 1112f673d1bf8bfb172f0eccbe4d3a908b3c65b55b33Kenny Root if (addr_is_in_MC_Chunk_default_REDZONE_SZB(mc, a)) { 1113ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ai->tag = Addr_Block; 1114ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ai->Addr.Block.block_kind = Block_Freed; 1115ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ai->Addr.Block.block_desc = "block"; 1116ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ai->Addr.Block.block_szB = mc->szB; 1117ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ai->Addr.Block.rwoffset = (Word)a - (Word)mc->data; 1118ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ai->Addr.Block.lastchange = mc->where; 1119ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return; 1120ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 1121ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown mc = mc->next; 1122ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 1123ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* -- Search for a currently malloc'd block which might bracket it. -- */ 1124ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown VG_(HT_ResetIter)(MC_(malloc_list)); 1125ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown while ( (mc = VG_(HT_Next)(MC_(malloc_list))) ) { 1126f673d1bf8bfb172f0eccbe4d3a908b3c65b55b33Kenny Root if (addr_is_in_MC_Chunk_default_REDZONE_SZB(mc, a)) { 1127ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ai->tag = Addr_Block; 1128ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ai->Addr.Block.block_kind = Block_Mallocd; 1129ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ai->Addr.Block.block_desc = "block"; 1130ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ai->Addr.Block.block_szB = mc->szB; 1131ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ai->Addr.Block.rwoffset = (Word)a - (Word)mc->data; 1132ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ai->Addr.Block.lastchange = mc->where; 1133ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return; 1134ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 1135ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 1136ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* -- Perhaps the variable type/location data describes it? -- */ 1137ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ai->Addr.Variable.descr1 1138ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown = VG_(newXA)( VG_(malloc), "mc.da.descr1", 1139ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown VG_(free), sizeof(HChar) ); 1140ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ai->Addr.Variable.descr2 1141ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown = VG_(newXA)( VG_(malloc), "mc.da.descr2", 1142ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown VG_(free), sizeof(HChar) ); 1143ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 1144ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown (void) VG_(get_data_description)( ai->Addr.Variable.descr1, 1145ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ai->Addr.Variable.descr2, a ); 1146ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* If there's nothing in descr1/2, free them. Why is it safe to to 1147ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown VG_(indexXA) at zero here? Because VG_(get_data_description) 1148ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown guarantees to zero terminate descr1/2 regardless of the outcome 1149ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown of the call. So there's always at least one element in each XA 1150ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown after the call. 1151ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown */ 1152ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (0 == VG_(strlen)( VG_(indexXA)( ai->Addr.Variable.descr1, 0 ))) { 1153ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown VG_(deleteXA)( ai->Addr.Variable.descr1 ); 1154ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ai->Addr.Variable.descr1 = NULL; 1155ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 1156ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (0 == VG_(strlen)( VG_(indexXA)( ai->Addr.Variable.descr2, 0 ))) { 1157ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown VG_(deleteXA)( ai->Addr.Variable.descr2 ); 1158ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ai->Addr.Variable.descr2 = NULL; 1159ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 1160ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* Assume (assert) that VG_(get_data_description) fills in descr1 1161ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown before it fills in descr2 */ 1162ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (ai->Addr.Variable.descr1 == NULL) 1163ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown tl_assert(ai->Addr.Variable.descr2 == NULL); 1164ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* So did we get lucky? */ 1165ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (ai->Addr.Variable.descr1 != NULL) { 1166ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ai->tag = Addr_Variable; 1167ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return; 1168ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 1169ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* -- Have a look at the low level data symbols - perhaps it's in 1170ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown there. -- */ 1171ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown VG_(memset)( &ai->Addr.DataSym.name, 1172ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 0, sizeof(ai->Addr.DataSym.name)); 1173ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (VG_(get_datasym_and_offset)( 1174ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown a, &ai->Addr.DataSym.name[0], 1175ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown sizeof(ai->Addr.DataSym.name)-1, 1176ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown &ai->Addr.DataSym.offset )) { 1177ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ai->tag = Addr_DataSym; 1178ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown tl_assert( ai->Addr.DataSym.name 1179ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown [ sizeof(ai->Addr.DataSym.name)-1 ] == 0); 1180ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return; 1181ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 1182ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* -- Perhaps it's on a thread's stack? -- */ 1183ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown VG_(thread_stack_reset_iter)(&tid); 1184ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown while ( VG_(thread_stack_next)(&tid, &stack_min, &stack_max) ) { 1185ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (stack_min - VG_STACK_REDZONE_SZB <= a && a <= stack_max) { 1186ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ai->tag = Addr_Stack; 1187ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ai->Addr.Stack.tid = tid; 1188ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return; 1189ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 1190ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 1191ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* -- last ditch attempt at classification -- */ 1192ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown tl_assert( sizeof(ai->Addr.SectKind.objname) > 4 ); 1193ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown VG_(memset)( &ai->Addr.SectKind.objname, 1194ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 0, sizeof(ai->Addr.SectKind.objname)); 1195ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown VG_(strcpy)( ai->Addr.SectKind.objname, "???" ); 1196ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown sect = VG_(DebugInfo_sect_kind)( &ai->Addr.SectKind.objname[0], 1197ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown sizeof(ai->Addr.SectKind.objname)-1, a); 1198ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (sect != Vg_SectUnknown) { 1199ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ai->tag = Addr_SectKind; 1200ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ai->Addr.SectKind.kind = sect; 1201ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown tl_assert( ai->Addr.SectKind.objname 1202ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown [ sizeof(ai->Addr.SectKind.objname)-1 ] == 0); 1203ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return; 1204ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 1205ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* -- Clueless ... -- */ 1206ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ai->tag = Addr_Unknown; 1207ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return; 1208ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown} 1209ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 1210ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* Fill in *origin_ec as specified by otag, or NULL it out if otag 1211ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown does not refer to a known origin. */ 1212ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic void update_origin ( /*OUT*/ExeContext** origin_ec, 1213ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown UInt otag ) 1214ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{ 1215ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown UInt ecu = otag & ~3; 1216ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown *origin_ec = NULL; 1217ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (VG_(is_plausible_ECU)(ecu)) { 1218ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown *origin_ec = VG_(get_ExeContext_from_ECU)( ecu ); 1219ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 1220ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown} 1221ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 1222ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* Updates the copy with address info if necessary (but not for all errors). */ 1223ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownUInt MC_(update_Error_extra)( Error* err ) 1224ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{ 1225ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown MC_Error* extra = VG_(get_error_extra)(err); 1226ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 1227ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown switch (VG_(get_error_kind)(err)) { 1228ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown // These ones don't have addresses associated with them, and so don't 1229ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown // need any updating. 1230ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case Err_CoreMem: 1231ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown //case Err_Value: 1232ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown //case Err_Cond: 1233ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case Err_Overlap: 1234ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown // For Err_Leaks the returned size does not matter -- they are always 1235ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown // shown with VG_(unique_error)() so they 'extra' not copied. But 1236ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown // we make it consistent with the others. 1237ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case Err_Leak: 1238ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return sizeof(MC_Error); 1239ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 1240ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown // For value errors, get the ExeContext corresponding to the 1241ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown // origin tag. Note that it is a kludge to assume that 1242ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown // a length-1 trace indicates a stack origin. FIXME. 1243ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case Err_Value: 1244ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown update_origin( &extra->Err.Value.origin_ec, 1245ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown extra->Err.Value.otag ); 1246ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return sizeof(MC_Error); 1247ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case Err_Cond: 1248ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown update_origin( &extra->Err.Cond.origin_ec, 1249ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown extra->Err.Cond.otag ); 1250ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return sizeof(MC_Error); 1251ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case Err_RegParam: 1252ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown update_origin( &extra->Err.RegParam.origin_ec, 1253ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown extra->Err.RegParam.otag ); 1254ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return sizeof(MC_Error); 1255ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 1256ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown // These ones always involve a memory address. 1257ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case Err_Addr: 1258ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown describe_addr ( VG_(get_error_address)(err), 1259ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown &extra->Err.Addr.ai ); 1260ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return sizeof(MC_Error); 1261ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case Err_MemParam: 1262ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown describe_addr ( VG_(get_error_address)(err), 1263ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown &extra->Err.MemParam.ai ); 1264ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown update_origin( &extra->Err.MemParam.origin_ec, 1265ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown extra->Err.MemParam.otag ); 1266ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return sizeof(MC_Error); 1267ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case Err_Jump: 1268ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown describe_addr ( VG_(get_error_address)(err), 1269ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown &extra->Err.Jump.ai ); 1270ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return sizeof(MC_Error); 1271ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case Err_User: 1272ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown describe_addr ( VG_(get_error_address)(err), 1273ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown &extra->Err.User.ai ); 1274ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown update_origin( &extra->Err.User.origin_ec, 1275ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown extra->Err.User.otag ); 1276ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return sizeof(MC_Error); 1277ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case Err_Free: 1278ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown describe_addr ( VG_(get_error_address)(err), 1279ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown &extra->Err.Free.ai ); 1280ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return sizeof(MC_Error); 1281ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case Err_IllegalMempool: 1282ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown describe_addr ( VG_(get_error_address)(err), 1283ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown &extra->Err.IllegalMempool.ai ); 1284ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return sizeof(MC_Error); 1285ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 1286ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown // Err_FreeMismatches have already had their address described; this is 1287ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown // possible because we have the MC_Chunk on hand when the error is 1288ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown // detected. However, the address may be part of a user block, and if so 1289ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown // we override the pre-determined description with a user block one. 1290ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case Err_FreeMismatch: { 1291ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown tl_assert(extra && Block_Mallocd == 1292ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown extra->Err.FreeMismatch.ai.Addr.Block.block_kind); 1293ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown (void)client_block_maybe_describe( VG_(get_error_address)(err), 1294ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown &extra->Err.FreeMismatch.ai ); 1295ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return sizeof(MC_Error); 1296ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 1297ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 1298ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown default: VG_(tool_panic)("mc_update_extra: bad errkind"); 1299ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 1300ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown} 1301ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 1302f673d1bf8bfb172f0eccbe4d3a908b3c65b55b33Kenny Root 1303ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic Bool client_block_maybe_describe( Addr a, 1304ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /*OUT*/AddrInfo* ai ) 1305ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{ 1306ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown UWord i; 1307ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown CGenBlock* cgbs = NULL; 1308ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown UWord cgb_used = 0; 1309ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 1310ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown MC_(get_ClientBlock_array)( &cgbs, &cgb_used ); 1311ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (cgbs == NULL) 1312ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown tl_assert(cgb_used == 0); 1313ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 1314ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* Perhaps it's a general block ? */ 1315ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown for (i = 0; i < cgb_used; i++) { 1316ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (cgbs[i].start == 0 && cgbs[i].size == 0) 1317ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown continue; 1318ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown // Use zero as the redzone for client blocks. 1319ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (VG_(addr_is_in_block)(a, cgbs[i].start, cgbs[i].size, 0)) { 1320ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ai->tag = Addr_Block; 1321ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ai->Addr.Block.block_kind = Block_UserG; 1322ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ai->Addr.Block.block_desc = cgbs[i].desc; 1323ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ai->Addr.Block.block_szB = cgbs[i].size; 1324ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ai->Addr.Block.rwoffset = (Word)(a) - (Word)(cgbs[i].start); 1325ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ai->Addr.Block.lastchange = cgbs[i].where; 1326ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return True; 1327ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 1328ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 1329ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return False; 1330ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown} 1331ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 1332ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 1333f673d1bf8bfb172f0eccbe4d3a908b3c65b55b33Kenny Rootstatic Bool mempool_block_maybe_describe( Addr a, 1334f673d1bf8bfb172f0eccbe4d3a908b3c65b55b33Kenny Root /*OUT*/AddrInfo* ai ) 1335f673d1bf8bfb172f0eccbe4d3a908b3c65b55b33Kenny Root{ 1336f673d1bf8bfb172f0eccbe4d3a908b3c65b55b33Kenny Root MC_Mempool* mp; 1337f673d1bf8bfb172f0eccbe4d3a908b3c65b55b33Kenny Root tl_assert( MC_(mempool_list) ); 1338f673d1bf8bfb172f0eccbe4d3a908b3c65b55b33Kenny Root 1339f673d1bf8bfb172f0eccbe4d3a908b3c65b55b33Kenny Root VG_(HT_ResetIter)( MC_(mempool_list) ); 1340f673d1bf8bfb172f0eccbe4d3a908b3c65b55b33Kenny Root while ( (mp = VG_(HT_Next)(MC_(mempool_list))) ) { 1341f673d1bf8bfb172f0eccbe4d3a908b3c65b55b33Kenny Root if (mp->chunks != NULL) { 1342f673d1bf8bfb172f0eccbe4d3a908b3c65b55b33Kenny Root MC_Chunk* mc; 1343f673d1bf8bfb172f0eccbe4d3a908b3c65b55b33Kenny Root VG_(HT_ResetIter)(mp->chunks); 1344f673d1bf8bfb172f0eccbe4d3a908b3c65b55b33Kenny Root while ( (mc = VG_(HT_Next)(mp->chunks)) ) { 1345f673d1bf8bfb172f0eccbe4d3a908b3c65b55b33Kenny Root if (addr_is_in_MC_Chunk_with_REDZONE_SZB(mc, a, mp->rzB)) { 1346f673d1bf8bfb172f0eccbe4d3a908b3c65b55b33Kenny Root ai->tag = Addr_Block; 1347f673d1bf8bfb172f0eccbe4d3a908b3c65b55b33Kenny Root ai->Addr.Block.block_kind = Block_MempoolChunk; 1348f673d1bf8bfb172f0eccbe4d3a908b3c65b55b33Kenny Root ai->Addr.Block.block_desc = "block"; 1349f673d1bf8bfb172f0eccbe4d3a908b3c65b55b33Kenny Root ai->Addr.Block.block_szB = mc->szB; 1350f673d1bf8bfb172f0eccbe4d3a908b3c65b55b33Kenny Root ai->Addr.Block.rwoffset = (Word)a - (Word)mc->data; 1351f673d1bf8bfb172f0eccbe4d3a908b3c65b55b33Kenny Root ai->Addr.Block.lastchange = mc->where; 1352f673d1bf8bfb172f0eccbe4d3a908b3c65b55b33Kenny Root return True; 1353f673d1bf8bfb172f0eccbe4d3a908b3c65b55b33Kenny Root } 1354f673d1bf8bfb172f0eccbe4d3a908b3c65b55b33Kenny Root } 1355f673d1bf8bfb172f0eccbe4d3a908b3c65b55b33Kenny Root } 1356f673d1bf8bfb172f0eccbe4d3a908b3c65b55b33Kenny Root } 1357f673d1bf8bfb172f0eccbe4d3a908b3c65b55b33Kenny Root return False; 1358f673d1bf8bfb172f0eccbe4d3a908b3c65b55b33Kenny Root} 1359f673d1bf8bfb172f0eccbe4d3a908b3c65b55b33Kenny Root 1360f673d1bf8bfb172f0eccbe4d3a908b3c65b55b33Kenny Root 1361ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/*------------------------------------------------------------*/ 1362ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/*--- Suppressions ---*/ 1363ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/*------------------------------------------------------------*/ 1364ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 1365ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Browntypedef 1366ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown enum { 1367ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ParamSupp, // Bad syscall params 1368ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown UserSupp, // Errors arising from client-request checks 1369ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown CoreMemSupp, // Memory errors in core (pthread ops, signal handling) 1370ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 1371ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown // Undefined value errors of given size 1372ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Value1Supp, Value2Supp, Value4Supp, Value8Supp, Value16Supp, 1373ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 1374ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown // Undefined value error in conditional. 1375ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown CondSupp, 1376ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 1377ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown // Unaddressable read/write attempt at given size 1378ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Addr1Supp, Addr2Supp, Addr4Supp, Addr8Supp, Addr16Supp, 1379ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 1380ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown JumpSupp, // Jump to unaddressable target 1381ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown FreeSupp, // Invalid or mismatching free 1382ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown OverlapSupp, // Overlapping blocks in memcpy(), strcpy(), etc 1383ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown LeakSupp, // Something to be suppressed in a leak check. 1384ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown MempoolSupp, // Memory pool suppression. 1385ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 1386ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown MC_SuppKind; 1387ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 1388ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownBool MC_(is_recognised_suppression) ( Char* name, Supp* su ) 1389ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{ 1390ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown SuppKind skind; 1391ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 1392ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (VG_STREQ(name, "Param")) skind = ParamSupp; 1393ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown else if (VG_STREQ(name, "User")) skind = UserSupp; 1394ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown else if (VG_STREQ(name, "CoreMem")) skind = CoreMemSupp; 1395ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown else if (VG_STREQ(name, "Addr1")) skind = Addr1Supp; 1396ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown else if (VG_STREQ(name, "Addr2")) skind = Addr2Supp; 1397ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown else if (VG_STREQ(name, "Addr4")) skind = Addr4Supp; 1398ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown else if (VG_STREQ(name, "Addr8")) skind = Addr8Supp; 1399ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown else if (VG_STREQ(name, "Addr16")) skind = Addr16Supp; 1400ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown else if (VG_STREQ(name, "Jump")) skind = JumpSupp; 1401ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown else if (VG_STREQ(name, "Free")) skind = FreeSupp; 1402ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown else if (VG_STREQ(name, "Leak")) skind = LeakSupp; 1403ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown else if (VG_STREQ(name, "Overlap")) skind = OverlapSupp; 1404ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown else if (VG_STREQ(name, "Mempool")) skind = MempoolSupp; 1405ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown else if (VG_STREQ(name, "Cond")) skind = CondSupp; 1406ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown else if (VG_STREQ(name, "Value0")) skind = CondSupp; /* backwards compat */ 1407ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown else if (VG_STREQ(name, "Value1")) skind = Value1Supp; 1408ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown else if (VG_STREQ(name, "Value2")) skind = Value2Supp; 1409ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown else if (VG_STREQ(name, "Value4")) skind = Value4Supp; 1410ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown else if (VG_STREQ(name, "Value8")) skind = Value8Supp; 1411ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown else if (VG_STREQ(name, "Value16")) skind = Value16Supp; 1412ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown else 1413ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return False; 1414ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 1415ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown VG_(set_supp_kind)(su, skind); 1416ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return True; 1417ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown} 1418ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 1419ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownBool MC_(read_extra_suppression_info) ( Int fd, Char** bufpp, 1420ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown SizeT* nBufp, Supp *su ) 1421ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{ 1422ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Bool eof; 1423ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 1424ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (VG_(get_supp_kind)(su) == ParamSupp) { 1425ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown eof = VG_(get_line) ( fd, bufpp, nBufp, NULL ); 1426ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (eof) return False; 1427ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown VG_(set_supp_string)(su, VG_(strdup)("mc.resi.1", *bufpp)); 1428ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 1429ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return True; 1430ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown} 1431ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 1432ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownBool MC_(error_matches_suppression) ( Error* err, Supp* su ) 1433ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{ 1434ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Int su_szB; 1435ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown MC_Error* extra = VG_(get_error_extra)(err); 1436ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ErrorKind ekind = VG_(get_error_kind )(err); 1437ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 1438ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown switch (VG_(get_supp_kind)(su)) { 1439ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case ParamSupp: 1440ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return ((ekind == Err_RegParam || ekind == Err_MemParam) 1441ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown && VG_STREQ(VG_(get_error_string)(err), 1442ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown VG_(get_supp_string)(su))); 1443ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 1444ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case UserSupp: 1445ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return (ekind == Err_User); 1446ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 1447ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case CoreMemSupp: 1448ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return (ekind == Err_CoreMem 1449ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown && VG_STREQ(VG_(get_error_string)(err), 1450ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown VG_(get_supp_string)(su))); 1451ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 1452ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case Value1Supp: su_szB = 1; goto value_case; 1453ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case Value2Supp: su_szB = 2; goto value_case; 1454ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case Value4Supp: su_szB = 4; goto value_case; 1455ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case Value8Supp: su_szB = 8; goto value_case; 1456ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case Value16Supp:su_szB =16; goto value_case; 1457ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown value_case: 1458ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return (ekind == Err_Value && extra->Err.Value.szB == su_szB); 1459ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 1460ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case CondSupp: 1461ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return (ekind == Err_Cond); 1462ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 1463ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case Addr1Supp: su_szB = 1; goto addr_case; 1464ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case Addr2Supp: su_szB = 2; goto addr_case; 1465ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case Addr4Supp: su_szB = 4; goto addr_case; 1466ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case Addr8Supp: su_szB = 8; goto addr_case; 1467ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case Addr16Supp:su_szB =16; goto addr_case; 1468ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown addr_case: 1469ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return (ekind == Err_Addr && extra->Err.Addr.szB == su_szB); 1470ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 1471ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case JumpSupp: 1472ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return (ekind == Err_Jump); 1473ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 1474ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case FreeSupp: 1475ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return (ekind == Err_Free || ekind == Err_FreeMismatch); 1476ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 1477ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case OverlapSupp: 1478ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return (ekind == Err_Overlap); 1479ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 1480ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case LeakSupp: 1481ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return (ekind == Err_Leak); 1482ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 1483ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case MempoolSupp: 1484ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return (ekind == Err_IllegalMempool); 1485ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 1486ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown default: 1487ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown VG_(printf)("Error:\n" 1488ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown " unknown suppression type %d\n", 1489ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown VG_(get_supp_kind)(su)); 1490ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown VG_(tool_panic)("unknown suppression type in " 1491ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "MC_(error_matches_suppression)"); 1492ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 1493ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown} 1494ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 1495ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownChar* MC_(get_error_name) ( Error* err ) 1496ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{ 1497ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown switch (VG_(get_error_kind)(err)) { 1498ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case Err_RegParam: return "Param"; 1499ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case Err_MemParam: return "Param"; 1500ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case Err_User: return "User"; 1501ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case Err_FreeMismatch: return "Free"; 1502ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case Err_IllegalMempool: return "Mempool"; 1503ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case Err_Free: return "Free"; 1504ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case Err_Jump: return "Jump"; 1505ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case Err_CoreMem: return "CoreMem"; 1506ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case Err_Overlap: return "Overlap"; 1507ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case Err_Leak: return "Leak"; 1508ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case Err_Cond: return "Cond"; 1509ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case Err_Addr: { 1510ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown MC_Error* extra = VG_(get_error_extra)(err); 1511ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown switch ( extra->Err.Addr.szB ) { 1512ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case 1: return "Addr1"; 1513ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case 2: return "Addr2"; 1514ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case 4: return "Addr4"; 1515ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case 8: return "Addr8"; 1516ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case 16: return "Addr16"; 1517ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown default: VG_(tool_panic)("unexpected size for Addr"); 1518ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 1519ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 1520ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case Err_Value: { 1521ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown MC_Error* extra = VG_(get_error_extra)(err); 1522ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown switch ( extra->Err.Value.szB ) { 1523ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case 1: return "Value1"; 1524ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case 2: return "Value2"; 1525ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case 4: return "Value4"; 1526ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case 8: return "Value8"; 1527ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case 16: return "Value16"; 1528ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown default: VG_(tool_panic)("unexpected size for Value"); 1529ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 1530ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 1531ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown default: VG_(tool_panic)("get_error_name: unexpected type"); 1532ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 1533ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown} 1534ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 1535ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownBool MC_(get_extra_suppression_info) ( Error* err, 1536ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /*OUT*/Char* buf, Int nBuf ) 1537ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{ 1538ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ErrorKind ekind = VG_(get_error_kind )(err); 1539ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown tl_assert(buf); 1540ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown tl_assert(nBuf >= 16); // stay sane 1541ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (Err_RegParam == ekind || Err_MemParam == ekind) { 1542ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Char* errstr = VG_(get_error_string)(err); 1543ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown tl_assert(errstr); 1544ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown VG_(snprintf)(buf, nBuf-1, "%s", errstr); 1545ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return True; 1546ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } else { 1547ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return False; 1548ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 1549ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown} 1550ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 1551ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 1552ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/*--------------------------------------------------------------------*/ 1553ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/*--- end mc_errors.c ---*/ 1554ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/*--------------------------------------------------------------------*/ 1555