]> git.ipfire.org Git - thirdparty/valgrind.git/commitdiff
FreeBSD reallocarray: behaves like realloc on allocation failure
authorPaul Floyd <pjfloyd@wanadoo.fr>
Sun, 8 Feb 2026 16:57:30 +0000 (17:57 +0100)
committerPaul Floyd <pjfloyd@wanadoo.fr>
Sun, 8 Feb 2026 16:57:30 +0000 (17:57 +0100)
It was behaving like reallocf which frees the ptr if the allocation
fails. That's wrong, it behaves like realloc which does not free
ptr. Updated the one regression test.

I also noticed that the error message always mentions realloc
even for reallocf and reallocarray.

coregrind/m_replacemalloc/vg_replace_malloc.c
memcheck/tests/amd64-freebsd/reallocarray.c
memcheck/tests/amd64-freebsd/reallocarray.stderr.exp

index 12b01f678dd4ea6b469133fa3df36fc59b9091b1..5672eda097eaf3e21cccd6e364d16576145be9d2 100644 (file)
@@ -1729,7 +1729,6 @@ extern int * __error(void) __attribute__((weak));
       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; \
       } \
    } \
index ee3a94d879148ebeb657731d3f5828f05cbc8629..24ed47072cc8f3b7b8f6cec51dc0988f48025bdc 100644 (file)
@@ -2,29 +2,46 @@
 #include <assert.h>
 #include <errno.h>
 #include <stdint.h>
+#include <stdio.h>
 #include "../../memcheck.h"
 
 int main(void)
 {
    int *pi = NULL;
+   int *newpi;
    VALGRIND_DO_LEAK_CHECK;
+   /* should succeed */
    pi = reallocarray(pi, 10U, sizeof(int));
+   assert(pi);
+   fprintf(stderr, "Added leak check, expect 40 bytes still reachable\n");
    VALGRIND_DO_ADDED_LEAK_CHECK;
+   /* on FreeBSD this does not free pi */
    pi = reallocarray(pi, 0U, sizeof(int));
+   assert(pi);
+   fprintf(stderr, "Added leak check, expect 1 byte still reachable\n");
    VALGRIND_DO_ADDED_LEAK_CHECK;
    pi = reallocarray(pi, 10U, 0U);
+   assert(pi);
    free(pi);
+   fprintf(stderr, "Added leak check, expect all blocks freed\n");
    VALGRIND_DO_CHANGED_LEAK_CHECK;
    pi = NULL;
    pi = reallocarray(pi, 10U, sizeof(int));
+   assert(pi);
+   fprintf(stderr, "Added leak check, expect 40 bytes still reachable\n");
    VALGRIND_DO_ADDED_LEAK_CHECK;
    errno = 0;
-   pi = reallocarray(pi, 1UL << 49, 1U);
-   assert(!pi);
+   /* this will fail in the mallloc lib, not enough memory */
+   newpi = reallocarray(pi, 1UL << 49, 1U);
+   assert(!newpi);
    assert(errno == ENOMEM);
+   fprintf(stderr, "Added leak check, expect 40 bytes still reachable\n");
    VALGRIND_DO_CHANGED_LEAK_CHECK;
-   pi = reallocarray(pi, SIZE_MAX/1000U, SIZE_MAX/1000U);
-   assert(!pi);
+   /* this will fail the reallocarray precondition */
+   newpi = reallocarray(pi, SIZE_MAX/1000U, SIZE_MAX/1000U);
+   assert(!newpi);
    assert(errno == ENOMEM);
+   free(pi);
+   fprintf(stderr, "Added leak check, expect all blocks freed\n");
    VALGRIND_DO_CHANGED_LEAK_CHECK;
 }
index 2550709ab6ebd09fcc48e6a245a9c26ecd1bc34a..c5dac41c5dc7e1b02ca06a6d326f5dd6c82b042a 100644 (file)
@@ -1,6 +1,7 @@
 
 All heap blocks were freed -- no leaks are possible
 
+Added leak check, expect 40 bytes still reachable
 LEAK SUMMARY:
    definitely lost: 0 (+0) bytes in 0 (+0) blocks
    indirectly lost: 0 (+0) bytes in 0 (+0) blocks
@@ -12,11 +13,12 @@ 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)
+   by 0x........: main (reallocarray.c:19)
  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)
+   by 0x........: main (reallocarray.c:14)
 
+Added leak check, expect 1 byte still reachable
 LEAK SUMMARY:
    definitely lost: 0 (+0) bytes in 0 (+0) blocks
    indirectly lost: 0 (+0) bytes in 0 (+0) blocks
@@ -28,13 +30,15 @@ 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)
+   by 0x........: main (reallocarray.c:23)
  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)
+   by 0x........: main (reallocarray.c:19)
 
+Added leak check, expect all blocks freed
 All heap blocks were freed -- no leaks are possible
 
+Added leak check, expect 40 bytes still reachable
 LEAK SUMMARY:
    definitely lost: 0 (+0) bytes in 0 (+0) blocks
    indirectly lost: 0 (+0) bytes in 0 (+0) blocks
@@ -44,8 +48,17 @@ LEAK SUMMARY:
 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
+Added leak check, expect 40 bytes still reachable
+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
 
+Added leak check, expect all blocks freed
 All heap blocks were freed -- no leaks are possible