diff --git a/NEWS b/NEWS index a86170091..ae0ad720a 100644 --- a/NEWS +++ b/NEWS @@ -33,6 +33,12 @@ X86/MacOSX 10.10 and 10.11 and AMD64/MacOSX 10.10 and 10.11. * 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 ' shows the validity bits of bytes at . The monitor command 'xb' is easier to use than get_vbits when you need to associate byte data value with diff --git a/memcheck/docs/mc-manual.xml b/memcheck/docs/mc-manual.xml index 4b70e64a1..1aa7eff3e 100644 --- a/memcheck/docs/mc-manual.xml +++ b/memcheck/docs/mc-manual.xml @@ -990,7 +990,7 @@ is - + Controls which stack trace(s) to keep for malloc'd and/or diff --git a/memcheck/mc_main.c b/memcheck/mc_main.c index 674a50d71..e3ed7139a 100644 --- a/memcheck/mc_main.c +++ b/memcheck/mc_main.c @@ -5708,7 +5708,7 @@ UInt MC_(clo_leak_check_heuristics) = 0; 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; @@ -5907,7 +5907,7 @@ static void mc_print_usage(void) " --malloc-fill= fill malloc'd areas with given value\n" " --free-fill= 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 ); diff --git a/memcheck/tests/big_blocks_freed_list.stderr.exp b/memcheck/tests/big_blocks_freed_list.stderr.exp index 3c4c7286f..d0fd803a6 100644 --- a/memcheck/tests/big_blocks_freed_list.stderr.exp +++ b/memcheck/tests/big_blocks_freed_list.stderr.exp @@ -4,12 +4,18 @@ Invalid read of size 1 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) @@ -20,24 +26,36 @@ Invalid read of size 1 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: diff --git a/memcheck/tests/cond_ld.vgtest b/memcheck/tests/cond_ld.vgtest index acc0bfe04..5c83e2689 100644 --- a/memcheck/tests/cond_ld.vgtest +++ b/memcheck/tests/cond_ld.vgtest @@ -1,4 +1,4 @@ prog: cond_ld_st args: loads -vgopts: -q +vgopts: -q --keep-stacktraces=alloc-then-free stderr_filter_args: cond_ld_st diff --git a/memcheck/tests/cond_st.vgtest b/memcheck/tests/cond_st.vgtest index 2ccf00c4a..fbb8181a7 100644 --- a/memcheck/tests/cond_st.vgtest +++ b/memcheck/tests/cond_st.vgtest @@ -1,4 +1,4 @@ prog: cond_ld_st args: stores -vgopts: -q +vgopts: -q --keep-stacktraces=alloc-then-free stderr_filter_args: cond_ld_st diff --git a/memcheck/tests/custom_alloc.vgtest b/memcheck/tests/custom_alloc.vgtest index 9c7fa4106..047275632 100644 --- a/memcheck/tests/custom_alloc.vgtest +++ b/memcheck/tests/custom_alloc.vgtest @@ -1,2 +1,2 @@ prog: custom_alloc -vgopts: -q +vgopts: -q --keep-stacktraces=alloc-then-free diff --git a/memcheck/tests/doublefree.stderr.exp b/memcheck/tests/doublefree.stderr.exp index 9ed5375c7..7560e3a77 100644 --- a/memcheck/tests/doublefree.stderr.exp +++ b/memcheck/tests/doublefree.stderr.exp @@ -4,4 +4,7 @@ Invalid free() / delete / delete[] / realloc() 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) diff --git a/memcheck/tests/err_disable1.stderr.exp b/memcheck/tests/err_disable1.stderr.exp index 8762bf1d4..02bf2599d 100644 --- a/memcheck/tests/err_disable1.stderr.exp +++ b/memcheck/tests/err_disable1.stderr.exp @@ -10,6 +10,9 @@ Invalid read of size 1 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) --------- @@ -23,6 +26,9 @@ Invalid read of size 1 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) --------- @@ -33,6 +39,9 @@ Invalid read of size 1 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) @@ -40,6 +49,9 @@ Invalid read of size 1 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 --------- diff --git a/memcheck/tests/err_disable2.stderr.exp b/memcheck/tests/err_disable2.stderr.exp index 82cd04f44..7146da7a0 100644 --- a/memcheck/tests/err_disable2.stderr.exp +++ b/memcheck/tests/err_disable2.stderr.exp @@ -7,6 +7,9 @@ Invalid read of size 1 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) --------- diff --git a/memcheck/tests/err_disable3.stderr.exp b/memcheck/tests/err_disable3.stderr.exp index 0f1f8b770..2b6d74d6e 100644 --- a/memcheck/tests/err_disable3.stderr.exp +++ b/memcheck/tests/err_disable3.stderr.exp @@ -15,6 +15,9 @@ Invalid read of size 1 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 --------- @@ -32,4 +35,7 @@ Invalid read of size 1 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) diff --git a/memcheck/tests/err_disable4.stderr.exp b/memcheck/tests/err_disable4.stderr.exp index cfacfd783..acc01ad82 100644 --- a/memcheck/tests/err_disable4.stderr.exp +++ b/memcheck/tests/err_disable4.stderr.exp @@ -1506,6 +1506,9 @@ Invalid read of size 1 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) ------ diff --git a/memcheck/tests/err_disable_arange1.stderr.exp b/memcheck/tests/err_disable_arange1.stderr.exp index cb6a2db62..35257d16c 100644 --- a/memcheck/tests/err_disable_arange1.stderr.exp +++ b/memcheck/tests/err_disable_arange1.stderr.exp @@ -6,6 +6,9 @@ Invalid write of size 4 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. @@ -24,6 +27,9 @@ Invalid write of size 4 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. diff --git a/memcheck/tests/fprw.vgtest b/memcheck/tests/fprw.vgtest index 6dfbf0cb4..4179391b1 100644 --- a/memcheck/tests/fprw.vgtest +++ b/memcheck/tests/fprw.vgtest @@ -1,2 +1,2 @@ -vgopts: -q +vgopts: -q --keep-stacktraces=alloc-then-free prog: fprw diff --git a/memcheck/tests/malloc1.stderr.exp b/memcheck/tests/malloc1.stderr.exp index b440a8380..bbf804122 100644 --- a/memcheck/tests/malloc1.stderr.exp +++ b/memcheck/tests/malloc1.stderr.exp @@ -5,6 +5,10 @@ Invalid write of size 1 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) diff --git a/memcheck/tests/malloc2.stderr.exp b/memcheck/tests/malloc2.stderr.exp index f1a075b65..36fb84823 100644 --- a/memcheck/tests/malloc2.stderr.exp +++ b/memcheck/tests/malloc2.stderr.exp @@ -3,6 +3,9 @@ Invalid write of size 1 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:...) @@ -10,4 +13,7 @@ Invalid free() / delete / delete[] / realloc() 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) diff --git a/memcheck/tests/memalign_test.stderr.exp b/memcheck/tests/memalign_test.stderr.exp index aa8d58833..e9dc1afe5 100644 --- a/memcheck/tests/memalign_test.stderr.exp +++ b/memcheck/tests/memalign_test.stderr.exp @@ -4,4 +4,8 @@ Invalid free() / delete / delete[] / realloc() 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) diff --git a/memcheck/tests/noisy_child.stderr.exp b/memcheck/tests/noisy_child.stderr.exp index 2f583438b..675fc643d 100644 --- a/memcheck/tests/noisy_child.stderr.exp +++ b/memcheck/tests/noisy_child.stderr.exp @@ -4,6 +4,9 @@ Invalid write of size 1 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) @@ -11,6 +14,9 @@ Invalid write of size 1 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: diff --git a/memcheck/tests/partial_load_dflt.vgtest b/memcheck/tests/partial_load_dflt.vgtest index b1c6b27c4..a95bb6289 100644 --- a/memcheck/tests/partial_load_dflt.vgtest +++ b/memcheck/tests/partial_load_dflt.vgtest @@ -1,3 +1,4 @@ prog: partial_load +vgopts: --keep-stacktraces=alloc-then-free stderr_filter: filter_allocs stderr_filter_args: partial_load.c diff --git a/memcheck/tests/partial_load_ok.vgtest b/memcheck/tests/partial_load_ok.vgtest index d4003a77d..0c9caa108 100644 --- a/memcheck/tests/partial_load_ok.vgtest +++ b/memcheck/tests/partial_load_ok.vgtest @@ -1,4 +1,4 @@ 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 diff --git a/memcheck/tests/suppfree.stderr.exp b/memcheck/tests/suppfree.stderr.exp index 62f5cccc7..0340e61c1 100644 --- a/memcheck/tests/suppfree.stderr.exp +++ b/memcheck/tests/suppfree.stderr.exp @@ -12,4 +12,7 @@ Invalid free() / delete / delete[] / realloc() 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) diff --git a/memcheck/tests/test-plo-no.vgtest b/memcheck/tests/test-plo-no.vgtest index 247a13489..14d4be32e 100644 --- a/memcheck/tests/test-plo-no.vgtest +++ b/memcheck/tests/test-plo-no.vgtest @@ -1,2 +1,2 @@ prog: test-plo -vgopts: -q +vgopts: -q --keep-stacktraces=alloc-then-free diff --git a/memcheck/tests/test-plo-yes.vgtest b/memcheck/tests/test-plo-yes.vgtest index ace614cec..b37aeb5d3 100644 --- a/memcheck/tests/test-plo-yes.vgtest +++ b/memcheck/tests/test-plo-yes.vgtest @@ -1,3 +1,3 @@ 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 diff --git a/memcheck/tests/xml1.vgtest b/memcheck/tests/xml1.vgtest index 4d83a9faa..6585b18f4 100644 --- a/memcheck/tests/xml1.vgtest +++ b/memcheck/tests/xml1.vgtest @@ -1,3 +1,3 @@ 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