|
From: <sv...@va...> - 2009-07-15 02:32:09
|
Author: njn
Date: 2009-07-15 03:31:45 +0100 (Wed, 15 Jul 2009)
New Revision: 10455
Log:
Ignore MALLOCLIKE_BLOCK/FREELIKE_BLOCK if addr==0. Fixes bug 137073. DRD
now has its own copy of custom_alloc.c which is a little different to
Memcheck's; making them both work with the same version was too difficult.
Added:
trunk/drd/tests/custom_alloc.c
Modified:
trunk/coregrind/m_scheduler/scheduler.c
trunk/drd/tests/Makefile.am
trunk/drd/tests/custom_alloc.vgtest
trunk/include/valgrind.h
trunk/memcheck/tests/custom_alloc.c
Modified: trunk/coregrind/m_scheduler/scheduler.c
===================================================================
--- trunk/coregrind/m_scheduler/scheduler.c 2009-07-14 16:45:48 UTC (rev 10454)
+++ trunk/coregrind/m_scheduler/scheduler.c 2009-07-15 02:31:45 UTC (rev 10455)
@@ -1465,7 +1465,18 @@
SET_CLREQ_RETVAL( tid, 0 ); /* return value is meaningless */
break;
+ case VG_USERREQ__MALLOCLIKE_BLOCK:
+ case VG_USERREQ__FREELIKE_BLOCK:
+ // Ignore them if the addr is NULL; otherwise pass onto the tool.
+ if (!arg[1]) {
+ SET_CLREQ_RETVAL( tid, 0 ); /* return value is meaningless */
+ break;
+ } else {
+ goto my_default;
+ }
+
default:
+ my_default:
if (os_client_request(tid, arg)) {
// do nothing, os_client_request() handled it
} else if (VG_(needs).client_requests) {
Modified: trunk/drd/tests/Makefile.am
===================================================================
--- trunk/drd/tests/Makefile.am 2009-07-14 16:45:48 UTC (rev 10454)
+++ trunk/drd/tests/Makefile.am 2009-07-15 02:31:45 UTC (rev 10455)
@@ -222,6 +222,7 @@
check_PROGRAMS = \
+ custom_alloc \
fp_race \
hold_lock \
linuxthreads_det \
Added: trunk/drd/tests/custom_alloc.c
===================================================================
--- trunk/drd/tests/custom_alloc.c (rev 0)
+++ trunk/drd/tests/custom_alloc.c 2009-07-15 02:31:45 UTC (rev 10455)
@@ -0,0 +1,90 @@
+#include <unistd.h>
+#include "tests/sys_mman.h"
+#include <assert.h>
+#include <stdlib.h>
+
+#include "../drd.h"
+
+#define SUPERBLOCK_SIZE 100000
+
+//-------------------------------------------------------------------------
+// Allocator
+//-------------------------------------------------------------------------
+
+void* get_superblock(void)
+{
+ void* p = mmap( 0, SUPERBLOCK_SIZE, PROT_READ|PROT_WRITE|PROT_EXEC,
+ MAP_PRIVATE|MAP_ANONYMOUS, -1, 0 );
+
+ assert(p != ((void*)(-1)));
+
+ return p;
+}
+
+// has a redzone
+static void* custom_alloc(int size)
+{
+#define RZ 8
+ static void* hp = 0; // current heap pointer
+ static void* hp_lim = 0; // maximum usable byte in current block
+ int size2 = size + RZ*2;
+ void* p;
+
+ if (hp + size2 > hp_lim) {
+ hp = get_superblock();
+ hp_lim = hp + SUPERBLOCK_SIZE - 1;
+ }
+
+ p = hp + RZ;
+ hp += size2;
+
+ VALGRIND_MALLOCLIKE_BLOCK( p, size, RZ, /*is_zeroed*/1 );
+ return (void*)p;
+}
+
+static void custom_free(void* p)
+{
+ // don't actually free any memory... but mark it as freed
+ VALGRIND_FREELIKE_BLOCK( p, RZ );
+}
+#undef RZ
+
+
+
+//-------------------------------------------------------------------------
+// Rest
+//-------------------------------------------------------------------------
+
+void make_leak(void)
+{
+ int* array2 = custom_alloc(sizeof(int) * 10);
+ array2 = 0; // leak
+ return;
+}
+
+int main(void)
+{
+ int* array;
+ int* array3;
+
+ array = custom_alloc(sizeof(int) * 10);
+ array[8] = 8;
+ array[9] = 8;
+ array[10] = 10; // invalid write (ok w/o MALLOCLIKE -- in superblock)
+
+ custom_free(array); // ok
+
+ custom_free(NULL); // invalid free (ok without MALLOCLIKE)
+
+ array3 = malloc(sizeof(int) * 10);
+ custom_free(array3); // mismatched free (ok without MALLOCLIKE)
+
+ make_leak();
+ return array[0]; // use after free (ok without MALLOCLIKE)
+ // (nb: initialised because is_zeroed==1 above)
+ // unfortunately not identified as being in a free'd
+ // block because the freeing of the block and shadow
+ // chunk isn't postponed.
+
+ // leak from make_leak()
+}
Modified: trunk/drd/tests/custom_alloc.vgtest
===================================================================
--- trunk/drd/tests/custom_alloc.vgtest 2009-07-14 16:45:48 UTC (rev 10454)
+++ trunk/drd/tests/custom_alloc.vgtest 2009-07-15 02:31:45 UTC (rev 10455)
@@ -1 +1 @@
-prog: ../../memcheck/tests/custom_alloc
+prog: custom_alloc
Modified: trunk/include/valgrind.h
===================================================================
--- trunk/include/valgrind.h 2009-07-14 16:45:48 UTC (rev 10454)
+++ trunk/include/valgrind.h 2009-07-15 02:31:45 UTC (rev 10455)
@@ -3886,6 +3886,8 @@
superblocks, rather than mmap() or brk(), this will not work properly --
you'll likely get assertion failures during leak detection. This is
because Valgrind doesn't like seeing overlapping heap blocks. Sorry.
+
+ Ignored if addr == 0.
*/
#define VALGRIND_MALLOCLIKE_BLOCK(addr, sizeB, rzB, is_zeroed) \
{unsigned int _qzz_res; \
@@ -3894,7 +3896,9 @@
addr, sizeB, rzB, is_zeroed, 0); \
}
-/* See the comment for VALGRIND_MALLOCLIKE_BLOCK for details. */
+/* See the comment for VALGRIND_MALLOCLIKE_BLOCK for details.
+ Ignored if addr == 0.
+*/
#define VALGRIND_FREELIKE_BLOCK(addr, rzB) \
{unsigned int _qzz_res; \
VALGRIND_DO_CLIENT_REQUEST(_qzz_res, 0, \
Modified: trunk/memcheck/tests/custom_alloc.c
===================================================================
--- trunk/memcheck/tests/custom_alloc.c 2009-07-14 16:45:48 UTC (rev 10454)
+++ trunk/memcheck/tests/custom_alloc.c 2009-07-15 02:31:45 UTC (rev 10455)
@@ -70,8 +70,8 @@
int main(void)
{
- int* array;
- int* array3;
+ int *array, *array3;
+ int x;
array = custom_alloc(sizeof(int) * 10);
array[8] = 8;
@@ -80,17 +80,24 @@
custom_free(array); // ok
- custom_free(NULL); // invalid free (ok without MALLOCLIKE)
+ custom_free((void*)0x1); // invalid free
array3 = malloc(sizeof(int) * 10);
custom_free(array3); // mismatched free (ok without MALLOCLIKE)
make_leak();
- return array[0]; // use after free (ok without MALLOCLIKE/MAKE_MEM_NOACCESS)
+ x = array[0]; // use after free (ok without MALLOCLIKE/MAKE_MEM_NOACCESS)
// (nb: initialised because is_zeroed==1 above)
// unfortunately not identified as being in a free'd
// block because the freeing of the block and shadow
// chunk isn't postponed.
+
+ // Bug 137073: passing 0 to MALLOCLIKE_BLOCK was causing an assertion
+ // failure. Test for this (and likewise for FREELIKE_BLOCK).
+ //VALGRIND_MALLOCLIKE_BLOCK(0,0,0,0);
+ //VALGRIND_FREELIKE_BLOCK(0,0);
+ return x;
+
// leak from make_leak()
}
|