]> git.ipfire.org Git - thirdparty/valgrind.git/commitdiff
Bug 514613 again (closing </still_reachable> xml tag)
authorPaul Floyd <pjfloyd@wanadoo.fr>
Wed, 28 Jan 2026 12:38:39 +0000 (13:38 +0100)
committerPaul Floyd <pjfloyd@wanadoo.fr>
Wed, 28 Jan 2026 19:47:59 +0000 (20:47 +0100)
Always close the tag after the heuristic details.

Add 4 testcases, one with no errors, one with a simple leak,
one with a simple reachable and one "Xmas tree" test (in
reference to the TCP/IP Christmas tree packet
https://en.wikipedia.org/wiki/Christmas_tree_packet). That
has most of the errors that memcheck can produce.

All of these tests get checked by xmllint.

12 files changed:
.gitignore
memcheck/mc_leakcheck.c
memcheck/tests/Makefile.am
memcheck/tests/nothing.c [new file with mode: 0644]
memcheck/tests/nothing_xml.vgtest [new file with mode: 0644]
memcheck/tests/simple_leak.c [new file with mode: 0644]
memcheck/tests/simple_leak_xml.vgtest [new file with mode: 0644]
memcheck/tests/simple_reachable.c [new file with mode: 0644]
memcheck/tests/simple_reachable_xml.vgtest [new file with mode: 0644]
memcheck/tests/xmas_tree.cpp [new file with mode: 0644]
memcheck/tests/xmas_tree_xml.supp [new file with mode: 0644]
memcheck/tests/xmas_tree_xml.vgtest [new file with mode: 0644]

index 12221dc8df0c20111eb4940942c9017500b6f5db..3276d8c660939b4e0d5b1b8ba26db6d660d9b64a 100644 (file)
 /memcheck/tests/new_nothrow
 /memcheck/tests/new_override
 /memcheck/tests/noisy_child
+/memcheck/tests/nothing
 /memcheck/tests/null_socket
 /memcheck/tests/origin1-yes
 /memcheck/tests/origin2-not-quite
 /memcheck/tests/sendmsg
 /memcheck/tests/sh-mem
 /memcheck/tests/sh-mem-random
+/memcheck/tests/simple_leak
+/memcheck/tests/simple_reachable
 /memcheck/tests/sized_aligned_new_delete_args
 /memcheck/tests/sized_aligned_new_delete_misaligned1
 /memcheck/tests/sized_aligned_new_delete_misaligned2
 /memcheck/tests/wrapmalloc
 /memcheck/tests/wrapmallocstatic
 /memcheck/tests/writev1
+/memcheck/tests/xmas_tree
 /memcheck/tests/xml1
 /memcheck/tests/zeropage
 
index 4df0b180d5d1bb10ff12c2a6cde16213a91c47c5..b0056b65bd3e97c1e94b03d36a5fec1f13dc11b7 100644 (file)
@@ -1768,23 +1768,23 @@ static void print_results(ThreadId tid, LeakCheckParams* lcp)
       umsg_or_xml(VG_(clo_xml) ?
                   "  <still_reachable>\n"
                   "    <bytes>%'lu%s</bytes>\n"
-                  "    <blocks>%'lu%s</blocks>\n"
-                  "  </still_reachable>\n" :
+                  "    <blocks>%'lu%s</blocks>\n" :
                   "   still reachable: %'lu%s bytes in %'lu%s blocks\n",
                 MC_(bytes_reachable), 
                 DBY (MC_(bytes_reachable), old_bytes_reachable), 
                 MC_(blocks_reachable),
                 DBL (MC_(blocks_reachable), old_blocks_reachable));
-      for (i = 0; i < N_LEAK_CHECK_HEURISTICS; i++)
+      for (i = 0; i < N_LEAK_CHECK_HEURISTICS; i++) {
          if (old_blocks_heuristically_reachable[i] > 0 
              || MC_(blocks_heuristically_reachable)[i] > 0) {
             umsg_or_xml(VG_(clo_xml) ? "" : "                      of which "
                       "reachable via heuristic:\n");
             break;
          }
-      for (i = 0; i < N_LEAK_CHECK_HEURISTICS; i++)
-         if (old_blocks_heuristically_reachable[i] > 0 
-             || MC_(blocks_heuristically_reachable)[i] > 0)
+      }
+      for (i = 0; i < N_LEAK_CHECK_HEURISTICS; i++) {
+         if (old_blocks_heuristically_reachable[i] > 0
+             || MC_(blocks_heuristically_reachable)[i] > 0) {
             umsg_or_xml(VG_(clo_xml) ?
                         "    <reachable_heuristic>\n"
                         "      <kind>%ls</kind>\n"
@@ -1800,7 +1800,9 @@ static void print_results(ThreadId tid, LeakCheckParams* lcp)
                       MC_(blocks_heuristically_reachable)[i],
                       DBL (MC_(blocks_heuristically_reachable)[i],
                            old_blocks_heuristically_reachable[i]));
-      if (VG_(clo_xml) && MC_(bytes_reachable)) {
+         }
+      }
+      if (VG_(clo_xml)) {
          umsg_or_xml("  </still_reachable>\n");
       }
       umsg_or_xml(VG_(clo_xml) ?
index eb601405302948854b3051f5616102dbe28375e3..6a6eee61df4043c3e130247b257142274cdb3e36 100644 (file)
@@ -311,6 +311,7 @@ EXTRA_DIST = \
        new_nothrow.vgtest \
        new_override.stderr.exp new_override.stdout.exp new_override.vgtest \
        noisy_child.vgtest noisy_child.stderr.exp \
+       nothing_xml.vgtest \
        null_socket.vgtest \
        origin1-yes.vgtest origin1-yes.stderr.exp \
                origin1-yes.stderr.exp-freebsd \
@@ -402,6 +403,7 @@ EXTRA_DIST = \
            sigkill.stderr.exp-glibc-2.28 sigkill.vgtest \
        signal2.stderr.exp signal2.stdout.exp signal2.vgtest \
        sigprocmask.stderr.exp sigprocmask.stderr.exp2 sigprocmask.vgtest \
+       simple_leak_xml.vgtest simple_reachable_xml.vgtest \
        sized_delete.stderr.exp sized_delete.stderr.exp-x86 sized_delete.vgtest \
        static_malloc.stderr.exp static_malloc.vgtest \
        stpncpy.vgtest stpncpy.stderr.exp \
@@ -475,6 +477,7 @@ EXTRA_DIST = \
        wrapmalloc.vgtest wrapmalloc.stdout.exp \
        wrapmallocstatic.vgtest wrapmallocstatic.stdout.exp \
        writev1.stderr.exp writev1.stderr.exp-solaris writev1.vgtest \
+       xmas_tree_xml.vgtest xmas_tree_xml.supp \
        xml1.stderr.exp xml1.stdout.exp xml1.vgtest xml1.stderr.exp-s390x-mvc
 
 check_PROGRAMS = \
@@ -536,6 +539,7 @@ check_PROGRAMS = \
        mismatches new_override metadata \
        nanoleak_supp nanoleak2 new_nothrow \
        noisy_child \
+       nothing \
        null_socket \
        origin1-yes origin2-not-quite origin3-no \
        origin4-many origin5-bz2 origin6-fp \
@@ -553,7 +557,9 @@ check_PROGRAMS = \
        sbfragment \
        sendmsg \
        sh-mem sh-mem-random \
-       sigaltstack signal2 sigprocmask static_malloc sigkill \
+       sigaltstack signal2 sigprocmask \
+       simple_leak simple_reachable \
+       static_malloc sigkill \
        strchr \
        str_tester \
        supp_unknown supp1 supp2 suppfree \
@@ -572,7 +578,8 @@ check_PROGRAMS = \
        wmemcmp \
        wrap1 wrap2 wrap3 wrap4 wrap5 wrap6 wrap7 wrap7so.so wrap8 \
        wrapmalloc wrapmallocso.so wrapmallocstatic \
-       writev1
+       writev1 \
+       xmas_tree
 
 if !SOLARIS_SUN_STUDIO_AS
 # Sun Studio assembler fails on "IDENT too long"
@@ -970,3 +977,5 @@ endif
 writev1_CFLAGS         = $(AM_CFLAGS) @FLAG_W_NO_STRINGOP_OVERFLOW@ @FLAG_W_NO_STRINGOP_OVERREAD@
 xml1_CFLAGS             = $(AM_CFLAGS) -D_GNU_SOURCE @FLAG_W_NO_UNINITIALIZED@ @FLAG_W_NO_USE_AFTER_FREE@
 
+xmas_tree_SOURCES      = xmas_tree.cpp
+xmas_tree_CXXFLAGS     = ${AM_CXXFLAGS} @FLAG_W_NO_UNINITIALIZED@ @FLAG_W_NO_MISMATCHED_NEW_DELETE@ @FLAG_W_ALLOC_SIZE_LARGER_THAN@
diff --git a/memcheck/tests/nothing.c b/memcheck/tests/nothing.c
new file mode 100644 (file)
index 0000000..2e424a5
--- /dev/null
@@ -0,0 +1,5 @@
+/* no errors, except Darwin */
+int main()
+{
+}
+
diff --git a/memcheck/tests/nothing_xml.vgtest b/memcheck/tests/nothing_xml.vgtest
new file mode 100644 (file)
index 0000000..db2eca4
--- /dev/null
@@ -0,0 +1,4 @@
+prereq: which xmllint > /dev/null
+prog: nothing
+args: | xmllint --noout -
+vgopts: --xml=yes --xml-fd=1
diff --git a/memcheck/tests/simple_leak.c b/memcheck/tests/simple_leak.c
new file mode 100644 (file)
index 0000000..b94dade
--- /dev/null
@@ -0,0 +1,10 @@
+#include <stdlib.h>
+
+static void *p;
+
+int main ()
+{
+  p = malloc (1024);
+  p = NULL;
+}
+
diff --git a/memcheck/tests/simple_leak_xml.vgtest b/memcheck/tests/simple_leak_xml.vgtest
new file mode 100644 (file)
index 0000000..9652b32
--- /dev/null
@@ -0,0 +1,4 @@
+prereq: which xmllint > /dev/null
+prog: simple_leak
+args: | xmllint --noout -
+vgopts: --xml=yes --xml-fd=1
diff --git a/memcheck/tests/simple_reachable.c b/memcheck/tests/simple_reachable.c
new file mode 100644 (file)
index 0000000..4fe1ada
--- /dev/null
@@ -0,0 +1,9 @@
+#include <stdlib.h>
+
+static void *p;
+
+int main ()
+{
+  p = malloc (1024);
+}
+
diff --git a/memcheck/tests/simple_reachable_xml.vgtest b/memcheck/tests/simple_reachable_xml.vgtest
new file mode 100644 (file)
index 0000000..a64cb2a
--- /dev/null
@@ -0,0 +1,4 @@
+prereq: which xmllint > /dev/null
+prog: simple_reachable
+args: | xmllint --noout -
+vgopts: --xml=yes --xml-fd=1
diff --git a/memcheck/tests/xmas_tree.cpp b/memcheck/tests/xmas_tree.cpp
new file mode 100644 (file)
index 0000000..680833b
--- /dev/null
@@ -0,0 +1,90 @@
+#include <new>
+#include <cstdlib>
+#include <cstring>
+#include <unistd.h>
+#include "../memcheck.h"
+
+struct Ae
+{
+   virtual ~Ae()
+   {
+   }
+};
+struct Be
+{
+   virtual ~Be()
+   {
+   }
+};
+struct Ce : public Ae, public Be
+{
+   virtual ~Ce()
+   {
+   }
+};
+
+void* reachable;
+Be *interior;
+
+int suppress_me()
+{
+   int qqq;
+   if (qqq)
+       return 2;
+    return 1;
+}
+
+int main()
+{
+    std::align_val_t misalign(static_cast<std::align_val_t>(63U));
+    std::align_val_t align(static_cast<std::align_val_t>(64U));
+    std::align_val_t align2(static_cast<std::align_val_t>(32U));
+    std::size_t size(32);
+    std::size_t badsize(42);
+    std::nothrow_t tag;
+    int count{0};
+
+    char *mem = static_cast<char*>(operator new[](size, tag));
+    if (mem[31])
+        ++count;
+    if (mem[32])
+        ++count;
+    operator delete(mem, misalign, tag);
+
+    mem = static_cast<char*>(operator new(size, align, tag));
+    operator delete(mem, align2, tag);
+
+    mem = static_cast<char*>(malloc(20));
+    mem = static_cast<char*>(realloc(mem, 0));
+    delete mem;
+
+    mem = static_cast<char*>(operator new[](size));
+    memcpy(mem+10, mem+5, 10);
+    operator delete[](mem, badsize);
+
+    mem = static_cast<char*>(malloc(-1));
+
+    int fd{42};
+    int bad;
+    fd += bad;
+    fd -= bad;
+    char* buf{nullptr};
+    ++buf;
+    write(fd, buf, fd);
+
+    int zzz;
+    VALGRIND_CHECK_MEM_IS_DEFINED(&zzz, 4);
+
+    reachable = malloc(10);
+    mem = static_cast<char*>(malloc(20));
+
+    char* indirect = static_cast<char*>(malloc(30));
+    memcpy(&mem[8], &indirect, sizeof(indirect));
+    mem = nullptr;
+
+    count += suppress_me();
+
+    interior = new Ce;  // interior ptr.
+
+    return count;
+}
diff --git a/memcheck/tests/xmas_tree_xml.supp b/memcheck/tests/xmas_tree_xml.supp
new file mode 100644 (file)
index 0000000..2643371
--- /dev/null
@@ -0,0 +1,7 @@
+{
+   Hello, suppression World!
+   Memcheck:Cond
+   fun:_Z11suppress_mev
+   fun:main
+}
+
diff --git a/memcheck/tests/xmas_tree_xml.vgtest b/memcheck/tests/xmas_tree_xml.vgtest
new file mode 100644 (file)
index 0000000..5061ad1
--- /dev/null
@@ -0,0 +1,4 @@
+prereq: which xmllint > /dev/null
+prog: xmas_tree
+args: | xmllint --noout -
+vgopts: --xml=yes --xml-fd=1 --leak-check=full --suppressions=xmas_tree_xml.supp --leak-check-heuristics=multipleinheritance