From: Paul Floyd Date: Thu, 9 Nov 2023 06:58:02 +0000 (+0100) Subject: Bug 475498 - Add reallocarray wrapper X-Git-Tag: VALGRIND_3_23_0~285 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=993cdf80a15ecf2cdaaa10a120cb29949f22605f;p=thirdparty%2Fvalgrind.git Bug 475498 - Add reallocarray wrapper --- diff --git a/.gitignore b/.gitignore index f743eb172c..da322ecf1d 100644 --- a/.gitignore +++ b/.gitignore @@ -1073,6 +1073,7 @@ /memcheck/tests/amd64-linux/access_below_sp /memcheck/tests/amd64-linux/defcfaexpr /memcheck/tests/amd64-linux/int3-amd64 +/memcheck/tests/amd64-linux/reallocarray /memcheck/tests/amd64-linux/Makefile /memcheck/tests/amd64-linux/Makefile.in @@ -1419,6 +1420,7 @@ /memcheck/tests/amd64-freebsd/Makefile.in /memcheck/tests/amd64-freebsd/posix_fadvise /memcheck/tests/amd64-freebsd/posix_fallocate +/memcheck/tests/amd64-freebsd/reallocarray /memcheck/tests/amd64-freebsd/reallocf # /memcheck/tests/x86-freebsd @@ -1431,6 +1433,7 @@ /memcheck/tests/x86-freebsd/Makefile.in /memcheck/tests/x86-freebsd/posix_fadvise /memcheck/tests/x86-freebsd/posix_fallocate +/memcheck/tests/x86-freebsd/reallocarray # /mpi/ /mpi/*.dSYM diff --git a/NEWS b/NEWS index d861150bf6..5b62d05260 100644 --- a/NEWS +++ b/NEWS @@ -23,6 +23,7 @@ bugzilla (https://bugs.kde.org/enter_bug.cgi?product=valgrind) rather than mailing the developers (or mailing lists) directly -- bugs that are not entered into bugzilla tend to get forgotten about or ignored. +475498 Add reallocarray wrapper 476320 Build failure with GCC 476535 Difference in allocation size for massif/tests/overloaded-new between clang++/libc++ and g++/libstdc++ diff --git a/coregrind/m_replacemalloc/vg_replace_malloc.c b/coregrind/m_replacemalloc/vg_replace_malloc.c index 7859f5f325..1e6764aee9 100644 --- a/coregrind/m_replacemalloc/vg_replace_malloc.c +++ b/coregrind/m_replacemalloc/vg_replace_malloc.c @@ -87,6 +87,8 @@ 10070 CALLOC 10080 ZONEREALLOC 10090 REALLOC + 10091 REALLOCF + 10092 REALLOCARRAY 10100 ZONEMEMALIGN 10110 MEMALIGN 10120 VALLOC @@ -1685,19 +1687,55 @@ extern int * __error(void) __attribute__((weak)); return v; \ } +#define REALLOCARRAY(soname, fnname) \ + \ + void* VG_REPLACE_FUNCTION_EZU(10092,soname,fnname) \ + ( void* ptrV, SizeT nmemb, SizeT size );\ + void* VG_REPLACE_FUNCTION_EZU(10092,soname,fnname) \ + ( void* ptrV, SizeT nmemb, SizeT size ) \ + { \ + void* v; \ + \ + DO_INIT; \ + TRIGGER_MEMCHECK_ERROR_IF_UNDEFINED(ptrV); \ + TRIGGER_MEMCHECK_ERROR_IF_UNDEFINED(nmemb); \ + TRIGGER_MEMCHECK_ERROR_IF_UNDEFINED(size); \ + MALLOC_TRACE("reallocarray(%p,%llu,%llu)", ptrV, (ULong)nmemb, (ULong)size ); \ + if (nmemb > 0 && (SizeT)-1 / nmemb < size) { \ + SET_ERRNO_ENOMEM; \ + return NULL; \ + } \ + v = (void*)VALGRIND_NON_SIMD_CALL2( info.tl_realloc, ptrV, nmemb*size ); \ + MALLOC_TRACE(" = %p\n", v ); \ + if (v == NULL) { \ + if (!(size*nmemb == 0U && info.clo_realloc_zero_bytes_frees == True)) {\ + VG_REPLACE_FUNCTION_EZU(10050,VG_Z_LIBC_SONAME,free)(ptrV); \ + SET_ERRNO_ENOMEM; \ + } \ + } \ + MALLOC_TRACE(" = %p\n", v ); \ + return v; \ + } + #if defined(VGO_linux) REALLOC(VG_Z_LIBC_SONAME, realloc); REALLOC(SO_SYN_MALLOC, realloc); + REALLOCARRAY(VG_Z_LIBC_SONAME, reallocarray); + REALLOCARRAY(SO_SYN_MALLOC, reallocarray); #elif defined(VGO_freebsd) REALLOC(VG_Z_LIBC_SONAME, realloc); REALLOC(SO_SYN_MALLOC, realloc); REALLOCF(VG_Z_LIBC_SONAME, reallocf); REALLOCF(SO_SYN_MALLOC, reallocf); + REALLOCARRAY(VG_Z_LIBC_SONAME, reallocarray); + REALLOCARRAY(SO_SYN_MALLOC, reallocarray); #elif defined(VGO_darwin) REALLOC(VG_Z_LIBC_SONAME, realloc); REALLOC(SO_SYN_MALLOC, realloc); + REALLOCF(VG_Z_LIBC_SONAME, reallocf); + REALLOCF(SO_SYN_MALLOC, reallocf); ZONEREALLOC(VG_Z_LIBC_SONAME, malloc_zone_realloc); ZONEREALLOC(SO_SYN_MALLOC, malloc_zone_realloc); @@ -1705,7 +1743,8 @@ extern int * __error(void) __attribute__((weak)); REALLOC(VG_Z_LIBC_SONAME, realloc); REALLOC(VG_Z_LIBUMEM_SO_1, realloc); REALLOC(SO_SYN_MALLOC, realloc); - + REALLOCARRAY(VG_Z_LIBC_SONAME, reallocarray); + REALLOCARRAY(SO_SYN_MALLOC, reallocarray); #endif diff --git a/memcheck/tests/amd64-freebsd/Makefile.am b/memcheck/tests/amd64-freebsd/Makefile.am index 1e663ab30c..e33607f20e 100644 --- a/memcheck/tests/amd64-freebsd/Makefile.am +++ b/memcheck/tests/amd64-freebsd/Makefile.am @@ -8,11 +8,13 @@ EXTRA_DIST = \ posix_fallocate.vgtest \ posix_fadvise.stderr.exp \ posix_fallocate.stderr.exp \ + reallocarray.vgtest \ + reallocarray.stderr.exp \ reallocf.vgtest \ reallocf.stderr.exp check_PROGRAMS = \ - posix_fadvise posix_fallocate reallocf + posix_fadvise posix_fallocate reallocarray reallocf AM_CFLAGS += @FLAG_M64@ AM_CXXFLAGS += @FLAG_M64@ diff --git a/memcheck/tests/amd64-freebsd/reallocarray.c b/memcheck/tests/amd64-freebsd/reallocarray.c new file mode 100644 index 0000000000..ee3a94d879 --- /dev/null +++ b/memcheck/tests/amd64-freebsd/reallocarray.c @@ -0,0 +1,30 @@ +#include +#include +#include +#include +#include "../../memcheck.h" + +int main(void) +{ + int *pi = NULL; + VALGRIND_DO_LEAK_CHECK; + pi = reallocarray(pi, 10U, sizeof(int)); + VALGRIND_DO_ADDED_LEAK_CHECK; + pi = reallocarray(pi, 0U, sizeof(int)); + VALGRIND_DO_ADDED_LEAK_CHECK; + pi = reallocarray(pi, 10U, 0U); + free(pi); + VALGRIND_DO_CHANGED_LEAK_CHECK; + pi = NULL; + pi = reallocarray(pi, 10U, sizeof(int)); + VALGRIND_DO_ADDED_LEAK_CHECK; + errno = 0; + pi = reallocarray(pi, 1UL << 49, 1U); + assert(!pi); + assert(errno == ENOMEM); + VALGRIND_DO_CHANGED_LEAK_CHECK; + pi = reallocarray(pi, SIZE_MAX/1000U, SIZE_MAX/1000U); + assert(!pi); + assert(errno == ENOMEM); + VALGRIND_DO_CHANGED_LEAK_CHECK; +} diff --git a/memcheck/tests/amd64-freebsd/reallocarray.stderr.exp b/memcheck/tests/amd64-freebsd/reallocarray.stderr.exp new file mode 100644 index 0000000000..2550709ab6 --- /dev/null +++ b/memcheck/tests/amd64-freebsd/reallocarray.stderr.exp @@ -0,0 +1,59 @@ + +All heap blocks were freed -- no leaks are possible + +LEAK SUMMARY: + definitely lost: 0 (+0) bytes in 0 (+0) blocks + indirectly lost: 0 (+0) bytes in 0 (+0) blocks + possibly lost: 0 (+0) bytes in 0 (+0) blocks + still reachable: 40 (+40) bytes in 1 (+1) blocks + suppressed: 0 (+0) bytes in 0 (+0) blocks +Reachable blocks (those to which a pointer was found) are not shown. +To see them, rerun with: --leak-check=full --show-leak-kinds=all + +realloc() with size 0 + at 0x........: reallocarray (vg_replace_malloc.c:...) + by 0x........: main (reallocarray.c:13) + Address 0x........ is 0 bytes inside a block of size 40 alloc'd + at 0x........: reallocarray (vg_replace_malloc.c:...) + by 0x........: main (reallocarray.c:11) + +LEAK SUMMARY: + definitely lost: 0 (+0) bytes in 0 (+0) blocks + indirectly lost: 0 (+0) bytes in 0 (+0) blocks + possibly lost: 0 (+0) bytes in 0 (+0) blocks + still reachable: 1 (-39) bytes in 1 (+0) blocks + suppressed: 0 (+0) bytes in 0 (+0) blocks +Reachable blocks (those to which a pointer was found) are not shown. +To see them, rerun with: --leak-check=full --show-leak-kinds=all + +realloc() with size 0 + at 0x........: reallocarray (vg_replace_malloc.c:...) + by 0x........: main (reallocarray.c:15) + Address 0x........ is 0 bytes inside a block of size 1 alloc'd + at 0x........: reallocarray (vg_replace_malloc.c:...) + by 0x........: main (reallocarray.c:13) + +All heap blocks were freed -- no leaks are possible + +LEAK SUMMARY: + definitely lost: 0 (+0) bytes in 0 (+0) blocks + indirectly lost: 0 (+0) bytes in 0 (+0) blocks + possibly lost: 0 (+0) bytes in 0 (+0) blocks + still reachable: 40 (+39) bytes in 1 (+0) blocks + suppressed: 0 (+0) bytes in 0 (+0) blocks +Reachable blocks (those to which a pointer was found) are not shown. +To see them, rerun with: --leak-check=full --show-leak-kinds=all + +All heap blocks were freed -- no leaks are possible + +All heap blocks were freed -- no leaks are possible + + +HEAP SUMMARY: + in use at exit: 0 bytes in 0 blocks + total heap usage: 5 allocs, 5 frees, 562,949,953,421,394 bytes allocated + +For a detailed leak analysis, rerun with: --leak-check=full + +For lists of detected and suppressed errors, rerun with: -s +ERROR SUMMARY: 2 errors from 2 contexts (suppressed: 0 from 0) diff --git a/memcheck/tests/amd64-freebsd/reallocarray.vgtest b/memcheck/tests/amd64-freebsd/reallocarray.vgtest new file mode 100644 index 0000000000..4d8878fc68 --- /dev/null +++ b/memcheck/tests/amd64-freebsd/reallocarray.vgtest @@ -0,0 +1,2 @@ +prereq: test -e ./reallocarray +prog: reallocarray diff --git a/memcheck/tests/amd64-linux/Makefile.am b/memcheck/tests/amd64-linux/Makefile.am index 94f5d0f143..9000dce0b7 100644 --- a/memcheck/tests/amd64-linux/Makefile.am +++ b/memcheck/tests/amd64-linux/Makefile.am @@ -10,12 +10,14 @@ EXTRA_DIST = \ access_below_sp_2.vgtest \ access_below_sp_2.stderr.exp access_below_sp_2.stdout.exp \ defcfaexpr.vgtest defcfaexpr.stderr.exp \ - int3-amd64.vgtest int3-amd64.stderr.exp int3-amd64.stdout.exp + int3-amd64.vgtest int3-amd64.stderr.exp int3-amd64.stdout.exp \ + reallocarray.vgtest reallocarray.stderr.exp check_PROGRAMS = \ access_below_sp \ defcfaexpr \ - int3-amd64 + int3-amd64 \ + reallocarray AM_CFLAGS += @FLAG_M64@ diff --git a/memcheck/tests/amd64-linux/reallocarray.c b/memcheck/tests/amd64-linux/reallocarray.c new file mode 100644 index 0000000000..8765ca4997 --- /dev/null +++ b/memcheck/tests/amd64-linux/reallocarray.c @@ -0,0 +1,30 @@ +#include +#include +#include +#include +#include "../../memcheck.h" + +int main(void) +{ + int *pi = NULL; + VALGRIND_DO_LEAK_CHECK; + pi = reallocarray(pi, 10U, sizeof(int)); + VALGRIND_DO_ADDED_LEAK_CHECK; + pi = reallocarray(pi, 0U, sizeof(int)); + VALGRIND_DO_ADDED_LEAK_CHECK; + pi = malloc(10U); + pi = reallocarray(pi, 10U, 0U); + VALGRIND_DO_CHANGED_LEAK_CHECK; + pi = NULL; + pi = reallocarray(pi, 10U, sizeof(int)); + VALGRIND_DO_ADDED_LEAK_CHECK; + errno = 0; + pi = reallocarray(pi, 1UL << 49, 1U); + assert(!pi); + assert(errno == ENOMEM); + VALGRIND_DO_CHANGED_LEAK_CHECK; + pi = reallocarray(pi, SIZE_MAX/1000U, SIZE_MAX/1000U); + assert(!pi); + assert(errno == ENOMEM); + VALGRIND_DO_CHANGED_LEAK_CHECK; +} diff --git a/memcheck/tests/amd64-linux/reallocarray.stderr.exp b/memcheck/tests/amd64-linux/reallocarray.stderr.exp new file mode 100644 index 0000000000..a1c8439cc9 --- /dev/null +++ b/memcheck/tests/amd64-linux/reallocarray.stderr.exp @@ -0,0 +1,52 @@ + +All heap blocks were freed -- no leaks are possible + +LEAK SUMMARY: + definitely lost: 0 (+0) bytes in 0 (+0) blocks + indirectly lost: 0 (+0) bytes in 0 (+0) blocks + possibly lost: 0 (+0) bytes in 0 (+0) blocks + still reachable: 40 (+40) bytes in 1 (+1) blocks + suppressed: 0 (+0) bytes in 0 (+0) blocks +Reachable blocks (those to which a pointer was found) are not shown. +To see them, rerun with: --leak-check=full --show-leak-kinds=all + +realloc() with size 0 + at 0x........: reallocarray (vg_replace_malloc.c:...) + by 0x........: main (reallocarray.c:13) + Address 0x........ is 0 bytes inside a block of size 40 alloc'd + at 0x........: reallocarray (vg_replace_malloc.c:...) + by 0x........: main (reallocarray.c:11) + +All heap blocks were freed -- no leaks are possible + +realloc() with size 0 + at 0x........: reallocarray (vg_replace_malloc.c:...) + by 0x........: main (reallocarray.c:16) + Address 0x........ is 0 bytes inside a block of size 10 alloc'd + at 0x........: malloc (vg_replace_malloc.c:...) + by 0x........: main (reallocarray.c:15) + +All heap blocks were freed -- no leaks are possible + +LEAK SUMMARY: + definitely lost: 0 (+0) bytes in 0 (+0) blocks + indirectly lost: 0 (+0) bytes in 0 (+0) blocks + possibly lost: 0 (+0) bytes in 0 (+0) blocks + still reachable: 40 (+0) bytes in 1 (+0) blocks + suppressed: 0 (+0) bytes in 0 (+0) blocks +Reachable blocks (those to which a pointer was found) are not shown. +To see them, rerun with: --leak-check=full --show-leak-kinds=all + +All heap blocks were freed -- no leaks are possible + +All heap blocks were freed -- no leaks are possible + + +HEAP SUMMARY: + in use at exit: 0 bytes in 0 blocks + total heap usage: 4 allocs, 4 frees, 562,949,953,421,402 bytes allocated + +For a detailed leak analysis, rerun with: --leak-check=full + +For lists of detected and suppressed errors, rerun with: -s +ERROR SUMMARY: 2 errors from 2 contexts (suppressed: 0 from 0) diff --git a/memcheck/tests/amd64-linux/reallocarray.vgtest b/memcheck/tests/amd64-linux/reallocarray.vgtest new file mode 100644 index 0000000000..4d8878fc68 --- /dev/null +++ b/memcheck/tests/amd64-linux/reallocarray.vgtest @@ -0,0 +1,2 @@ +prereq: test -e ./reallocarray +prog: reallocarray diff --git a/memcheck/tests/x86-freebsd/Makefile.am b/memcheck/tests/x86-freebsd/Makefile.am index 116c7186a3..913914a043 100644 --- a/memcheck/tests/x86-freebsd/Makefile.am +++ b/memcheck/tests/x86-freebsd/Makefile.am @@ -7,10 +7,12 @@ EXTRA_DIST = \ posix_fadvise.vgtest \ posix_fallocate.vgtest \ posix_fadvise.stderr.exp \ - posix_fallocate.stderr.exp + posix_fallocate.stderr.exp \ + reallocarray.vgtest \ + reallocarray.stderr.exp check_PROGRAMS = \ - posix_fadvise posix_fallocate + posix_fadvise posix_fallocate reallocarray # Linux also adds $(FLAG_MMMX) $(FLAG_MSSE) to the first two AM_CFLAGS += @FLAG_M32@ diff --git a/memcheck/tests/x86-freebsd/reallocarray.c b/memcheck/tests/x86-freebsd/reallocarray.c new file mode 100644 index 0000000000..5004c66691 --- /dev/null +++ b/memcheck/tests/x86-freebsd/reallocarray.c @@ -0,0 +1,26 @@ +#include +#include +#include +#include +#include "../../memcheck.h" + +int main(void) +{ + int *pi = NULL; + VALGRIND_DO_LEAK_CHECK; + pi = reallocarray(pi, 10U, sizeof(int)); + VALGRIND_DO_ADDED_LEAK_CHECK; + pi = reallocarray(pi, 0U, sizeof(int)); + VALGRIND_DO_ADDED_LEAK_CHECK; + pi = reallocarray(pi, 10U, 0U); + free(pi); + VALGRIND_DO_CHANGED_LEAK_CHECK; + pi = NULL; + pi = reallocarray(pi, 10U, sizeof(int)); + VALGRIND_DO_ADDED_LEAK_CHECK; + VALGRIND_DO_CHANGED_LEAK_CHECK; + pi = reallocarray(pi, SIZE_MAX/1000U, SIZE_MAX/1000U); + assert(!pi); + assert(errno == ENOMEM); + VALGRIND_DO_CHANGED_LEAK_CHECK; +} diff --git a/memcheck/tests/x86-freebsd/reallocarray.stderr.exp b/memcheck/tests/x86-freebsd/reallocarray.stderr.exp new file mode 100644 index 0000000000..e40310ffb8 --- /dev/null +++ b/memcheck/tests/x86-freebsd/reallocarray.stderr.exp @@ -0,0 +1,73 @@ + +All heap blocks were freed -- no leaks are possible + +LEAK SUMMARY: + definitely lost: 0 (+0) bytes in 0 (+0) blocks + indirectly lost: 0 (+0) bytes in 0 (+0) blocks + possibly lost: 0 (+0) bytes in 0 (+0) blocks + still reachable: 40 (+40) bytes in 1 (+1) blocks + suppressed: 0 (+0) bytes in 0 (+0) blocks +Reachable blocks (those to which a pointer was found) are not shown. +To see them, rerun with: --leak-check=full --show-leak-kinds=all + +realloc() with size 0 + at 0x........: reallocarray (vg_replace_malloc.c:...) + by 0x........: main (reallocarray.c:13) + Address 0x........ is 0 bytes inside a block of size 40 alloc'd + at 0x........: reallocarray (vg_replace_malloc.c:...) + by 0x........: main (reallocarray.c:11) + +LEAK SUMMARY: + definitely lost: 0 (+0) bytes in 0 (+0) blocks + indirectly lost: 0 (+0) bytes in 0 (+0) blocks + possibly lost: 0 (+0) bytes in 0 (+0) blocks + still reachable: 1 (-39) bytes in 1 (+0) blocks + suppressed: 0 (+0) bytes in 0 (+0) blocks +Reachable blocks (those to which a pointer was found) are not shown. +To see them, rerun with: --leak-check=full --show-leak-kinds=all + +realloc() with size 0 + at 0x........: reallocarray (vg_replace_malloc.c:...) + by 0x........: main (reallocarray.c:15) + Address 0x........ is 0 bytes inside a block of size 1 alloc'd + at 0x........: reallocarray (vg_replace_malloc.c:...) + by 0x........: main (reallocarray.c:13) + +All heap blocks were freed -- no leaks are possible + +LEAK SUMMARY: + definitely lost: 0 (+0) bytes in 0 (+0) blocks + indirectly lost: 0 (+0) bytes in 0 (+0) blocks + possibly lost: 0 (+0) bytes in 0 (+0) blocks + still reachable: 40 (+39) bytes in 1 (+0) blocks + suppressed: 0 (+0) bytes in 0 (+0) blocks +Reachable blocks (those to which a pointer was found) are not shown. +To see them, rerun with: --leak-check=full --show-leak-kinds=all + +LEAK SUMMARY: + definitely lost: 0 (+0) bytes in 0 (+0) blocks + indirectly lost: 0 (+0) bytes in 0 (+0) blocks + possibly lost: 0 (+0) bytes in 0 (+0) blocks + still reachable: 40 (+0) bytes in 1 (+0) blocks + suppressed: 0 (+0) bytes in 0 (+0) blocks +Reachable blocks (those to which a pointer was found) are not shown. +To see them, rerun with: --leak-check=full --show-leak-kinds=all + +LEAK SUMMARY: + definitely lost: 0 (+0) bytes in 0 (+0) blocks + indirectly lost: 0 (+0) bytes in 0 (+0) blocks + possibly lost: 0 (+0) bytes in 0 (+0) blocks + still reachable: 40 (+0) bytes in 1 (+0) blocks + suppressed: 0 (+0) bytes in 0 (+0) blocks +Reachable blocks (those to which a pointer was found) are not shown. +To see them, rerun with: --leak-check=full --show-leak-kinds=all + + +HEAP SUMMARY: + in use at exit: 40 bytes in 1 blocks + total heap usage: 4 allocs, 3 frees, 82 bytes allocated + +For a detailed leak analysis, rerun with: --leak-check=full + +For lists of detected and suppressed errors, rerun with: -s +ERROR SUMMARY: 2 errors from 2 contexts (suppressed: 0 from 0) diff --git a/memcheck/tests/x86-freebsd/reallocarray.vgtest b/memcheck/tests/x86-freebsd/reallocarray.vgtest new file mode 100644 index 0000000000..4d8878fc68 --- /dev/null +++ b/memcheck/tests/x86-freebsd/reallocarray.vgtest @@ -0,0 +1,2 @@ +prereq: test -e ./reallocarray +prog: reallocarray