]> git.ipfire.org Git - thirdparty/valgrind.git/commitdiff
Bug 466104 - aligned_alloc problems, part 1
authorPaul Floyd <pjfloyd@wanadoo.fr>
Mon, 6 Mar 2023 20:50:01 +0000 (21:50 +0100)
committerPaul Floyd <pjfloyd@wanadoo.fr>
Mon, 6 Mar 2023 20:50:01 +0000 (21:50 +0100)
I think that these are all now done.
This commit refactors memalign and updates manual-core.xml
to say some behaviour of Valgrind depends on the build time
OS and libraries.

NEWS
coregrind/m_replacemalloc/vg_replace_malloc.c
docs/xml/manual-core.xml

diff --git a/NEWS b/NEWS
index 61c4e03053bb681c079f5c55ff5645ea9509042c..bc3f4a363b9ca8a6a96459169bc9c46c013b9e19 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -98,6 +98,7 @@ are not entered into bugzilla tend to get forgotten about or ignored.
 464859  Build failures with GCC-13 (drd tsan_unittest)
 464969  D language demangling
 465435  m_libcfile.c:66 (vgPlain_safe_fd): Assertion 'newfd >= VG_(fd_hard_limit)' failed.
+466104  aligned_alloc problems, part 1
 n-i-bz  FreeBSD rfork syscall fail with EINVAL or ENOSYS rather than VG_(unimplemented)
 
 To see details of a given bug, visit
index 18cbb7f88e8b69fdf5fb3e55bd265b8cfa5f7bd6..6addfe80f9b9bdf0223e0264f20899d1a7b4f8dd 100644 (file)
@@ -1506,6 +1506,7 @@ extern int *___errno (void) __attribute__((weak));
   *
   */
 
+ /* @todo PJF exactly what is the behaviour if this? */
 #define ZONEMEMALIGN(soname, fnname) \
    \
    void* VG_REPLACE_FUNCTION_EZU(10100,soname,fnname) \
@@ -1534,8 +1535,34 @@ extern int *___errno (void) __attribute__((weak));
       return v; \
    }
 
-#if defined(VGO_linux)
-#if !defined(MUSL_LIBC)
+#if defined(VGO_freebsd)
+#define VG_MEMALIGN_MAKE_SIZE_MULTIPLE_ALIGN 1
+#else
+#define VG_MEMALIG_MAKE_SIZE_MULTIPLE_ALIGN 0
+#endif
+
+#if defined(VGO_solaris)
+#define VG_MEMALIGN_ALIGN_POWER_TWO 0
+#else
+#define VG_MEMALIGN_ALIGN_POWER_TWO 1
+#endif
+
+#if defined(VGO_solaris)
+#define VG_MEMALIGD_ALIGN_FACTOR_FOUR 1
+#else
+#define VG_MEMALIGN_ALIGN_FACTOR_FOUR 0
+#endif
+
+#if defined(MUSL_LIBC)
+#define VG_MEMALIGN_NO_SIZE_ZERO 0
+#else
+#define VG_MEMALIGN_NO_SIZE_ZERO 1
+#endif
+
+
+
+#if defined(VGO_linux) && !defined(MUSL_LIBC)
+
 #define MEMALIGN(soname, fnname) \
    \
    void* VG_REPLACE_FUNCTION_EZU(10110,soname,fnname) \
@@ -1562,34 +1589,8 @@ extern int *___errno (void) __attribute__((weak));
       if (!v) SET_ERRNO_ENOMEM; \
       return v; \
    }
-#else /* MUSL_LIBC */
-#define MEMALIGN(soname, fnname) \
-   \
-   void* VG_REPLACE_FUNCTION_EZU(10110,soname,fnname) \
-          ( SizeT alignment, SizeT size ); \
-   void* VG_REPLACE_FUNCTION_EZU(10110,soname,fnname) \
-          ( SizeT alignment, SizeT size ) \
-   { \
-      void *mem; \
-      \
-      DO_INIT; \
-      if ((alignment & (alignment - 1)) != 0) { \
-         SET_ERRNO_EINVAL; \
-         return 0; \
-      } \
-     /* Round up to minimum alignment if necessary. */ \
-     if (alignment < VG_MIN_MALLOC_SZB) \
-         alignment = VG_MIN_MALLOC_SZB; \
-      \
-      mem = (void*)VALGRIND_NON_SIMD_CALL2( info.tl_memalign, alignment, size ); \
-      \
-      if (!mem) SET_ERRNO_ENOMEM; \
-      \
-      return mem; \
-   }
-#endif
 
-#elif defined(VGO_freebsd)
+#else
 
 #define MEMALIGN(soname, fnname) \
    \
@@ -1601,70 +1602,31 @@ extern int *___errno (void) __attribute__((weak));
       void *mem; \
       \
       DO_INIT; \
-      TRIGGER_MEMCHECK_ERROR_IF_UNDEFINED(size); \
-      MALLOC_TRACE("memalign(al %llu, size %llu)\n", \
-               (ULong)alignment, (ULong)size ); \
-      if ((alignment & (alignment - 1)) != 0) { \
+      MALLOC_TRACE("memalign(alignment %llu, size %llu)", \
+                   (ULong)alignment, (ULong)size ); \
+      if ((VG_MEMALIGN_NO_SIZE_ZERO && (alignment == 0)) \
+          || (VG_MEMALIGN_ALIGN_POWER_TWO && (alignment & (alignment - 1)) != 0) \
+          || (VG_MEMALIGN_ALIGN_FACTOR_FOUR && (alignment % 4 != 0))) { \
          SET_ERRNO_EINVAL; \
          return 0; \
       } \
       /* Round up to minimum alignment if necessary. */ \
-        if (alignment < VG_MIN_MALLOC_SZB) \
-            alignment = VG_MIN_MALLOC_SZB; \
-      \
-      mem = (void*)VALGRIND_NON_SIMD_CALL2( info.tl_memalign, \
-               alignment, VG_ALIGN_ROUNDUP(size, alignment) ); \
-      \
-      if (!mem) SET_ERRNO_ENOMEM; \
-      \
-      return mem; \
-   }
-
-#elif defined(VGO_solaris)
-
-// In the Illumos source there is a macro MINSIZE
-// which is sizeof (TREE) - sizeof (WORD)
-// struct TREE contains 6 WORDS
-// so MINSIZE is 5 words
-//
-// In gdb I get the impression that sizeof (WORD) is 16
-#define VG_MEMALIGN_MINSIZE (5*VG_WORDSIZE)
-
-#define MEMALIGN(soname, fnname) \
-   \
-   void* VG_REPLACE_FUNCTION_EZU(10110,soname,fnname) \
-          ( SizeT alignment, SizeT size ); \
-   void* VG_REPLACE_FUNCTION_EZU(10110,soname,fnname) \
-          ( SizeT alignment, SizeT size ) \
-   { \
-      void *mem; \
+      if (alignment < VG_MIN_MALLOC_SZB) \
+         alignment = VG_MIN_MALLOC_SZB; \
+      /* Solaris allows non-power of 2 alignment but not Valgrind. */ \
+      while (0 != (alignment & (alignment - 1))) alignment++; \
       \
-      DO_INIT; \
-      MALLOC_TRACE("memalign(al %llu, size %llu)\n", \
-               (ULong)alignment, (ULong)size ); \
-      if (alignment == 0 \
-          || (size == 0) \
-          || (alignment & 3)) { \
-         SET_ERRNO_EINVAL; \
-         return 0; \
+      if (VG_MEMALIGN_MAKE_SIZE_MULTIPLE_ALIGN) { \
+         size = ((size + alignment - 1)/alignment)*alignment; \
       } \
-      size = VG_ALIGN_ROUNDUP(size, VG_WORDSIZE); \
-      if (size < VG_MEMALIGN_MINSIZE) \
-         size = VG_MEMALIGN_MINSIZE; \
-      alignment = VG_ALIGN_ROUNDUP(alignment, VG_WORDSIZE); \
-      while (alignment < VG_MEMALIGN_MINSIZE + VG_WORDSIZE) \
-         alignment <<= 1U; \
       \
-      mem = (void*)VALGRIND_NON_SIMD_CALL2( info.tl_memalign, \
-               alignment, VG_ALIGN_ROUNDUP(size, alignment) ); \
+      mem = (void*)VALGRIND_NON_SIMD_CALL2( info.tl_memalign, alignment, size ); \
       \
       if (!mem) SET_ERRNO_ENOMEM; \
       \
       return mem; \
    }
 
-// no Darwin
-
 #endif
 
 #if defined(VGO_linux)
@@ -1955,6 +1917,7 @@ extern int *___errno (void) __attribute__((weak));
     { \
        void *mem; \
        \
+       DO_INIT; \
        TRIGGER_MEMCHECK_ERROR_IF_UNDEFINED(size); \
        MALLOC_TRACE("aligned_alloc(al %llu, size %llu)", \
                 (ULong)alignment, (ULong)size ); \
@@ -1982,6 +1945,7 @@ extern int *___errno (void) __attribute__((weak));
     { \
        void *mem; \
        \
+       DO_INIT; \
        MALLOC_TRACE("aligned_alloc(al %llu, size %llu)", \
                 (ULong)alignment, (ULong)size ); \
        if ((VG_ALIGNED_ALLOC_NO_SIZE_ZERO && (alignment == 0)) \
index 558d1f62df62ab9bbbd10a53afd38e4a4c86e136..3a91c930fa4917cc292ae1fea452af06493936db 100644 (file)
@@ -82,6 +82,11 @@ To make it easier to write suppressions, you can use the
 print out a suppression for each reported error, which you can then
 copy into a suppressions file.</para>
 
+<para>Valgrind will try to match the behaviour of applications
+compiled to run on the same OS and libraries that Valgrind was
+built with. If you use different libraries or a different
+OS version there may be some small differences in behaviour.</para>
+
 <para>Different error-checking tools report different kinds of errors.
 The suppression mechanism therefore allows you to say which tool or
 tool(s) each suppression applies to.</para>