mirror of
https://github.com/Zenithsiz/ftmemsim-valgrind.git
synced 2026-02-03 10:05:29 +00:00
Merge r9299..r9303 (various leak-check test fixes) from the DARWIN branch.
git-svn-id: svn://svn.valgrind.org/valgrind/trunk@9304
This commit is contained in:
parent
64b679b95b
commit
e97076e0f3
5
NEWS
5
NEWS
@ -1,6 +1,11 @@
|
||||
|
||||
Release 3.5.0 (???)
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
* A new Memcheck client request VALGRIND_COUNT_LEAK_BLOCKS has been added.
|
||||
It is similar to VALGRIND_COUNT_LEAKS but counts blocks instead of bytes.
|
||||
[XXX: consider adding VALGRIND_COUNT_LEAK_BYTES as a synonym and
|
||||
deprecating VALGRIND_COUNT_LEAKS, which wasn't a good name to begin with]
|
||||
|
||||
* The location of some install files has changed. This should not affect
|
||||
most users. Those who might be affected:
|
||||
|
||||
|
||||
@ -1177,6 +1177,13 @@ arguments.</para>
|
||||
<varname>VALGRIND_DO_LEAK_CHECK</varname>.</para>
|
||||
</listitem>
|
||||
|
||||
<listitem>
|
||||
<para><varname>VALGRIND_COUNT_LEAK_BLOCKS</varname>: identical to
|
||||
<varname>VALGRIND_COUNT_LEAKS</varname> except that it returns the
|
||||
number of blocks rather than the number of bytes in each
|
||||
category.</para>
|
||||
</listitem>
|
||||
|
||||
<listitem>
|
||||
<para><varname>VALGRIND_GET_VBITS</varname> and
|
||||
<varname>VALGRIND_SET_VBITS</varname>: allow you to get and set the
|
||||
|
||||
@ -249,6 +249,13 @@ extern SizeT MC_(bytes_dubious);
|
||||
extern SizeT MC_(bytes_reachable);
|
||||
extern SizeT MC_(bytes_suppressed);
|
||||
|
||||
/* For VALGRIND_COUNT_LEAK_BLOCKS client request */
|
||||
extern SizeT MC_(blocks_leaked);
|
||||
extern SizeT MC_(blocks_indirect);
|
||||
extern SizeT MC_(blocks_dubious);
|
||||
extern SizeT MC_(blocks_reachable);
|
||||
extern SizeT MC_(blocks_suppressed);
|
||||
|
||||
typedef
|
||||
enum {
|
||||
LC_Off,
|
||||
|
||||
@ -211,6 +211,12 @@ SizeT MC_(bytes_dubious) = 0;
|
||||
SizeT MC_(bytes_reachable) = 0;
|
||||
SizeT MC_(bytes_suppressed) = 0;
|
||||
|
||||
SizeT MC_(blocks_leaked) = 0;
|
||||
SizeT MC_(blocks_indirect) = 0;
|
||||
SizeT MC_(blocks_dubious) = 0;
|
||||
SizeT MC_(blocks_reachable) = 0;
|
||||
SizeT MC_(blocks_suppressed) = 0;
|
||||
|
||||
static Int lc_compar(void* n1, void* n2)
|
||||
{
|
||||
MC_Chunk* mc1 = *(MC_Chunk**)n1;
|
||||
@ -399,12 +405,6 @@ static void lc_do_leakcheck(Int clique)
|
||||
}
|
||||
}
|
||||
|
||||
static SizeT blocks_leaked;
|
||||
static SizeT blocks_indirect;
|
||||
static SizeT blocks_dubious;
|
||||
static SizeT blocks_reachable;
|
||||
static SizeT blocks_suppressed;
|
||||
|
||||
static void full_report(ThreadId tid)
|
||||
{
|
||||
Int i;
|
||||
@ -515,24 +515,24 @@ static void full_report(ThreadId tid)
|
||||
print_record );
|
||||
|
||||
if (is_suppressed) {
|
||||
blocks_suppressed += p_min->num_blocks;
|
||||
MC_(bytes_suppressed) += p_min->total_bytes;
|
||||
MC_(blocks_suppressed) += p_min->num_blocks;
|
||||
MC_(bytes_suppressed) += p_min->total_bytes;
|
||||
|
||||
} else if (Unreached == p_min->loss_mode) {
|
||||
blocks_leaked += p_min->num_blocks;
|
||||
MC_(bytes_leaked) += p_min->total_bytes;
|
||||
MC_(blocks_leaked) += p_min->num_blocks;
|
||||
MC_(bytes_leaked) += p_min->total_bytes;
|
||||
|
||||
} else if (IndirectLeak == p_min->loss_mode) {
|
||||
blocks_indirect += p_min->num_blocks;
|
||||
MC_(bytes_indirect) += p_min->total_bytes;
|
||||
MC_(blocks_indirect) += p_min->num_blocks;
|
||||
MC_(bytes_indirect) += p_min->total_bytes;
|
||||
|
||||
} else if (Interior == p_min->loss_mode) {
|
||||
blocks_dubious += p_min->num_blocks;
|
||||
MC_(bytes_dubious) += p_min->total_bytes;
|
||||
} else if (Interior == p_min->loss_mode) {
|
||||
MC_(blocks_dubious) += p_min->num_blocks;
|
||||
MC_(bytes_dubious) += p_min->total_bytes;
|
||||
|
||||
} else if (Proper == p_min->loss_mode) {
|
||||
blocks_reachable += p_min->num_blocks;
|
||||
MC_(bytes_reachable) += p_min->total_bytes;
|
||||
} else if (Proper == p_min->loss_mode) {
|
||||
MC_(blocks_reachable) += p_min->num_blocks;
|
||||
MC_(bytes_reachable) += p_min->total_bytes;
|
||||
|
||||
} else {
|
||||
VG_(tool_panic)("generic_detect_memory_leaks: unknown loss mode");
|
||||
@ -551,22 +551,22 @@ static void make_summary(void)
|
||||
|
||||
switch(lc_markstack[i].state) {
|
||||
case Unreached:
|
||||
blocks_leaked++;
|
||||
MC_(blocks_leaked)++;
|
||||
MC_(bytes_leaked) += size;
|
||||
break;
|
||||
|
||||
case Proper:
|
||||
blocks_reachable++;
|
||||
MC_(blocks_reachable)++;
|
||||
MC_(bytes_reachable) += size;
|
||||
break;
|
||||
|
||||
case Interior:
|
||||
blocks_dubious++;
|
||||
MC_(blocks_dubious)++;
|
||||
MC_(bytes_dubious) += size;
|
||||
break;
|
||||
|
||||
case IndirectLeak: /* shouldn't happen */
|
||||
blocks_indirect++;
|
||||
MC_(blocks_indirect)++;
|
||||
MC_(bytes_indirect) += size;
|
||||
break;
|
||||
}
|
||||
@ -812,11 +812,11 @@ void MC_(do_detect_memory_leaks) (
|
||||
if (VG_(clo_verbosity) > 0 && !VG_(clo_xml))
|
||||
VG_(message)(Vg_UserMsg, "checked %'lu bytes.", lc_scanned);
|
||||
|
||||
blocks_leaked = MC_(bytes_leaked) = 0;
|
||||
blocks_indirect = MC_(bytes_indirect) = 0;
|
||||
blocks_dubious = MC_(bytes_dubious) = 0;
|
||||
blocks_reachable = MC_(bytes_reachable) = 0;
|
||||
blocks_suppressed = MC_(bytes_suppressed) = 0;
|
||||
MC_(blocks_leaked) = MC_(bytes_leaked) = 0;
|
||||
MC_(blocks_indirect) = MC_(bytes_indirect) = 0;
|
||||
MC_(blocks_dubious) = MC_(bytes_dubious) = 0;
|
||||
MC_(blocks_reachable) = MC_(bytes_reachable) = 0;
|
||||
MC_(blocks_suppressed) = MC_(bytes_suppressed) = 0;
|
||||
|
||||
if (mode == LC_Full)
|
||||
full_report(tid);
|
||||
@ -827,23 +827,23 @@ void MC_(do_detect_memory_leaks) (
|
||||
VG_(message)(Vg_UserMsg, "");
|
||||
VG_(message)(Vg_UserMsg, "LEAK SUMMARY:");
|
||||
VG_(message)(Vg_UserMsg, " definitely lost: %'lu bytes in %'lu blocks.",
|
||||
MC_(bytes_leaked), blocks_leaked );
|
||||
if (blocks_indirect > 0)
|
||||
MC_(bytes_leaked), MC_(blocks_leaked) );
|
||||
if (MC_(blocks_indirect) > 0)
|
||||
VG_(message)(Vg_UserMsg, " indirectly lost: %'lu bytes in %'lu blocks.",
|
||||
MC_(bytes_indirect), blocks_indirect );
|
||||
MC_(bytes_indirect), MC_(blocks_indirect) );
|
||||
VG_(message)(Vg_UserMsg, " possibly lost: %'lu bytes in %'lu blocks.",
|
||||
MC_(bytes_dubious), blocks_dubious );
|
||||
MC_(bytes_dubious), MC_(blocks_dubious) );
|
||||
VG_(message)(Vg_UserMsg, " still reachable: %'lu bytes in %'lu blocks.",
|
||||
MC_(bytes_reachable), blocks_reachable );
|
||||
MC_(bytes_reachable), MC_(blocks_reachable) );
|
||||
VG_(message)(Vg_UserMsg, " suppressed: %'lu bytes in %'lu blocks.",
|
||||
MC_(bytes_suppressed), blocks_suppressed );
|
||||
MC_(bytes_suppressed), MC_(blocks_suppressed) );
|
||||
if (mode == LC_Summary
|
||||
&& (blocks_leaked + blocks_indirect
|
||||
+ blocks_dubious + blocks_reachable) > 0) {
|
||||
&& (MC_(blocks_leaked) + MC_(blocks_indirect)
|
||||
+ MC_(blocks_dubious) + MC_(blocks_reachable)) > 0) {
|
||||
VG_(message)(Vg_UserMsg,
|
||||
"Rerun with --leak-check=full to see details of leaked memory.");
|
||||
}
|
||||
if (blocks_reachable > 0 && !MC_(clo_show_reachable) && mode == LC_Full) {
|
||||
if (MC_(blocks_reachable) > 0 && !MC_(clo_show_reachable) && mode == LC_Full) {
|
||||
VG_(message)(Vg_UserMsg,
|
||||
"Reachable blocks (those to which a pointer was found) are not shown.");
|
||||
VG_(message)(Vg_UserMsg,
|
||||
|
||||
@ -1056,9 +1056,9 @@ INLINE Bool MC_(in_ignored_range) ( Addr a )
|
||||
|
||||
static Bool isHex ( UChar c )
|
||||
{
|
||||
return ((c >= '0' && c <= '9')
|
||||
|| (c >= 'a' && c <= 'f')
|
||||
|| (c >= 'A' && c <= 'F'));
|
||||
return ((c >= '0' && c <= '9') ||
|
||||
(c >= 'a' && c <= 'f') ||
|
||||
(c >= 'A' && c <= 'F'));
|
||||
}
|
||||
|
||||
static UInt fromHex ( UChar c )
|
||||
@ -5005,7 +5005,23 @@ static Bool mc_handle_client_request ( ThreadId tid, UWord* arg, UWord* ret )
|
||||
*argp[4] = MC_(bytes_suppressed);
|
||||
// there is no argp[5]
|
||||
//*argp[5] = MC_(bytes_indirect);
|
||||
// XXX need to make *argp[1-4] defined
|
||||
// XXX need to make *argp[1-4] defined; currently done in the
|
||||
// VALGRIND_COUNT_LEAKS_MACRO by initialising them to zero.
|
||||
*ret = 0;
|
||||
return True;
|
||||
}
|
||||
case VG_USERREQ__COUNT_LEAK_BLOCKS: { /* count leaked blocks */
|
||||
UWord** argp = (UWord**)arg;
|
||||
// MC_(blocks_leaked) et al were set by the last leak check (or zero
|
||||
// if no prior leak checks performed).
|
||||
*argp[1] = MC_(blocks_leaked) + MC_(blocks_indirect);
|
||||
*argp[2] = MC_(blocks_dubious);
|
||||
*argp[3] = MC_(blocks_reachable);
|
||||
*argp[4] = MC_(blocks_suppressed);
|
||||
// there is no argp[5]
|
||||
//*argp[5] = MC_(blocks_indirect);
|
||||
// XXX need to make *argp[1-4] defined; currently done in the
|
||||
// VALGRIND_COUNT_LEAK_BLOCKS_MACRO by initialising them to zero.
|
||||
*ret = 0;
|
||||
return True;
|
||||
}
|
||||
|
||||
@ -93,6 +93,9 @@ typedef
|
||||
|
||||
VG_USERREQ__MAKE_MEM_DEFINED_IF_ADDRESSABLE,
|
||||
|
||||
/* Not next to VG_USERREQ__COUNT_LEAKS because it was added later. */
|
||||
VG_USERREQ__COUNT_LEAK_BLOCKS,
|
||||
|
||||
/* This is just for memcheck's internal use - don't use it */
|
||||
_VG_USERREQ__MEMCHECK_RECORD_OVERLAP_ERROR
|
||||
= VG_USERREQ_TOOL_BASE('M','C') + 256
|
||||
@ -228,7 +231,7 @@ typedef
|
||||
specified, which works no matter what type 'leaked', 'dubious', etc
|
||||
are. We also initialise '_qzz_leaked', etc because
|
||||
VG_USERREQ__COUNT_LEAKS doesn't mark the values returned as
|
||||
initialised. */ \
|
||||
defined. */ \
|
||||
{unsigned long _qzz_res; \
|
||||
unsigned long _qzz_leaked = 0, _qzz_dubious = 0; \
|
||||
unsigned long _qzz_reachable = 0, _qzz_suppressed = 0; \
|
||||
@ -242,6 +245,28 @@ typedef
|
||||
suppressed = _qzz_suppressed; \
|
||||
}
|
||||
|
||||
/* Return number of leaked, dubious, reachable and suppressed bytes found by
|
||||
all previous leak checks. They must be lvalues. */
|
||||
#define VALGRIND_COUNT_LEAK_BLOCKS(leaked, dubious, reachable, suppressed) \
|
||||
/* For safety on 64-bit platforms we assign the results to private
|
||||
unsigned long variables, then assign these to the lvalues the user
|
||||
specified, which works no matter what type 'leaked', 'dubious', etc
|
||||
are. We also initialise '_qzz_leaked', etc because
|
||||
VG_USERREQ__COUNT_LEAKS doesn't mark the values returned as
|
||||
defined. */ \
|
||||
{unsigned long _qzz_res; \
|
||||
unsigned long _qzz_leaked = 0, _qzz_dubious = 0; \
|
||||
unsigned long _qzz_reachable = 0, _qzz_suppressed = 0; \
|
||||
VALGRIND_DO_CLIENT_REQUEST(_qzz_res, 0, \
|
||||
VG_USERREQ__COUNT_LEAK_BLOCKS, \
|
||||
&_qzz_leaked, &_qzz_dubious, \
|
||||
&_qzz_reachable, &_qzz_suppressed, 0); \
|
||||
leaked = _qzz_leaked; \
|
||||
dubious = _qzz_dubious; \
|
||||
reachable = _qzz_reachable; \
|
||||
suppressed = _qzz_suppressed; \
|
||||
}
|
||||
|
||||
|
||||
/* Get the validity data for addresses [zza..zza+zznbytes-1] and copy it
|
||||
into the provided zzvbits array. Return values:
|
||||
|
||||
@ -23,7 +23,7 @@ endif
|
||||
|
||||
DIST_SUBDIRS = x86 amd64 linux x86-linux .
|
||||
|
||||
noinst_SCRIPTS = filter_allocs filter_leak_check_size \
|
||||
noinst_SCRIPTS = filter_allocs \
|
||||
filter_stderr filter_xml \
|
||||
filter_varinfo3
|
||||
|
||||
@ -59,7 +59,7 @@ EXTRA_DIST = $(noinst_SCRIPTS) \
|
||||
inits.stderr.exp inits.vgtest \
|
||||
inline.stderr.exp inline.stdout.exp inline.vgtest \
|
||||
leak-0.vgtest leak-0.stderr.exp \
|
||||
leak-cycle.vgtest leak-cycle.stderr.exp leak-cycle.stderr.exp64 \
|
||||
leak-cycle.vgtest leak-cycle.stderr.exp \
|
||||
leak-pool-0.vgtest leak-pool-0.stderr.exp leak-pool-0.stderr.exp64 \
|
||||
leak-pool-1.vgtest leak-pool-1.stderr.exp leak-pool-1.stderr.exp64 \
|
||||
leak-pool-2.vgtest leak-pool-2.stderr.exp leak-pool-2.stderr.exp64 \
|
||||
@ -68,7 +68,6 @@ EXTRA_DIST = $(noinst_SCRIPTS) \
|
||||
leak-pool-5.vgtest leak-pool-5.stderr.exp leak-pool-5.stderr.exp64 \
|
||||
leak-tree.vgtest leak-tree.stderr.exp \
|
||||
leak-tree.stderr.exp2 leak-tree.stderr.exp64 \
|
||||
leak-regroot.vgtest leak-regroot.stderr.exp \
|
||||
leakotron.vgtest leakotron.stdout.exp leakotron.stderr.exp \
|
||||
linux-syslog-syscall linux-syslog-syscall.stderr.exp \
|
||||
linux-syscalls-2007 linux-syscalls-2007.stderr.exp \
|
||||
@ -188,7 +187,7 @@ check_PROGRAMS = \
|
||||
doublefree error_counts errs1 exitprog execve execve2 erringfds \
|
||||
file_locking \
|
||||
fprw fwrite inits inline \
|
||||
leak-0 leak-cycle leak-pool leak-tree leak-regroot leakotron \
|
||||
leak-0 leak-cycle leak-pool leak-tree leakotron \
|
||||
linux-syslog-syscall \
|
||||
linux-syscalls-2007 \
|
||||
long_namespace_xml \
|
||||
|
||||
@ -2,6 +2,7 @@
|
||||
#include <stdlib.h>
|
||||
#include <assert.h>
|
||||
#include "../memcheck.h"
|
||||
#include "leak.h"
|
||||
|
||||
int main(void)
|
||||
{
|
||||
@ -10,16 +11,13 @@ int main(void)
|
||||
int* reachable;
|
||||
int* dubious;
|
||||
int* leaked;
|
||||
long n_reachable = 0;
|
||||
long n_dubious = 0;
|
||||
long n_leaked = 0;
|
||||
long n_suppressed = 0;
|
||||
DECLARE_LEAK_COUNTERS;
|
||||
|
||||
/* we require these longs to have same size as a machine word */
|
||||
assert(sizeof(long) == sizeof(void*));
|
||||
|
||||
/* Error counting */
|
||||
printf("errors: %d\n", VALGRIND_COUNT_ERRORS);
|
||||
printf("errors: %d\n\n", VALGRIND_COUNT_ERRORS);
|
||||
|
||||
if (x == 0) {
|
||||
y++;
|
||||
@ -27,14 +25,16 @@ int main(void)
|
||||
y--;
|
||||
}
|
||||
|
||||
printf("errors: %d\n", VALGRIND_COUNT_ERRORS);
|
||||
printf("errors: %d\n\n", VALGRIND_COUNT_ERRORS);
|
||||
|
||||
// Get a baseline, after start-up and also after printf (because Darwin
|
||||
// printf allocates memory the first time it's called!)
|
||||
GET_INITIAL_LEAK_COUNTS;
|
||||
|
||||
/* Leak checking */
|
||||
VALGRIND_DO_LEAK_CHECK;
|
||||
VALGRIND_COUNT_LEAKS(n_leaked, n_dubious, n_reachable, n_suppressed);
|
||||
if (n_reachable == 24) n_reachable = 0; /* handle glibc differences */
|
||||
printf("leaks: %ldB, %ldB, %ldB, %ldB\n",
|
||||
n_leaked, n_dubious, n_reachable, n_suppressed);
|
||||
GET_FINAL_LEAK_COUNTS;
|
||||
PRINT_LEAK_COUNTS(stdout);
|
||||
printf("\n");
|
||||
|
||||
leaked = malloc(77);
|
||||
leaked = 0;
|
||||
@ -44,12 +44,9 @@ int main(void)
|
||||
|
||||
reachable = malloc(99);
|
||||
|
||||
VALGRIND_DO_LEAK_CHECK;
|
||||
VALGRIND_DO_LEAK_CHECK;
|
||||
VALGRIND_COUNT_LEAKS(n_leaked, n_dubious, n_reachable, n_suppressed);
|
||||
if (n_reachable == 123) n_reachable = 99; /* handle glibc differences */
|
||||
printf("leaks: %ldB, %ldB, %ldB, %ldB\n",
|
||||
n_leaked, n_dubious, n_reachable, n_suppressed);
|
||||
GET_FINAL_LEAK_COUNTS;
|
||||
PRINT_LEAK_COUNTS(stdout);
|
||||
printf("\n");
|
||||
|
||||
printf("errors: %d\n", VALGRIND_COUNT_ERRORS);
|
||||
|
||||
|
||||
@ -1,5 +1,15 @@
|
||||
errors: 0
|
||||
|
||||
errors: 1
|
||||
leaks: 0B, 0B, 0B, 0B
|
||||
leaks: 77B, 88B, 99B, 0B
|
||||
|
||||
leaked: 0 bytes in 0 blocks
|
||||
dubious: 0 bytes in 0 blocks
|
||||
reachable: 0 bytes in 0 blocks
|
||||
suppressed: 0 bytes in 0 blocks
|
||||
|
||||
leaked: 77 bytes in 1 blocks
|
||||
dubious: 88 bytes in 1 blocks
|
||||
reachable: 99 bytes in 1 blocks
|
||||
suppressed: 0 bytes in 0 blocks
|
||||
|
||||
errors: 1
|
||||
|
||||
@ -1,4 +0,0 @@
|
||||
#! /bin/sh
|
||||
|
||||
./filter_stderr |
|
||||
sed "s/checked [0-9,]* bytes./checked ... bytes./"
|
||||
@ -31,5 +31,13 @@ perl -p -0 -e 's/(Syscall param[^\n<]*)\n( (at|by)[^\n]*\n)*/$1\n ...\n/gs'
|
||||
|
||||
# Something similar for XML output. Chops everything within
|
||||
# <stack>...</stack>.
|
||||
perl -p -0 -e 's/(<what>Syscall param[^\n]*)\n([^\n]*(stack|frame|ip|obj|fn)[^\n]*\n)*/$1\n/gs'
|
||||
perl -p -0 -e 's/(<what>Syscall param[^\n]*)\n([^\n]*(stack|frame|ip|obj|fn)[^\n]*\n)*/$1\n/gs' |
|
||||
|
||||
# Leak check filtering.
|
||||
sed "s/checked [0-9,]* bytes./checked ... bytes./" |
|
||||
|
||||
# More leak check filtering. For systems that do extra libc allocations
|
||||
# (eg. Darwin) there may be extra (reachable, and thus not shown) loss
|
||||
# records. So we filter out the loss record numbers.
|
||||
perl -p -e "s/lost in loss record \d+ of \d+/lost in loss record ... of .../"
|
||||
|
||||
|
||||
@ -1,15 +1,23 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include "leak.h"
|
||||
#include "../memcheck.h"
|
||||
|
||||
/*
|
||||
Live 0-sized blocks were being reported as leaked.
|
||||
*/
|
||||
// Live 0-sized blocks were being reported as leaked.
|
||||
// Also, test that a pointer in a register is handled correctly.
|
||||
int main()
|
||||
{
|
||||
void *volatile foo = malloc(0);
|
||||
DECLARE_LEAK_COUNTERS;
|
||||
|
||||
//printf("&foo=%p foo=%p\n", &foo, foo);
|
||||
VALGRIND_DO_LEAK_CHECK;
|
||||
register char *foo;
|
||||
|
||||
GET_INITIAL_LEAK_COUNTS;
|
||||
|
||||
foo = malloc(0);
|
||||
|
||||
GET_FINAL_LEAK_COUNTS;
|
||||
|
||||
PRINT_LEAK_COUNTS(stderr);
|
||||
|
||||
free(foo);
|
||||
return 0;
|
||||
|
||||
@ -1,17 +1,4 @@
|
||||
|
||||
searching for pointers to 1 not-freed blocks.
|
||||
checked ... bytes.
|
||||
|
||||
LEAK SUMMARY:
|
||||
definitely lost: 0 bytes in 0 blocks.
|
||||
possibly lost: 0 bytes in 0 blocks.
|
||||
still reachable: 0 bytes in 1 blocks.
|
||||
suppressed: 0 bytes in 0 blocks.
|
||||
Reachable blocks (those to which a pointer was found) are not shown.
|
||||
To see them, rerun with: --leak-check=full --show-reachable=yes
|
||||
|
||||
ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)
|
||||
malloc/free: in use at exit: 0 bytes in 0 blocks.
|
||||
malloc/free: 1 allocs, 1 frees, 0 bytes allocated.
|
||||
For a detailed leak analysis, rerun with: --leak-check=yes
|
||||
For counts of detected errors, rerun with: -v
|
||||
leaked: 0 bytes in 0 blocks
|
||||
dubious: 0 bytes in 0 blocks
|
||||
reachable: 0 bytes in 1 blocks
|
||||
suppressed: 0 bytes in 0 blocks
|
||||
|
||||
@ -1,18 +0,0 @@
|
||||
|
||||
searching for pointers to 2 not-freed blocks.
|
||||
checked ... bytes.
|
||||
|
||||
LEAK SUMMARY:
|
||||
definitely lost: 0 bytes in 0 blocks.
|
||||
indirectly lost: 0 bytes in 0 blocks.
|
||||
possibly lost: 0 bytes in 0 blocks.
|
||||
still reachable: 24 bytes in 2 blocks.
|
||||
suppressed: 0 bytes in 0 blocks.
|
||||
Reachable blocks (those to which a pointer was found) are not shown.
|
||||
To see them, rerun with: --leak-check=full --show-reachable=yes
|
||||
|
||||
ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)
|
||||
malloc/free: in use at exit: 0 bytes in 0 blocks.
|
||||
malloc/free: 2 allocs, 2 frees, 24 bytes allocated.
|
||||
For a detailed leak analysis, rerun with: --leak-check=yes
|
||||
For counts of detected errors, rerun with: -v
|
||||
@ -1,2 +1,2 @@
|
||||
prog: leak-0
|
||||
stderr_filter: filter_leak_check_size
|
||||
vgopts: -q
|
||||
|
||||
@ -1,14 +1,18 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include "leak.h"
|
||||
#include "../memcheck.h"
|
||||
|
||||
struct n {
|
||||
struct n *l;
|
||||
struct n *r;
|
||||
// This ensures it's the same size on 32-bit and 64-bit platforms.
|
||||
char padding[ 2 * (8 - sizeof(struct n*)) ];
|
||||
};
|
||||
|
||||
struct n *mk(struct n *l, struct n *r)
|
||||
{
|
||||
struct n *n = malloc(sizeof(*n));
|
||||
struct n *n = malloc(sizeof(struct n));
|
||||
n->l = l;
|
||||
n->r = r;
|
||||
|
||||
@ -27,19 +31,21 @@ static struct n *mkcycle()
|
||||
return a;
|
||||
}
|
||||
|
||||
|
||||
int main()
|
||||
{
|
||||
DECLARE_LEAK_COUNTERS;
|
||||
|
||||
struct n *volatile c1, *volatile c2;
|
||||
|
||||
GET_INITIAL_LEAK_COUNTS;
|
||||
|
||||
/* two simple cycles */
|
||||
c1 = mkcycle();
|
||||
c2 = mkcycle();
|
||||
|
||||
c1 = c2 = 0;
|
||||
|
||||
//VALGRIND_DO_LEAK_CHECK;
|
||||
|
||||
/* one cycle linked to another */
|
||||
c1 = mkcycle();
|
||||
c2 = mkcycle();
|
||||
@ -53,8 +59,6 @@ int main()
|
||||
|
||||
c1 = c2 = 0;
|
||||
|
||||
//VALGRIND_DO_LEAK_CHECK;
|
||||
|
||||
/* two linked cycles */
|
||||
c1 = mkcycle();
|
||||
c2 = mkcycle();
|
||||
@ -64,7 +68,9 @@ int main()
|
||||
|
||||
c1 = c2 = 0;
|
||||
|
||||
VALGRIND_DO_LEAK_CHECK;
|
||||
GET_FINAL_LEAK_COUNTS;
|
||||
|
||||
PRINT_LEAK_COUNTS(stderr);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -1,43 +1,31 @@
|
||||
leaked: 288 bytes in 18 blocks
|
||||
dubious: 0 bytes in 0 blocks
|
||||
reachable: 0 bytes in 0 blocks
|
||||
suppressed: 0 bytes in 0 blocks
|
||||
|
||||
searching for pointers to 18 not-freed blocks.
|
||||
checked ... bytes.
|
||||
|
||||
24 (8 direct, 16 indirect) bytes in 1 blocks are definitely lost in loss record 15 of 18
|
||||
48 (16 direct, 32 indirect) bytes in 1 blocks are definitely lost in loss record ... of ...
|
||||
at 0x........: malloc (vg_replace_malloc.c:...)
|
||||
by 0x........: mk (leak-cycle.c:11)
|
||||
by 0x........: mkcycle (leak-cycle.c:22)
|
||||
by 0x........: main (leak-cycle.c:36)
|
||||
by 0x........: mk (leak-cycle.c:15)
|
||||
by 0x........: mkcycle (leak-cycle.c:26)
|
||||
by 0x........: main (leak-cycle.c:44)
|
||||
|
||||
|
||||
24 (8 direct, 16 indirect) bytes in 1 blocks are definitely lost in loss record 16 of 18
|
||||
48 (16 direct, 32 indirect) bytes in 1 blocks are definitely lost in loss record ... of ...
|
||||
at 0x........: malloc (vg_replace_malloc.c:...)
|
||||
by 0x........: mk (leak-cycle.c:11)
|
||||
by 0x........: mkcycle (leak-cycle.c:22)
|
||||
by 0x........: main (leak-cycle.c:37)
|
||||
|
||||
|
||||
48 (8 direct, 40 indirect) bytes in 1 blocks are definitely lost in loss record 17 of 18
|
||||
at 0x........: malloc (vg_replace_malloc.c:...)
|
||||
by 0x........: mk (leak-cycle.c:11)
|
||||
by 0x........: mkcycle (leak-cycle.c:22)
|
||||
by 0x........: mk (leak-cycle.c:15)
|
||||
by 0x........: mkcycle (leak-cycle.c:26)
|
||||
by 0x........: main (leak-cycle.c:45)
|
||||
|
||||
|
||||
48 (8 direct, 40 indirect) bytes in 1 blocks are definitely lost in loss record 18 of 18
|
||||
96 (16 direct, 80 indirect) bytes in 1 blocks are definitely lost in loss record ... of ...
|
||||
at 0x........: malloc (vg_replace_malloc.c:...)
|
||||
by 0x........: mk (leak-cycle.c:11)
|
||||
by 0x........: mkcycle (leak-cycle.c:22)
|
||||
by 0x........: main (leak-cycle.c:59)
|
||||
by 0x........: mk (leak-cycle.c:15)
|
||||
by 0x........: mkcycle (leak-cycle.c:26)
|
||||
by 0x........: main (leak-cycle.c:51)
|
||||
|
||||
LEAK SUMMARY:
|
||||
definitely lost: 32 bytes in 4 blocks.
|
||||
indirectly lost: 112 bytes in 14 blocks.
|
||||
possibly lost: 0 bytes in 0 blocks.
|
||||
still reachable: 0 bytes in 0 blocks.
|
||||
suppressed: 0 bytes in 0 blocks.
|
||||
|
||||
ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)
|
||||
malloc/free: in use at exit: 144 bytes in 18 blocks.
|
||||
malloc/free: 18 allocs, 0 frees, 144 bytes allocated.
|
||||
For a detailed leak analysis, rerun with: --leak-check=yes
|
||||
For counts of detected errors, rerun with: -v
|
||||
96 (16 direct, 80 indirect) bytes in 1 blocks are definitely lost in loss record ... of ...
|
||||
at 0x........: malloc (vg_replace_malloc.c:...)
|
||||
by 0x........: mk (leak-cycle.c:15)
|
||||
by 0x........: mkcycle (leak-cycle.c:26)
|
||||
by 0x........: main (leak-cycle.c:63)
|
||||
|
||||
@ -1,45 +0,0 @@
|
||||
|
||||
searching for pointers to 19 not-freed blocks.
|
||||
checked ... bytes.
|
||||
|
||||
24 (8+16) bytes in 1 blocks are definitely lost in loss record 15 of 19
|
||||
at 0x........: malloc (vg_replace_malloc.c:...)
|
||||
by 0x........: mk (leak-cycle.c:11)
|
||||
by 0x........: mkcycle (leak-cycle.c:22)
|
||||
by 0x........: main (leak-cycle.c:36)
|
||||
|
||||
|
||||
24 (8+16) bytes in 1 blocks are definitely lost in loss record 16 of 19
|
||||
at 0x........: malloc (vg_replace_malloc.c:...)
|
||||
by 0x........: mk (leak-cycle.c:11)
|
||||
by 0x........: mkcycle (leak-cycle.c:22)
|
||||
by 0x........: main (leak-cycle.c:37)
|
||||
|
||||
|
||||
48 (8+40) bytes in 1 blocks are definitely lost in loss record 18 of 19
|
||||
at 0x........: malloc (vg_replace_malloc.c:...)
|
||||
by 0x........: mk (leak-cycle.c:11)
|
||||
by 0x........: mkcycle (leak-cycle.c:22)
|
||||
by 0x........: main (leak-cycle.c:45)
|
||||
|
||||
|
||||
48 (8+40) bytes in 1 blocks are definitely lost in loss record 19 of 19
|
||||
at 0x........: malloc (vg_replace_malloc.c:...)
|
||||
by 0x........: mk (leak-cycle.c:11)
|
||||
by 0x........: mkcycle (leak-cycle.c:22)
|
||||
by 0x........: main (leak-cycle.c:59)
|
||||
|
||||
LEAK SUMMARY:
|
||||
definitely lost: 32 bytes in 4 blocks.
|
||||
indirectly lost: 112 bytes in 14 blocks.
|
||||
possibly lost: 0 bytes in 0 blocks.
|
||||
still reachable: 24 bytes in 1 blocks.
|
||||
suppressed: 0 bytes in 0 blocks.
|
||||
Reachable blocks (those to which a pointer was found) are not shown.
|
||||
To see them, rerun with: --show-reachable=yes
|
||||
|
||||
ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)
|
||||
malloc/free: in use at exit: 144 bytes in 18 blocks.
|
||||
malloc/free: 19 allocs, 1 frees, 168 bytes allocated.
|
||||
For a detailed leak analysis, rerun with: --leak-check=yes
|
||||
For counts of detected errors, rerun with: -v
|
||||
@ -1,43 +0,0 @@
|
||||
|
||||
searching for pointers to 18 not-freed blocks.
|
||||
checked ... bytes.
|
||||
|
||||
48 (16 direct, 32 indirect) bytes in 1 blocks are definitely lost in loss record 15 of 18
|
||||
at 0x........: malloc (vg_replace_malloc.c:...)
|
||||
by 0x........: mk (leak-cycle.c:11)
|
||||
by 0x........: mkcycle (leak-cycle.c:22)
|
||||
by 0x........: main (leak-cycle.c:36)
|
||||
|
||||
|
||||
48 (16 direct, 32 indirect) bytes in 1 blocks are definitely lost in loss record 16 of 18
|
||||
at 0x........: malloc (vg_replace_malloc.c:...)
|
||||
by 0x........: mk (leak-cycle.c:11)
|
||||
by 0x........: mkcycle (leak-cycle.c:22)
|
||||
by 0x........: main (leak-cycle.c:37)
|
||||
|
||||
|
||||
96 (16 direct, 80 indirect) bytes in 1 blocks are definitely lost in loss record 17 of 18
|
||||
at 0x........: malloc (vg_replace_malloc.c:...)
|
||||
by 0x........: mk (leak-cycle.c:11)
|
||||
by 0x........: mkcycle (leak-cycle.c:22)
|
||||
by 0x........: main (leak-cycle.c:45)
|
||||
|
||||
|
||||
96 (16 direct, 80 indirect) bytes in 1 blocks are definitely lost in loss record 18 of 18
|
||||
at 0x........: malloc (vg_replace_malloc.c:...)
|
||||
by 0x........: mk (leak-cycle.c:11)
|
||||
by 0x........: mkcycle (leak-cycle.c:22)
|
||||
by 0x........: main (leak-cycle.c:59)
|
||||
|
||||
LEAK SUMMARY:
|
||||
definitely lost: 64 bytes in 4 blocks.
|
||||
indirectly lost: 224 bytes in 14 blocks.
|
||||
possibly lost: 0 bytes in 0 blocks.
|
||||
still reachable: 0 bytes in 0 blocks.
|
||||
suppressed: 0 bytes in 0 blocks.
|
||||
|
||||
ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)
|
||||
malloc/free: in use at exit: 288 bytes in 18 blocks.
|
||||
malloc/free: 18 allocs, 0 frees, 288 bytes allocated.
|
||||
For a detailed leak analysis, rerun with: --leak-check=yes
|
||||
For counts of detected errors, rerun with: -v
|
||||
@ -1,3 +1,2 @@
|
||||
prog: leak-cycle
|
||||
vgopts: --leak-resolution=high
|
||||
stderr_filter: filter_leak_check_size
|
||||
vgopts: -q --leak-check=yes --leak-resolution=high
|
||||
|
||||
@ -1,15 +0,0 @@
|
||||
#include "../memcheck.h"
|
||||
#include <stdlib.h>
|
||||
|
||||
int main()
|
||||
{
|
||||
register char *foo /* asm("esi") */;
|
||||
|
||||
foo = malloc(10); /* not leaked */
|
||||
|
||||
VALGRIND_DO_LEAK_CHECK;
|
||||
|
||||
free(foo);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@ -1,17 +0,0 @@
|
||||
|
||||
searching for pointers to 1 not-freed blocks.
|
||||
checked ... bytes.
|
||||
|
||||
LEAK SUMMARY:
|
||||
definitely lost: 0 bytes in 0 blocks.
|
||||
possibly lost: 0 bytes in 0 blocks.
|
||||
still reachable: 10 bytes in 1 blocks.
|
||||
suppressed: 0 bytes in 0 blocks.
|
||||
Reachable blocks (those to which a pointer was found) are not shown.
|
||||
To see them, rerun with: --leak-check=full --show-reachable=yes
|
||||
|
||||
ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)
|
||||
malloc/free: in use at exit: 0 bytes in 0 blocks.
|
||||
malloc/free: 1 allocs, 1 frees, 10 bytes allocated.
|
||||
For a detailed leak analysis, rerun with: --leak-check=yes
|
||||
For counts of detected errors, rerun with: -v
|
||||
@ -1,18 +0,0 @@
|
||||
|
||||
searching for pointers to 2 not-freed blocks.
|
||||
checked ... bytes.
|
||||
|
||||
LEAK SUMMARY:
|
||||
definitely lost: 0 bytes in 0 blocks.
|
||||
indirectly lost: 0 bytes in 0 blocks.
|
||||
possibly lost: 0 bytes in 0 blocks.
|
||||
still reachable: 34 bytes in 2 blocks.
|
||||
suppressed: 0 bytes in 0 blocks.
|
||||
Reachable blocks (those to which a pointer was found) are not shown.
|
||||
To see them, rerun with: --leak-check=full --show-reachable=yes
|
||||
|
||||
ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)
|
||||
malloc/free: in use at exit: 0 bytes in 0 blocks.
|
||||
malloc/free: 2 allocs, 2 frees, 34 bytes allocated.
|
||||
For a detailed leak analysis, rerun with: --leak-check=yes
|
||||
For counts of detected errors, rerun with: -v
|
||||
@ -1,2 +0,0 @@
|
||||
prog: leak-regroot
|
||||
stderr_filter: filter_leak_check_size
|
||||
@ -2,7 +2,7 @@
|
||||
searching for pointers to 11 not-freed blocks.
|
||||
checked ... bytes.
|
||||
|
||||
72 (8 direct, 64 indirect) bytes in 1 blocks are definitely lost in loss record 11 of 11
|
||||
72 (8 direct, 64 indirect) bytes in 1 blocks are definitely lost in loss record ... of ...
|
||||
at 0x........: malloc (vg_replace_malloc.c:...)
|
||||
by 0x........: mk (leak-tree.c:11)
|
||||
by 0x........: main (leak-tree.c:25)
|
||||
@ -19,19 +19,19 @@ searching for pointers to 14 not-freed blocks.
|
||||
checked ... bytes.
|
||||
|
||||
|
||||
8 bytes in 1 blocks are definitely lost in loss record 1 of 14
|
||||
8 bytes in 1 blocks are definitely lost in loss record ... of ...
|
||||
at 0x........: malloc (vg_replace_malloc.c:...)
|
||||
by 0x........: mk (leak-tree.c:11)
|
||||
by 0x........: main (leak-tree.c:39)
|
||||
|
||||
|
||||
88 (8 direct, 80 indirect) bytes in 1 blocks are definitely lost in loss record 13 of 14
|
||||
88 (8 direct, 80 indirect) bytes in 1 blocks are definitely lost in loss record ... of ...
|
||||
at 0x........: malloc (vg_replace_malloc.c:...)
|
||||
by 0x........: mk (leak-tree.c:11)
|
||||
by 0x........: main (leak-tree.c:25)
|
||||
|
||||
|
||||
16 (8 direct, 8 indirect) bytes in 1 blocks are definitely lost in loss record 14 of 14
|
||||
16 (8 direct, 8 indirect) bytes in 1 blocks are definitely lost in loss record ... of ...
|
||||
at 0x........: malloc (vg_replace_malloc.c:...)
|
||||
by 0x........: mk (leak-tree.c:11)
|
||||
by 0x........: main (leak-tree.c:38)
|
||||
|
||||
@ -2,7 +2,7 @@
|
||||
searching for pointers to 11 not-freed blocks.
|
||||
checked ... bytes.
|
||||
|
||||
8 bytes in 1 blocks are definitely lost in loss record 1 of 11
|
||||
8 bytes in 1 blocks are definitely lost in loss record ... of ...
|
||||
at 0x........: malloc (vg_replace_malloc.c:...)
|
||||
by 0x........: mk (leak-tree.c:11)
|
||||
by 0x........: main (leak-tree.c:25)
|
||||
@ -18,19 +18,19 @@ searching for pointers to 14 not-freed blocks.
|
||||
checked ... bytes.
|
||||
|
||||
|
||||
8 bytes in 1 blocks are definitely lost in loss record 1 of 14
|
||||
8 bytes in 1 blocks are definitely lost in loss record ... of ...
|
||||
at 0x........: malloc (vg_replace_malloc.c:...)
|
||||
by 0x........: mk (leak-tree.c:11)
|
||||
by 0x........: main (leak-tree.c:39)
|
||||
|
||||
|
||||
8 bytes in 1 blocks are definitely lost in loss record 2 of 14
|
||||
8 bytes in 1 blocks are definitely lost in loss record ... of ...
|
||||
at 0x........: malloc (vg_replace_malloc.c:...)
|
||||
by 0x........: mk (leak-tree.c:11)
|
||||
by 0x........: main (leak-tree.c:38)
|
||||
|
||||
|
||||
40 (8 direct, 32 indirect) bytes in 1 blocks are definitely lost in loss record 14 of 14
|
||||
40 (8 direct, 32 indirect) bytes in 1 blocks are definitely lost in loss record ... of ...
|
||||
at 0x........: malloc (vg_replace_malloc.c:...)
|
||||
by 0x........: mk (leak-tree.c:11)
|
||||
by 0x........: main (leak-tree.c:25)
|
||||
|
||||
@ -2,7 +2,7 @@
|
||||
searching for pointers to 11 not-freed blocks.
|
||||
checked ... bytes.
|
||||
|
||||
80 (16 direct, 64 indirect) bytes in 1 blocks are definitely lost in loss record 11 of 11
|
||||
80 (16 direct, 64 indirect) bytes in 1 blocks are definitely lost in loss record ... of ...
|
||||
at 0x........: malloc (vg_replace_malloc.c:...)
|
||||
by 0x........: mk (leak-tree.c:11)
|
||||
by 0x........: main (leak-tree.c:25)
|
||||
@ -19,19 +19,19 @@ searching for pointers to 14 not-freed blocks.
|
||||
checked ... bytes.
|
||||
|
||||
|
||||
16 bytes in 1 blocks are definitely lost in loss record 1 of 14
|
||||
16 bytes in 1 blocks are definitely lost in loss record ... of ...
|
||||
at 0x........: malloc (vg_replace_malloc.c:...)
|
||||
by 0x........: mk (leak-tree.c:11)
|
||||
by 0x........: main (leak-tree.c:39)
|
||||
|
||||
|
||||
16 bytes in 1 blocks are definitely lost in loss record 2 of 14
|
||||
16 bytes in 1 blocks are definitely lost in loss record ... of ...
|
||||
at 0x........: malloc (vg_replace_malloc.c:...)
|
||||
by 0x........: mk (leak-tree.c:11)
|
||||
by 0x........: main (leak-tree.c:38)
|
||||
|
||||
|
||||
80 (16 direct, 64 indirect) bytes in 1 blocks are definitely lost in loss record 14 of 14
|
||||
80 (16 direct, 64 indirect) bytes in 1 blocks are definitely lost in loss record ... of ...
|
||||
at 0x........: malloc (vg_replace_malloc.c:...)
|
||||
by 0x........: mk (leak-tree.c:11)
|
||||
by 0x........: main (leak-tree.c:25)
|
||||
|
||||
@ -1,3 +1,2 @@
|
||||
prog: leak-tree
|
||||
vgopts: --leak-resolution=high
|
||||
stderr_filter: filter_leak_check_size
|
||||
|
||||
43
memcheck/tests/leak.h
Normal file
43
memcheck/tests/leak.h
Normal file
@ -0,0 +1,43 @@
|
||||
// These counters are used to get a delta between leak counts at startup
|
||||
// (eg. due to libc) and later on. Necessary to get reliable leak tests
|
||||
// across different platforms.
|
||||
#define DECLARE_LEAK_COUNTERS \
|
||||
long L0_bytes = 0, L_bytes = 0, L0_blocks = 0, L_blocks = 0; \
|
||||
long D0_bytes = 0, D_bytes = 0, D0_blocks = 0, D_blocks = 0; \
|
||||
long R0_bytes = 0, R_bytes = 0, R0_blocks = 0, R_blocks = 0; \
|
||||
long S0_bytes = 0, S_bytes = 0, S0_blocks = 0, S_blocks = 0
|
||||
|
||||
// Set a baseline, in case allocations have already happened.
|
||||
#define GET_INITIAL_LEAK_COUNTS \
|
||||
do { \
|
||||
VALGRIND_DO_QUICK_LEAK_CHECK; \
|
||||
VALGRIND_COUNT_LEAKS( L0_bytes, D0_bytes, R0_bytes, S0_bytes );\
|
||||
VALGRIND_COUNT_LEAK_BLOCKS(L0_blocks, D0_blocks, R0_blocks, S0_blocks); \
|
||||
} while (0)
|
||||
|
||||
// Set a baseline, in case allocations have already happened.
|
||||
#define GET_FINAL_LEAK_COUNTS \
|
||||
do { \
|
||||
VALGRIND_DO_QUICK_LEAK_CHECK; \
|
||||
VALGRIND_COUNT_LEAKS( L_bytes, D_bytes, R_bytes, S_bytes ); \
|
||||
VALGRIND_COUNT_LEAK_BLOCKS(L_blocks, D_blocks, R_blocks, S_blocks); \
|
||||
L_bytes -= L0_bytes; L_blocks -= L0_blocks; \
|
||||
D_bytes -= D0_bytes; D_blocks -= D0_blocks; \
|
||||
R_bytes -= R0_bytes; R_blocks -= R0_blocks; \
|
||||
S_bytes -= S0_bytes; S_blocks -= S0_blocks; \
|
||||
} while (0)
|
||||
|
||||
// Print leak counts. When used in conjunction with -q the normal counts
|
||||
// aren't shown, which is what we want.
|
||||
#define PRINT_LEAK_COUNTS(where) \
|
||||
do { \
|
||||
fprintf(where,"leaked: %3ld bytes in %2ld blocks\n", \
|
||||
L_bytes,L_blocks); \
|
||||
fprintf(where,"dubious: %3ld bytes in %2ld blocks\n", \
|
||||
D_bytes,D_blocks); \
|
||||
fprintf(where,"reachable: %3ld bytes in %2ld blocks\n", \
|
||||
R_bytes,R_blocks); \
|
||||
fprintf(where,"suppressed: %3ld bytes in %2ld blocks\n", \
|
||||
S_bytes,S_blocks); \
|
||||
} while (0)
|
||||
|
||||
@ -2,6 +2,7 @@
|
||||
#include <stdlib.h>
|
||||
#include <assert.h>
|
||||
#include "../memcheck.h"
|
||||
#include "leak.h"
|
||||
|
||||
/*
|
||||
Incompetent memory management
|
||||
@ -10,7 +11,7 @@
|
||||
structure with refcounting.
|
||||
*/
|
||||
|
||||
static int bytes, blocks;
|
||||
static long bytes, blocks;
|
||||
|
||||
struct node {
|
||||
struct node *l, *r;
|
||||
@ -95,63 +96,49 @@ static struct node *mk()
|
||||
int main()
|
||||
{
|
||||
int i;
|
||||
long base_definite, base_dubious, base_reachable, base_suppressed;
|
||||
long definite, dubious, reachable, suppressed;
|
||||
int total;
|
||||
long total;
|
||||
DECLARE_LEAK_COUNTERS;
|
||||
|
||||
/* we require these longs to have same size as a machine word */
|
||||
assert(sizeof(long) == sizeof(void*));
|
||||
|
||||
/* get a baseline in case the runtime allocated some memory */
|
||||
VALGRIND_DO_LEAK_CHECK;
|
||||
base_definite = base_dubious = base_reachable = base_suppressed = 0;
|
||||
VALGRIND_COUNT_LEAKS(base_definite, base_dubious,
|
||||
base_reachable, base_suppressed);
|
||||
GET_INITIAL_LEAK_COUNTS;
|
||||
|
||||
for(i = 0; i < ITER; i++) {
|
||||
for (i = 0; i < ITER; i++) {
|
||||
mk();
|
||||
|
||||
if ((i % (ITER/10)) == 0) {
|
||||
if (0)
|
||||
printf("%d living blocks, %d bytes\n",
|
||||
printf("%ld living blocks, %ld bytes\n",
|
||||
blocks, bytes);
|
||||
VALGRIND_DO_LEAK_CHECK;
|
||||
//VALGRIND_DO_LEAK_CHECK;
|
||||
}
|
||||
}
|
||||
|
||||
/* "free all memory" */
|
||||
for(i = 0; i < N; i++)
|
||||
for (i = 0; i < N; i++)
|
||||
assign(&nodes[i], NULL);
|
||||
|
||||
|
||||
if (0)
|
||||
printf("FINISHED: %d living blocks, %d bytes\n",
|
||||
printf("FINISHED: %ld living blocks, %ld bytes\n",
|
||||
blocks, bytes);
|
||||
|
||||
VALGRIND_DO_LEAK_CHECK;
|
||||
GET_FINAL_LEAK_COUNTS;
|
||||
|
||||
/* Shouldn't be necessary, but COUNT_LEAKS doesn't define its
|
||||
result values */
|
||||
definite = dubious = reachable = suppressed = 0;
|
||||
VALGRIND_COUNT_LEAKS(definite, dubious, reachable, suppressed);
|
||||
total = L_bytes + D_bytes + R_bytes + S_bytes;
|
||||
|
||||
definite -= base_definite;
|
||||
dubious -= base_dubious;
|
||||
reachable -= base_reachable;
|
||||
suppressed -= base_suppressed;
|
||||
if (0) {
|
||||
PRINT_LEAK_COUNTS(stderr);
|
||||
}
|
||||
|
||||
total = definite+dubious+reachable+suppressed;
|
||||
|
||||
if (0)
|
||||
printf("leaks: definite %d, dubious %d, reachable %d, suppressed %d = %d\n",
|
||||
(int)definite, (int)dubious, (int)reachable, (int)suppressed, total);
|
||||
|
||||
if (reachable != 0)
|
||||
if (R_bytes != 0)
|
||||
printf("FAILED: I freed everything, "
|
||||
"but there's still %d bytes reachable\n",
|
||||
(int)reachable);
|
||||
"but there's still %ld bytes (in %ld blocks) reachable\n",
|
||||
R_bytes, R_blocks);
|
||||
else if (total != bytes)
|
||||
printf("FAILED: I count %d bytes, leakcheck says %d\n",
|
||||
printf("FAILED: I count %ld bytes, leakcheck says %ld\n",
|
||||
bytes, total);
|
||||
else
|
||||
printf("PASS\n");
|
||||
|
||||
@ -35,25 +35,25 @@ Invalid write of size 1
|
||||
by 0x........: main (mempool.c:148)
|
||||
|
||||
|
||||
10 bytes in 1 blocks are definitely lost in loss record 2 of 5
|
||||
10 bytes in 1 blocks are definitely lost in loss record ... of ...
|
||||
at 0x........: allocate (mempool.c:99)
|
||||
by 0x........: test (mempool.c:135)
|
||||
by 0x........: main (mempool.c:148)
|
||||
|
||||
|
||||
10 bytes in 1 blocks are definitely lost in loss record 3 of 5
|
||||
10 bytes in 1 blocks are definitely lost in loss record ... of ...
|
||||
at 0x........: allocate (mempool.c:99)
|
||||
by 0x........: test (mempool.c:115)
|
||||
by 0x........: main (mempool.c:148)
|
||||
|
||||
|
||||
20 bytes in 1 blocks are definitely lost in loss record 4 of 5
|
||||
20 bytes in 1 blocks are definitely lost in loss record ... of ...
|
||||
at 0x........: allocate (mempool.c:99)
|
||||
by 0x........: test (mempool.c:116)
|
||||
by 0x........: main (mempool.c:148)
|
||||
|
||||
|
||||
28 (20 direct, 8 indirect) bytes in 1 blocks are definitely lost in loss record 5 of 5
|
||||
28 (20 direct, 8 indirect) bytes in 1 blocks are definitely lost in loss record ... of ...
|
||||
at 0x........: malloc (vg_replace_malloc.c:...)
|
||||
by 0x........: make_pool (mempool.c:37)
|
||||
by 0x........: test (mempool.c:111)
|
||||
|
||||
@ -35,25 +35,25 @@ Invalid write of size 1
|
||||
by 0x........: main (mempool.c:148)
|
||||
|
||||
|
||||
10 bytes in 1 blocks are definitely lost in loss record 1 of 5
|
||||
10 bytes in 1 blocks are definitely lost in loss record ... of ...
|
||||
at 0x........: allocate (mempool.c:99)
|
||||
by 0x........: test (mempool.c:135)
|
||||
by 0x........: main (mempool.c:148)
|
||||
|
||||
|
||||
10 bytes in 1 blocks are definitely lost in loss record 2 of 5
|
||||
10 bytes in 1 blocks are definitely lost in loss record ... of ...
|
||||
at 0x........: allocate (mempool.c:99)
|
||||
by 0x........: test (mempool.c:115)
|
||||
by 0x........: main (mempool.c:148)
|
||||
|
||||
|
||||
20 bytes in 1 blocks are definitely lost in loss record 4 of 5
|
||||
20 bytes in 1 blocks are definitely lost in loss record ... of ...
|
||||
at 0x........: allocate (mempool.c:99)
|
||||
by 0x........: test (mempool.c:116)
|
||||
by 0x........: main (mempool.c:148)
|
||||
|
||||
|
||||
48 (32 direct, 16 indirect) bytes in 1 blocks are definitely lost in loss record 5 of 5
|
||||
48 (32 direct, 16 indirect) bytes in 1 blocks are definitely lost in loss record ... of ...
|
||||
at 0x........: malloc (vg_replace_malloc.c:...)
|
||||
by 0x........: make_pool (mempool.c:37)
|
||||
by 0x........: test (mempool.c:111)
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
|
||||
1,000 bytes in 1 blocks are definitely lost in loss record 1 of 1
|
||||
1,000 bytes in 1 blocks are definitely lost in loss record ... of ...
|
||||
at 0x........: malloc (vg_replace_malloc.c:...)
|
||||
by 0x........: main (nanoleak.c:6)
|
||||
|
||||
@ -1,3 +1,2 @@
|
||||
vgopts: --leak-check=yes -q
|
||||
prog: nanoleak
|
||||
stderr_filter: filter_leak_check_size
|
||||
|
||||
@ -1,3 +1,2 @@
|
||||
vgopts: --leak-check=yes --suppressions=nanoleak.supp -q
|
||||
prog: nanoleak
|
||||
stderr_filter: filter_leak_check_size
|
||||
|
||||
@ -1,5 +1,6 @@
|
||||
/*
|
||||
Make sure that leak-check's pointer tracing avoids traps
|
||||
Make sure that leak-check's pointer tracing avoids traps, i.e. tricky
|
||||
memory areas where it could crash if not careful.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
@ -45,14 +46,16 @@ int main()
|
||||
}
|
||||
|
||||
ptrs = malloc(nptrs * sizeof(char *));
|
||||
for(i = 0; i < nptrs; i++)
|
||||
for (i = 0; i < nptrs; i++)
|
||||
ptrs[i] = (char *)((long)i << stepbits);
|
||||
|
||||
/* lay some traps */
|
||||
/* non-RWX memory, and MAP_NORESERVE if present */
|
||||
map = mmap(0, stepsize * 2, PROT_NONE, MAP_PRIVATE|MAP_NORESERVE|MAP_ANONYMOUS, -1, 0);
|
||||
if (map == (char *)-1)
|
||||
perror("trap 1 failed");
|
||||
|
||||
/* write-only memory, and MAP_NORESERVE if supported */
|
||||
map = mmap(0, stepsize * 2, PROT_WRITE, MAP_PRIVATE|MAP_NORESERVE|MAP_ANONYMOUS, -1, 0);
|
||||
if (map == (char *)-1)
|
||||
perror("trap 2 failed");
|
||||
@ -60,12 +63,12 @@ int main()
|
||||
/* non-zero mmap of a zero-length file -> SIGBUS */
|
||||
fd = open("./pointer-trace-test-file", O_RDWR | O_CREAT | O_EXCL, 0600);
|
||||
unlink("./pointer-trace-test-file");
|
||||
|
||||
map = mmap(0, stepsize * 2, PROT_WRITE|PROT_READ, MAP_PRIVATE, fd, 0);
|
||||
if (map == (char *)-1)
|
||||
perror("trap 3 failed");
|
||||
//printf("trap 3 = %p-%p\n", map, map+stepsize*2);
|
||||
|
||||
/* unmapped memory that's marked as defined */
|
||||
map = mmap(0, 256*1024, PROT_NONE, MAP_PRIVATE|MAP_NORESERVE|MAP_ANONYMOUS, -1, 0);
|
||||
if (map == (char *)-1)
|
||||
perror("trap 4 failed");
|
||||
@ -76,7 +79,11 @@ int main()
|
||||
|
||||
VALGRIND_DO_LEAK_CHECK;
|
||||
|
||||
ptrs = 0;
|
||||
free(ptrs);
|
||||
|
||||
// We deliberately make a leak, it'll be obvious if something went
|
||||
// wrong because the message won't be printed.
|
||||
ptrs = malloc(1000);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -1,28 +1,4 @@
|
||||
|
||||
searching for pointers to 1 not-freed blocks.
|
||||
checked ... bytes.
|
||||
|
||||
LEAK SUMMARY:
|
||||
definitely lost: 0 bytes in 0 blocks.
|
||||
possibly lost: 0 bytes in 0 blocks.
|
||||
still reachable: 1,048,576 bytes in 1 blocks.
|
||||
suppressed: 0 bytes in 0 blocks.
|
||||
Reachable blocks (those to which a pointer was found) are not shown.
|
||||
To see them, rerun with: --leak-check=full --show-reachable=yes
|
||||
|
||||
ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)
|
||||
malloc/free: in use at exit: 1,048,576 bytes in 1 blocks.
|
||||
malloc/free: 1 allocs, 0 frees, 1,048,576 bytes allocated.
|
||||
For counts of detected errors, rerun with: -v
|
||||
searching for pointers to 1 not-freed blocks.
|
||||
checked ... bytes.
|
||||
|
||||
1,048,576 bytes in 1 blocks are definitely lost in loss record 1 of 1
|
||||
1,000 bytes in 1 blocks are definitely lost in loss record ... of ...
|
||||
at 0x........: malloc (vg_replace_malloc.c:...)
|
||||
by 0x........: main (pointer-trace.c:47)
|
||||
|
||||
LEAK SUMMARY:
|
||||
definitely lost: 1,048,576 bytes in 1 blocks.
|
||||
possibly lost: 0 bytes in 0 blocks.
|
||||
still reachable: 0 bytes in 0 blocks.
|
||||
suppressed: 0 bytes in 0 blocks.
|
||||
by 0x........: main (pointer-trace.c:86)
|
||||
|
||||
@ -1,32 +0,0 @@
|
||||
|
||||
searching for pointers to 2 not-freed blocks.
|
||||
checked ... bytes.
|
||||
|
||||
LEAK SUMMARY:
|
||||
definitely lost: 0 bytes in 0 blocks.
|
||||
indirectly lost: 0 bytes in 0 blocks.
|
||||
possibly lost: 0 bytes in 0 blocks.
|
||||
still reachable: 1,048,600 bytes in 2 blocks.
|
||||
suppressed: 0 bytes in 0 blocks.
|
||||
Reachable blocks (those to which a pointer was found) are not shown.
|
||||
To see them, rerun with: --leak-check=full --show-reachable=yes
|
||||
|
||||
ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)
|
||||
malloc/free: in use at exit: 1,048,576 bytes in 1 blocks.
|
||||
malloc/free: 2 allocs, 1 frees, 1,048,600 bytes allocated.
|
||||
For counts of detected errors, rerun with: -v
|
||||
searching for pointers to 1 not-freed blocks.
|
||||
checked ... bytes.
|
||||
|
||||
1,048,576 bytes in 1 blocks are definitely lost in loss record 1 of 1
|
||||
at 0x........: malloc (vg_replace_malloc.c:...)
|
||||
by 0x........: main (pointer-trace.c:24)
|
||||
|
||||
LEAK SUMMARY:
|
||||
definitely lost: 1,048,576 bytes in 1 blocks.
|
||||
indirectly lost: 0 bytes in 0 blocks.
|
||||
possibly lost: 0 bytes in 0 blocks.
|
||||
still reachable: 0 bytes in 0 blocks.
|
||||
suppressed: 0 bytes in 0 blocks.
|
||||
Reachable blocks (those to which a pointer was found) are not shown.
|
||||
To see them, rerun with: --leak-check=full --show-reachable=yes
|
||||
@ -1,30 +0,0 @@
|
||||
|
||||
searching for pointers to 1 not-freed blocks.
|
||||
checked ... bytes.
|
||||
|
||||
LEAK SUMMARY:
|
||||
definitely lost: 0 bytes in 0 blocks.
|
||||
possibly lost: 0 bytes in 0 blocks.
|
||||
still reachable: 1,048,576 bytes in 1 blocks.
|
||||
suppressed: 0 bytes in 0 blocks.
|
||||
Reachable blocks (those to which a pointer was found) are not shown.
|
||||
To see them, rerun with: --leak-check=full --show-reachable=yes
|
||||
|
||||
ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)
|
||||
malloc/free: in use at exit: 1,048,576 bytes in 1 blocks.
|
||||
malloc/free: 1 allocs, 0 frees, 1,048,576 bytes allocated.
|
||||
For counts of detected errors, rerun with: -v
|
||||
searching for pointers to 1 not-freed blocks.
|
||||
checked ... bytes.
|
||||
|
||||
1,048,576 bytes in 1 blocks are possibly lost in loss record 1 of 1
|
||||
at 0x........: malloc (vg_replace_malloc.c:...)
|
||||
by 0x........: main (pointer-trace.c:24)
|
||||
|
||||
LEAK SUMMARY:
|
||||
definitely lost: 0 bytes in 0 blocks.
|
||||
possibly lost: 1,048,576 bytes in 1 blocks.
|
||||
still reachable: 0 bytes in 0 blocks.
|
||||
suppressed: 0 bytes in 0 blocks.
|
||||
Reachable blocks (those to which a pointer was found) are not shown.
|
||||
To see them, rerun with: --leak-check=full --show-reachable=yes
|
||||
@ -1,30 +0,0 @@
|
||||
|
||||
searching for pointers to 1 not-freed blocks.
|
||||
checked ... bytes.
|
||||
|
||||
LEAK SUMMARY:
|
||||
definitely lost: 0 bytes in 0 blocks.
|
||||
possibly lost: 0 bytes in 0 blocks.
|
||||
still reachable: 2,097,152 bytes in 1 blocks.
|
||||
suppressed: 0 bytes in 0 blocks.
|
||||
Reachable blocks (those to which a pointer was found) are not shown.
|
||||
To see them, rerun with: --leak-check=full --show-reachable=yes
|
||||
|
||||
ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)
|
||||
malloc/free: in use at exit: 2,097,152 bytes in 1 blocks.
|
||||
malloc/free: 1 allocs, 0 frees, 2,097,152 bytes allocated.
|
||||
For counts of detected errors, rerun with: -v
|
||||
searching for pointers to 1 not-freed blocks.
|
||||
checked ... bytes.
|
||||
|
||||
2,097,152 bytes in 1 blocks are definitely lost in loss record 1 of 1
|
||||
at 0x........: malloc (vg_replace_malloc.c:...)
|
||||
by 0x........: main (pointer-trace.c:24)
|
||||
|
||||
LEAK SUMMARY:
|
||||
definitely lost: 2,097,152 bytes in 1 blocks.
|
||||
possibly lost: 0 bytes in 0 blocks.
|
||||
still reachable: 0 bytes in 0 blocks.
|
||||
suppressed: 0 bytes in 0 blocks.
|
||||
Reachable blocks (those to which a pointer was found) are not shown.
|
||||
To see them, rerun with: --leak-check=full --show-reachable=yes
|
||||
@ -1,3 +1,2 @@
|
||||
prog: pointer-trace
|
||||
vgopts: --leak-check=yes
|
||||
stderr_filter: filter_leak_check_size
|
||||
vgopts: -q --leak-check=yes
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
|
||||
1,000 bytes in 1,000 blocks are definitely lost in loss record 1 of 1
|
||||
1,000 bytes in 1,000 blocks are definitely lost in loss record ... of ...
|
||||
at 0x........: malloc (vg_replace_malloc.c:...)
|
||||
by 0x........: test (trivialleak.c:8)
|
||||
by 0x........: main (trivialleak.c:12)
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
|
||||
999 bytes in 999 blocks are definitely lost in loss record 2 of 2
|
||||
999 bytes in 999 blocks are definitely lost in loss record ... of ...
|
||||
at 0x........: malloc (vg_replace_malloc.c:...)
|
||||
by 0x........: test (trivialleak.c:8)
|
||||
by 0x........: main (trivialleak.c:12)
|
||||
|
||||
@ -1,3 +1,2 @@
|
||||
vgopts: --leak-check=yes -q
|
||||
prog: trivialleak
|
||||
stderr_filter: filter_leak_check_size
|
||||
|
||||
@ -382,7 +382,7 @@
|
||||
<unique>0x........</unique>
|
||||
<tid>...</tid>
|
||||
<kind>Leak_DefinitelyLost</kind>
|
||||
<what>396 bytes in 1 blocks are definitely lost in loss record 1 of 1</what>
|
||||
<what>396 bytes in 1 blocks are definitely lost in loss record ... of ...</what>
|
||||
<leakedbytes>396</leakedbytes>
|
||||
<leakedblocks>1</leakedblocks>
|
||||
<stack>
|
||||
|
||||
@ -382,7 +382,7 @@
|
||||
<unique>0x........</unique>
|
||||
<tid>...</tid>
|
||||
<kind>Leak_DefinitelyLost</kind>
|
||||
<what>396 bytes in 1 blocks are definitely lost in loss record 1 of 1</what>
|
||||
<what>396 bytes in 1 blocks are definitely lost in loss record ... of ...</what>
|
||||
<leakedbytes>396</leakedbytes>
|
||||
<leakedblocks>1</leakedblocks>
|
||||
<stack>
|
||||
|
||||
@ -382,7 +382,7 @@
|
||||
<unique>0x........</unique>
|
||||
<tid>...</tid>
|
||||
<kind>Leak_DefinitelyLost</kind>
|
||||
<what>396 bytes in 1 blocks are definitely lost in loss record 1 of 1</what>
|
||||
<what>396 bytes in 1 blocks are definitely lost in loss record ... of ...</what>
|
||||
<leakedbytes>396</leakedbytes>
|
||||
<leakedblocks>1</leakedblocks>
|
||||
<stack>
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user