diff --git a/helgrind/hg_main.c b/helgrind/hg_main.c index d95173e41..9a03ca402 100644 --- a/helgrind/hg_main.c +++ b/helgrind/hg_main.c @@ -1965,11 +1965,13 @@ void* SK_(realloc) ( void* p, Int new_size ) if (hc->size == new_size) { /* size unchanged */ + hc->where = VG_(get_ExeContext)(tid); return p; } else if (hc->size > new_size) { /* new size is smaller */ hc->size = new_size; + hc->where = VG_(get_ExeContext)(tid); return p; } else { diff --git a/memcheck/mac_malloc_wrappers.c b/memcheck/mac_malloc_wrappers.c index 879bffd3b..536cc2e12 100644 --- a/memcheck/mac_malloc_wrappers.c +++ b/memcheck/mac_malloc_wrappers.c @@ -354,6 +354,7 @@ void* SK_(realloc) ( void* p, Int new_size ) if (mc->size == new_size) { /* size unchanged */ + mc->where = VG_(get_ExeContext)(tid); VGP_POPCC(VgpCliMalloc); return p; @@ -361,6 +362,7 @@ void* SK_(realloc) ( void* p, Int new_size ) /* new size is smaller */ MAC_(die_mem_heap)( mc->data+new_size, mc->size-new_size ); mc->size = new_size; + mc->where = VG_(get_ExeContext)(tid); VGP_POPCC(VgpCliMalloc); return p; diff --git a/memcheck/tests/Makefile.am b/memcheck/tests/Makefile.am index 86b20a398..4f9dc16aa 100644 --- a/memcheck/tests/Makefile.am +++ b/memcheck/tests/Makefile.am @@ -44,6 +44,7 @@ EXTRA_DIST = $(noinst_SCRIPTS) \ pushfpopf.stderr.exp pushfpopf.stdout.exp pushfpopf.vgtest \ realloc1.stderr.exp realloc1.vgtest \ realloc2.stderr.exp realloc2.vgtest \ + realloc3.stderr.exp realloc3.vgtest \ sigaltstack.stderr.exp sigaltstack.vgtest \ signal2.stderr.exp \ signal2.stdout.exp signal2.vgtest \ @@ -64,7 +65,7 @@ check_PROGRAMS = \ malloc1 malloc2 malloc3 manuel1 manuel2 manuel3 \ memalign_test memcmptest mmaptest nanoleak null_socket \ overlap pushfpopf \ - realloc1 realloc2 sigaltstack signal2 supp1 supp2 suppfree \ + realloc1 realloc2 realloc3 sigaltstack signal2 supp1 supp2 suppfree \ trivialleak tronical weirdioctl \ mismatches new_override metadata threadederrno @@ -103,6 +104,7 @@ overlap_SOURCES = overlap.c pushfpopf_SOURCES = pushfpopf_c.c pushfpopf_s.s realloc1_SOURCES = realloc1.c realloc2_SOURCES = realloc2.c +realloc3_SOURCES = realloc3.c signal2_SOURCES = signal2.c supp1_SOURCES = supp.c supp2_SOURCES = supp.c diff --git a/memcheck/tests/realloc3.c b/memcheck/tests/realloc3.c new file mode 100644 index 000000000..0c6a5f8a0 --- /dev/null +++ b/memcheck/tests/realloc3.c @@ -0,0 +1,28 @@ +/* For a long time (from Valgrind 1.0 to 1.9.6, AFAICT) when realloc() was + called and made a block smaller, or didn't change its size, the + ExeContext of the block was not updated; therefore any errors that + referred to it would state that it was allocated not by the realloc(), + but by the previous malloc() or whatever. While this is true in one + sense, it is misleading and not what you'd expect. This test + demonstrates this -- 'x' and 'y' are unchanged and shrunk, and their + ExeContexts should be updated upon their realloc(). I hope that's clear. +*/ +#include + +int main(void) +{ + int* x = malloc(5); + int* y = malloc(10); + int* z = malloc(2); + int a, b, c; + + x = realloc(x, 5); // same size + y = realloc(y, 5); // make smaller + z = realloc(z, 5); // make bigger + + a = (x[5] == 0xdeadbeef ? 1 : 0); + b = (y[5] == 0xdeadbeef ? 1 : 0); + c = (z[5] == 0xdeadbeef ? 1 : 0); + + return a + b + c; +} diff --git a/memcheck/tests/realloc3.stderr.exp b/memcheck/tests/realloc3.stderr.exp new file mode 100644 index 000000000..67041889c --- /dev/null +++ b/memcheck/tests/realloc3.stderr.exp @@ -0,0 +1,29 @@ +Invalid read of size 4 + at 0x........: main (realloc3.c:23) + by 0x........: __libc_start_main (...libc...) + by 0x........: ... + Address 0x........ is 15 bytes after a block of size 5 alloc'd + at 0x........: realloc (vg_replace_malloc.c:...) + by 0x........: main (realloc3.c:19) + by 0x........: __libc_start_main (...libc...) + by 0x........: ... + +Invalid read of size 4 + at 0x........: main (realloc3.c:24) + by 0x........: __libc_start_main (...libc...) + by 0x........: ... + Address 0x........ is 15 bytes after a block of size 5 alloc'd + at 0x........: realloc (vg_replace_malloc.c:...) + by 0x........: main (realloc3.c:20) + by 0x........: __libc_start_main (...libc...) + by 0x........: ... + +Invalid read of size 4 + at 0x........: main (realloc3.c:25) + by 0x........: __libc_start_main (...libc...) + by 0x........: ... + Address 0x........ is 15 bytes after a block of size 5 alloc'd + at 0x........: realloc (vg_replace_malloc.c:...) + by 0x........: main (realloc3.c:21) + by 0x........: __libc_start_main (...libc...) + by 0x........: ... diff --git a/memcheck/tests/realloc3.vgtest b/memcheck/tests/realloc3.vgtest new file mode 100644 index 000000000..ff295abac --- /dev/null +++ b/memcheck/tests/realloc3.vgtest @@ -0,0 +1,2 @@ +prog: realloc3 +vgopts: -q