|
From: <sv...@va...> - 2005-04-27 22:46:40
|
Author: sewardj
Date: 2005-04-27 23:46:36 +0100 (Wed, 27 Apr 2005)
New Revision: 3577
Modified:
trunk/memcheck/mac_leakcheck.c
trunk/memcheck/mac_shared.h
trunk/memcheck/mc_main.c
Log:
Reinstate the leak checker; it works at least on x86.
Modified: trunk/memcheck/mac_leakcheck.c
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
--- trunk/memcheck/mac_leakcheck.c 2005-04-27 11:40:27 UTC (rev 3576)
+++ trunk/memcheck/mac_leakcheck.c 2005-04-27 22:46:36 UTC (rev 3577)
@@ -175,8 +175,8 @@
static Addr lc_max_mallocd_addr;
static SizeT lc_scanned;
=20
-static Bool (*lc_is_valid_chunk) (UInt chunk);
-static Bool (*lc_is_valid_address)(Addr addr);
+static Bool (*lc_is_within_valid_secondary) (Addr addr);
+static Bool (*lc_is_valid_aligned_word) (Addr addr);
=20
static const Char *pp_lossmode(Reachedness lossmode)
{
@@ -324,7 +324,6 @@
cliques, and clique is the index of the current clique leader. */
static void _lc_scan_memory(Addr start, SizeT len, Int clique)
{
-#if 0
Addr ptr =3D ROUNDUP(start, sizeof(Addr));
Addr end =3D ROUNDDN(start+len, sizeof(Addr));
vki_sigset_t sigmask;
@@ -340,11 +339,11 @@
!VG_(is_addressable)(ptr, sizeof(Addr), VKI_PROT_READ))
ptr =3D PGROUNDUP(ptr+1); /* first page bad */
=20
- while(ptr < end) {
+ while (ptr < end) {
Addr addr;
=20
/* Skip invalid chunks */
- if (!(*lc_is_valid_chunk)(PM_IDX(ptr))) {
+ if (!(*lc_is_within_valid_secondary)(ptr)) {
ptr =3D ROUNDUP(ptr+1, SECONDARY_SIZE);
continue;
}
@@ -357,7 +356,7 @@
}
=20
if (__builtin_setjmp(memscan_jmpbuf) =3D=3D 0) {
- if ((*lc_is_valid_address)(ptr)) {
+ if ((*lc_is_valid_aligned_word)(ptr)) {
addr =3D *(Addr *)ptr;
_lc_markstack_push(addr, clique);
} else if (0 && VG_DEBUG_LEAKCHECK)
@@ -374,7 +373,6 @@
=20
VG_(sigprocmask)(VKI_SIG_SETMASK, &sigmask, NULL);
VG_(set_fault_catcher)(NULL);
-#endif
}
=20
=20
@@ -570,8 +568,8 @@
*/
void MAC_(do_detect_memory_leaks) (
ThreadId tid, LeakCheckMode mode,
- Bool (*is_valid_64k_chunk) ( UInt ),
- Bool (*is_valid_address) ( Addr )
+ Bool (*is_within_valid_secondary) ( Addr ),
+ Bool (*is_valid_aligned_word) ( Addr )
)
{
Int i;
@@ -622,8 +620,8 @@
}
lc_markstack_top =3D -1;
=20
- lc_is_valid_chunk =3D is_valid_64k_chunk;
- lc_is_valid_address =3D is_valid_address;
+ lc_is_within_valid_secondary =3D is_within_valid_secondary;
+ lc_is_valid_aligned_word =3D is_valid_aligned_word;
=20
lc_scanned =3D 0;
=20
Modified: trunk/memcheck/mac_shared.h
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
--- trunk/memcheck/mac_shared.h 2005-04-27 11:40:27 UTC (rev 3576)
+++ trunk/memcheck/mac_shared.h 2005-04-27 22:46:36 UTC (rev 3577)
@@ -203,6 +203,12 @@
/* expand 1 bit -> 8 */
#define BIT_TO_BYTE(b) ((~(((UChar)(b) & 1) - 1)) & 0xFF)
=20
+/* The number of entries in the primary map can be altered. However
+ we hardwire the assumption that each secondary map covers precisely
+ 64k of address space. */
+#define SECONDARY_SIZE 65536 /* DO NOT CHANGE */
+#define SECONDARY_MASK (SECONDARY_SIZE-1) /* DO NOT CHANGE */
+
//zz #define SECONDARY_SHIFT 16
//zz #define SECONDARY_SIZE (1 << SECONDARY_SHIFT)
//zz #define SECONDARY_MASK (SECONDARY_SIZE - 1)
@@ -407,8 +413,8 @@
=20
extern void MAC_(do_detect_memory_leaks) (
ThreadId tid, LeakCheckMode mode,
- Bool (*is_valid_64k_chunk) ( UInt ),
- Bool (*is_valid_address) ( Addr )
+ Bool (*is_within_valid_secondary) ( Addr ),
+ Bool (*is_valid_aligned_word) ( Addr )
);
=20
extern VGA_REGPARM(1) void MAC_(new_mem_stack_4) ( Addr old_ESP );
Modified: trunk/memcheck/mc_main.c
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
--- trunk/memcheck/mc_main.c 2005-04-27 11:40:27 UTC (rev 3576)
+++ trunk/memcheck/mc_main.c 2005-04-27 22:46:36 UTC (rev 3577)
@@ -114,12 +114,6 @@
=20
/* --------------- Basic configuration --------------- */
=20
-/* The number of entries in the primary map can be altered. However
- we hardwire the assumption that each secondary map covers precisely
- 64k of address space. */
-#define SECONDARY_SIZE 65536 /* DO NOT CHANGE */
-#define SECONDARY_MASK (SECONDARY_SIZE-1) /* DO NOT CHANGE */
-
/* Only change this. N_PRIMARY_MAP *must* be a power of 2. */
#define N_PRIMARY_BITS 16
=20
@@ -210,12 +204,12 @@
=20
/* Find an entry in the auxiliary map. If an entry is found, move it
one step closer to the front of the array, then return its address.
- If an entry is not found, allocate one. Note carefully that
+ If an entry is not found, return NULL. Note carefully that
because a each call potentially rearranges the entries, each call
to this function invalidates ALL AuxMapEnt*s previously obtained by
calling this fn. =20
*/
-static AuxMapEnt* find_or_alloc_in_auxmap ( Addr a )
+static AuxMapEnt* maybe_find_in_auxmap ( Addr a )
{
UWord i;
tl_assert(a > MAX_PRIMARY_ADDRESS);
@@ -241,6 +235,23 @@
return &auxmap[i];
}
=20
+ return NULL;
+}
+
+
+/* Find an entry in the auxiliary map. If an entry is found, move it
+ one step closer to the front of the array, then return its address.
+ If an entry is not found, allocate one. Note carefully that
+ because a each call potentially rearranges the entries, each call
+ to this function invalidates ALL AuxMapEnt*s previously obtained by
+ calling this fn. =20
+*/
+static AuxMapEnt* find_or_alloc_in_auxmap ( Addr a )
+{
+ AuxMapEnt* am =3D maybe_find_in_auxmap(a);
+ if (am)
+ return am;
+
/* We didn't find it. Hmm. This is a new piece of address space.
We'll need to allocate a new AuxMap entry for it. */
if (auxmap_used >=3D auxmap_size) {
@@ -281,6 +292,23 @@
}
}
=20
+/* If 'a' has a SecMap, produce it. Else produce NULL. But don't
+ allocate one if one doesn't already exist. This is used by the
+ leak checker.
+*/
+static SecMap* maybe_get_secmap_for ( Addr a )
+{
+ if (a <=3D MAX_PRIMARY_ADDRESS) {
+ UWord pm_off =3D a >> 16;
+ return primary_map[ pm_off ];
+ } else {
+ AuxMapEnt* am =3D maybe_find_in_auxmap(a);
+ return am ? am->sm : NULL;
+ }
+}
+
+
+
/* Produce the secmap for 'a', either from the primary map or by
ensuring there is an entry for it in the aux primary map. The
secmap may not be a distinguished one, since the caller will want
@@ -1655,55 +1683,59 @@
//zz=20
//zz return 1;
//zz }
-//zz=20
-//zz=20
-//zz /*------------------------------------------------------------*/
-//zz /*--- Detecting leaked (unreachable) malloc'd blocks. ---*/
-//zz /*------------------------------------------------------------*/
-//zz=20
-//zz /* For the memory leak detector, say whether an entire 64k chunk of
-//zz address space is possibly in use, or not. If in doubt return
-//zz True.
-//zz */
-//zz static
-//zz Bool mc_is_valid_64k_chunk ( UInt chunk_number )
-//zz {
-//zz tl_assert(chunk_number >=3D 0 && chunk_number < PRIMARY_SIZE);
-//zz if (primary_map[chunk_number] =3D=3D DSM_NOTADDR) {
-//zz /* Definitely not in use. */
-//zz return False;
-//zz } else {
-//zz return True;
-//zz }
-//zz }
-//zz=20
-//zz=20
-//zz /* For the memory leak detector, say whether or not a given word
-//zz address is to be regarded as valid. */
-//zz static
-//zz Bool mc_is_valid_address ( Addr a )
-//zz {
-//zz UInt vbytes;
-//zz UChar abits;
-//zz tl_assert(VG_IS_4_ALIGNED(a));
-//zz abits =3D get_abits4_ALIGNED(a);
-//zz vbytes =3D get_vbytes4_ALIGNED(a);
-//zz if (abits =3D=3D VGM_NIBBLE_VALID && vbytes =3D=3D VGM_WORD_VALI=
D) {
-//zz return True;
-//zz } else {
-//zz return False;
-//zz }
-//zz }
=20
=20
+/*------------------------------------------------------------*/
+/*--- Detecting leaked (unreachable) malloc'd blocks. ---*/
+/*------------------------------------------------------------*/
+
+/* For the memory leak detector, say whether an entire 64k chunk of
+ address space is possibly in use, or not. If in doubt return
+ True.
+*/
+static
+Bool mc_is_within_valid_secondary ( Addr a )
+{
+ SecMap* sm =3D maybe_get_secmap_for ( a );
+ if (sm =3D=3D NULL || sm =3D=3D &sm_distinguished[SM_DIST_NOACCESS]) =
{
+ /* Definitely not in use. */
+ return False;
+ } else {
+ return True;
+ }
+}
+
+
+/* For the memory leak detector, say whether or not a given word
+ address is to be regarded as valid. */
+static
+Bool mc_is_valid_aligned_word ( Addr a )
+{
+ tl_assert(sizeof(UWord) =3D=3D 4 || sizeof(UWord) =3D=3D 8);
+ if (sizeof(UWord) =3D=3D 4) {
+ tl_assert(VG_IS_4_ALIGNED(a));
+ } else {
+ tl_assert(VG_IS_8_ALIGNED(a));
+ }
+ if (mc_check_readable( a, sizeof(UWord), NULL ) =3D=3D MC_Ok) {
+ return True;
+ } else {
+ return False;
+ }
+}
+
+
/* Leak detector for this tool. We don't actually do anything, merely
run the generic leak detector with suitable parameters for this
tool. */
static void mc_detect_memory_leaks ( ThreadId tid, LeakCheckMode mode )
{
- VG_(printf)("memcheck: leak detection currently disabled\n");
- // MAC_(do_detect_memory_leaks) (=20
- // tid, mode, mc_is_valid_64k_chunk, mc_is_valid_address );
+ MAC_(do_detect_memory_leaks) (=20
+ tid,=20
+ mode,=20
+ mc_is_within_valid_secondary,=20
+ mc_is_valid_aligned_word=20
+ );
}
=20
=20
|