From 23a683adf803eef405d248cc9c2a7eb08a7300e2 Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Fri, 12 Apr 2019 21:27:37 +0200 Subject: [PATCH] bpo-36618: Add -fmax-type-align=8 flag for clang (GH-12809) Add -fmax-type-align=8 to CFLAGS when clang compiler is detected. The pymalloc memory allocator aligns memory on 8 bytes. On x86-64, clang expects alignment on 16 bytes by default and so uses MOVAPS instruction which can lead to segmentation fault. Instruct clang that Python is limited to alignemnt on 8 bytes to use MOVUPS instruction instead: slower but don't trigger a SIGSEGV if the memory is not aligned on 16 bytes. Sadly, the flag must be expected to CFLAGS and not just CFLAGS_NODIST, since third party C extensions can have the same issue. --- .../2019-04-12-19-49-10.bpo-36618.gcI9iq.rst | 8 ++++ configure | 42 +++++++++++++------ configure.ac | 41 ++++++++++++------ 3 files changed, 65 insertions(+), 26 deletions(-) create mode 100644 Misc/NEWS.d/next/Build/2019-04-12-19-49-10.bpo-36618.gcI9iq.rst diff --git a/Misc/NEWS.d/next/Build/2019-04-12-19-49-10.bpo-36618.gcI9iq.rst b/Misc/NEWS.d/next/Build/2019-04-12-19-49-10.bpo-36618.gcI9iq.rst new file mode 100644 index 00000000000..597dd67b46e --- /dev/null +++ b/Misc/NEWS.d/next/Build/2019-04-12-19-49-10.bpo-36618.gcI9iq.rst @@ -0,0 +1,8 @@ +Add ``-fmax-type-align=8`` to CFLAGS when clang compiler is detected. The +pymalloc memory allocator aligns memory on 8 bytes. On x86-64, clang expects +alignment on 16 bytes by default and so uses MOVAPS instruction which can +lead to segmentation fault. Instruct clang that Python is limited to +alignemnt on 8 bytes to use MOVUPS instruction instead: slower but don't +trigger a SIGSEGV if the memory is not aligned on 16 bytes. Sadly, the flag +must be expected to ``CFLAGS`` and not just ``CFLAGS_NODIST``, since third +party C extensions can have the same issue. diff --git a/configure b/configure index 72589fdb78c..ac1e66a96bb 100755 --- a/configure +++ b/configure @@ -6813,6 +6813,19 @@ esac # compiler and platform. BASECFLAGS tweaks need to be made even if the # user set OPT. +case $CC in + *clang*) + cc_is_clang=1 + ;; + *) + if $CC --version 2>&1 | grep -q clang + then + cc_is_clang=1 + else + cc_is_clang= + fi +esac + # tweak OPT based on compiler and platform, only if the user didn't set # it on the command line @@ -6826,19 +6839,6 @@ then WRAP="-fwrapv" fi - case $CC in - *clang*) - cc_is_clang=1 - ;; - *) - if $CC --version 2>&1 | grep -q clang - then - cc_is_clang=1 - else - cc_is_clang= - fi - esac - if test -n "${cc_is_clang}" then # Clang also needs -fwrapv @@ -6879,6 +6879,21 @@ then esac fi +if test -n "${cc_is_clang}" +then + # bpo-36618: Add -fmax-type-align=8 to CFLAGS when clang compiler is + # detected. The pymalloc memory allocator aligns memory on 8 bytes. On + # x86-64, clang expects alignment on 16 bytes by default and so uses MOVAPS + # instruction which can lead to segmentation fault. Instruct clang that + # Python is limited to alignemnt on 8 bytes to use MOVUPS instruction + # instead: slower but don't trigger a SIGSEGV if the memory is not aligned + # on 16 bytes. + # + # Sadly, the flag must be expected to CFLAGS and not just CFLAGS_NODIST, + # since third party C extensions can have the same issue. + CFLAGS="$CFLAGS -fmax-type-align=8" +fi + @@ -10200,6 +10215,7 @@ fi + if test "x$ac_cv_env_PKG_CONFIG_set" != "xset"; then if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}pkg-config", so it can be a program name with args. diff --git a/configure.ac b/configure.ac index 30e8587cb08..863b34245ad 100644 --- a/configure.ac +++ b/configure.ac @@ -1464,6 +1464,19 @@ esac # compiler and platform. BASECFLAGS tweaks need to be made even if the # user set OPT. +case $CC in + *clang*) + cc_is_clang=1 + ;; + *) + if $CC --version 2>&1 | grep -q clang + then + cc_is_clang=1 + else + cc_is_clang= + fi +esac + # tweak OPT based on compiler and platform, only if the user didn't set # it on the command line AC_SUBST(OPT) @@ -1477,19 +1490,6 @@ then WRAP="-fwrapv" fi - case $CC in - *clang*) - cc_is_clang=1 - ;; - *) - if $CC --version 2>&1 | grep -q clang - then - cc_is_clang=1 - else - cc_is_clang= - fi - esac - if test -n "${cc_is_clang}" then # Clang also needs -fwrapv @@ -1530,6 +1530,21 @@ then esac fi +if test -n "${cc_is_clang}" +then + # bpo-36618: Add -fmax-type-align=8 to CFLAGS when clang compiler is + # detected. The pymalloc memory allocator aligns memory on 8 bytes. On + # x86-64, clang expects alignment on 16 bytes by default and so uses MOVAPS + # instruction which can lead to segmentation fault. Instruct clang that + # Python is limited to alignemnt on 8 bytes to use MOVUPS instruction + # instead: slower but don't trigger a SIGSEGV if the memory is not aligned + # on 16 bytes. + # + # Sadly, the flag must be expected to CFLAGS and not just CFLAGS_NODIST, + # since third party C extensions can have the same issue. + CFLAGS="$CFLAGS -fmax-type-align=8" +fi + AC_SUBST(BASECFLAGS) AC_SUBST(CFLAGS_NODIST) AC_SUBST(LDFLAGS_NODIST)