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