)]}'
{
  "commit": "4ed40146f17ea71e94b629600a8d540436367607",
  "tree": "8378317656d46c4cd266f1590d8c115aeee6e345",
  "parents": [
    "646853df13492e2260befd5a13dba29af3c6be46"
  ],
  "author": {
    "name": "Pablo Galindo Salgado",
    "email": "Pablogsal@gmail.com",
    "time": "Wed May 06 15:03:37 2026"
  },
  "committer": {
    "name": "GitHub",
    "email": "noreply@github.com",
    "time": "Wed May 06 15:03:37 2026"
  },
  "message": "gh-149202: Fix frame pointer unwinding on s390x and ARM (GH-149362)\n\n-fno-omit-frame-pointer is not enough to make every target walkable by the\nsimple manual frame pointer unwinder.\n\nThe helper used by test_frame_pointer_unwind used to assume the frame pointer\nnamed a two-word record where fp[0] was the previous frame pointer and fp[1]\nwas the return address. That is only the generic layout used by some targets.\nThis patch keeps that default, but moves the slots behind named offsets so\narchitecture-specific layouts can describe where the backchain and return\naddress really live.\n\nOn s390x, GCC and Clang do not emit a usable backchain unless -mbackchain is\nenabled. Without it, the unwinder stops at the current C frame and the test\nreports no Python frames. Once backchains are present, the helper must also\nstop at the current thread\u0027s known C stack bounds; otherwise it can follow the\nfinal backchain far enough to dereference an invalid frame and segfault.\nFor Linux s390x backchain frames, the documented z/Architecture stack-frame\nlayout saves r14, the return-address register, at byte offset 112 from the\nframe pointer, so read the return address from that named slot instead of fp[1].\n\nThe 112-byte offset comes from Linux\u0027s s390 debugging documentation: its Stack\nFrame Layout table shows z/Architecture backchain frames with the backchain at\noffset 0 and saved r14 of the caller function at offset 112:\nhttps://www.kernel.org/doc/html/v5.3/s390/debugging390.html#stack-frame-layout\n\nThis helper remains scoped to Linux s390x backchain frames. GNU SFrame\u0027s s390x\nnotes state that the s390x ELF ABI does not generally mandate where RA and FP\nare saved, or whether they are saved at all:\nhttps://sourceware.org/binutils/docs/sframe-spec.html#s390x\n\nAs Jens Remus noted, -fno-omit-frame-pointer is not needed when -mbackchain is\npresent.\n\nOn 32-bit ARM, GCC defaults to Thumb mode on common armhf toolchains. The Thumb\nprologue keeps the saved frame pointer and link register at offsets that depend\non the generated frame, which breaks the fp[0]/fp[1] walk used by the helper.\nUse -marm when it is supported for frame-pointer builds, and teach the helper\nthe GCC ARM-mode slots where the previous frame pointer is at fp[-1] and the\nsaved LR return address is at fp[0].\n\n\nCo-authored-by: Petr Viktorin \u003cencukou@gmail.com\u003e\nCo-authored-by: Victor Stinner \u003cvstinner@python.org\u003e",
  "tree_diff": [
    {
      "type": "modify",
      "old_id": "653f28ddbabfa4b8a6870774f0a6e2377add6e03",
      "old_mode": 33188,
      "old_path": "Doc/howto/perf_profiling.rst",
      "new_id": "657cb287ad3d60551112d9d6a2eeaff9887bd38c",
      "new_mode": 33188,
      "new_path": "Doc/howto/perf_profiling.rst"
    },
    {
      "type": "modify",
      "old_id": "086f6bfa22ad4ac4cd15da68dd6c8d198fe0115c",
      "old_mode": 33188,
      "old_path": "Doc/using/configure.rst",
      "new_id": "62c53c283825c8f6530a5e3ad81fa3d05ea864ea",
      "new_mode": 33188,
      "new_path": "Doc/using/configure.rst"
    },
    {
      "type": "modify",
      "old_id": "f3bcdd5f1a35b9c02c601337577b2e10b00ddaa3",
      "old_mode": 33188,
      "old_path": "Doc/whatsnew/3.15.rst",
      "new_id": "98af62a412fab75e8c887cc70805112e33a1cbfa",
      "new_mode": 33188,
      "new_path": "Doc/whatsnew/3.15.rst"
    },
    {
      "type": "modify",
      "old_id": "4081e1cbd8aaacabf0324f916cef3f877efed08c",
      "old_mode": 33188,
      "old_path": "Lib/test/test_frame_pointer_unwind.py",
      "new_id": "5cd94e5b27f394e30a1b1721adc409e9526ad96f",
      "new_mode": 33188,
      "new_path": "Lib/test/test_frame_pointer_unwind.py"
    },
    {
      "type": "modify",
      "old_id": "f82ca91f5ba00098795cab0c8bf56cce64685b18",
      "old_mode": 33188,
      "old_path": "Misc/NEWS.d/next/Core_and_Builtins/2026-04-05-16-10-00.gh-issue-149202.W8sQeR.rst",
      "new_id": "aae1529547c8370be8f241736c437675dce02230",
      "new_mode": 33188,
      "new_path": "Misc/NEWS.d/next/Core_and_Builtins/2026-04-05-16-10-00.gh-issue-149202.W8sQeR.rst"
    },
    {
      "type": "modify",
      "old_id": "23ef4f13be3b5ff60f9f45f01daea23c6ce7a670",
      "old_mode": 33188,
      "old_path": "Modules/_testinternalcapi.c",
      "new_id": "73451b5117fa8cac9ba26c42fe811e017103c238",
      "new_mode": 33188,
      "new_path": "Modules/_testinternalcapi.c"
    },
    {
      "type": "modify",
      "old_id": "d4a0a9d74b7631ba2a6b452620f640f6ee69fc3d",
      "old_mode": 33261,
      "old_path": "configure",
      "new_id": "f970bf9b7ba3c74393e9d25b6215c1c1950ddd0e",
      "new_mode": 33261,
      "new_path": "configure"
    },
    {
      "type": "modify",
      "old_id": "395bfc3065117164a38dde5c251ace355b232722",
      "old_mode": 33188,
      "old_path": "configure.ac",
      "new_id": "9f91a10c2918cf7d1eb2893532b8f0bbf5451838",
      "new_mode": 33188,
      "new_path": "configure.ac"
    },
    {
      "type": "modify",
      "old_id": "4eeec330466441093d4c1d9ed2d9c61946658259",
      "old_mode": 33188,
      "old_path": "pyconfig.h.in",
      "new_id": "ad372255445d1387fdcf8869165629a9b456bf14",
      "new_mode": 33188,
      "new_path": "pyconfig.h.in"
    }
  ]
}
