Default value changed following discussion on valdev.
Giving more information for errors with freed blocks can help
when investigating difficult problems (e.g. double free, programs
using 'cleanup list' collecting different types of memory, ...)
Regression tested on various setup (x86, ppc64, s390x, amd64, debian or fedora)
Tests that have only one exp files have been updated to use the output
of the new default value in their .exp file.
Tests having more than one exp file have been changed so as to
specify explicitely the previous clo default value (i.e. adding
--keep-stacktraces=alloc-then-free in the vgtest file).
Possibly, some tests might fail on non tested platforms
(e.g. mips, macos, solaris, tilegx).
Fixes should be straightforward, using one of the above fix techniques.
git-svn-id: svn://svn.valgrind.org/valgrind/trunk@15597
* Memcheck:
+ - Default value for --keep-stacktraces has been changed to alloc-and-free.
+ This has a small cost in memory (one word per malloc-ed block) but
+ allows memcheck to e.g. give the 3 stacktraces of a dangling reference:
+ Where the block was allocated, where it was freed, and where it is
+ acccessed after free.
+
- A new monitor command 'xb <addr> <len>' shows the validity bits of
<len> bytes at <addr>. The monitor command 'xb' is easier to use
than get_vbits when you need to associate byte data value with
<varlistentry id="opt.keep-stacktraces" xreflabel="--keep-stacktraces">
<term>
- <option><![CDATA[--keep-stacktraces=alloc|free|alloc-and-free|alloc-then-free|none [default: alloc-then-free] ]]></option>
+ <option><![CDATA[--keep-stacktraces=alloc|free|alloc-and-free|alloc-then-free|none [default: alloc-and-free] ]]></option>
</term>
<listitem>
<para>Controls which stack trace(s) to keep for malloc'd and/or
Bool MC_(clo_workaround_gcc296_bugs) = False;
Int MC_(clo_malloc_fill) = -1;
Int MC_(clo_free_fill) = -1;
-KeepStacktraces MC_(clo_keep_stacktraces) = KS_alloc_then_free;
+KeepStacktraces MC_(clo_keep_stacktraces) = KS_alloc_and_free;
Int MC_(clo_mc_level) = 2;
Bool MC_(clo_show_mismatched_frees) = True;
Bool MC_(clo_expensive_definedness_check) = False;
" --malloc-fill=<hexnumber> fill malloc'd areas with given value\n"
" --free-fill=<hexnumber> fill free'd areas with given value\n"
" --keep-stacktraces=alloc|free|alloc-and-free|alloc-then-free|none\n"
-" stack trace(s) to keep for malloc'd/free'd areas [alloc-then-free]\n"
+" stack trace(s) to keep for malloc'd/free'd areas [alloc-and-free]\n"
" --show-mismatched-frees=no|yes show frees that don't match the allocator? [yes]\n"
, plo_default
);
Address 0x........ is 1,000 bytes inside a block of size 1,000,015 free'd
at 0x........: free (vg_replace_malloc.c:...)
by 0x........: main (big_blocks_freed_list.c:21)
+ Block was alloc'd at
+ at 0x........: malloc (vg_replace_malloc.c:...)
+ by 0x........: main (big_blocks_freed_list.c:19)
Invalid read of size 1
at 0x........: main (big_blocks_freed_list.c:23)
Address 0x........ is 1,000 bytes inside a block of size 900,000 free'd
at 0x........: free (vg_replace_malloc.c:...)
by 0x........: main (big_blocks_freed_list.c:20)
+ Block was alloc'd at
+ at 0x........: malloc (vg_replace_malloc.c:...)
+ by 0x........: main (big_blocks_freed_list.c:18)
Invalid read of size 1
at 0x........: main (big_blocks_freed_list.c:33)
Address 0x........ is 2,000 bytes inside a block of size 900,000 free'd
at 0x........: free (vg_replace_malloc.c:...)
by 0x........: main (big_blocks_freed_list.c:20)
+ Block was alloc'd at
+ at 0x........: malloc (vg_replace_malloc.c:...)
+ by 0x........: main (big_blocks_freed_list.c:18)
Invalid read of size 1
at 0x........: main (big_blocks_freed_list.c:41)
Address 0x........ is 10 bytes inside a block of size 10,000 free'd
at 0x........: free (vg_replace_malloc.c:...)
by 0x........: main (big_blocks_freed_list.c:28)
+ Block was alloc'd at
+ at 0x........: malloc (vg_replace_malloc.c:...)
+ by 0x........: main (big_blocks_freed_list.c:27)
Invalid read of size 1
at 0x........: main (big_blocks_freed_list.c:46)
Address 0x........ is 10 bytes inside a block of size 1,000,015 free'd
at 0x........: free (vg_replace_malloc.c:...)
by 0x........: main (big_blocks_freed_list.c:40)
+ Block was alloc'd at
+ at 0x........: malloc (vg_replace_malloc.c:...)
+ by 0x........: main (big_blocks_freed_list.c:39)
Invalid read of size 1
at 0x........: main (big_blocks_freed_list.c:55)
Address 0x........ is 10 bytes inside a block of size 10,000 free'd
at 0x........: free (vg_replace_malloc.c:...)
by 0x........: main (big_blocks_freed_list.c:28)
+ Block was alloc'd at
+ at 0x........: malloc (vg_replace_malloc.c:...)
+ by 0x........: main (big_blocks_freed_list.c:27)
HEAP SUMMARY:
prog: cond_ld_st
args: loads
-vgopts: -q
+vgopts: -q --keep-stacktraces=alloc-then-free
stderr_filter_args: cond_ld_st
prog: cond_ld_st
args: stores
-vgopts: -q
+vgopts: -q --keep-stacktraces=alloc-then-free
stderr_filter_args: cond_ld_st
prog: custom_alloc
-vgopts: -q
+vgopts: -q --keep-stacktraces=alloc-then-free
Address 0x........ is 0 bytes inside a block of size 177 free'd
at 0x........: free (vg_replace_malloc.c:...)
by 0x........: main (doublefree.c:10)
+ Block was alloc'd at
+ at 0x........: malloc (vg_replace_malloc.c:...)
+ by 0x........: main (doublefree.c:8)
Address 0x........ is 5 bytes inside a block of size 10 free'd
at 0x........: free (vg_replace_malloc.c:...)
by 0x........: main (err_disable1.c:27)
+ Block was alloc'd at
+ at 0x........: malloc (vg_replace_malloc.c:...)
+ by 0x........: main (err_disable1.c:26)
--------- disabled (expect 0) ---------
Address 0x........ is 5 bytes inside a block of size 10 free'd
at 0x........: free (vg_replace_malloc.c:...)
by 0x........: main (err_disable1.c:27)
+ Block was alloc'd at
+ at 0x........: malloc (vg_replace_malloc.c:...)
+ by 0x........: main (err_disable1.c:26)
--------- MULTI-LEVEL TEST (expect 2) ---------
Address 0x........ is 5 bytes inside a block of size 10 free'd
at 0x........: free (vg_replace_malloc.c:...)
by 0x........: main (err_disable1.c:27)
+ Block was alloc'd at
+ at 0x........: malloc (vg_replace_malloc.c:...)
+ by 0x........: main (err_disable1.c:26)
Invalid read of size 1
at 0x........: err (err_disable1.c:21)
Address 0x........ is 5 bytes inside a block of size 10 free'd
at 0x........: free (vg_replace_malloc.c:...)
by 0x........: main (err_disable1.c:27)
+ Block was alloc'd at
+ at 0x........: malloc (vg_replace_malloc.c:...)
+ by 0x........: main (err_disable1.c:26)
--------- MULTI-LEVEL TEST end ---------
Address 0x........ is 5 bytes inside a block of size 10 free'd
at 0x........: free (vg_replace_malloc.c:...)
by 0x........: main (err_disable2.c:28)
+ Block was alloc'd at
+ at 0x........: malloc (vg_replace_malloc.c:...)
+ by 0x........: main (err_disable2.c:27)
--------- disabled (expect 0) ---------
Address 0x........ is 5 bytes inside a block of size 10 free'd
at 0x........: free (vg_replace_malloc.c:...)
by 0x........: main (err_disable3.c:42)
+ Block was alloc'd at
+ at 0x........: malloc (vg_replace_malloc.c:...)
+ by 0x........: main (err_disable3.c:41)
--------- c: end ---------
Address 0x........ is 5 bytes inside a block of size 10 free'd
at 0x........: free (vg_replace_malloc.c:...)
by 0x........: main (err_disable3.c:42)
+ Block was alloc'd at
+ at 0x........: malloc (vg_replace_malloc.c:...)
+ by 0x........: main (err_disable3.c:41)
Address 0x........ is 5 bytes inside a block of size 10 free'd
at 0x........: free (vg_replace_malloc.c:...)
by 0x........: main (err_disable4.c:81)
+ Block was alloc'd at
+ at 0x........: malloc (vg_replace_malloc.c:...)
+ by 0x........: main (err_disable4.c:80)
-------- Got 498 errors (expected 498 ==> PASS) ------
Address 0x........ is 492 bytes inside a block of size 4,000 free'd
at 0x........: free (vg_replace_malloc.c:...)
by 0x........: main (err_disable_arange1.c:15)
+ Block was alloc'd at
+ at 0x........: malloc (vg_replace_malloc.c:...)
+ by 0x........: main (err_disable_arange1.c:14)
Disabling address error reporting for the range.
Address 0x........ is 3,156 bytes inside a block of size 4,000 free'd
at 0x........: free (vg_replace_malloc.c:...)
by 0x........: main (err_disable_arange1.c:15)
+ Block was alloc'd at
+ at 0x........: malloc (vg_replace_malloc.c:...)
+ by 0x........: main (err_disable_arange1.c:14)
Exiting. Expect warnings of 2 remaining ranges.
-vgopts: -q
+vgopts: -q --keep-stacktraces=alloc-then-free
prog: fprw
at 0x........: free (vg_replace_malloc.c:...)
by 0x........: really (malloc1.c:19)
by 0x........: main (malloc1.c:9)
+ Block was alloc'd at
+ at 0x........: malloc (vg_replace_malloc.c:...)
+ by 0x........: really (malloc1.c:16)
+ by 0x........: main (malloc1.c:9)
Invalid write of size 1
at 0x........: really (malloc1.c:23)
Address 0x........ is 0 bytes inside a block of size 772 free'd
at 0x........: free (vg_replace_malloc.c:...)
by 0x........: main (malloc2.c:49)
+ Block was alloc'd at
+ at 0x........: malloc (vg_replace_malloc.c:...)
+ by 0x........: main (malloc2.c:41)
Invalid free() / delete / delete[] / realloc()
at 0x........: free (vg_replace_malloc.c:...)
Address 0x........ is 0 bytes inside a block of size 772 free'd
at 0x........: free (vg_replace_malloc.c:...)
by 0x........: main (malloc2.c:49)
+ Block was alloc'd at
+ at 0x........: malloc (vg_replace_malloc.c:...)
+ by 0x........: main (malloc2.c:41)
Address 0x........ is 0 bytes inside a block of size 111,110 free'd
at 0x........: free (vg_replace_malloc.c:...)
by 0x........: main (memalign_test.c:23)
+ Block was alloc'd at
+ at 0x........: memalign (vg_replace_malloc.c:...)
+ by 0x........: valloc (vg_replace_malloc.c:...)
+ by 0x........: main (memalign_test.c:16)
Address 0x........ is 5 bytes inside a block of size 10 free'd
at 0x........: free (vg_replace_malloc.c:...)
by 0x........: main (noisy_child.c:24)
+ Block was alloc'd at
+ at 0x........: malloc (vg_replace_malloc.c:...)
+ by 0x........: main (noisy_child.c:23)
Invalid write of size 1
at 0x........: do_parent_badness (noisy_child.c:16)
Address 0x........ is 0 bytes after a block of size 10 free'd
at 0x........: free (vg_replace_malloc.c:...)
by 0x........: main (noisy_child.c:24)
+ Block was alloc'd at
+ at 0x........: malloc (vg_replace_malloc.c:...)
+ by 0x........: main (noisy_child.c:23)
HEAP SUMMARY:
prog: partial_load
+vgopts: --keep-stacktraces=alloc-then-free
stderr_filter: filter_allocs
stderr_filter_args: partial_load.c
prog: partial_load
-vgopts: --partial-loads-ok=yes
+vgopts: --partial-loads-ok=yes --keep-stacktraces=alloc-then-free
stderr_filter: filter_allocs
stderr_filter_args: partial_load.c
by 0x........: bbb (suppfree.c:17)
by 0x........: aaa (suppfree.c:22)
by 0x........: main (suppfree.c:36)
+ Block was alloc'd at
+ at 0x........: malloc (vg_replace_malloc.c:...)
+ by 0x........: main (suppfree.c:32)
prog: test-plo
-vgopts: -q
+vgopts: -q --keep-stacktraces=alloc-then-free
prereq: ! ../../tests/arch_test ppc32 && ! ../../tests/arch_test ppc64 && ! ../../tests/arch_test s390x && ! ../../tests/mips_features mips-be
prog: test-plo
-vgopts: -q --partial-loads-ok=yes
+vgopts: -q --partial-loads-ok=yes --keep-stacktraces=alloc-then-free
prog: xml1
-vgopts: --xml=yes --xml-fd=2 --log-file=/dev/null
+vgopts: --xml=yes --xml-fd=2 --log-file=/dev/null --keep-stacktraces=alloc-then-free
stderr_filter: filter_xml