yihong0618 和朋友们的频道 头像

消息来源频道

yihong0618 和朋友们的频道

@hyi0618

频道8,612 位成员公开可见0 人在线

yihong0618 和朋友们的频道

成员规模8,612 位成员
在线情况0 人在线
消息总数10,129 条消息
浏览量总数3,297,173 次浏览

在这个频道里搜索消息……

t.me/hyi0618

我仔细读了读 NadeshikoManju@薫る花は凛と咲く7月5日播出 两个多月前的博客 https://www.manjusaka.blog/posts/2025/04/26/3-14-is-one-of-the-best-python-version/
很有意思,甚至似乎发现了 manju 老师不小心错过的好东西😇
总之 manju 老师在 https://t.me/ManjusakaH/462 里说的这个 _PyRuntime 其实早在 Python 3.7 就有了,并非 3.14 的新东西,我已在官方 docker image python:3.7 中确认
$ s objdump -T /proc/$(pidof python)/root//usr/local/lib/libpython3.7m.so.1.0 | grep _PyRuntime
0000000000310e40 g DO .bss 00000000000005f0 Base _PyRuntime
这意味着从 3.7 开始的整个 gdb for python 支持 (libpython.py) 都可以直接重写了,那些基于栈搜索,寻找特定栈帧 _PyEval_EvalFrameDefault 的古代做法,将可以全部修改为基于 _PyRuntime 这个稳定 API。什么找不到栈帧、tstate/frame 变量被优化、被迫退化到从 rsp 开始暴力摸栈,的魅力时刻,全部扔掉!_PyRuntime 原地暴露所有线程的 tstate:
(gdb) p _PyRuntime.main_tstate
$12 = (PyThreadState *) 0xade800 <_PyRuntime+299040>
(gdb) p _PyRuntime.interpreters.head->threads.head
$13 = (PyThreadState *) 0x6199f20
(gdb) p _PyRuntime.interpreters.head->threads.head->next
$14 = (PyThreadState *) 0x618c370
(gdb) p _PyRuntime.interpreters.head->threads.head->next->next
$15 = (PyThreadState *) 0x61a54b0
(gdb) p _PyRuntime.interpreters.head->threads.head->next->next->next
$16 = (PyThreadState *) 0x6136350
(gdb) p _PyRuntime.interpreters.head->threads.head->next->next->next->next
$17 = (PyThreadState *) 0x61947b0
(gdb) p _PyRuntime.interpreters.head->threads.head->next->next->next->next->next
$18 = (PyThreadState *) 0x613df00
(gdb) p _PyRuntime.interpreters.head->threads.head->next->next->next->next->next->next
$19 = (PyThreadState *) 0xade800 <_PyRuntime+299040>
(gdb) p _PyRuntime.interpreters.head->threads.head->next->next->next->next->next->next->next
$20 = (PyThreadState *) 0x0
当然需要一些特定的 offsets,这一点我历来是打表爱好者:既然 python --version 是稳定的获取 cpython 版本的 API,那 debugger 直接硬编码就行了,如
sizeof_PyASCIIObject = {312: 48, 313: 40}
就可以用来记录 python3.12 和 3.13 的 sizeof(PyASCIIObject)。写死,狠狠写死。
更多 gdb -p $(pidof python) 和 pep-768, pycum 见🐶