]> git.ipfire.org Git - thirdparty/valgrind.git/commitdiff
Ignore MALLOCLIKE_BLOCK/FREELIKE_BLOCK if addr==0. Fixes bug 137073. DRD
authorNicholas Nethercote <njn@valgrind.org>
Wed, 15 Jul 2009 02:31:45 +0000 (02:31 +0000)
committerNicholas Nethercote <njn@valgrind.org>
Wed, 15 Jul 2009 02:31:45 +0000 (02:31 +0000)
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.

git-svn-id: svn://svn.valgrind.org/valgrind/trunk@10455

coregrind/m_scheduler/scheduler.c
drd/tests/Makefile.am
drd/tests/custom_alloc.c [new file with mode: 0644]
drd/tests/custom_alloc.vgtest
include/valgrind.h
memcheck/tests/custom_alloc.c

index 59f59686be83ff858f86cf0550c354c9f547bd7f..91bb20cd813e595ee6d3dd4cb78a9db21ca1794b 100644 (file)
@@ -1465,7 +1465,18 @@ void do_client_request ( ThreadId tid )
          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) {
index e4abf7b2c4cb5998f7b3ffbbf5ad39bd275d6574..f59180ee54e56697878ded533ae81a05dd20e1a7 100644 (file)
@@ -222,6 +222,7 @@ EXTRA_DIST =                                        \
 
 
 check_PROGRAMS =      \
+  custom_alloc        \
   fp_race             \
   hold_lock           \
   linuxthreads_det    \
diff --git a/drd/tests/custom_alloc.c b/drd/tests/custom_alloc.c
new file mode 100644 (file)
index 0000000..8032ba2
--- /dev/null
@@ -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()
+}
index 705903af0f5689e4ecc2d6137b4f42ee61061b53..2b8a1415428f7a2631fbe7b5b20968211d6a3f98 100644 (file)
@@ -1 +1 @@
-prog: ../../memcheck/tests/custom_alloc
+prog: custom_alloc
index 44c97391af60d0b3e053840e545030dc5ca8610b..bdb037c2de064ae21230e1cc6eab587b3a4430c9 100644 (file)
@@ -3886,6 +3886,8 @@ VALGRIND_PRINTF_BACKTRACE(const char *format, ...)
    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 @@ VALGRIND_PRINTF_BACKTRACE(const char *format, ...)
                                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,                       \
index 5ad965c6f03144ce7d596801065a3b754a9daf88..fb16979998db740f7a00202d73e5e71d71876cda 100644 (file)
@@ -70,8 +70,8 @@ void make_leak(void)
 
 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 @@ int main(void)
 
    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()
 }