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.
/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
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"
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) ?
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 \
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 \
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 = \
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 \
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 \
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"
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@
--- /dev/null
+/* no errors, except Darwin */
+int main()
+{
+}
+
--- /dev/null
+prereq: which xmllint > /dev/null
+prog: nothing
+args: | xmllint --noout -
+vgopts: --xml=yes --xml-fd=1
--- /dev/null
+#include <stdlib.h>
+
+static void *p;
+
+int main ()
+{
+ p = malloc (1024);
+ p = NULL;
+}
+
--- /dev/null
+prereq: which xmllint > /dev/null
+prog: simple_leak
+args: | xmllint --noout -
+vgopts: --xml=yes --xml-fd=1
--- /dev/null
+#include <stdlib.h>
+
+static void *p;
+
+int main ()
+{
+ p = malloc (1024);
+}
+
--- /dev/null
+prereq: which xmllint > /dev/null
+prog: simple_reachable
+args: | xmllint --noout -
+vgopts: --xml=yes --xml-fd=1
--- /dev/null
+#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;
+}
--- /dev/null
+{
+ Hello, suppression World!
+ Memcheck:Cond
+ fun:_Z11suppress_mev
+ fun:main
+}
+
--- /dev/null
+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