@@ -25,21 +25,41 @@ def _frame_pointers_expected(machine):
2525 )
2626 if value
2727 )
28+
2829 if "no-omit-frame-pointer" in cflags :
30+ # For example, configure adds -fno-omit-frame-pointer if Python
31+ # has perf trampoline (PY_HAVE_PERF_TRAMPOLINE) and Python is built
32+ # in debug mode.
2933 return True
3034 if "omit-frame-pointer" in cflags :
3135 return False
36+
3237 if sys .platform == "darwin" :
3338 # macOS x86_64/ARM64 always have frame pointer by default.
3439 return True
40+
3541 if sys .platform == "linux" :
3642 if machine in {"aarch64" , "arm64" }:
3743 # 32-bit Linux is not supported
3844 if sys .maxsize < 2 ** 32 :
3945 return None
4046 return True
4147 if machine == "x86_64" :
48+ final_opt = ""
49+ for opt in cflags .split ():
50+ if opt .startswith ('-O' ):
51+ final_opt = opt
52+ if final_opt in ("-O0" , "-Og" , "-O1" ):
53+ # Unwinding works if the optimization level is low
54+ return True
55+
56+ Py_ENABLE_SHARED = int (sysconfig .get_config_var ('Py_ENABLE_SHARED' ) or '0' )
57+ if Py_ENABLE_SHARED :
58+ # Unwinding does crash using gcc -O2 or gcc -O3
59+ # when Python is built with --enable-shared
60+ return "crash"
4261 return False
62+
4363 if sys .platform == "win32" :
4464 # MSVC ignores /Oy and /Oy- on x64/ARM64.
4565 if machine == "arm64" :
@@ -153,10 +173,14 @@ class FramePointerUnwindTests(unittest.TestCase):
153173
154174 def setUp (self ):
155175 super ().setUp ()
176+
156177 machine = platform .machine ().lower ()
157178 expected = _frame_pointers_expected (machine )
158179 if expected is None :
159180 self .skipTest (f"unsupported architecture for frame pointer check: { machine } " )
181+ if expected == "crash" :
182+ self .skipTest (f"test does crash on { machine } " )
183+
160184 try :
161185 _testinternalcapi .manual_frame_pointer_unwind ()
162186 except RuntimeError as exc :
0 commit comments