Skip to content

Commit 460ab96

Browse files
Mark 831 as final and update based on implementation
1 parent 19f5087 commit 460ab96

1 file changed

Lines changed: 28 additions & 12 deletions

File tree

peps/pep-0831.rst

Lines changed: 28 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -5,13 +5,15 @@ Author: Pablo Galindo Salgado <pablogsal@python.org>,
55
Savannah Ostrowski <savannah@python.org>,
66
Diego Russo <diego.russo@arm.com>,
77
Discussions-To: https://discuss.python.org/t/106958
8-
Status: Accepted
8+
Status: Final
99
Type: Standards Track
1010
Created: 14-Mar-2026
1111
Python-Version: 3.15
1212
Post-History: `13-Apr-2026 <https://discuss.python.org/t/106958>`__
1313
Resolution: `30-Apr-2026 <https://discuss.python.org/t/106958/6>`__
1414

15+
.. canonical-doc:: :external+py3.15:option:`--without-frame-pointers`
16+
1517
Abstract
1618
========
1719

@@ -470,11 +472,12 @@ Build System Changes
470472
The following changes are made to ``configure.ac``::
471473

472474
AX_CHECK_COMPILE_FLAG([-fno-omit-frame-pointer],
473-
[CFLAGS="$CFLAGS -fno-omit-frame-pointer"])
475+
[BASECFLAGS="$BASECFLAGS -fno-omit-frame-pointer"])
474476
AX_CHECK_COMPILE_FLAG([-mno-omit-leaf-frame-pointer],
475-
[CFLAGS="$CFLAGS -mno-omit-leaf-frame-pointer"])
477+
[BASECFLAGS="$BASECFLAGS -mno-omit-leaf-frame-pointer"])
476478

477-
Using ``CFLAGS`` ensures:
479+
The flags are prepended to ``BASECFLAGS`` (rather than ``CFLAGS_NODIST``) so
480+
they propagate to third-party builds via ``sysconfig``. This ensures:
478481

479482
1. The flags apply to all ``*.c`` files compiled as part of the interpreter:
480483
the ``python`` binary, ``libpython``, and built-in extension modules under
@@ -483,6 +486,18 @@ Using ``CFLAGS`` ensures:
483486
extensions built against this Python (via ``pip``, Setuptools, or direct
484487
``sysconfig`` queries) inherit frame pointers by default.
485488

489+
Several architectures need adjustments to produce a walkable frame-pointer
490+
chain:
491+
492+
* On 32-bit ARM, ``-marm`` (GCC) or ``-mno-thumb`` (Clang) is added to force
493+
ARM mode, since GCC's default Thumb prologue does not preserve the
494+
``fp[0]``/``fp[1]`` layout the simple unwinder expects.
495+
* On s390x, ``-mbackchain`` is added *instead* of the frame-pointer flags;
496+
GCC and Clang do not emit a usable backchain on s390x without it.
497+
* On ppc64le, no compiler flags are added: the Power ABI already requires
498+
compilers to maintain a back chain by default, so unwinding works without
499+
``-fno-omit-frame-pointer``.
500+
486501
This is an intentional design choice. For profiling data to be useful, the
487502
frame-pointer chain must be continuous through the entire call stack. A gap at
488503
any C extension boundary is as harmful as a gap in the interpreter itself. By
@@ -502,7 +517,7 @@ A new ``configure`` option is added::
502517

503518
--without-frame-pointers
504519

505-
When specified, neither flag is added to ``CFLAGS``. This is appropriate for
520+
When specified, neither flag is added to ``BASECFLAGS``. This is appropriate for
506521
deployments that have measured an unacceptable regression on their specific
507522
workload, or for distributions that inject frame-pointer flags at a higher
508523
level and wish to avoid double-specification, analogous to Fedora's per-package
@@ -550,9 +565,10 @@ recommendation for earlier versions.
550565
Platform Scope
551566
--------------
552567

553-
Both flags are accepted by GCC and Clang on all supported Linux architectures
554-
(x86-64, AArch64, s390x, RISC-V, ARM). On macOS with Apple Silicon, the ARM64
555-
ABI mandates frame pointers; the flags are redundant but harmless.
568+
Both flags are accepted by GCC and Clang on x86-64, AArch64, RISC-V, and
569+
32-bit ARM. s390x and ppc64le require different handling (see above). On
570+
macOS with Apple Silicon, the ARM64 ABI mandates frame pointers; the flags
571+
are redundant but harmless.
556572

557573
On Windows x64, MSVC does not use frame pointers for stack unwinding. Instead,
558574
the Windows x64 ABI mandates ``.pdata`` / ``.xdata`` unwind metadata for every
@@ -746,15 +762,15 @@ formalised by GCC 4.6 in 2011. The industry has since broadly reversed course:
746762

747763
CPython has not yet adopted this change.
748764

749-
Why Not Use ``CFLAGS_NODIST`` Instead of ``CFLAGS``
750-
---------------------------------------------------
765+
Why Not Use ``CFLAGS_NODIST`` Instead of ``BASECFLAGS``
766+
-------------------------------------------------------
751767

752768
CPython's build system provides ``CFLAGS_NODIST`` specifically for flags that
753769
should apply to the interpreter but not propagate to extension module builds
754770
via ``sysconfig``. Using ``CFLAGS_NODIST`` would confine the overhead to the
755771
interpreter itself.
756772

757-
This PEP deliberately chooses ``CFLAGS`` over ``CFLAGS_NODIST`` because frame
773+
This PEP deliberately chooses ``BASECFLAGS`` over ``CFLAGS_NODIST`` because frame
758774
pointers are only useful when the chain is continuous. Unlike debugging aids
759775
such as sanitizers or assertions, which are useful even when applied to a
760776
single component, a frame-pointer chain with a gap at a C extension boundary
@@ -772,7 +788,7 @@ not exhibit the same call density and sees negligible overhead.
772788
As Gregory Szorc (``python-build-standalone`` creator) noted: "Turning the
773789
corner on the long tail of compiled extensions having frame pointers will take
774790
years. So the sooner we start..." [#pbs992]_ Propagating the flags via
775-
``CFLAGS`` is how CPython starts that process.
791+
``BASECFLAGS`` is how CPython starts that process.
776792

777793
Alternatives to Frame-Pointer Unwinding
778794
---------------------------------------

0 commit comments

Comments
 (0)