_Py_ThreadId() fails to compile with clang on Windows ARM64 (MSYS2 CLANGARM64)
还没有人认领这个 Issue。
- 主要语言
- Python
- 星标
- 77.2k
- 派生
- 35.9k
- PR 合并指标
- PR 指标待抓取
描述
Bug report
Bug description:
Building a free-threaded extension module for Windows ARM64 with MSYS2's CLANGARM64 (llvm-mingw) toolchain fails to compile Include/object.h:
object.h:200:11: error: call to undeclared function '__getReg'; ISO C99 and later do not
support implicit function declarations [-Wimplicit-function-declaration]
200 | tid = __getReg(18);
| ^
Example actions run where I tried to build jq.py.
Minimal repro
/* repro.c */
#include <Python.h>
uintptr_t repro(void) { return _Py_ThreadId(); }
$ gcc -c repro.c -O1 -Wall -DPy_GIL_DISABLED=1 -I <freethreaded-arm64-headers>
In file included from repro.c:1:
In file included from Python.h:81:
object.h:200:11: error: call to undeclared function '__getReg'; ISO C99 and later do not
support implicit function declarations [-Wimplicit-function-declaration]
200 | tid = __getReg(18);
| ^
1 error generated.
(gcc here is mingw-w64-clang-aarch64-gcc-compat, i.e. clang.)
_Py_ThreadId() reaches this branch, added in #124609 / GH-124663 for GCC:
#elif defined(__MINGW32__) && defined(_M_ARM64)
tid = __getReg(18);
clang does not define _M_ARM64 but mingw-w64 does, in _mingw_mac.h:
#if defined(__aarch64__) && !defined(_M_ARM64)
# define _M_ARM64 1
which is pulled in transitively by pyconfig.h. So the condition is true all aarch64 compilers. clang's predefines here are:
#define _WIN32 1
#define __GNUC__ 4
#define __MINGW32__ 1
#define __MINGW64__ 1
#define __aarch64__ 1
#define __clang__ 1
Why __getReg is unavailable to clang
- clang's
intrin.hdeclaresunsigned __int64 __getReg(int);, but only inside#ifdef _MSC_VER. For a*-windows-gnutarget the header takes the#include_next <intrin.h>path and defers to mingw-w64. - mingw-w64's
intrin.hdeclares__getRegonly via__MACHINEIA64(Itanium), which expands to nothing unless__ia64__. There is no__MACHINEARM64entry for it. - It is also not a clang builtin.
Note that falling through to the __aarch64__ branch is not a valid fix:
#elif defined(__aarch64__)
__asm__ ("mrs %0, tpidr_el0" : "=r" (tid));
On Windows ARM64 tpidr_el0 reads as 0 on every thread, whereas x18 holds the TEB and is correctly per-thread:
main x18=000000cc3736d000 tpidr_el0=0000000000000000 NtCurrentTeb=000000cc3736d000
thr1 x18=000000cc37371000 tpidr_el0=0000000000000000 NtCurrentTeb=000000cc37371000
thr2 x18=000000cc37373000 tpidr_el0=0000000000000000 NtCurrentTeb=000000cc37373000
A constant 0 would collide with _Py_UNOWNED_TID, so this would compile cleanly and then misbehave silently — the same failure mode discussed in #124609.
Suggested fix
Keep __getReg for GCC and give clang a dedicated branch reading x18:
#elif defined(__MINGW32__) && defined(_M_ARM64) && !defined(__clang__)
tid = __getReg(18);
#elif defined(__MINGW32__) && defined(_M_ARM64)
__asm__ ("mov %0, x18" : "=r" (tid)); // Windows/ARM64 keeps the TEB in x18
I have verified that this compiles and generates the expected read.
Versions tested
- CPython 3.14 (free-threaded)
- Windows 11 Pro 10.0.28000 ARM64
- clang 22.1.8 (MSYS2 CLANGARM64)
CPython versions tested on:
3.14
Operating systems tested on:
Windows
Linked PRs
- gh-157252
- gh-157253
贡献指南
从这里开始
- 先读完整个 Issue,再读项目的贡献指南。
- 在 Issue 下留言说明你要接手 —— 这能避免两个人做同样的事。
- Fork 仓库,在一个分支上完成修改。
- 提交 Pull Request,并在描述里引用这个 Issue 编号。
调研方向
从 Include/object.h 中的 _Py_ThreadId() 平台分支开始,使用提供的 repro.c 示例和编译器命令重现该故障。查看链接的 PR gh-157252 和 gh-157253,了解已经在进行的工作。当 free-threaded Windows ARM64 CLANGARM64 的复现代码能够编译并正确读取每线程标识符时,即表示完成。
由索引模型根据 Issue 内容生成。
评估
- 技术栈
- c, python
- 领域
- build-system, operating-systems
- Issue 类型
- 缺陷
- 难度
- 3/5
- 预计耗时
- 1-2 天
- 活跃度
- 停滞
- 描述清晰度
- 描述清楚
- 新手友好度
- 30/100