mirror of
https://github.com/Zenithsiz/ftmemsim-valgrind.git
synced 2026-02-03 18:13:01 +00:00
Merge exp-ptrcheck/ changes from branches/MESSAGING_TIDYUP r10464.
See trunk r10465 commit message for details. git-svn-id: svn://svn.valgrind.org/valgrind/trunk@10469
This commit is contained in:
parent
d6407ffc63
commit
97c1ddae79
@ -1023,7 +1023,8 @@ void set_mem ( Addr a, SizeT len, Seg* seg )
|
||||
|
||||
if (len > 100 * 1000 * 1000)
|
||||
VG_(message)(Vg_UserMsg,
|
||||
"Warning: set address range state: large range %lu", len);
|
||||
"Warning: set address range state: large range %lu\n",
|
||||
len);
|
||||
|
||||
a = VG_ROUNDDN(a, sizeof(UWord));
|
||||
end = VG_ROUNDUP(a + len, sizeof(UWord));
|
||||
@ -2061,7 +2062,7 @@ void h_post_reg_write_clientcall(ThreadId tid, PtrdiffT guest_state_offset,
|
||||
else if (f == (Addr)h_replace_free
|
||||
|| f == (Addr)h_replace___builtin_delete
|
||||
|| f == (Addr)h_replace___builtin_vec_delete
|
||||
// || f == (Addr)VG_(cli_block_size)
|
||||
// || f == (Addr)VG_(cli_block_size)
|
||||
|| f == (Addr)VG_(message))
|
||||
{
|
||||
// Probably best to set the (non-existent!) return value to
|
||||
@ -5308,25 +5309,25 @@ void h_fini ( Int exitcode )
|
||||
{
|
||||
if (VG_(clo_verbosity) >= 2) {
|
||||
VG_(message)(Vg_DebugMsg,
|
||||
" h_: %'10llu client allocs, %'10llu client frees",
|
||||
" h_: %'10llu client allocs, %'10llu client frees\n",
|
||||
stats__client_mallocs, stats__client_frees);
|
||||
VG_(message)(Vg_DebugMsg,
|
||||
" h_: %'10llu Segs allocd, %'10llu Segs recycled",
|
||||
" h_: %'10llu Segs allocd, %'10llu Segs recycled\n",
|
||||
stats__segs_allocd, stats__segs_recycled);
|
||||
}
|
||||
|
||||
#if 0
|
||||
if (h_clo_lossage_check) {
|
||||
VG_(message)(Vg_UserMsg, "");
|
||||
VG_(message)(Vg_UserMsg, "%12lld total memory references",
|
||||
VG_(message)(Vg_UserMsg, "\n");
|
||||
VG_(message)(Vg_UserMsg, "%12lld total memory references\n",
|
||||
stats__tot_mem_refs);
|
||||
VG_(message)(Vg_UserMsg, "%12lld of which are in a known segment",
|
||||
VG_(message)(Vg_UserMsg, "%12lld of which are in a known segment\n",
|
||||
stats__refs_in_a_seg);
|
||||
VG_(message)(Vg_UserMsg, "%12lld of which are 'lost' w.r.t the seg",
|
||||
VG_(message)(Vg_UserMsg, "%12lld of which are 'lost' w.r.t the seg\n",
|
||||
stats__refs_lost_seg);
|
||||
VG_(message)(Vg_UserMsg, "");
|
||||
VG_(message)(Vg_UserMsg, "\n");
|
||||
show_lossage();
|
||||
VG_(message)(Vg_UserMsg, "");
|
||||
VG_(message)(Vg_UserMsg, "\n");
|
||||
} else {
|
||||
tl_assert( 0 == VG_(OSetGen_Size)(lossage) );
|
||||
}
|
||||
|
||||
@ -38,6 +38,7 @@
|
||||
#include "pub_tool_basics.h"
|
||||
#include "pub_tool_libcbase.h"
|
||||
#include "pub_tool_libcprint.h"
|
||||
#include "pub_tool_xarray.h"
|
||||
#include "pub_tool_mallocfree.h"
|
||||
#include "pub_tool_libcassert.h"
|
||||
#include "pub_tool_options.h"
|
||||
@ -96,7 +97,7 @@ void pc_print_debug_usage(void)
|
||||
|
||||
//////////////////////////////////////////////////////////////
|
||||
// //
|
||||
// Error management //
|
||||
// Error management -- storage //
|
||||
// //
|
||||
//////////////////////////////////////////////////////////////
|
||||
|
||||
@ -133,8 +134,8 @@ typedef
|
||||
Addr addr;
|
||||
SSizeT sszB; /* -ve is write, +ve is read */
|
||||
Seg* vseg;
|
||||
Char descr1[96];
|
||||
Char descr2[96];
|
||||
XArray* descr1; /* XArray* of HChar */
|
||||
XArray* descr2; /* XArray* of HChar */
|
||||
Char datasym[96];
|
||||
PtrdiffT datasymoff;
|
||||
} Heap;
|
||||
@ -250,6 +251,47 @@ Bool pc_eq_Error ( VgRes res, Error* e1, Error* e2 )
|
||||
}
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////
|
||||
// //
|
||||
// Error management -- printing //
|
||||
// //
|
||||
//////////////////////////////////////////////////////////////
|
||||
|
||||
/* This is the "this error is due to be printed shortly; so have a
|
||||
look at it any print any preamble you want" function. Which, in
|
||||
Ptrcheck, we don't use. Hence a no-op.
|
||||
*/
|
||||
void pc_before_pp_Error ( Error* err ) {
|
||||
}
|
||||
|
||||
/* Do a printf-style operation on either the XML or normal output
|
||||
channel, depending on the setting of VG_(clo_xml).
|
||||
*/
|
||||
static void emit_WRK ( HChar* format, va_list vargs )
|
||||
{
|
||||
if (VG_(clo_xml)) {
|
||||
VG_(vprintf_xml)(format, vargs);
|
||||
} else {
|
||||
VG_(vmessage)(Vg_UserMsg, format, vargs);
|
||||
}
|
||||
}
|
||||
static void emit ( HChar* format, ... ) PRINTF_CHECK(1, 2);
|
||||
static void emit ( HChar* format, ... )
|
||||
{
|
||||
va_list vargs;
|
||||
va_start(vargs, format);
|
||||
emit_WRK(format, vargs);
|
||||
va_end(vargs);
|
||||
}
|
||||
static void emiN ( HChar* format, ... ) /* With NO FORMAT CHECK */
|
||||
{
|
||||
va_list vargs;
|
||||
va_start(vargs, format);
|
||||
emit_WRK(format, vargs);
|
||||
va_end(vargs);
|
||||
}
|
||||
|
||||
|
||||
static Char* readwrite(SSizeT sszB)
|
||||
{
|
||||
return ( sszB < 0 ? "write" : "read" );
|
||||
@ -261,6 +303,8 @@ static Word Word__abs ( Word w ) {
|
||||
|
||||
void pc_pp_Error ( Error* err )
|
||||
{
|
||||
const Bool xml = VG_(clo_xml); /* a shorthand, that's all */
|
||||
|
||||
XError *xe = (XError*)VG_(get_error_extra)(err);
|
||||
tl_assert(xe);
|
||||
|
||||
@ -268,15 +312,34 @@ void pc_pp_Error ( Error* err )
|
||||
|
||||
//----------------------------------------------------------
|
||||
case XE_SorG:
|
||||
tl_assert(xe);
|
||||
VG_(message)(Vg_UserMsg, "Invalid %s of size %ld",
|
||||
xe->XE.SorG.sszB < 0 ? "write" : "read",
|
||||
Word__abs(xe->XE.SorG.sszB) );
|
||||
VG_(pp_ExeContext)( VG_(get_error_where)(err) );
|
||||
VG_(message)(Vg_UserMsg, " Address %#lx expected vs actual:",
|
||||
xe->XE.SorG.addr);
|
||||
VG_(message)(Vg_UserMsg, " Expected: %s", &xe->XE.SorG.expect[0] );
|
||||
VG_(message)(Vg_UserMsg, " Actual: %s", &xe->XE.SorG.actual[0] );
|
||||
|
||||
if (xml) {
|
||||
|
||||
emit( " <kind>SorG</kind>\n");
|
||||
emit( " <what>Invalid %s of size %ld</what>\n",
|
||||
xe->XE.SorG.sszB < 0 ? "write" : "read",
|
||||
Word__abs(xe->XE.SorG.sszB) );
|
||||
VG_(pp_ExeContext)( VG_(get_error_where)(err) );
|
||||
|
||||
emit( " <auxwhat>Address %#lx expected vs actual:</auxwhat>\n",
|
||||
xe->XE.SorG.addr );
|
||||
emiN( " <auxwhat>Expected: %t</auxwhat>\n",
|
||||
&xe->XE.SorG.expect[0] );
|
||||
emiN( " <auxwhat>Actual: %t</auxwhat>\n",
|
||||
&xe->XE.SorG.actual[0] );
|
||||
|
||||
} else {
|
||||
|
||||
emit( "Invalid %s of size %ld\n",
|
||||
xe->XE.SorG.sszB < 0 ? "write" : "read",
|
||||
Word__abs(xe->XE.SorG.sszB) );
|
||||
VG_(pp_ExeContext)( VG_(get_error_where)(err) );
|
||||
|
||||
emit( " Address %#lx expected vs actual:\n", xe->XE.SorG.addr );
|
||||
emit( " Expected: %s\n", &xe->XE.SorG.expect[0] );
|
||||
emit( " Actual: %s\n", &xe->XE.SorG.actual[0] );
|
||||
|
||||
}
|
||||
break;
|
||||
|
||||
//----------------------------------------------------------
|
||||
@ -289,12 +352,29 @@ void pc_pp_Error ( Error* err )
|
||||
|
||||
if (NONPTR == vseg) {
|
||||
// Access via a non-pointer
|
||||
VG_(message)(Vg_UserMsg, "Invalid %s of size %ld",
|
||||
readwrite(xe->XE.Heap.sszB),
|
||||
Word__abs(xe->XE.Heap.sszB));
|
||||
VG_(pp_ExeContext)( VG_(get_error_where)(err) );
|
||||
VG_(message)(Vg_UserMsg,
|
||||
" Address %#lx is not derived from any known block", a);
|
||||
|
||||
if (xml) {
|
||||
|
||||
emit( " <kind>Heap</kind>\n");
|
||||
emit( " <what>Invalid %s of size %ld</what>\n",
|
||||
readwrite(xe->XE.Heap.sszB),
|
||||
Word__abs(xe->XE.Heap.sszB) );
|
||||
VG_(pp_ExeContext)( VG_(get_error_where)(err) );
|
||||
|
||||
emit( " <auxwhat>Address %#lx is not derived from "
|
||||
"any known block</auxwhat>\n", a );
|
||||
|
||||
} else {
|
||||
|
||||
emit( "Invalid %s of size %ld\n",
|
||||
readwrite(xe->XE.Heap.sszB),
|
||||
Word__abs(xe->XE.Heap.sszB) );
|
||||
VG_(pp_ExeContext)( VG_(get_error_where)(err) );
|
||||
|
||||
emit( " Address %#lx is not derived from "
|
||||
"any known block\n", a );
|
||||
|
||||
}
|
||||
|
||||
} else {
|
||||
// Access via a pointer, but outside its range.
|
||||
@ -308,30 +388,77 @@ void pc_pp_Error ( Error* err )
|
||||
? "Doubly-invalid" : "Invalid" );
|
||||
legit = ( Seg__is_freed(vseg) ? "once-" : "" );
|
||||
|
||||
VG_(message)(Vg_UserMsg, "%s %s of size %ld", how_invalid,
|
||||
readwrite(xe->XE.Heap.sszB),
|
||||
Word__abs(xe->XE.Heap.sszB));
|
||||
VG_(pp_ExeContext)( VG_(get_error_where)(err) );
|
||||
if (xml) {
|
||||
|
||||
emit( " <kind>Heap</kind>\n");
|
||||
emit( " <what>%s %s of size %ld</what>\n",
|
||||
how_invalid,
|
||||
readwrite(xe->XE.Heap.sszB),
|
||||
Word__abs(xe->XE.Heap.sszB) );
|
||||
VG_(pp_ExeContext)( VG_(get_error_where)(err) );
|
||||
|
||||
emit( " <auxwhat>Address %#lx is %lu bytes %s "
|
||||
"the accessing pointer's</auxwhat>\n",
|
||||
a, miss_size, place );
|
||||
emit( " <auxwhat>%slegitimate range, "
|
||||
"a block of size %lu %s</auxwhat>\n",
|
||||
legit, Seg__size(vseg),
|
||||
Seg__is_freed(vseg) ? "free'd" : "alloc'd" );
|
||||
VG_(pp_ExeContext)(Seg__where(vseg));
|
||||
|
||||
} else {
|
||||
|
||||
emit( "%s %s of size %ld\n",
|
||||
how_invalid,
|
||||
readwrite(xe->XE.Heap.sszB),
|
||||
Word__abs(xe->XE.Heap.sszB) );
|
||||
VG_(pp_ExeContext)( VG_(get_error_where)(err) );
|
||||
|
||||
emit( " Address %#lx is %lu bytes %s the accessing pointer's\n",
|
||||
a, miss_size, place );
|
||||
emit( " %slegitimate range, a block of size %lu %s\n",
|
||||
legit, Seg__size(vseg),
|
||||
Seg__is_freed(vseg) ? "free'd" : "alloc'd" );
|
||||
VG_(pp_ExeContext)(Seg__where(vseg));
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
/* If we have a better description of the address, show it.
|
||||
Note that in XML mode, it will already by nicely wrapped up
|
||||
in tags, either <auxwhat> or <xauxwhat>, so we can just emit
|
||||
it verbatim. */
|
||||
if (xml) {
|
||||
|
||||
if (xe->XE.Heap.descr1)
|
||||
emiN( " %t\n",
|
||||
(HChar*)VG_(indexXA)( xe->XE.Heap.descr1, 0 ) );
|
||||
if (xe->XE.Heap.descr2)
|
||||
emiN( " %t\n",
|
||||
(HChar*)VG_(indexXA)( xe->XE.Heap.descr2, 0 ) );
|
||||
if (xe->XE.Heap.datasym[0] != 0)
|
||||
emiN( " <auxwhat>Address 0x%llx is %llu bytes "
|
||||
"inside data symbol \"%t\"</auxwhat>\n",
|
||||
(ULong)xe->XE.Heap.addr,
|
||||
(ULong)xe->XE.Heap.datasymoff,
|
||||
xe->XE.Heap.datasym );
|
||||
|
||||
} else {
|
||||
|
||||
if (xe->XE.Heap.descr1)
|
||||
emit( " %s\n",
|
||||
(HChar*)VG_(indexXA)( xe->XE.Heap.descr1, 0 ) );
|
||||
if (xe->XE.Heap.descr2)
|
||||
emit( " %s\n",
|
||||
(HChar*)VG_(indexXA)( xe->XE.Heap.descr2, 0 ) );
|
||||
if (xe->XE.Heap.datasym[0] != 0)
|
||||
emit( " Address 0x%llx is %llu bytes "
|
||||
"inside data symbol \"%s\"\n",
|
||||
(ULong)xe->XE.Heap.addr,
|
||||
(ULong)xe->XE.Heap.datasymoff,
|
||||
xe->XE.Heap.datasym );
|
||||
|
||||
VG_(message)(Vg_UserMsg,
|
||||
" Address %#lx is %lu bytes %s the accessing pointer's",
|
||||
a, miss_size, place);
|
||||
VG_(message)(Vg_UserMsg,
|
||||
" %slegitimate range, a block of size %lu %s",
|
||||
legit, Seg__size(vseg),
|
||||
Seg__is_freed(vseg) ? "free'd" : "alloc'd" );
|
||||
VG_(pp_ExeContext)(Seg__where(vseg));
|
||||
}
|
||||
if (xe->XE.Heap.descr1[0] != 0)
|
||||
VG_(message)(Vg_UserMsg, " %s", xe->XE.Heap.descr1);
|
||||
if (xe->XE.Heap.descr2[0] != 0)
|
||||
VG_(message)(Vg_UserMsg, " %s", xe->XE.Heap.descr2);
|
||||
if (xe->XE.Heap.datasym[0] != 0)
|
||||
VG_(message)(Vg_UserMsg, " Address 0x%llx is %llu bytes "
|
||||
"inside data symbol \"%s\"",
|
||||
(ULong)xe->XE.Heap.addr,
|
||||
(ULong)xe->XE.Heap.datasymoff,
|
||||
xe->XE.Heap.datasym);
|
||||
break;
|
||||
}
|
||||
|
||||
@ -344,32 +471,69 @@ void pc_pp_Error ( Error* err )
|
||||
tl_assert(BOTTOM != seg1);
|
||||
tl_assert(BOTTOM != seg2 && UNKNOWN != seg2);
|
||||
|
||||
VG_(message)(Vg_UserMsg, "Invalid arguments to %s", xe->XE.Arith.opname);
|
||||
VG_(pp_ExeContext)( VG_(get_error_where)(err) );
|
||||
if (xml) {
|
||||
|
||||
if (seg1 != seg2) {
|
||||
if (NONPTR == seg1) {
|
||||
VG_(message)(Vg_UserMsg, " First arg not a pointer");
|
||||
} else if (UNKNOWN == seg1) {
|
||||
VG_(message)(Vg_UserMsg, " First arg may be a pointer");
|
||||
emit( " <kind>Arith</kind>\n");
|
||||
emit( " <what>Invalid arguments to %s</what>\n",
|
||||
xe->XE.Arith.opname );
|
||||
VG_(pp_ExeContext)( VG_(get_error_where)(err) );
|
||||
|
||||
if (seg1 != seg2) {
|
||||
if (NONPTR == seg1) {
|
||||
emit( " <auxwhat>First arg not a pointer</auxwhat>\n" );
|
||||
} else if (UNKNOWN == seg1) {
|
||||
emit( " <auxwhat>First arg may be a pointer</auxwhat>\n" );
|
||||
} else {
|
||||
emit( " <auxwhat>First arg derived from address %#lx of "
|
||||
"%lu-byte block alloc'd</auxwhat>\n",
|
||||
Seg__addr(seg1), Seg__size(seg1) );
|
||||
VG_(pp_ExeContext)(Seg__where(seg1));
|
||||
}
|
||||
which = "Second arg";
|
||||
} else {
|
||||
VG_(message)(Vg_UserMsg, " First arg derived from address %#lx of "
|
||||
"%lu-byte block alloc'd",
|
||||
Seg__addr(seg1), Seg__size(seg1) );
|
||||
VG_(pp_ExeContext)(Seg__where(seg1));
|
||||
which = "Both args";
|
||||
}
|
||||
which = "Second arg";
|
||||
if (NONPTR == seg2) {
|
||||
emit( " <auxwhat>%s not a pointer</auxwhat>\n", which );
|
||||
} else {
|
||||
emit( " <auxwhat>%s derived from address %#lx of "
|
||||
"%lu-byte block alloc'd</auxwhat>\n",
|
||||
which, Seg__addr(seg2), Seg__size(seg2) );
|
||||
VG_(pp_ExeContext)(Seg__where(seg2));
|
||||
}
|
||||
|
||||
} else {
|
||||
which = "Both args";
|
||||
}
|
||||
if (NONPTR == seg2) {
|
||||
VG_(message)(Vg_UserMsg, " %s not a pointer", which);
|
||||
} else {
|
||||
VG_(message)(Vg_UserMsg, " %s derived from address %#lx of "
|
||||
"%lu-byte block alloc'd",
|
||||
which, Seg__addr(seg2), Seg__size(seg2) );
|
||||
VG_(pp_ExeContext)(Seg__where(seg2));
|
||||
|
||||
emit( "Invalid arguments to %s\n",
|
||||
xe->XE.Arith.opname );
|
||||
VG_(pp_ExeContext)( VG_(get_error_where)(err) );
|
||||
|
||||
if (seg1 != seg2) {
|
||||
if (NONPTR == seg1) {
|
||||
emit( " First arg not a pointer\n" );
|
||||
} else if (UNKNOWN == seg1) {
|
||||
emit( " First arg may be a pointer\n" );
|
||||
} else {
|
||||
emit( " First arg derived from address %#lx of "
|
||||
"%lu-byte block alloc'd\n",
|
||||
Seg__addr(seg1), Seg__size(seg1) );
|
||||
VG_(pp_ExeContext)(Seg__where(seg1));
|
||||
}
|
||||
which = "Second arg";
|
||||
} else {
|
||||
which = "Both args";
|
||||
}
|
||||
if (NONPTR == seg2) {
|
||||
emit( " %s not a pointer\n", which );
|
||||
} else {
|
||||
emit( " %s derived from address %#lx of "
|
||||
"%lu-byte block alloc'd\n",
|
||||
which, Seg__addr(seg2), Seg__size(seg2) );
|
||||
VG_(pp_ExeContext)(Seg__where(seg2));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
@ -392,40 +556,88 @@ void pc_pp_Error ( Error* err )
|
||||
// freed block
|
||||
tl_assert(is_known_segment(seglo));
|
||||
tl_assert(Seg__is_freed(seglo)); // XXX what if it's now recycled?
|
||||
VG_(message)(Vg_UserMsg, "%s%s contains unaddressable byte(s)",
|
||||
what, s);
|
||||
VG_(pp_ExeContext)( VG_(get_error_where)(err) );
|
||||
|
||||
VG_(message)(Vg_UserMsg, " Address %#lx is %ld bytes inside a "
|
||||
"%ld-byte block free'd",
|
||||
lo, lo-Seg__addr(seglo),
|
||||
Seg__size(seglo) );
|
||||
VG_(pp_ExeContext)(Seg__where(seglo));
|
||||
if (xml) {
|
||||
|
||||
emit( " <kind>SysParam</kind>\n");
|
||||
emit( " <what>%s%s contains unaddressable byte(s)</what>\n",
|
||||
what, s );
|
||||
VG_(pp_ExeContext)( VG_(get_error_where)(err) );
|
||||
|
||||
emit( " <auxwhat>Address %#lx is %ld bytes inside a "
|
||||
"%ld-byte block free'd</auxwhat>\n",
|
||||
lo, lo-Seg__addr(seglo), Seg__size(seglo) );
|
||||
VG_(pp_ExeContext)(Seg__where(seglo));
|
||||
|
||||
} else {
|
||||
|
||||
emit( " %s%s contains unaddressable byte(s)\n",
|
||||
what, s );
|
||||
VG_(pp_ExeContext)( VG_(get_error_where)(err) );
|
||||
|
||||
emit( " Address %#lx is %ld bytes inside a "
|
||||
"%ld-byte block free'd\n",
|
||||
lo, lo-Seg__addr(seglo), Seg__size(seglo) );
|
||||
VG_(pp_ExeContext)(Seg__where(seglo));
|
||||
|
||||
}
|
||||
|
||||
} else {
|
||||
// mismatch
|
||||
VG_(message)(Vg_UserMsg, "%s%s is non-contiguous", what, s);
|
||||
VG_(pp_ExeContext)( VG_(get_error_where)(err) );
|
||||
|
||||
if (UNKNOWN == seglo) {
|
||||
VG_(message)(Vg_UserMsg, " First byte is not inside a known block");
|
||||
if (xml) {
|
||||
|
||||
emit( " <kind>SysParam</kind>\n");
|
||||
emit( " <what>%s%s is non-contiguous</what>\n",
|
||||
what, s );
|
||||
VG_(pp_ExeContext)( VG_(get_error_where)(err) );
|
||||
|
||||
if (UNKNOWN == seglo) {
|
||||
emit( " <auxwhat>First byte is "
|
||||
"not inside a known block</auxwhat>\n" );
|
||||
} else {
|
||||
emit( " <auxwhat>First byte (%#lx) is %ld bytes inside a "
|
||||
"%ld-byte block alloc'd</auxwhat>\n",
|
||||
lo, lo-Seg__addr(seglo), Seg__size(seglo) );
|
||||
VG_(pp_ExeContext)(Seg__where(seglo));
|
||||
}
|
||||
|
||||
if (UNKNOWN == seghi) {
|
||||
emit( " <auxwhat>Last byte is "
|
||||
"not inside a known block</auxwhat>\n" );
|
||||
} else {
|
||||
emit( " <auxwhat>Last byte (%#lx) is %ld bytes inside a "
|
||||
"%ld-byte block alloc'd</auxwhat>\n",
|
||||
hi, hi-Seg__addr(seghi), Seg__size(seghi) );
|
||||
VG_(pp_ExeContext)(Seg__where(seghi));
|
||||
}
|
||||
|
||||
} else {
|
||||
VG_(message)(Vg_UserMsg, " First byte (%#lx) is %ld bytes inside a "
|
||||
"%ld-byte block alloc'd",
|
||||
lo, lo-Seg__addr(seglo),
|
||||
Seg__size(seglo) );
|
||||
VG_(pp_ExeContext)(Seg__where(seglo));
|
||||
|
||||
emit( "%s%s is non-contiguous\n",
|
||||
what, s );
|
||||
VG_(pp_ExeContext)( VG_(get_error_where)(err) );
|
||||
|
||||
if (UNKNOWN == seglo) {
|
||||
emit( " First byte is not inside a known block\n" );
|
||||
} else {
|
||||
emit( " First byte (%#lx) is %ld bytes inside a "
|
||||
"%ld-byte block alloc'd\n",
|
||||
lo, lo-Seg__addr(seglo), Seg__size(seglo) );
|
||||
VG_(pp_ExeContext)(Seg__where(seglo));
|
||||
}
|
||||
|
||||
if (UNKNOWN == seghi) {
|
||||
emit( " Last byte is not inside a known block\n" );
|
||||
} else {
|
||||
emit( " Last byte (%#lx) is %ld bytes inside a "
|
||||
"%ld-byte block alloc'd\n",
|
||||
hi, hi-Seg__addr(seghi), Seg__size(seghi) );
|
||||
VG_(pp_ExeContext)(Seg__where(seghi));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if (UNKNOWN == seghi) {
|
||||
VG_(message)(Vg_UserMsg, " Last byte is not inside a known block");
|
||||
} else {
|
||||
VG_(message)(Vg_UserMsg, " Last byte (%#lx) is %ld bytes inside a "
|
||||
"%ld-byte block alloc'd",
|
||||
hi, hi-Seg__addr(seghi),
|
||||
Seg__size(seghi) );
|
||||
VG_(pp_ExeContext)(Seg__where(seghi));
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
@ -442,38 +654,71 @@ UInt pc_update_Error_extra ( Error* err )
|
||||
tl_assert(xe);
|
||||
switch (xe->tag) {
|
||||
case XE_SorG:
|
||||
return sizeof(XError);
|
||||
break;
|
||||
case XE_Heap: {
|
||||
tl_assert(sizeof(xe->XE.Heap.descr1) == sizeof(xe->XE.Heap.descr2));
|
||||
tl_assert(sizeof(xe->XE.Heap.descr1) > 0);
|
||||
Bool have_descr;
|
||||
|
||||
tl_assert(sizeof(xe->XE.Heap.datasym) > 0);
|
||||
VG_(memset)(&xe->XE.Heap.descr1, 0, sizeof(xe->XE.Heap.descr1));
|
||||
VG_(memset)(&xe->XE.Heap.descr2, 0, sizeof(xe->XE.Heap.descr2));
|
||||
xe->XE.Heap.datasymoff = 0;
|
||||
xe->XE.Heap.datasym[0] = 0;
|
||||
|
||||
tl_assert(!xe->XE.Heap.descr1);
|
||||
tl_assert(!xe->XE.Heap.descr2);
|
||||
|
||||
xe->XE.Heap.descr1
|
||||
= VG_(newXA)( VG_(malloc), "pc.update_extra.Heap.descr1",
|
||||
VG_(free), sizeof(HChar) );
|
||||
xe->XE.Heap.descr2
|
||||
= VG_(newXA)( VG_(malloc), "pc.update_extra.Heap.descr1",
|
||||
VG_(free), sizeof(HChar) );
|
||||
|
||||
VG_(memset)(&xe->XE.Heap.datasym, 0, sizeof(xe->XE.Heap.datasym));
|
||||
xe->XE.Heap.datasymoff = 0;
|
||||
if (VG_(get_data_description)( &xe->XE.Heap.descr1[0],
|
||||
&xe->XE.Heap.descr2[0],
|
||||
sizeof(xe->XE.Heap.descr1)-1,
|
||||
xe->XE.Heap.addr )) {
|
||||
tl_assert(xe->XE.Heap.descr1[sizeof(xe->XE.Heap.descr1)-1] == 0);
|
||||
tl_assert(xe->XE.Heap.descr1[sizeof(xe->XE.Heap.descr2)-1] == 0);
|
||||
|
||||
have_descr
|
||||
= VG_(get_data_description)( xe->XE.Heap.descr1,
|
||||
xe->XE.Heap.descr2,
|
||||
xe->XE.Heap.addr );
|
||||
|
||||
/* If there's nothing in descr1/2, free it. Why is it safe to
|
||||
to VG_(indexXA) at zero here? Because
|
||||
VG_(get_data_description) guarantees to zero terminate
|
||||
descr1/2 regardless of the outcome of the call. So there's
|
||||
always at least one element in each XA after the call.
|
||||
*/
|
||||
if (0 == VG_(strlen)( VG_(indexXA)( xe->XE.Heap.descr1, 0 ))
|
||||
|| !have_descr) {
|
||||
VG_(deleteXA)( xe->XE.Heap.descr1 );
|
||||
xe->XE.Heap.descr1 = NULL;
|
||||
}
|
||||
else
|
||||
if (VG_(get_datasym_and_offset)( xe->XE.Heap.addr,
|
||||
&xe->XE.Heap.datasym[0],
|
||||
sizeof(xe->XE.Heap.datasym)-1,
|
||||
&xe->XE.Heap.datasymoff )) {
|
||||
tl_assert(xe->XE.Heap.datasym[sizeof(xe->XE.Heap.datasym)-1] == 0);
|
||||
if (0 == VG_(strlen)( VG_(indexXA)( xe->XE.Heap.descr2, 0 ))
|
||||
|| !have_descr) {
|
||||
VG_(deleteXA)( xe->XE.Heap.descr2 );
|
||||
xe->XE.Heap.descr2 = NULL;
|
||||
}
|
||||
return sizeof(XError);
|
||||
|
||||
/* If Dwarf3 info produced nothing useful, see at least if
|
||||
we can fish something useful out of the ELF symbol info. */
|
||||
if (!have_descr) {
|
||||
if (VG_(get_datasym_and_offset)(
|
||||
xe->XE.Heap.addr, &xe->XE.Heap.datasym[0],
|
||||
sizeof(xe->XE.Heap.datasym)-1,
|
||||
&xe->XE.Heap.datasymoff )
|
||||
) {
|
||||
tl_assert(xe->XE.Heap.datasym[sizeof(xe->XE.Heap.datasym)-1]
|
||||
== 0);
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
case XE_Arith:
|
||||
return sizeof(XError);
|
||||
break;
|
||||
case XE_SysParam:
|
||||
return sizeof(XError);
|
||||
break;
|
||||
default:
|
||||
VG_(tool_panic)("update_extra");
|
||||
}
|
||||
return sizeof(XError);
|
||||
}
|
||||
|
||||
Bool pc_is_recognised_suppression ( Char* name, Supp *su )
|
||||
|
||||
@ -47,8 +47,9 @@ void h_record_arith_error( Seg* seg1, Seg* seg2, HChar* opname );
|
||||
void h_record_sysparam_error( ThreadId tid, CorePart part, Char* s,
|
||||
Addr lo, Addr hi, Seg* seglo, Seg* seghi );
|
||||
|
||||
Bool pc_eq_Error ( VgRes res, Error* e1, Error* e2 );
|
||||
void pc_pp_Error ( Error* err );
|
||||
Bool pc_eq_Error ( VgRes res, Error* e1, Error* e2 );
|
||||
void pc_before_pp_Error ( Error* err );
|
||||
void pc_pp_Error ( Error* err );
|
||||
UInt pc_update_Error_extra ( Error* err );
|
||||
Bool pc_is_recognised_suppression ( Char* name, Supp *su );
|
||||
Bool pc_read_extra_suppression_info ( Int fd, Char* buf,
|
||||
|
||||
@ -130,11 +130,14 @@ static void pc_post_clo_init ( void )
|
||||
# elif defined(VGA_ppc32) || defined(VGA_ppc64)
|
||||
if (VG_(clo_verbosity) >= 1 && sg_clo_enable_sg_checks) {
|
||||
VG_(message)(Vg_UserMsg,
|
||||
"WARNING: exp-ptrcheck on ppc32/ppc64 platforms: stack and global array");
|
||||
"WARNING: exp-ptrcheck on ppc32/ppc64 platforms: "
|
||||
"stack and global array\n");
|
||||
VG_(message)(Vg_UserMsg,
|
||||
"WARNING: checking is not currently supported. Only heap checking is");
|
||||
"WARNING: checking is not currently supported. "
|
||||
"Only heap checking is\n");
|
||||
VG_(message)(Vg_UserMsg,
|
||||
"WARNING: supported. Disabling s/g checks (like --enable-sg-checks=no).");
|
||||
"WARNING: supported. Disabling s/g checks "
|
||||
"(like --enable-sg-checks=no).\n");
|
||||
}
|
||||
sg_clo_enable_sg_checks = False;
|
||||
# else
|
||||
@ -179,6 +182,7 @@ static void pc_pre_clo_init(void)
|
||||
|
||||
VG_(needs_core_errors) ();
|
||||
VG_(needs_tool_errors) (pc_eq_Error,
|
||||
pc_before_pp_Error,
|
||||
pc_pp_Error,
|
||||
True,/*show TIDs for errors*/
|
||||
pc_update_Error_extra,
|
||||
@ -188,6 +192,8 @@ static void pc_pre_clo_init(void)
|
||||
pc_get_error_name,
|
||||
pc_print_extra_suppression_info);
|
||||
|
||||
VG_(needs_xml_output) ();
|
||||
|
||||
VG_(needs_syscall_wrapper)( h_pre_syscall,
|
||||
h_post_syscall );
|
||||
|
||||
|
||||
@ -223,16 +223,16 @@ static Word StackBlocks__cmp ( XArray* fb1s, XArray* fb2s )
|
||||
static void pp_StackBlocks ( XArray* sbs )
|
||||
{
|
||||
Word i, n = VG_(sizeXA)( sbs );
|
||||
VG_(message)(Vg_DebugMsg, "<<< STACKBLOCKS" );
|
||||
VG_(message)(Vg_DebugMsg, "<<< STACKBLOCKS\n" );
|
||||
for (i = 0; i < n; i++) {
|
||||
StackBlock* sb = (StackBlock*)VG_(indexXA)( sbs, i );
|
||||
VG_(message)(Vg_DebugMsg,
|
||||
" StackBlock{ off %ld szB %lu spRel:%c isVec:%c \"%s\" }",
|
||||
" StackBlock{ off %ld szB %lu spRel:%c isVec:%c \"%s\" }\n",
|
||||
sb->base, sb->szB, sb->spRel ? 'Y' : 'N',
|
||||
sb->isVec ? 'Y' : 'N', &sb->name[0]
|
||||
);
|
||||
}
|
||||
VG_(message)(Vg_DebugMsg, ">>> STACKBLOCKS" );
|
||||
VG_(message)(Vg_DebugMsg, ">>> STACKBLOCKS\n" );
|
||||
}
|
||||
|
||||
|
||||
@ -345,12 +345,12 @@ static XArray* /* of StackBlock */
|
||||
if (moans > 0 && !VG_(clo_xml)) {
|
||||
moans--;
|
||||
VG_(message)(Vg_UserMsg, "Warning: bogus DWARF3 info: "
|
||||
"overlapping stack blocks");
|
||||
"overlapping stack blocks\n");
|
||||
if (VG_(clo_verbosity) >= 2)
|
||||
pp_StackBlocks(orig);
|
||||
if (moans == 0)
|
||||
VG_(message)(Vg_UserMsg, "Further instances of this "
|
||||
"message will not be shown" );
|
||||
"message will not be shown\n" );
|
||||
}
|
||||
VG_(dropTailXA)( orig, VG_(sizeXA)( orig ));
|
||||
break;
|
||||
@ -740,7 +740,7 @@ static void add_block_to_GlobalTree (
|
||||
if (already_present && moans > 0 && !VG_(clo_xml)) {
|
||||
moans--;
|
||||
VG_(message)(Vg_UserMsg, "Warning: bogus DWARF3 info: "
|
||||
"overlapping global blocks");
|
||||
"overlapping global blocks\n");
|
||||
if (VG_(clo_verbosity) >= 2) {
|
||||
GlobalTree__pp( gitree,
|
||||
"add_block_to_GlobalTree: non-exact duplicate" );
|
||||
@ -750,7 +750,7 @@ static void add_block_to_GlobalTree (
|
||||
}
|
||||
if (moans == 0)
|
||||
VG_(message)(Vg_UserMsg, "Further instances of this "
|
||||
"message will not be shown" );
|
||||
"message will not be shown\n" );
|
||||
}
|
||||
/* tl_assert(!already_present); */
|
||||
}
|
||||
@ -1830,7 +1830,7 @@ void shadowStack_new_frame ( ThreadId tid,
|
||||
if (0 && (sb || gb))
|
||||
VG_(message)(Vg_DebugMsg,
|
||||
"exp-sgcheck: new max tree sizes: "
|
||||
"StackTree %ld, GlobalTree %ld",
|
||||
"StackTree %ld, GlobalTree %ld\n",
|
||||
stats__max_sitree_size, stats__max_gitree_size );
|
||||
}
|
||||
} else {
|
||||
@ -2454,32 +2454,32 @@ void sg_fini(Int exitcode)
|
||||
{
|
||||
if (VG_(clo_verbosity) >= 2) {
|
||||
VG_(message)(Vg_DebugMsg,
|
||||
" sg_: %'llu total accesses, of which:", stats__total_accesses);
|
||||
" sg_: %'llu total accesses, of which:\n", stats__total_accesses);
|
||||
VG_(message)(Vg_DebugMsg,
|
||||
" sg_: stack0: %'12llu classify",
|
||||
" sg_: stack0: %'12llu classify\n",
|
||||
stats__classify_Stack0);
|
||||
VG_(message)(Vg_DebugMsg,
|
||||
" sg_: stackN: %'12llu classify",
|
||||
" sg_: stackN: %'12llu classify\n",
|
||||
stats__classify_StackN);
|
||||
VG_(message)(Vg_DebugMsg,
|
||||
" sg_: global: %'12llu classify",
|
||||
" sg_: global: %'12llu classify\n",
|
||||
stats__classify_Global);
|
||||
VG_(message)(Vg_DebugMsg,
|
||||
" sg_: unknown: %'12llu classify",
|
||||
" sg_: unknown: %'12llu classify\n",
|
||||
stats__classify_Unknown);
|
||||
VG_(message)(Vg_DebugMsg,
|
||||
" sg_: %'llu Invars preened, of which %'llu changed",
|
||||
" sg_: %'llu Invars preened, of which %'llu changed\n",
|
||||
stats__Invars_preened, stats__Invars_changed);
|
||||
VG_(message)(Vg_DebugMsg,
|
||||
" sg_: t_i_b_MT: %'12llu", stats__t_i_b_empty);
|
||||
" sg_: t_i_b_MT: %'12llu\n", stats__t_i_b_empty);
|
||||
VG_(message)(Vg_DebugMsg,
|
||||
" sg_: qcache: %'llu searches, %'llu probes, %'llu misses",
|
||||
" sg_: qcache: %'llu searches, %'llu probes, %'llu misses\n",
|
||||
stats__qcache_queries, stats__qcache_probes, stats__qcache_misses);
|
||||
VG_(message)(Vg_DebugMsg,
|
||||
" sg_: htab-fast: %'llu hits",
|
||||
" sg_: htab-fast: %'llu hits\n",
|
||||
stats__htab_fast);
|
||||
VG_(message)(Vg_DebugMsg,
|
||||
" sg_: htab-slow: %'llu searches, %'llu probes, %'llu resizes",
|
||||
" sg_: htab-slow: %'llu searches, %'llu probes, %'llu resizes\n",
|
||||
stats__htab_searches, stats__htab_probes, stats__htab_resizes);
|
||||
}
|
||||
}
|
||||
|
||||
@ -23,6 +23,7 @@ EXTRA_DIST = \
|
||||
hackedbz2.stderr.exp-glibc28-amd64 \
|
||||
hp_bounds.vgtest hp_bounds.stderr.exp \
|
||||
hp_dangle.vgtest hp_dangle.stderr.exp \
|
||||
hsg.vgtest hsg.stdout.exp hsg.stderr.exp \
|
||||
idiv.vgtest-disabled idiv.stderr.exp \
|
||||
imul.vgtest-disabled imul.stderr.exp \
|
||||
justify.vgtest justify.stderr.exp \
|
||||
@ -61,7 +62,7 @@ EXTRA_DIST = \
|
||||
check_PROGRAMS = \
|
||||
add and arith bad_percentify base cmp fp \
|
||||
globalerr hackedbz2 \
|
||||
hp_bounds hp_dangle idiv imul \
|
||||
hp_bounds hp_dangle hsg idiv imul \
|
||||
justify mm not neg or partial \
|
||||
preen_invars preen_invars_so.so \
|
||||
pth_create pth_specific realloc \
|
||||
|
||||
48
exp-ptrcheck/tests/hsg.c
Normal file
48
exp-ptrcheck/tests/hsg.c
Normal file
@ -0,0 +1,48 @@
|
||||
|
||||
/* A simple test to demonstrate heap, stack, and global overrun
|
||||
detection. */
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
short ga[100];
|
||||
|
||||
__attribute__((noinline))
|
||||
int addup_wrongly ( short* arr )
|
||||
{
|
||||
int sum = 0, i;
|
||||
for (i = 0; i <= 100; i++)
|
||||
sum += (int)arr[i];
|
||||
return sum;
|
||||
}
|
||||
|
||||
__attribute__((noinline))
|
||||
int do_other_stuff ( void )
|
||||
{
|
||||
short la[100];
|
||||
return 123 + addup_wrongly(la);
|
||||
}
|
||||
|
||||
__attribute__((noinline))
|
||||
int do_stupid_malloc_stuff ( void )
|
||||
{
|
||||
int sum = 0;
|
||||
unsigned char* duh = malloc(100 * sizeof(char));
|
||||
sum += duh[-1];
|
||||
free(duh);
|
||||
sum += duh[50];
|
||||
return sum;
|
||||
}
|
||||
|
||||
int main ( void )
|
||||
{
|
||||
long s = addup_wrongly(ga);
|
||||
s += do_other_stuff();
|
||||
s += do_stupid_malloc_stuff();
|
||||
if (s == 123456789) {
|
||||
fprintf(stdout, "well, i never!\n");
|
||||
} else {
|
||||
fprintf(stdout, "boringly as expected\n");
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
231
exp-ptrcheck/tests/hsg.stderr.exp
Normal file
231
exp-ptrcheck/tests/hsg.stderr.exp
Normal file
@ -0,0 +1,231 @@
|
||||
<?xml version="1.0"?>
|
||||
|
||||
<valgrindoutput>
|
||||
|
||||
<protocolversion>4</protocolversion>
|
||||
<protocoltool>exp-ptrcheck</protocoltool>
|
||||
|
||||
<preamble>
|
||||
<line>...</line>
|
||||
<line>...</line>
|
||||
<line>...</line>
|
||||
<line>...</line>
|
||||
<line>...</line>
|
||||
<line>...</line>
|
||||
<line>...</line>
|
||||
</preamble>
|
||||
|
||||
<pid>...</pid>
|
||||
<ppid>...</ppid>
|
||||
<tool>exp-ptrcheck</tool>
|
||||
|
||||
<args>
|
||||
<vargv>...</vargv>
|
||||
<argv>
|
||||
<exe>./hsg</exe>
|
||||
</argv>
|
||||
</args>
|
||||
|
||||
<status>
|
||||
<state>RUNNING</state>
|
||||
<time>...</time>
|
||||
</status>
|
||||
|
||||
<error>
|
||||
<unique>0x........</unique>
|
||||
<tid>...</tid>
|
||||
<kind>SorG</kind>
|
||||
<what>Invalid read of size 2</what>
|
||||
<stack>
|
||||
<frame>
|
||||
<ip>0x........</ip>
|
||||
<obj>...</obj>
|
||||
<fn>addup_wrongly</fn>
|
||||
<dir>...</dir>
|
||||
<file>hsg.c</file>
|
||||
<line>...</line>
|
||||
</frame>
|
||||
<frame>
|
||||
<ip>0x........</ip>
|
||||
<obj>...</obj>
|
||||
<fn>main</fn>
|
||||
<dir>...</dir>
|
||||
<file>hsg.c</file>
|
||||
<line>...</line>
|
||||
</frame>
|
||||
</stack>
|
||||
<auxwhat>Address 0x........ expected vs actual:</auxwhat>
|
||||
<auxwhat>Expected: global array "ga" in object with soname "NONE"</auxwhat>
|
||||
<auxwhat>Actual: unknown</auxwhat>
|
||||
</error>
|
||||
|
||||
<error>
|
||||
<unique>0x........</unique>
|
||||
<tid>...</tid>
|
||||
<kind>SorG</kind>
|
||||
<what>Invalid read of size 2</what>
|
||||
<stack>
|
||||
<frame>
|
||||
<ip>0x........</ip>
|
||||
<obj>...</obj>
|
||||
<fn>addup_wrongly</fn>
|
||||
<dir>...</dir>
|
||||
<file>hsg.c</file>
|
||||
<line>...</line>
|
||||
</frame>
|
||||
<frame>
|
||||
<ip>0x........</ip>
|
||||
<obj>...</obj>
|
||||
<fn>do_other_stuff</fn>
|
||||
<dir>...</dir>
|
||||
<file>hsg.c</file>
|
||||
<line>...</line>
|
||||
</frame>
|
||||
<frame>
|
||||
<ip>0x........</ip>
|
||||
<obj>...</obj>
|
||||
<fn>main</fn>
|
||||
<dir>...</dir>
|
||||
<file>hsg.c</file>
|
||||
<line>...</line>
|
||||
</frame>
|
||||
</stack>
|
||||
<auxwhat>Address 0x........ expected vs actual:</auxwhat>
|
||||
<auxwhat>Expected: stack array "la" in frame 1 back from here</auxwhat>
|
||||
<auxwhat>Actual: unknown</auxwhat>
|
||||
</error>
|
||||
|
||||
<error>
|
||||
<unique>0x........</unique>
|
||||
<tid>...</tid>
|
||||
<kind>Heap</kind>
|
||||
<what>Invalid read of size 1</what>
|
||||
<stack>
|
||||
<frame>
|
||||
<ip>0x........</ip>
|
||||
<obj>...</obj>
|
||||
<fn>do_stupid_malloc_stuff</fn>
|
||||
<dir>...</dir>
|
||||
<file>hsg.c</file>
|
||||
<line>...</line>
|
||||
</frame>
|
||||
<frame>
|
||||
<ip>0x........</ip>
|
||||
<obj>...</obj>
|
||||
<fn>main</fn>
|
||||
<dir>...</dir>
|
||||
<file>hsg.c</file>
|
||||
<line>...</line>
|
||||
</frame>
|
||||
</stack>
|
||||
<auxwhat>Address 0x........ is 1 bytes before the accessing pointer's</auxwhat>
|
||||
<auxwhat>legitimate range, a block of size 100 alloc'd</auxwhat>
|
||||
<stack>
|
||||
<frame>
|
||||
<ip>0x........</ip>
|
||||
<obj>...</obj>
|
||||
<fn>malloc</fn>
|
||||
<dir>...</dir>
|
||||
<file>vg_replace_malloc.c</file>
|
||||
<line>...</line>
|
||||
</frame>
|
||||
<frame>
|
||||
<ip>0x........</ip>
|
||||
<obj>...</obj>
|
||||
<fn>do_stupid_malloc_stuff</fn>
|
||||
<dir>...</dir>
|
||||
<file>hsg.c</file>
|
||||
<line>...</line>
|
||||
</frame>
|
||||
<frame>
|
||||
<ip>0x........</ip>
|
||||
<obj>...</obj>
|
||||
<fn>main</fn>
|
||||
<dir>...</dir>
|
||||
<file>hsg.c</file>
|
||||
<line>...</line>
|
||||
</frame>
|
||||
</stack>
|
||||
</error>
|
||||
|
||||
<error>
|
||||
<unique>0x........</unique>
|
||||
<tid>...</tid>
|
||||
<kind>Heap</kind>
|
||||
<what>Invalid read of size 1</what>
|
||||
<stack>
|
||||
<frame>
|
||||
<ip>0x........</ip>
|
||||
<obj>...</obj>
|
||||
<fn>do_stupid_malloc_stuff</fn>
|
||||
<dir>...</dir>
|
||||
<file>hsg.c</file>
|
||||
<line>...</line>
|
||||
</frame>
|
||||
<frame>
|
||||
<ip>0x........</ip>
|
||||
<obj>...</obj>
|
||||
<fn>main</fn>
|
||||
<dir>...</dir>
|
||||
<file>hsg.c</file>
|
||||
<line>...</line>
|
||||
</frame>
|
||||
</stack>
|
||||
<auxwhat>Address 0x........ is 50 bytes inside the accessing pointer's</auxwhat>
|
||||
<auxwhat>once-legitimate range, a block of size 100 free'd</auxwhat>
|
||||
<stack>
|
||||
<frame>
|
||||
<ip>0x........</ip>
|
||||
<obj>...</obj>
|
||||
<fn>free</fn>
|
||||
<dir>...</dir>
|
||||
<file>vg_replace_malloc.c</file>
|
||||
<line>...</line>
|
||||
</frame>
|
||||
<frame>
|
||||
<ip>0x........</ip>
|
||||
<obj>...</obj>
|
||||
<fn>do_stupid_malloc_stuff</fn>
|
||||
<dir>...</dir>
|
||||
<file>hsg.c</file>
|
||||
<line>...</line>
|
||||
</frame>
|
||||
<frame>
|
||||
<ip>0x........</ip>
|
||||
<obj>...</obj>
|
||||
<fn>main</fn>
|
||||
<dir>...</dir>
|
||||
<file>hsg.c</file>
|
||||
<line>...</line>
|
||||
</frame>
|
||||
</stack>
|
||||
</error>
|
||||
|
||||
<status>
|
||||
<state>FINISHED</state>
|
||||
<time>...</time>
|
||||
</status>
|
||||
|
||||
<errorcounts>
|
||||
<pair>
|
||||
<count>...</count>
|
||||
<unique>0x........</unique>
|
||||
</pair>
|
||||
<pair>
|
||||
<count>...</count>
|
||||
<unique>0x........</unique>
|
||||
</pair>
|
||||
<pair>
|
||||
<count>...</count>
|
||||
<unique>0x........</unique>
|
||||
</pair>
|
||||
<pair>
|
||||
<count>...</count>
|
||||
<unique>0x........</unique>
|
||||
</pair>
|
||||
</errorcounts>
|
||||
|
||||
<suppcounts>...</suppcounts>
|
||||
|
||||
</valgrindoutput>
|
||||
|
||||
1
exp-ptrcheck/tests/hsg.stdout.exp
Normal file
1
exp-ptrcheck/tests/hsg.stdout.exp
Normal file
@ -0,0 +1 @@
|
||||
boringly as expected
|
||||
3
exp-ptrcheck/tests/hsg.vgtest
Normal file
3
exp-ptrcheck/tests/hsg.vgtest
Normal file
@ -0,0 +1,3 @@
|
||||
prog: hsg
|
||||
vgopts: --xml=yes --xml-fd=2 --log-file=/dev/null
|
||||
stderr_filter: ../../memcheck/tests/filter_xml
|
||||
@ -8,12 +8,12 @@
|
||||
|
||||
int main(void)
|
||||
{
|
||||
int i = 11;
|
||||
int i = 11; int fd = open("/dev/null", O_WRONLY);
|
||||
char* buf = malloc(sizeof(char) * 6);
|
||||
char c = buf[-1]; // LoadStoreErr
|
||||
char* x = buf + (long)buf; // ArithErr
|
||||
char* y = (char*)((long)buf * i); // AsmErr
|
||||
write(-1, buf+3, 5); // SysParamErr
|
||||
|
||||
write(fd, buf+3, 5); // SysParamErr
|
||||
close(fd);
|
||||
return x-y+c;
|
||||
}
|
||||
|
||||
@ -1,4 +1,10 @@
|
||||
|
||||
Warning: invalid file descriptor -1 in syscall write()
|
||||
Syscall param write(buf) is non-contiguous
|
||||
at 0x........: write (in /...libc...)
|
||||
by 0x........: main (supp.c:16)
|
||||
First byte (0x........) is 3 bytes inside a 6-byte block alloc'd
|
||||
at 0x........: malloc (vg_replace_malloc.c:...)
|
||||
by 0x........: main (supp.c:12)
|
||||
Last byte is not inside a known block
|
||||
|
||||
ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)
|
||||
ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 0 from 0)
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user