]> git.ipfire.org Git - thirdparty/valgrind.git/commitdiff
Minor mods to stop make the leak detector behave properly for the
authorJulian Seward <jseward@acm.org>
Wed, 5 Jun 2002 20:28:33 +0000 (20:28 +0000)
committerJulian Seward <jseward@acm.org>
Wed, 5 Jun 2002 20:28:33 +0000 (20:28 +0000)
following kind of stupid test program
   int main (void) { char* a = malloc(100); return 0; }
which many people seem fond of trying for some reason.
In general the leak detector works fine.

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

14 files changed:
coregrind/vg_include.h
coregrind/vg_malloc2.c
coregrind/vg_memory.c
coregrind/vg_mylibc.c
coregrind/vg_scheduler.c
coregrind/vg_transtab.c
tests/Makefile.am
tests/nanoleak.c [new file with mode: 0644]
vg_include.h
vg_malloc2.c
vg_memory.c
vg_mylibc.c
vg_scheduler.c
vg_transtab.c

index ec923b18814ba70f71906f87ad6293f50bc119c9..9474b60596e3a47d7fa64bb63a2d93804ee880cb 100644 (file)
@@ -915,7 +915,7 @@ extern void VG_(panic) ( Char* str )
             __attribute__ ((__noreturn__));
 
 /* Get memory by anonymous mmap. */
-extern void* VG_(get_memory_from_mmap) ( Int nBytes );
+extern void* VG_(get_memory_from_mmap) ( Int nBytes, Char* who );
 
 /* Crude stand-in for the glibc system() call. */
 extern Int VG_(system) ( Char* cmd );
index ab87bdb5c5c0e644525f22fab376a96d4e2a53fa..87f580d01ac3bada44d34a602c7a2d787511aa29 100644 (file)
@@ -233,7 +233,8 @@ Superblock* newSuperblock ( Arena* a, Int cszW )
    cszW += 2; /* Take into account sb->next and sb->n_words fields */
    if (cszW < a->min_sblockW) cszW = a->min_sblockW;
    while ((cszW % VKI_WORDS_PER_PAGE) > 0) cszW++;
-   sb = VG_(get_memory_from_mmap) ( cszW * sizeof(Word) );
+   sb = VG_(get_memory_from_mmap) ( cszW * sizeof(Word), 
+                                    "newSuperblock" );
    sb->n_payload_words = cszW - 2;
    a->bytes_mmaped += cszW * sizeof(Word);
    if (0)
index cd8eba12fa386272b6661f751d8aad4bcbf46967..4b4fe0cff5f87be730987683dfa40ebcb1e8f500 100644 (file)
@@ -332,7 +332,7 @@ static SecMap* alloc_secondary_map ( __attribute__ ((unused))
       although this isn't important, so the following assert is
       spurious. */
    vg_assert(0 == (sizeof(SecMap) % VKI_BYTES_PER_PAGE));
-   map = VG_(get_memory_from_mmap)( sizeof(SecMap) );
+   map = VG_(get_memory_from_mmap)( sizeof(SecMap), caller );
 
    for (i = 0; i < 8192; i++)
       map->abits[i] = VGM_BYTE_INVALID; /* Invalid address */
@@ -1963,8 +1963,40 @@ static Addr          vglc_max_mallocd_addr;
 static 
 void vg_detect_memory_leaks_notify_addr ( Addr a, UInt word_at_a )
 {
-   Int sh_no;
-   Addr ptr = (Addr)word_at_a;
+   Int  sh_no;
+   Addr ptr;
+
+   /* Rule out some known causes of bogus pointers.  Mostly these do
+      not cause much trouble because only a few false pointers can
+      ever lurk in these places.  This mainly stops it reporting that
+      blocks are still reachable in stupid test programs like this
+
+         int main (void) { char* a = malloc(100); return 0; }
+
+      which people seem inordinately fond of writing, for some reason.  
+
+      Note that this is a complete kludge.  It would be better to
+      ignore any addresses corresponding to valgrind.so's .bss and
+      .data segments, but I cannot think of a reliable way to identify
+      where the .bss segment has been put.  If you can, drop me a
+      line.  
+   */
+   if (a >= ((Addr)(&VG_(stack)))
+       && a <= ((Addr)(&VG_(stack))) + sizeof(VG_(stack))) {
+      return;
+   }
+   if (a >= ((Addr)(&VG_(m_state_static)))
+       && a <= ((Addr)(&VG_(m_state_static))) + sizeof(VG_(m_state_static))) {
+      return;
+   }
+   if (a == (Addr)(&vglc_min_mallocd_addr))
+      return;
+   if (a == (Addr)(&vglc_max_mallocd_addr))
+      return;
+
+   /* OK, let's get on and do something Useful for a change. */
+
+   ptr = (Addr)word_at_a;
    if (ptr >= vglc_min_mallocd_addr && ptr <= vglc_max_mallocd_addr) {
       /* Might be legitimate; we'll have to investigate further. */
       sh_no = find_shadow_for ( ptr, vglc_shadows, vglc_n_shadows );
@@ -1975,6 +2007,7 @@ void vg_detect_memory_leaks_notify_addr ( Addr a, UInt word_at_a )
                          + vglc_shadows[sh_no]->size);
          /* Decide whether Proper-ly or Interior-ly reached. */
          if (ptr == vglc_shadows[sh_no]->data) {
+            if (0) VG_(printf)("pointer at %p to %p\n", a, word_at_a );
             vglc_reachedness[sh_no] = Proper;
          } else {
             if (vglc_reachedness[sh_no] == Unreached)
@@ -2147,10 +2180,10 @@ void VG_(detect_memory_leaks) ( void )
 
    VG_(message)(Vg_UserMsg, "");
    VG_(message)(Vg_UserMsg, "LEAK SUMMARY:");
-   VG_(message)(Vg_UserMsg, "   possibly lost:   %d bytes in %d blocks.", 
-                            bytes_dubious, blocks_dubious );
    VG_(message)(Vg_UserMsg, "   definitely lost: %d bytes in %d blocks.", 
                             bytes_leaked, blocks_leaked );
+   VG_(message)(Vg_UserMsg, "   possibly lost:   %d bytes in %d blocks.", 
+                            bytes_dubious, blocks_dubious );
    VG_(message)(Vg_UserMsg, "   still reachable: %d bytes in %d blocks.", 
                             bytes_reachable, blocks_reachable );
    if (!VG_(clo_show_reachable)) {
index b2b62b4d003c4a7799e0a4cccae703c0ecf1cb10..4f8cb7192139c319e842a7b89b2f784d633cdf92 100644 (file)
@@ -1241,7 +1241,7 @@ void VG_(end_rdtsc_calibration) ( void )
    Primitive support for bagging memory via mmap.
    ------------------------------------------------------------------ */
 
-void* VG_(get_memory_from_mmap) ( Int nBytes )
+void* VG_(get_memory_from_mmap) ( Int nBytes, Char* who )
 {
    static UInt tot_alloc = 0;
    void* p = VG_(mmap)( 0, nBytes,
@@ -1250,8 +1250,9 @@ void* VG_(get_memory_from_mmap) ( Int nBytes )
    if (p != ((void*)(-1))) {
       tot_alloc += (UInt)nBytes;
       if (0)
-         VG_(printf)("get_memory_from_mmap: %d tot, %d req\n",
-                     tot_alloc, nBytes);
+         VG_(printf)(
+            "get_memory_from_mmap: %d tot, %d req = %p .. %p, caller %s\n",
+            tot_alloc, nBytes, p, ((char*)p) + nBytes - 1, who );
       return p;
    }
    VG_(printf)("vg_get_memory_from_mmap failed on request of %d\n", 
index 65a51966765e66e231af0e14c0c554d9bdc4aee9..4e68b67f80486a593bb6ce405af22163f73e0f50 100644 (file)
@@ -2116,7 +2116,8 @@ void do__apply_in_new_thread ( ThreadId parent_tid,
          assigning it for the first time. */
       vg_assert(VG_(threads)[tid].stack_size == 0);
       vg_assert(VG_(threads)[tid].stack_base == (Addr)NULL);
-      new_stack = (Addr)VG_(get_memory_from_mmap)( new_stk_szb );
+      new_stack = (Addr)VG_(get_memory_from_mmap)( new_stk_szb, 
+                                                   "new thread stack" );
       VG_(threads)[tid].stack_base = new_stack;
       VG_(threads)[tid].stack_size = new_stk_szb;
       VG_(threads)[tid].stack_highest_word
index a364df0b865fa4baa75fd6114a5c13fc53fb9851..e69dda2d0948233bf8c6d001c7ccf74e0d2ada3b 100644 (file)
@@ -508,11 +508,13 @@ void VG_(init_tt_tc) ( void )
 
    /* Allocate the translation table and translation cache. */
    vg_assert(vg_tc == NULL);
-   vg_tc = VG_(get_memory_from_mmap) ( VG_TC_SIZE * sizeof(UChar) );
+   vg_tc = VG_(get_memory_from_mmap) ( VG_TC_SIZE * sizeof(UChar), 
+                                       "trans-cache" );
    vg_assert(vg_tc != NULL);
 
    vg_assert(vg_tt == NULL);
-   vg_tt = VG_(get_memory_from_mmap) ( VG_TT_SIZE * sizeof(TTEntry) );
+   vg_tt = VG_(get_memory_from_mmap) ( VG_TT_SIZE * sizeof(TTEntry),
+                                       "trans-table" );
    vg_assert(vg_tt != NULL);
 
    /* The main translation table is empty. */
index d68b430d7594dafc67958ddb577f38a4f12852de..f873b9f66b652b2ad12cf86e6c300ed1a19f0524 100644 (file)
@@ -30,4 +30,4 @@ EXTRA_DIST = \
        pth_once.c weirdioctl.c pth_signal1.c pth_signal2.c \
        discard.c pth_semaphore1.c new_override.cpp pth_yield.c \
        sigaltstack.c erringfds.c sigwait_all.c \
-       pth_cancel1.c pth_cancel2.c pth_signal_gober.c
+       pth_cancel1.c pth_cancel2.c pth_signal_gober.c nanoleak.c
diff --git a/tests/nanoleak.c b/tests/nanoleak.c
new file mode 100644 (file)
index 0000000..2b7121c
--- /dev/null
@@ -0,0 +1,9 @@
+
+#include <malloc.h>
+
+int main ( void )
+{
+  volatile int* a = malloc(1000);
+  a[0] = 0;
+  return a[0];
+}
index ec923b18814ba70f71906f87ad6293f50bc119c9..9474b60596e3a47d7fa64bb63a2d93804ee880cb 100644 (file)
@@ -915,7 +915,7 @@ extern void VG_(panic) ( Char* str )
             __attribute__ ((__noreturn__));
 
 /* Get memory by anonymous mmap. */
-extern void* VG_(get_memory_from_mmap) ( Int nBytes );
+extern void* VG_(get_memory_from_mmap) ( Int nBytes, Char* who );
 
 /* Crude stand-in for the glibc system() call. */
 extern Int VG_(system) ( Char* cmd );
index ab87bdb5c5c0e644525f22fab376a96d4e2a53fa..87f580d01ac3bada44d34a602c7a2d787511aa29 100644 (file)
@@ -233,7 +233,8 @@ Superblock* newSuperblock ( Arena* a, Int cszW )
    cszW += 2; /* Take into account sb->next and sb->n_words fields */
    if (cszW < a->min_sblockW) cszW = a->min_sblockW;
    while ((cszW % VKI_WORDS_PER_PAGE) > 0) cszW++;
-   sb = VG_(get_memory_from_mmap) ( cszW * sizeof(Word) );
+   sb = VG_(get_memory_from_mmap) ( cszW * sizeof(Word), 
+                                    "newSuperblock" );
    sb->n_payload_words = cszW - 2;
    a->bytes_mmaped += cszW * sizeof(Word);
    if (0)
index cd8eba12fa386272b6661f751d8aad4bcbf46967..4b4fe0cff5f87be730987683dfa40ebcb1e8f500 100644 (file)
@@ -332,7 +332,7 @@ static SecMap* alloc_secondary_map ( __attribute__ ((unused))
       although this isn't important, so the following assert is
       spurious. */
    vg_assert(0 == (sizeof(SecMap) % VKI_BYTES_PER_PAGE));
-   map = VG_(get_memory_from_mmap)( sizeof(SecMap) );
+   map = VG_(get_memory_from_mmap)( sizeof(SecMap), caller );
 
    for (i = 0; i < 8192; i++)
       map->abits[i] = VGM_BYTE_INVALID; /* Invalid address */
@@ -1963,8 +1963,40 @@ static Addr          vglc_max_mallocd_addr;
 static 
 void vg_detect_memory_leaks_notify_addr ( Addr a, UInt word_at_a )
 {
-   Int sh_no;
-   Addr ptr = (Addr)word_at_a;
+   Int  sh_no;
+   Addr ptr;
+
+   /* Rule out some known causes of bogus pointers.  Mostly these do
+      not cause much trouble because only a few false pointers can
+      ever lurk in these places.  This mainly stops it reporting that
+      blocks are still reachable in stupid test programs like this
+
+         int main (void) { char* a = malloc(100); return 0; }
+
+      which people seem inordinately fond of writing, for some reason.  
+
+      Note that this is a complete kludge.  It would be better to
+      ignore any addresses corresponding to valgrind.so's .bss and
+      .data segments, but I cannot think of a reliable way to identify
+      where the .bss segment has been put.  If you can, drop me a
+      line.  
+   */
+   if (a >= ((Addr)(&VG_(stack)))
+       && a <= ((Addr)(&VG_(stack))) + sizeof(VG_(stack))) {
+      return;
+   }
+   if (a >= ((Addr)(&VG_(m_state_static)))
+       && a <= ((Addr)(&VG_(m_state_static))) + sizeof(VG_(m_state_static))) {
+      return;
+   }
+   if (a == (Addr)(&vglc_min_mallocd_addr))
+      return;
+   if (a == (Addr)(&vglc_max_mallocd_addr))
+      return;
+
+   /* OK, let's get on and do something Useful for a change. */
+
+   ptr = (Addr)word_at_a;
    if (ptr >= vglc_min_mallocd_addr && ptr <= vglc_max_mallocd_addr) {
       /* Might be legitimate; we'll have to investigate further. */
       sh_no = find_shadow_for ( ptr, vglc_shadows, vglc_n_shadows );
@@ -1975,6 +2007,7 @@ void vg_detect_memory_leaks_notify_addr ( Addr a, UInt word_at_a )
                          + vglc_shadows[sh_no]->size);
          /* Decide whether Proper-ly or Interior-ly reached. */
          if (ptr == vglc_shadows[sh_no]->data) {
+            if (0) VG_(printf)("pointer at %p to %p\n", a, word_at_a );
             vglc_reachedness[sh_no] = Proper;
          } else {
             if (vglc_reachedness[sh_no] == Unreached)
@@ -2147,10 +2180,10 @@ void VG_(detect_memory_leaks) ( void )
 
    VG_(message)(Vg_UserMsg, "");
    VG_(message)(Vg_UserMsg, "LEAK SUMMARY:");
-   VG_(message)(Vg_UserMsg, "   possibly lost:   %d bytes in %d blocks.", 
-                            bytes_dubious, blocks_dubious );
    VG_(message)(Vg_UserMsg, "   definitely lost: %d bytes in %d blocks.", 
                             bytes_leaked, blocks_leaked );
+   VG_(message)(Vg_UserMsg, "   possibly lost:   %d bytes in %d blocks.", 
+                            bytes_dubious, blocks_dubious );
    VG_(message)(Vg_UserMsg, "   still reachable: %d bytes in %d blocks.", 
                             bytes_reachable, blocks_reachable );
    if (!VG_(clo_show_reachable)) {
index b2b62b4d003c4a7799e0a4cccae703c0ecf1cb10..4f8cb7192139c319e842a7b89b2f784d633cdf92 100644 (file)
@@ -1241,7 +1241,7 @@ void VG_(end_rdtsc_calibration) ( void )
    Primitive support for bagging memory via mmap.
    ------------------------------------------------------------------ */
 
-void* VG_(get_memory_from_mmap) ( Int nBytes )
+void* VG_(get_memory_from_mmap) ( Int nBytes, Char* who )
 {
    static UInt tot_alloc = 0;
    void* p = VG_(mmap)( 0, nBytes,
@@ -1250,8 +1250,9 @@ void* VG_(get_memory_from_mmap) ( Int nBytes )
    if (p != ((void*)(-1))) {
       tot_alloc += (UInt)nBytes;
       if (0)
-         VG_(printf)("get_memory_from_mmap: %d tot, %d req\n",
-                     tot_alloc, nBytes);
+         VG_(printf)(
+            "get_memory_from_mmap: %d tot, %d req = %p .. %p, caller %s\n",
+            tot_alloc, nBytes, p, ((char*)p) + nBytes - 1, who );
       return p;
    }
    VG_(printf)("vg_get_memory_from_mmap failed on request of %d\n", 
index 65a51966765e66e231af0e14c0c554d9bdc4aee9..4e68b67f80486a593bb6ce405af22163f73e0f50 100644 (file)
@@ -2116,7 +2116,8 @@ void do__apply_in_new_thread ( ThreadId parent_tid,
          assigning it for the first time. */
       vg_assert(VG_(threads)[tid].stack_size == 0);
       vg_assert(VG_(threads)[tid].stack_base == (Addr)NULL);
-      new_stack = (Addr)VG_(get_memory_from_mmap)( new_stk_szb );
+      new_stack = (Addr)VG_(get_memory_from_mmap)( new_stk_szb, 
+                                                   "new thread stack" );
       VG_(threads)[tid].stack_base = new_stack;
       VG_(threads)[tid].stack_size = new_stk_szb;
       VG_(threads)[tid].stack_highest_word
index a364df0b865fa4baa75fd6114a5c13fc53fb9851..e69dda2d0948233bf8c6d001c7ccf74e0d2ada3b 100644 (file)
@@ -508,11 +508,13 @@ void VG_(init_tt_tc) ( void )
 
    /* Allocate the translation table and translation cache. */
    vg_assert(vg_tc == NULL);
-   vg_tc = VG_(get_memory_from_mmap) ( VG_TC_SIZE * sizeof(UChar) );
+   vg_tc = VG_(get_memory_from_mmap) ( VG_TC_SIZE * sizeof(UChar), 
+                                       "trans-cache" );
    vg_assert(vg_tc != NULL);
 
    vg_assert(vg_tt == NULL);
-   vg_tt = VG_(get_memory_from_mmap) ( VG_TT_SIZE * sizeof(TTEntry) );
+   vg_tt = VG_(get_memory_from_mmap) ( VG_TT_SIZE * sizeof(TTEntry),
+                                       "trans-table" );
    vg_assert(vg_tt != NULL);
 
    /* The main translation table is empty. */