[MDEV-29308] 10.8.4 fails to build on OpenBSD Created: 2022-08-16  Updated: 2022-08-22  Resolved: 2022-08-22

Status: Closed
Project: MariaDB Server
Component/s: Server
Affects Version/s: 10.6.9, 10.7.5, 10.8.4, 10.9.1, 10.10.1
Fix Version/s: 10.6.10, 10.7.6, 10.8.5, 10.9.3, 10.10.2

Type: Bug Priority: Blocker
Reporter: Brad Smith Assignee: Marko Mäkelä
Resolution: Fixed Votes: 0
Labels: None
Environment:

OpenBSD


Issue Links:
Problem/Incident
is caused by MDEV-28836 Correcting the cache alignment for Ta... Closed

 Description   

/home/ports/pobj/mariadb-10.8.4/bin/c++ -DDBUG_TRACE -DHAVE_CONFIG_H -I/home/ports/pobj/mariadb-10.8.4/mariadb-10.8.4/wsrep-lib/include -I/home/ports/pobj/mariadb-10.8.4/mariadb-10.8.4/wsrep-lib/wsrep-API/v26 -I/home/ports/pobj/mariadb-10.8.4/build-amd64/include -I/home/ports/pobj/mariadb-10.8.4/mariadb-10.8.4/include/providers -I/home/ports/pobj/mariadb-10.8.4/mariadb-10.8.4/tpool -I/home/ports/pobj/mariadb-10.8.4/mariadb-10.8.4/include -O2 -pipe  -I/usr/local/include -fstack-protector --param=ssp-buffer-size=4 -DNDEBUG -D_FORTIFY_SOURCE=2 -DDBUG_OFF -std=gnu++11 -MD -MT tpool/CMakeFiles/tpool.dir/tpool_generic.cc.o -MF tpool/CMakeFiles/tpool.dir/tpool_generic.cc.o.d -o tpool/CMakeFiles/tpool.dir/tpool_generic.cc.o -c /home/ports/pobj/mariadb-10.8.4/mariadb-10.8.4/tpool/tpool_generic.cc
In file included from /home/ports/pobj/mariadb-10.8.4/mariadb-10.8.4/tpool/tpool_generic.cc:36:
/home/ports/pobj/mariadb-10.8.4/mariadb-10.8.4/include/aligned.h:27:10: error: use of undeclared identifier 'aligned_alloc'; did you mean 'aligned_malloc'?
  return aligned_alloc(alignment, size);
         ^~~~~~~~~~~~~
         aligned_malloc
/home/ports/pobj/mariadb-10.8.4/mariadb-10.8.4/include/aligned.h:22:14: note: 'aligned_malloc' declared here
inline void *aligned_malloc(size_t size, size_t alignment)
             ^
1 error generated.



 Comments   
Comment by Marko Mäkelä [ 2022-08-16 ]

aligned_alloc() is defined in the standard ISO/IEC 9899:2011 a.k.a. C11. Because some systems do not support it yet, I implemented a compile-time check HAVE_ALIGNED_ALLOC.

We do not have OpenBSD in our CI systems. Can you please check if the following patch would fix this?

diff --git a/include/aligned.h b/include/aligned.h
index 0ae1f0d0848..2ae2c9e78f1 100644
--- a/include/aligned.h
+++ b/include/aligned.h
@@ -15,6 +15,7 @@
    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1335  USA */
 
 #ifdef HAVE_ALIGNED_ALLOC
+# include <stdlib.h>
 #elif defined __linux__
 # include <malloc.h>
 #endif

Comment by Brad Smith [ 2022-08-16 ]

I tried that before filing the bug report and that did not help.

From stdlib.h..

#if __ISO_C_VISIBLE >= 2011
void *
        aligned_alloc(size_t, size_t);
#endif

If I removed the #if __ISO_C_VISIBLE >= 2011 wrapper it builds.

Tracking it down further I see this in sys/cdefs..

/*
 * _ISOC99_SOURCE, _ISOC11_SOURCE, __STDC_VERSION__, and __cplusplus
 * override any of the other macros since they are non-exclusive.
 */
#if defined(_ISOC11_SOURCE) || \
    (defined(__STDC_VERSION__) && __STDC_VERSION__ >= 201112) || \
    (defined(__cplusplus) && __cplusplus >= 201703)
# undef __ISO_C_VISIBLE
# define __ISO_C_VISIBLE        2011
#elif defined(_ISOC99_SOURCE) || \
    (defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901) || \
    (defined(__cplusplus) && __cplusplus >= 201103)
# undef __ISO_C_VISIBLE
# define __ISO_C_VISIBLE        1999
#endif

It's hitting the second part. It looks like the function would be visible if building C+17 but not C+11.

Comment by Brad Smith [ 2022-08-16 ]

Looking at FreeBSD, NetBSD and DragonFly they all expose aligned_alloc() for C+11 by checking __cplusplus in addition to __ISO_C_VISIBLE or equivalent. So it looks like this is a header bug.

Comment by Marko Mäkelä [ 2022-08-17 ]

A possible work-around could be to run the following using a C++ compiler, so that we would fall back to posix_memalign().

CHECK_FUNCTION_EXISTS (aligned_alloc HAVE_ALIGNED_ALLOC)

I am not that familiar with CMake, and all checks seem to be for a C compiler.

Maybe a better work-around would be to declare the function in the header file, something like this:

diff --git a/include/aligned.h b/include/aligned.h
index 0ae1f0d0848..c9ca51f3e69 100644
--- a/include/aligned.h
+++ b/include/aligned.h
@@ -15,6 +15,9 @@
    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1335  USA */
 
 #ifdef HAVE_ALIGNED_ALLOC
+# if defined OpenBSD && (OpenBSD >= 200411) && defined __cplusplus
+extern "C" void *aligned_alloc(size_t, size_t);
+# endif
 #elif defined __linux__
 # include <malloc.h>
 #endif

The 200411 would have to be replaced with the earliest OpenBSD version that introduced aligned_alloc(). Would this work?

Comment by Brad Smith [ 2022-08-19 ]

I had to change the diff to the following..

Index: include/aligned.h
--- include/aligned.h.orig
+++ include/aligned.h
@@ -15,6 +15,12 @@
    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1335  USA */
 
 #ifdef HAVE_ALIGNED_ALLOC
+# if defined(__OpenBSD__)
+# include <sys/param.h>
+# if defined OpenBSD && (OpenBSD >= 200411) && defined __cplusplus
+extern "C" void *aligned_alloc(size_t, size_t);
+# endif
+# endif
 #elif defined __linux__
 # include <malloc.h>
 #endif

OpenBSD is defined in sys/param.h

sys/param..

#define OpenBSD 202210          /* OpenBSD version (year & month). */
#define OpenBSD7_2 1            /* OpenBSD 7.2 */

Comment by Brad Smith [ 2022-08-19 ]

I also noticed this from the build..

[573/1866] /home/ports/pobj/mariadb-10.8.4/bin/cc -DDBUG_TRACE -DHAVE_CONFIG_H -DHAVE_PCLMUL -DHAVE_SSE42 -I/home/ports/pobj/mariadb-10.8.4/mariadb-10.8.4/wsrep-lib/include -I/home/ports/pobj/mariadb-10.8.4/mariadb-10.8.4/wsrep-lib/wsrep-API/v26 -I/home/ports/pobj/mariadb-10.8.4/build-amd64/include -I/home/ports/po
bj/mariadb-10.8.4/mariadb-10.8.4/include/providers -I/home/ports/pobj/mariadb-10.8.4/mariadb-10.8.4/include -I/home/ports/pobj/mariadb-10.8.4/mariadb-10.8.4/mysys -O2 -pipe  -I/usr/local/include -fstack-protector --param=ssp-buffer-size=4 -DNDEBUG -D_FORTIFY_SOURCE=2 -DDBUG_OFF -fPIC -std=gnu99 -MD -MT mysys/CMakeF
iles/mysys.dir/my_lockmem.c.o -MF mysys/CMakeFiles/mysys.dir/my_lockmem.c.o.d -o mysys/CMakeFiles/mysys.dir/my_lockmem.c.o -c /home/ports/pobj/mariadb-10.8.4/mariadb-10.8.4/mysys/my_lockmem.c
In file included from /home/ports/pobj/mariadb-10.8.4/mariadb-10.8.4/mysys/my_lockmem.c:21:
/home/ports/pobj/mariadb-10.8.4/mariadb-10.8.4/include/aligned.h:33:10: warning: implicitly declaring library function 'aligned_alloc' with type 'void *(unsigned long, unsigned long)' [-Wimplicit-function-declaration]
  return aligned_alloc(alignment, size);
         ^
/home/ports/pobj/mariadb-10.8.4/mariadb-10.8.4/include/aligned.h:33:10: note: include the header <stdlib.h> or explicitly provide a declaration for 'aligned_alloc'
1 warning generated.

But that code is being built as C99 instead of C11.

Comment by Marko Mäkelä [ 2022-08-22 ]

Thank you. It did not occur to me that in modern C, the language dialect decides what is available in the library. An old example: snprintf() is a C99 feature, yet it was ‘always’ available even when the compiler defaulted to the C90 dialect. As you suggested, it probably is easiest not to attempt to use aligned_alloc(), but just use posix_memalign() instead. Linux and Microsoft Windows would be unaffected by that change.

Upgrading to C11 and C++17 might be an option, but it would not be trivial.
The compiler on CentOS 7 (GCC 4.8.5) barely supports a usable subset of C++11.

Generated at Thu Feb 08 10:07:31 UTC 2024 using Jira 8.20.16#820016-sha1:9d11dbea5f4be3d4cc21f03a88dd11d8c8687422.