mirror of
https://github.com/Zenithsiz/ftmemsim-valgrind.git
synced 2026-02-03 10:05:29 +00:00
- Removed leakotron. It was not a very useful test, and hard to make
portable. - Rewrote leak-tree to be deterministic and clearer. git-svn-id: svn://svn.valgrind.org/valgrind/trunk@9372
This commit is contained in:
parent
0e1eb4b6c9
commit
190ad4143e
@ -69,8 +69,6 @@ EXTRA_DIST = $(noinst_SCRIPTS) \
|
||||
leak-pool-4.vgtest leak-pool-4.stderr.exp \
|
||||
leak-pool-5.vgtest leak-pool-5.stderr.exp \
|
||||
leak-tree.vgtest leak-tree.stderr.exp \
|
||||
leak-tree.stderr.exp2 leak-tree.stderr.exp64 \
|
||||
leakotron.vgtest leakotron.stdout.exp leakotron.stderr.exp \
|
||||
linux-syslog-syscall linux-syslog-syscall.stderr.exp \
|
||||
linux-syscalls-2007 linux-syscalls-2007.stderr.exp \
|
||||
long_namespace_xml.vgtest long_namespace_xml.stdout.exp \
|
||||
@ -190,7 +188,7 @@ check_PROGRAMS = \
|
||||
fprw fwrite inits inline \
|
||||
leak-0 \
|
||||
leak-cases \
|
||||
leak-cycle leak-pool leak-tree leakotron \
|
||||
leak-cycle leak-pool leak-tree \
|
||||
linux-syslog-syscall \
|
||||
linux-syscalls-2007 \
|
||||
long_namespace_xml \
|
||||
|
||||
@ -1,46 +1,71 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include "leak.h"
|
||||
#include "../memcheck.h"
|
||||
|
||||
struct foo {
|
||||
struct foo *l, *r;
|
||||
};
|
||||
/* We build this tree:
|
||||
|
||||
A
|
||||
/ \
|
||||
B C
|
||||
/ \ / \
|
||||
D E F G
|
||||
|
||||
Then we leak D and C-F-G.
|
||||
*/
|
||||
|
||||
struct foo *mk(struct foo *l, struct foo *r)
|
||||
typedef
|
||||
struct _Node {
|
||||
struct _Node *l;
|
||||
struct _Node *r;
|
||||
// Padding ensures the structu is the same size on 32-bit and 64-bit
|
||||
// machines.
|
||||
char padding[16 - 2*sizeof(struct _Node*)];
|
||||
} Node;
|
||||
|
||||
Node* mk(void)
|
||||
{
|
||||
struct foo *f = malloc(sizeof(*f));
|
||||
f->l = l;
|
||||
f->r = r;
|
||||
|
||||
return f;
|
||||
Node *x = malloc(sizeof(Node));
|
||||
x->l = NULL;
|
||||
x->r = NULL;
|
||||
return x;
|
||||
}
|
||||
|
||||
int main()
|
||||
// This is a definite root.
|
||||
Node* t;
|
||||
|
||||
void f(void)
|
||||
{
|
||||
struct foo *volatile a, *volatile b, *volatile c;
|
||||
// Building like this rather than "t = mk(mk(mk(NULL, NULL), ...)" seems to
|
||||
// help avoid leaving pointers on the stack to supposedly-leaked blocks.
|
||||
t = mk(); // A
|
||||
t->l = mk(); // B
|
||||
t->r = mk(); // C (48(16d,32i)/1 definitely leaked from here)
|
||||
t->l->l = mk(); // D (16/1 definitely leaked from here)
|
||||
t->l->r = mk(); // E
|
||||
t->r->l = mk(); // F
|
||||
t->r->r = mk(); // G
|
||||
|
||||
b = mk(mk(0, 0), 0);
|
||||
|
||||
/* Partially leaked tree structure */
|
||||
a = mk(mk(mk(mk(mk(0, 0), 0), mk(mk(0, 0), b)), mk(0, 0)), mk(0,0));
|
||||
|
||||
a = NULL;
|
||||
|
||||
VALGRIND_DO_LEAK_CHECK;
|
||||
|
||||
b = NULL; /* now leak old b */
|
||||
|
||||
/* Completely leaked, but part of the structure is shared */
|
||||
b = mk(0,0);
|
||||
b->l = b;
|
||||
b->r = b;
|
||||
|
||||
a = mk(b,b);
|
||||
c = mk(b,b);
|
||||
|
||||
a = b = c = 0;
|
||||
|
||||
VALGRIND_DO_LEAK_CHECK;
|
||||
|
||||
return 0;
|
||||
// Sever B->D, leaking D
|
||||
t->l->l = NULL;
|
||||
|
||||
// Sever A->C, leaking C-F-G
|
||||
t->r = NULL;
|
||||
}
|
||||
|
||||
int main(void)
|
||||
{
|
||||
DECLARE_LEAK_COUNTERS;
|
||||
|
||||
GET_INITIAL_LEAK_COUNTS;
|
||||
|
||||
// See leak-cases.c for why we do the work in f().
|
||||
f();
|
||||
|
||||
GET_FINAL_LEAK_COUNTS;
|
||||
|
||||
PRINT_LEAK_COUNTS(stderr);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
@ -1,52 +1,17 @@
|
||||
leaked: 64 bytes in 4 blocks
|
||||
dubious: 0 bytes in 0 blocks
|
||||
reachable: 48 bytes in 3 blocks
|
||||
suppressed: 0 bytes in 0 blocks
|
||||
|
||||
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 ... of ...
|
||||
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:25)
|
||||
|
||||
LEAK SUMMARY:
|
||||
definitely lost: 8 bytes in 1 blocks.
|
||||
indirectly lost: 64 bytes in 8 blocks.
|
||||
possibly lost: 0 bytes in 0 blocks.
|
||||
still reachable: 16 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
|
||||
searching for pointers to 14 not-freed blocks.
|
||||
checked ... bytes.
|
||||
by 0x........: mk (leak-tree.c:28)
|
||||
by 0x........: f (leak-tree.c:44)
|
||||
by 0x........: main (leak-tree.c:63)
|
||||
|
||||
|
||||
8 bytes in 1 blocks are definitely lost in loss record ... of ...
|
||||
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-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 ... 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 ... of ...
|
||||
at 0x........: malloc (vg_replace_malloc.c:...)
|
||||
by 0x........: mk (leak-tree.c:11)
|
||||
by 0x........: main (leak-tree.c:38)
|
||||
|
||||
LEAK SUMMARY:
|
||||
definitely lost: 24 bytes in 3 blocks.
|
||||
indirectly lost: 88 bytes in 11 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
|
||||
|
||||
ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)
|
||||
malloc/free: in use at exit: 112 bytes in 14 blocks.
|
||||
malloc/free: 14 allocs, 0 frees, 112 bytes allocated.
|
||||
For a detailed leak analysis, rerun with: --leak-check=yes
|
||||
For counts of detected errors, rerun with: -v
|
||||
by 0x........: mk (leak-tree.c:28)
|
||||
by 0x........: f (leak-tree.c:43)
|
||||
by 0x........: main (leak-tree.c:63)
|
||||
|
||||
@ -1,52 +0,0 @@
|
||||
|
||||
searching for pointers to 11 not-freed blocks.
|
||||
checked ... bytes.
|
||||
|
||||
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)
|
||||
|
||||
LEAK SUMMARY:
|
||||
definitely lost: 8 bytes in 1 blocks.
|
||||
indirectly lost: 0 bytes in 0 blocks.
|
||||
possibly lost: 0 bytes in 0 blocks.
|
||||
still reachable: 80 bytes in 10 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
|
||||
searching for pointers to 14 not-freed blocks.
|
||||
checked ... bytes.
|
||||
|
||||
|
||||
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 ... 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 ... of ...
|
||||
at 0x........: malloc (vg_replace_malloc.c:...)
|
||||
by 0x........: mk (leak-tree.c:11)
|
||||
by 0x........: main (leak-tree.c:25)
|
||||
|
||||
LEAK SUMMARY:
|
||||
definitely lost: 24 bytes in 3 blocks.
|
||||
indirectly lost: 32 bytes in 4 blocks.
|
||||
possibly lost: 0 bytes in 0 blocks.
|
||||
still reachable: 56 bytes in 7 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: 112 bytes in 14 blocks.
|
||||
malloc/free: 14 allocs, 0 frees, 112 bytes allocated.
|
||||
For a detailed leak analysis, rerun with: --leak-check=yes
|
||||
For counts of detected errors, rerun with: -v
|
||||
@ -1,52 +0,0 @@
|
||||
|
||||
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 ... of ...
|
||||
at 0x........: malloc (vg_replace_malloc.c:...)
|
||||
by 0x........: mk (leak-tree.c:11)
|
||||
by 0x........: main (leak-tree.c:25)
|
||||
|
||||
LEAK SUMMARY:
|
||||
definitely lost: 16 bytes in 1 blocks.
|
||||
indirectly lost: 64 bytes in 4 blocks.
|
||||
possibly lost: 0 bytes in 0 blocks.
|
||||
still reachable: 96 bytes in 6 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
|
||||
searching for pointers to 14 not-freed blocks.
|
||||
checked ... bytes.
|
||||
|
||||
|
||||
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 ... 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 ... of ...
|
||||
at 0x........: malloc (vg_replace_malloc.c:...)
|
||||
by 0x........: mk (leak-tree.c:11)
|
||||
by 0x........: main (leak-tree.c:25)
|
||||
|
||||
LEAK SUMMARY:
|
||||
definitely lost: 48 bytes in 3 blocks.
|
||||
indirectly lost: 64 bytes in 4 blocks.
|
||||
possibly lost: 0 bytes in 0 blocks.
|
||||
still reachable: 112 bytes in 7 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: 224 bytes in 14 blocks.
|
||||
malloc/free: 14 allocs, 0 frees, 224 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-tree
|
||||
vgopts: --leak-resolution=high
|
||||
vgopts: -q --leak-check=full --leak-resolution=high
|
||||
|
||||
@ -1,146 +0,0 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <assert.h>
|
||||
#include "../memcheck.h"
|
||||
#include "leak.h"
|
||||
|
||||
/*
|
||||
Incompetent memory management
|
||||
|
||||
Simulate what happens when trying to manage a dense brancy cyclic
|
||||
structure with refcounting.
|
||||
*/
|
||||
|
||||
static long bytes, blocks;
|
||||
|
||||
struct node {
|
||||
struct node *l, *r;
|
||||
int ref;
|
||||
};
|
||||
|
||||
static void ref(struct node *n)
|
||||
{
|
||||
if (n)
|
||||
n->ref++;
|
||||
}
|
||||
|
||||
static void unref(struct node *n)
|
||||
{
|
||||
if (n && --n->ref == 0) {
|
||||
bytes -= sizeof(*n);
|
||||
blocks--;
|
||||
free(n);
|
||||
}
|
||||
}
|
||||
|
||||
static struct node *alloc()
|
||||
{
|
||||
struct node *n = malloc(sizeof(*n));
|
||||
n->l = n->r = NULL;
|
||||
n->ref = 0;
|
||||
|
||||
bytes += sizeof(*n);
|
||||
blocks++;
|
||||
|
||||
return n;
|
||||
}
|
||||
|
||||
static void assign(struct node **np, struct node *n)
|
||||
{
|
||||
ref(n);
|
||||
unref(*np);
|
||||
|
||||
*np = n;
|
||||
}
|
||||
|
||||
static int rrange(int range)
|
||||
{
|
||||
long long ret = rand() * (long long)range;
|
||||
|
||||
return (int)(ret / RAND_MAX);
|
||||
}
|
||||
|
||||
#define ITER 100000
|
||||
#define N 1000
|
||||
|
||||
static struct node *nodes[N];
|
||||
|
||||
static struct node *mk()
|
||||
{
|
||||
int idx = rrange(N);
|
||||
struct node *n;
|
||||
|
||||
/*
|
||||
50% recycle
|
||||
25% alloc new
|
||||
25% return NULL
|
||||
*/
|
||||
if (rand() > RAND_MAX/2) {
|
||||
/* recycle existing block */
|
||||
n = nodes[idx];
|
||||
} else if (rand() > RAND_MAX/2) {
|
||||
/* alloc new block */
|
||||
n = alloc();
|
||||
assign(&n->l, mk());
|
||||
assign(&n->r, mk());
|
||||
} else {
|
||||
/* no block */
|
||||
n = NULL;
|
||||
}
|
||||
|
||||
assign(&nodes[idx], n);
|
||||
|
||||
return n;
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
int i;
|
||||
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 */
|
||||
GET_INITIAL_LEAK_COUNTS;
|
||||
|
||||
for (i = 0; i < ITER; i++) {
|
||||
mk();
|
||||
|
||||
if ((i % (ITER/10)) == 0) {
|
||||
if (0)
|
||||
printf("%ld living blocks, %ld bytes\n",
|
||||
blocks, bytes);
|
||||
//VALGRIND_DO_LEAK_CHECK;
|
||||
}
|
||||
}
|
||||
|
||||
/* "free all memory" */
|
||||
for (i = 0; i < N; i++)
|
||||
assign(&nodes[i], NULL);
|
||||
|
||||
|
||||
if (0)
|
||||
printf("FINISHED: %ld living blocks, %ld bytes\n",
|
||||
blocks, bytes);
|
||||
|
||||
GET_FINAL_LEAK_COUNTS;
|
||||
|
||||
total = L_bytes + D_bytes + R_bytes + S_bytes;
|
||||
|
||||
if (0) {
|
||||
PRINT_LEAK_COUNTS(stderr);
|
||||
}
|
||||
|
||||
if (R_bytes != 0)
|
||||
printf("FAILED: I freed everything, "
|
||||
"but there's still %ld bytes (in %ld blocks) reachable\n",
|
||||
R_bytes, R_blocks);
|
||||
else if (total != bytes)
|
||||
printf("FAILED: I count %ld bytes, leakcheck says %ld\n",
|
||||
bytes, total);
|
||||
else
|
||||
printf("PASS\n");
|
||||
return 0;
|
||||
}
|
||||
@ -1 +0,0 @@
|
||||
PASS
|
||||
@ -1,2 +0,0 @@
|
||||
prog: leakotron
|
||||
stderr_filter: ../../tests/filter_sink
|
||||
Loading…
x
Reference in New Issue
Block a user