https://github.com/python/cpython/commit/612140e7ddc39eee8816ac397bf2f8302a174fc4
commit: 612140e7ddc39eee8816ac397bf2f8302a174fc4
branch: main
author: Petr Viktorin <[email protected]>
committer: encukou <[email protected]>
date: 2026-05-07T10:37:00+02:00
summary:

gh-149202: Fix frame pointer unwinding on ppc64le and armv7/clang (#149409)

- ppc64's backchain format is also different from x86
- On 32-bit ARM, clang needs `-mno-thumb`, not `-marm` like GCC

files:
M Doc/using/configure.rst
M Modules/_testinternalcapi.c
M configure
M configure.ac

diff --git a/Doc/using/configure.rst b/Doc/using/configure.rst
index 62c53c283825c8..a0e46ff4e375b6 100644
--- a/Doc/using/configure.rst
+++ b/Doc/using/configure.rst
@@ -789,14 +789,13 @@ also be used to improve performance.
 
    - ``-fno-omit-frame-pointer`` and/or ``-mno-omit-leaf-frame-pointer``
      are added when the compiler supports them.
-   - ``-marm`` is added on 32-bit ARM when supported,
+   - ``-marm`` and/or ``-mno-thumb`` is added on 32-bit ARM when supported,
    - on s390x platforms, when supported, ``-mbackchain`` is added *instead*.
      of the above frame pointer flags.
 
    Frame pointers enable profilers, debuggers, and system tracing tools
    (``perf``, ``eBPF``, ``dtrace``, ``gdb``) to walk the C call stack
-   without DWARF metadata.
-   The flags propagate to third-party C
+   without DWARF metadata. The flags propagate to third-party C
    extensions through :mod:`sysconfig`. On compilers that do not
    understand them, the build silently skips them.
 
diff --git a/Modules/_testinternalcapi.c b/Modules/_testinternalcapi.c
index c0a7680388e4a7..b8a22c439e853d 100644
--- a/Modules/_testinternalcapi.c
+++ b/Modules/_testinternalcapi.c
@@ -92,6 +92,12 @@ static const uintptr_t min_frame_pointer_addr = 0x1000;
 #  define FRAME_POINTER_NEXT_OFFSET 0
 #  define FRAME_POINTER_RETURN_OFFSET \
     (S390X_FRAME_RETURN_ADDRESS_OFFSET / (Py_ssize_t)sizeof(uintptr_t))
+#elif defined(__powerpc64__) || defined(__ppc64__)
+// ppc64le puts the return address at fp[2]; it saves the Condition Register
+// in fp[1]. See:
+// https://refspecs.linuxfoundation.org/ELF/ppc64/PPC-elf64abi-1.9.html#STACK
+#  define FRAME_POINTER_NEXT_OFFSET 0
+#  define FRAME_POINTER_RETURN_OFFSET 2
 #else
 #  define FRAME_POINTER_NEXT_OFFSET 0
 #  define FRAME_POINTER_RETURN_OFFSET 1
diff --git a/configure b/configure
index f970bf9b7ba3c7..3377bf7516ebd2 100755
--- a/configure
+++ b/configure
@@ -10346,7 +10346,7 @@ fi
       case $host_cpu in #(
   arm|armv*) :
 
-        { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether C 
compiler accepts -marm" >&5
+                { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether 
C compiler accepts -marm" >&5
 printf %s "checking whether C compiler accepts -marm... " >&6; }
 if test ${ax_cv_check_cflags__Werror__marm+y}
 then :
@@ -10384,6 +10384,49 @@ then :
 
           frame_pointer_cflags="$frame_pointer_cflags -marm"
 
+else case e in #(
+  e) : ;;
+esac
+fi
+
+        { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether C 
compiler accepts -mno-thumb" >&5
+printf %s "checking whether C compiler accepts -mno-thumb... " >&6; }
+if test ${ax_cv_check_cflags__Werror__mno_thumb+y}
+then :
+  printf %s "(cached) " >&6
+else case e in #(
+  e)
+  ax_check_save_flags=$CFLAGS
+  CFLAGS="$CFLAGS -Werror -mno-thumb"
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+int
+main (void)
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"
+then :
+  ax_cv_check_cflags__Werror__mno_thumb=yes
+else case e in #(
+  e) ax_cv_check_cflags__Werror__mno_thumb=no ;;
+esac
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext
+  CFLAGS=$ax_check_save_flags ;;
+esac
+fi
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: 
$ax_cv_check_cflags__Werror__mno_thumb" >&5
+printf "%s\n" "$ax_cv_check_cflags__Werror__mno_thumb" >&6; }
+if test "x$ax_cv_check_cflags__Werror__mno_thumb" = xyes
+then :
+
+          frame_pointer_cflags="$frame_pointer_cflags -mno-thumb"
+
 else case e in #(
   e) : ;;
 esac
diff --git a/configure.ac b/configure.ac
index 9f91a10c2918cf..fc2db4d5e8aebb 100644
--- a/configure.ac
+++ b/configure.ac
@@ -2549,9 +2549,13 @@ AS_VAR_IF([ac_cv_gcc_compat], [yes], [
         frame_pointer_cflags="$frame_pointer_cflags 
-mno-omit-leaf-frame-pointer"
       ], [], [-Werror])
       AS_CASE([$host_cpu], [arm|armv*], [
+        dnl GCC uses "-marm"; clang uses "-mno-thumb"
         AX_CHECK_COMPILE_FLAG([-marm], [
           frame_pointer_cflags="$frame_pointer_cflags -marm"
         ], [], [-Werror])
+        AX_CHECK_COMPILE_FLAG([-mno-thumb], [
+          frame_pointer_cflags="$frame_pointer_cflags -mno-thumb"
+        ], [], [-Werror])
       ])
       AS_CASE([$host_cpu], [s390*], [
         AX_CHECK_COMPILE_FLAG([-mbackchain], [

_______________________________________________
Python-checkins mailing list -- [email protected]
To unsubscribe send an email to [email protected]
https://mail.python.org/mailman3//lists/python-checkins.python.org
Member address: [email protected]

Reply via email to