Add a new heuristic 'length64' to detect interior pointers
pointing at offset 64bit of a block, when the first 8 bytes contains
the block size - 8. This is e.g. used by sqlite3MemMalloc.
Patch by Matthias Schwarzott (with small modif)
git-svn-id: svn://svn.valgrind.org/valgrind/trunk@14179 a5019735-40e9-0310-863c-91ae7b9d1cf9
diff --git a/memcheck/mc_leakcheck.c b/memcheck/mc_leakcheck.c
index 670d89f..cb8abd1 100644
--- a/memcheck/mc_leakcheck.c
+++ b/memcheck/mc_leakcheck.c
@@ -594,6 +594,7 @@
switch(h) {
case LchNone: return "none";
case LchStdString: return "stdstring";
+ case LchLength64: return "length64";
case LchNewArray: return "newarray";
case LchMultipleInheritance: return "multipleinheritance";
default: return "???invalid heuristic???";
@@ -672,6 +673,16 @@
return False;
}
+// true if a is properly aligned and points to 64bits of valid memory
+static Bool is_valid_aligned_ULong ( Addr a )
+{
+ if (sizeof(Word) == 8)
+ return MC_(is_valid_aligned_word)(a);
+
+ return MC_(is_valid_aligned_word)(a)
+ && MC_(is_valid_aligned_word)(a + 4);
+}
+
// If ch is heuristically reachable via an heuristic member of heur_set,
// returns this heuristic.
// If ch cannot be considered reachable using one of these heuristics,
@@ -712,6 +723,23 @@
}
}
+ if (HiS(LchLength64, heur_set)) {
+ // Detects inner pointers that point at 64bit offset (8 bytes) into a
+ // block following the length of the remaining as 64bit number
+ // (=total block size - 8).
+ // This is used e.g. by sqlite for tracking the total size of allocated
+ // memory.
+ // Note that on 64bit platforms, a block matching LchLength64 will
+ // also be matched by LchNewArray.
+ if ( ptr == ch->data + sizeof(ULong)
+ && is_valid_aligned_ULong(ch->data)) {
+ const ULong size = *((ULong*)ch->data);
+ if (size > 0 && (ch->szB - sizeof(ULong)) == size) {
+ return LchLength64;
+ }
+ }
+ }
+
if (HiS(LchNewArray, heur_set)) {
// Detects inner pointers at second word of new[] array, following
// a plausible nr of elements.
@@ -1058,7 +1086,7 @@
MC_(pp_describe_addr) (ptr);
if (lc_is_a_chunk_ptr(addr, &ch_no, &ch, &ex) ) {
Int h;
- for (h = LchStdString; h <= LchMultipleInheritance; h++) {
+ for (h = LchStdString; h < N_LEAK_CHECK_HEURISTICS; h++) {
if (heuristic_reachedness(addr, ch, ex, H2S(h)) == h) {
VG_(umsg)("block at %#lx considered reachable "
"by ptr %#lx using %s heuristic\n",