MAC_(pp_AddrInfo)(VG_(get_error_address)(err), &err_extra->addrinfo);
break;
- case OverlapErr:
- VG_(message)(Vg_UserMsg,
- "Source and destination overlap in %s",
- VG_(get_error_string)(err));
+ case OverlapErr: {
+ OverlapExtra* ov_extra = (OverlapExtra*)VG_(get_error_extra)(err);
+ if (ov_extra->len == -1)
+ VG_(message)(Vg_UserMsg,
+ "Source and destination overlap in %s(%p, %p)",
+ VG_(get_error_string)(err),
+ ov_extra->dst, ov_extra->src);
+ else
+ VG_(message)(Vg_UserMsg,
+ "Source and destination overlap in %s(%p, %p, %d)",
+ VG_(get_error_string)(err),
+ ov_extra->dst, ov_extra->src, ov_extra->len);
VG_(pp_ExeContext)( VG_(get_error_where)(err) );
break;
-
+ }
case LeakErr: {
/* Totally abusing the types of these spare fields... oh well. */
UInt n_this_record = (UInt)VG_(get_error_address)(err);
// This one not passed a ThreadId, so it grabs it itself.
-void MAC_(record_overlap_error) ( Char* function )
+void MAC_(record_overlap_error) ( Char* function, OverlapExtra* ov_extra )
{
- static Int n_strdups = 0;
- MAC_Error err_extra;
-
- /* Potential space leak; this strdup'd space is never
- reclaimed. Hence hacky sanity check. */
- if (n_strdups < 1000) {
- n_strdups++;
- function = VG_(strdup) ( function );
- } else {
- function = NULL;
- }
-
- MAC_(clear_MAC_Error)( &err_extra );
VG_(maybe_record_error)( VG_(get_current_or_recent_tid)(),
- OverlapErr, /*addr*/0, /*s*/function, &err_extra );
+ OverlapErr, /*addr*/0, /*s*/function, ov_extra );
}
-/* Updates the copy with address info if necessary (but not for LeakErrs). */
+/* Updates the copy with address info if necessary (but not for all errors). */
UInt SK_(update_extra)( Error* err )
{
- MAC_Error* extra;
-
+ switch (VG_(get_error_kind)(err)) {
+ case ValueErr:
+ case CoreMemErr:
+ case AddrErr:
+ case ParamErr:
+ case UserErr:
+ case FreeErr:
+ case FreeMismatchErr: {
+ MAC_Error* extra = (MAC_Error*)VG_(get_error_extra)(err);
+ if (extra != NULL && Undescribed == extra->addrinfo.akind) {
+ describe_addr ( VG_(get_error_address)(err), &(extra->addrinfo) );
+ }
+ return sizeof(MAC_Error);
+ }
/* Don't need to return the correct size -- LeakErrs are always shown with
VG_(unique_error)() so they're not copied anyway. */
- if (LeakErr == VG_(get_error_kind)(err))
- return 0;
-
- extra = (MAC_Error*)VG_(get_error_extra)(err);
-
- if (extra != NULL && Undescribed == extra->addrinfo.akind) {
- describe_addr ( VG_(get_error_address)(err), &(extra->addrinfo) );
+ case LeakErr: return 0;
+ case OverlapErr: return sizeof(OverlapExtra);
+ default: VG_(skin_panic)("update_extra: bad errkind");
}
-
- return sizeof(MAC_Error);
}
#define __VALGRIND_SOMESKIN_H
#include "valgrind.h"
-/* For snprintf(), ok because on simd CPU */
-#include <stdio.h>
-
/* ---------------------------------------------------------------------
The normal versions of these functions are hyper-optimised, which fools
Memcheck and cause spurious value warnings. So we replace them with
static __inline__
void complain2 ( Char* s, char* dst, const char* src )
{
- Char buf[256];
- snprintf(buf, 100, "%s(%p, %p)", s, dst, src );
- VALGRIND_NON_SIMD_CALL1( MAC_(record_overlap_error), buf );
+ OverlapExtra extra = {
+ .src = (Addr)src, .dst = (Addr)dst, .len = -1,
+ };
+ VALGRIND_NON_SIMD_CALL2( MAC_(record_overlap_error), s, &extra );
}
static __inline__
void complain3 ( Char* s, void* dst, const void* src, int n )
{
- Char buf[256];
- snprintf(buf, 100, "%s(%p, %p, %d)", s, dst, src, n );
- VALGRIND_NON_SIMD_CALL1( MAC_(record_overlap_error), buf );
+ /* Must wrap it up here, because we cannot pass 4 args to core */
+ OverlapExtra extra = {
+ .src = (Addr)src, .dst = (Addr)dst, .len = n,
+ };
+ VALGRIND_NON_SIMD_CALL2( MAC_(record_overlap_error), s, &extra );
}
char* strrchr ( const char* s, int c )
}
MAC_Error;
+/* Extra info for overlap errors */
+typedef
+ struct {
+ Addr src;
+ Addr dst;
+ Int len; // -1 if unused
+ }
+ OverlapExtra;
+
/* For malloc()/new/new[] vs. free()/delete/delete[] mismatch checking. */
typedef
enum {
extern void MAC_(record_jump_error) ( ThreadId tid, Addr a );
extern void MAC_(record_free_error) ( ThreadId tid, Addr a );
extern void MAC_(record_freemismatch_error)( ThreadId tid, Addr a );
-extern void MAC_(record_overlap_error) ( Char* function );
+extern void MAC_(record_overlap_error) ( Char* function, OverlapExtra* oe );
extern void MAC_(pp_shared_SkinError) ( Error* err);