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 {
if (mc->size == new_size) {
/* size unchanged */
+ mc->where = VG_(get_ExeContext)(tid);
VGP_POPCC(VgpCliMalloc);
return p;
/* 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;
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 \
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
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
--- /dev/null
+/* 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 <stdlib.h>
+
+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;
+}
--- /dev/null
+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........: ...
--- /dev/null
+prog: realloc3
+vgopts: -q