]> git.ipfire.org Git - thirdparty/valgrind.git/commitdiff
Bug 79362 - Debug info is lost for .so files when they are dlclose'd. Followup fix...
authorJulian Seward <jseward@acm.org>
Mon, 15 Jan 2018 10:25:12 +0000 (11:25 +0100)
committerJulian Seward <jseward@acm.org>
Mon, 15 Jan 2018 10:25:12 +0000 (11:25 +0100)
As reported by Matthias Schwarzott <zzam@gentoo.org>.  Testcase patch from him.  The fix is
for check_CFSI_related_invariants() to avoid checking for overlaps against DebugInfos that are
in 'archived' status, since -- if a previously dlopened-and-then-dlclosed object is later
re-dlopened -- this may cause an overlap between the active and archived DebugInfos, which
is of no consequence.  If the kernel maps the object to the same VMA the second time around
then there will *certainly* be an overlap.

coregrind/m_debuginfo/debuginfo.c
coregrind/m_debuginfo/priv_storage.h
memcheck/tests/linux/dlclose_leak-no-keep.stderr.exp
memcheck/tests/linux/dlclose_leak.c
memcheck/tests/linux/dlclose_leak.stderr.exp

index d481458436390d670805fe4043f8f02caa409ce0..3f86aced5e9fe9fc0e6d703284f5cefeba348bad 100644 (file)
@@ -673,7 +673,7 @@ static void check_CFSI_related_invariants ( const DebugInfo* di )
 
       /* invariant (1) */
       for (di2 = debugInfo_list; di2; di2 = di2->next) {
-         if (di2 == di)
+         if (di2 == di || is_DebugInfo_archived(di2))
             continue;
          for (j = 0; j < VG_(sizeXA)(di2->fsm.maps); j++) {
             const DebugInfoMapping* map2 = VG_(indexXA)(di2->fsm.maps, j);
index 6c471a00f7d341405987bff4999925e56b66faa0..713acbea87849cafa2c2a354f8f31604523bdcb4 100644 (file)
@@ -668,7 +668,7 @@ struct _DebugInfo {
 
       or the normal case, which is the AND of the following:
       (0) size of at least one rx mapping > 0
-      (1) no two DebugInfos with some rx mapping of size > 0 
+      (1) no two non-archived DebugInfos with some rx mapping of size > 0
           have overlapping rx mappings
       (2) [cfsi_minavma,cfsi_maxavma] does not extend beyond
           [avma,+size) of one rx mapping; that is, the former
index 107b7dd79eda6c5e10acd46ca2bd7726ed433070..01306c0e756787ecf9df4976353400b45e617ad2 100644 (file)
@@ -1,17 +1,17 @@
 Conditional jump or move depends on uninitialised value(s)
    at 0x........: jmp_on_uninit (dlclose_leak_so.c:10)
-   by 0x........: main (dlclose_leak.c:26)
+   by 0x........: main (dlclose_leak.c:29)
 
 Invalid read of size 1
-   at 0x........: main (dlclose_leak.c:29)
+   at 0x........: main (dlclose_leak.c:32)
  Address 0x........ is 1 bytes before a block of size 1 alloc'd
    at 0x........: malloc (vg_replace_malloc.c:...)
    ...
-   by 0x........: main (dlclose_leak.c:27)
+   by 0x........: main (dlclose_leak.c:30)
 
 done!
-1 bytes in 1 blocks are definitely lost in loss record ... of ...
+2 bytes in 2 blocks are definitely lost in loss record ... of ...
    at 0x........: malloc (vg_replace_malloc.c:...)
    ...
-   by 0x........: main (dlclose_leak.c:27)
+   by 0x........: main (dlclose_leak.c:30)
 
index 33fd2200f61b6887d2c8bcf0b6e692d8ebe830c5..329aaced3d7f109d7ebb7602fe0c648539ee7d83 100644 (file)
@@ -9,24 +9,28 @@
 int (*jmp_on_uninit)(void);
 char* (*alloc_1_byte)(void);
 
-int main(int argc, char** argv) {
-    char* memToLeak;
-    char x __attribute__((unused));
-    void* handle = dlopen("./dlclose_leak_so.so", RTLD_NOW);
-    if(!handle) {
-        printf("FAILURE to dlopen dlclose_leak_so.so\n");
-        return EXIT_FAILURE;
+int main(int argc, char** argv)
+{
+    for (int i = 0; i < 2; ++i)
+    {
+        char* memToLeak;
+        char x __attribute__((unused));
+        void* handle = dlopen("./dlclose_leak_so.so", RTLD_NOW);
+        if(!handle) {
+            printf("FAILURE to dlopen dlclose_leak_so.so\n");
+            return EXIT_FAILURE;
+        }
+        jmp_on_uninit = dlsym(handle,"jmp_on_uninit");
+        //fprintf(stderr, "jmp_on_uninit: %p\n", jmp_on_uninit);
+        assert(jmp_on_uninit);
+        alloc_1_byte = dlsym(handle,"alloc_1_byte");
+        //fprintf(stderr, "alloc_1_byte: %p\n", alloc_1_byte);
+        assert(alloc_1_byte);
+        (void)jmp_on_uninit();
+        memToLeak = alloc_1_byte();
+        dlclose(handle);
+        x = memToLeak[-1];
     }
-    jmp_on_uninit = dlsym(handle,"jmp_on_uninit");
-    //fprintf(stderr, "jmp_on_uninit: %p\n", jmp_on_uninit);
-    assert(jmp_on_uninit);
-    alloc_1_byte = dlsym(handle,"alloc_1_byte");
-    //fprintf(stderr, "alloc_1_byte: %p\n", alloc_1_byte);
-    assert(alloc_1_byte);
-    (void)jmp_on_uninit();
-    memToLeak = alloc_1_byte();
-    dlclose(handle);
-    x = memToLeak[-1];
     fprintf(stderr, "done!\n");
     return (EXIT_SUCCESS);
 }
index 3c5b44e38a7f1c4883cb466f282ff67cc7061d43..ca89db0842bf7c1d1da278d3e7ea5d6a3e79441b 100644 (file)
@@ -1,17 +1,26 @@
 Conditional jump or move depends on uninitialised value(s)
    at 0x........: jmp_on_uninit (dlclose_leak_so.c:10)
-   by 0x........: main (dlclose_leak.c:26)
+   by 0x........: main (dlclose_leak.c:29)
 
 Invalid read of size 1
-   at 0x........: main (dlclose_leak.c:29)
+   at 0x........: main (dlclose_leak.c:32)
  Address 0x........ is 1 bytes before a block of size 1 alloc'd
    at 0x........: malloc (vg_replace_malloc.c:...)
    by 0x........: alloc_1_byte (dlclose_leak_so.c:20)
-   by 0x........: main (dlclose_leak.c:27)
+   by 0x........: main (dlclose_leak.c:30)
+
+Conditional jump or move depends on uninitialised value(s)
+   at 0x........: jmp_on_uninit (dlclose_leak_so.c:10)
+   by 0x........: main (dlclose_leak.c:29)
 
 done!
 1 bytes in 1 blocks are definitely lost in loss record ... of ...
    at 0x........: malloc (vg_replace_malloc.c:...)
    by 0x........: alloc_1_byte (dlclose_leak_so.c:20)
-   by 0x........: main (dlclose_leak.c:27)
+   by 0x........: main (dlclose_leak.c:30)
+
+1 bytes in 1 blocks are definitely lost in loss record ... of ...
+   at 0x........: malloc (vg_replace_malloc.c:...)
+   by 0x........: alloc_1_byte (dlclose_leak_so.c:20)
+   by 0x........: main (dlclose_leak.c:30)