mirror of
https://github.com/Zenithsiz/ftmemsim-valgrind.git
synced 2026-02-05 03:07:56 +00:00
neatens other things up. Also, it adds the --gen-suppressions option for automatically generating suppressions for each error. Note that it changes the core/skin interface: SK_(dup_extra_and_update)() is replaced by SK_(update_extra)(), and SK_(get_error_name)() and SK_(print_extra_suppression_info)() are added. ----------------------------------------------------------------------------- details ----------------------------------------------------------------------------- Removed ac_common.c -- it just #included another .c file; moved the #include into ac_main.c. Introduced "mac_" prefixes for files shared between Addrcheck and Memcheck, to make it clearer which code is shared. Also using a "MAC_" prefix for functions and variables and types that are shared. Addrcheck doesn't see the "MC_" prefix at all. Factored out almost-identical mc_describe_addr() and describe_addr() (AddrCheck's version) into MAC_(describe_addr)(). Got rid of the "pp_ExeContext" closure passed to SK_(pp_SkinError)(), it wasn't really necessary. Introduced MAC_(pp_shared_SkinError)() for the error printing code shared by Addrcheck and Memcheck. Fixed some bogus stuff in Addrcheck error messages about "uninitialised bytes" (there because of an imperfect conversion from Memcheck). Moved the leak checker out of core (vg_memory.c), into mac_leakcheck.c. - This meant the hacky way of recording Leak errors, which was different to normal errors, could be changed to something better: introduced a function VG_(unique_error)(), which unlike VG_(maybe_record_error)() just prints the error (unless suppressed) but doesn't record it. Used for leaks; a much better solution all round as it allowed me to remove a lot of almost-identical code from leak handling (is_suppressible_leak(), leaksupp_matches_callers()). - As part of this, changed the horrible SK_(dup_extra_and_update) into the slightly less horrible SK_(update_extra), which returns the size of the `extra' part for the core to duplicate. - Also renamed it from VG_(generic_detect_memory_leaks)() to MAC_(do_detect_memory_leaks). In making the code nicer w.r.t suppressions and error reporting, I tied it a bit more closely to Memcheck/Addrcheck, and got rid of some of the args. It's not really "generic" any more, but then it never really was. (This could be undone, but there doesn't seem to be much point.) STREQ and STREQN were #defined in several places, and in two different ways. Made global macros VG_STREQ, VG_CLO_STREQ and VG_CLO_STREQN in vg_skin.h. Added the --gen-suppressions code. This required adding the functions SK_(get_error_name)() and SK_(print_extra_suppression_info)() for skins that use the error handling need. Added documentation for --gen-suppressions, and fixed some other minor document problems. Various other minor related changes too. git-svn-id: svn://svn.valgrind.org/valgrind/trunk@1517
180 lines
6.3 KiB
C
180 lines
6.3 KiB
C
|
|
/*--------------------------------------------------------------------*/
|
|
/*--- Management of memory error messages. ---*/
|
|
/*--- mc_errcontext.c ---*/
|
|
/*--------------------------------------------------------------------*/
|
|
|
|
/*
|
|
This file is part of MemCheck, a heavyweight Valgrind skin for
|
|
detecting memory errors.
|
|
|
|
Copyright (C) 2000-2002 Julian Seward
|
|
jseward@acm.org
|
|
|
|
This program is free software; you can redistribute it and/or
|
|
modify it under the terms of the GNU General Public License as
|
|
published by the Free Software Foundation; either version 2 of the
|
|
License, or (at your option) any later version.
|
|
|
|
This program is distributed in the hope that it will be useful, but
|
|
WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
General Public License for more details.
|
|
|
|
You should have received a copy of the GNU General Public License
|
|
along with this program; if not, write to the Free Software
|
|
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
|
|
02111-1307, USA.
|
|
|
|
The GNU General Public License is contained in the file COPYING.
|
|
*/
|
|
|
|
#include "mc_include.h"
|
|
|
|
/*------------------------------------------------------------*/
|
|
/*--- Printing errors ---*/
|
|
/*------------------------------------------------------------*/
|
|
|
|
void SK_(pp_SkinError) ( Error* err )
|
|
{
|
|
MAC_Error* err_extra = VG_(get_error_extra)(err);
|
|
|
|
switch (VG_(get_error_kind)(err)) {
|
|
case CoreMemErr:
|
|
if (err_extra->isWrite) {
|
|
VG_(message)(Vg_UserMsg,
|
|
"%s contains unaddressable byte(s)", VG_(get_error_string)(err));
|
|
} else {
|
|
VG_(message)(Vg_UserMsg,
|
|
"%s contains uninitialised or unaddressable byte(s)",
|
|
VG_(get_error_string)(err));
|
|
}
|
|
VG_(pp_ExeContext)( VG_(get_error_where)(err) );
|
|
break;
|
|
|
|
case ValueErr:
|
|
if (err_extra->size == 0) {
|
|
VG_(message)(
|
|
Vg_UserMsg,
|
|
"Conditional jump or move depends on uninitialised value(s)");
|
|
} else {
|
|
VG_(message)(Vg_UserMsg,
|
|
"Use of uninitialised value of size %d",
|
|
err_extra->size);
|
|
}
|
|
VG_(pp_ExeContext)( VG_(get_error_where)(err) );
|
|
break;
|
|
|
|
case AddrErr:
|
|
switch (err_extra->axskind) {
|
|
case ReadAxs:
|
|
VG_(message)(Vg_UserMsg, "Invalid read of size %d",
|
|
err_extra->size );
|
|
break;
|
|
case WriteAxs:
|
|
VG_(message)(Vg_UserMsg, "Invalid write of size %d",
|
|
err_extra->size );
|
|
break;
|
|
case ExecAxs:
|
|
VG_(message)(Vg_UserMsg, "Jump to the invalid address "
|
|
"stated on the next line");
|
|
break;
|
|
default:
|
|
VG_(skin_panic)("SK_(pp_SkinError)(axskind)");
|
|
}
|
|
VG_(pp_ExeContext)( VG_(get_error_where)(err) );
|
|
MAC_(pp_AddrInfo)(VG_(get_error_address)(err), &err_extra->addrinfo);
|
|
break;
|
|
|
|
case ParamErr:
|
|
if (err_extra->isWrite) {
|
|
VG_(message)(Vg_UserMsg,
|
|
"Syscall param %s contains unaddressable byte(s)",
|
|
VG_(get_error_string)(err));
|
|
} else {
|
|
VG_(message)(Vg_UserMsg,
|
|
"Syscall param %s contains uninitialised or "
|
|
"unaddressable byte(s)",
|
|
VG_(get_error_string)(err));
|
|
}
|
|
VG_(pp_ExeContext)( VG_(get_error_where)(err) );
|
|
MAC_(pp_AddrInfo)(VG_(get_error_address)(err), &err_extra->addrinfo);
|
|
break;
|
|
|
|
case UserErr:
|
|
if (err_extra->isWrite) {
|
|
VG_(message)(Vg_UserMsg,
|
|
"Unaddressable byte(s) found during client check request");
|
|
} else {
|
|
VG_(message)(Vg_UserMsg,
|
|
"Uninitialised or "
|
|
"unaddressable byte(s) found during client check request");
|
|
}
|
|
VG_(pp_ExeContext)( VG_(get_error_where)(err) );
|
|
MAC_(pp_AddrInfo)(VG_(get_error_address)(err), &err_extra->addrinfo);
|
|
break;
|
|
|
|
default:
|
|
MAC_(pp_shared_SkinError)(err);
|
|
break;
|
|
}
|
|
}
|
|
|
|
/*------------------------------------------------------------*/
|
|
/*--- Recording errors ---*/
|
|
/*------------------------------------------------------------*/
|
|
|
|
/* Creates a copy of the `extra' part, updates the copy with address info if
|
|
necessary, and returns the copy. */
|
|
/* This one called from generated code. */
|
|
void MC_(record_value_error) ( Int size )
|
|
{
|
|
MAC_Error err_extra;
|
|
|
|
MAC_(clear_MAC_Error)( &err_extra );
|
|
err_extra.size = size;
|
|
VG_(maybe_record_error)( NULL, ValueErr, /*addr*/0, /*s*/NULL, &err_extra );
|
|
}
|
|
|
|
/* This one called from non-generated code */
|
|
void MC_(record_user_error) ( ThreadState* tst, Addr a, Bool isWrite )
|
|
{
|
|
MAC_Error err_extra;
|
|
|
|
sk_assert(NULL != tst);
|
|
|
|
MAC_(clear_MAC_Error)( &err_extra );
|
|
err_extra.addrinfo.akind = Undescribed;
|
|
err_extra.isWrite = isWrite;
|
|
VG_(maybe_record_error)( tst, UserErr, a, /*s*/NULL, &err_extra );
|
|
}
|
|
|
|
/*------------------------------------------------------------*/
|
|
/*--- Suppressions ---*/
|
|
/*------------------------------------------------------------*/
|
|
|
|
Bool SK_(recognised_suppression) ( Char* name, Supp* su )
|
|
{
|
|
SuppKind skind;
|
|
|
|
if (MAC_(shared_recognised_suppression)(name, su))
|
|
return True;
|
|
|
|
/* Extra suppressions not used by Addrcheck */
|
|
else if (VG_STREQ(name, "Cond")) skind = Value0Supp;
|
|
else if (VG_STREQ(name, "Value0")) skind = Value0Supp; /* backwards compat */
|
|
else if (VG_STREQ(name, "Value1")) skind = Value1Supp;
|
|
else if (VG_STREQ(name, "Value2")) skind = Value2Supp;
|
|
else if (VG_STREQ(name, "Value4")) skind = Value4Supp;
|
|
else if (VG_STREQ(name, "Value8")) skind = Value8Supp;
|
|
else
|
|
return False;
|
|
|
|
VG_(set_supp_kind)(su, skind);
|
|
return True;
|
|
}
|
|
|
|
/*--------------------------------------------------------------------*/
|
|
/*--- end mc_errcontext.c ---*/
|
|
/*--------------------------------------------------------------------*/
|