如何编译和调试Python内核源码?(开源python编译器)
off999 2024-09-21 20:54 40 浏览 0 评论
写在前面
如果对Python源码感兴趣,那“窥探”其实现的最佳方式就是调教它,不,调试它。
获取源代码
Python的官方默认实现为CPython,即C语言实现(主要指解释器的实现,其他实现见Other Interpreter Implementations)。CPython的源代码可以从官网pyhton.org或者github.com/python/cpython获取,目前最新的稳定版本为3.8.0,于2019.10.14发布。这里,从官网 https://www.python.org/downloads/release/python-380/ 下载源码压缩包,如下图所示,
源代码的组织
解压后,目录结构如下
{ Python-3.8.0 } ? tree -d -L 1 .
.
├── Doc # rst(reStructuredText)格式官方文档,用其生成https://docs.python.org/
├── Grammar # Python的EBNF(Extended Backus–Naur form)语法定义文件
├── Include # .h 头文件
├── Lib # .py 纯Python实现的标准库
├── m4 # ?
├── Mac # Mac-specific code,支持MacOS
├── Misc # Things that do not belong elsewhere.
├── Modules # C实现的标准库,内含.c .asm .macros .h
├── Objects # 内置数据类型实现
├── Parser # Python语法分析器源码
├── PC # Windows-specific code,支持Windows
├── PCbuild # Windows生成文件,for MSVC
├── Programs # main函数文件,用于生成可执行文件,如python.exe的入口文件
├── Python # CPython解释器源码
└── Tools # 独立工具代码,used to maintain Python
CPython的源码组织结构如下,摘抄自CPython Source Code Layout,
源码文件分门别类存放,而且,无论是py实现的标准库、c实现的标准库、内置数据类型还是内置函数,在Lib/test/和Doc/library/目录下都有与之对应的test_x.py测试文件和rst文档文件(对于内置数据类型和函数,其文档集中保存在stdtypes.rst和functions.rst)。比如,内置类型int位于Objects/longobject.c文件中。
下面正式开始编译CPython。
windows下编译CPython
据Compile and build on Windows,Python3.6及之后的版本可以使用VS2017编译,安装VS2017时,记得勾选 Python development 和 Python native development tools,有备无患。
安装好VS2017后,双击PCbuild/pcbuild.sln,打开解决方案。因为我们的关注点仅在Python内核和解释器部分,所以仅编译python和pythoncore,其他模块暂时忽略,具体地,
- 切换到debug win32
- 右键解决方案→属性→配置属性
- 仅勾选项目python和pythoncore
- 确定
此时再“生成解决方案”,生成目录为PCbuild/win32,内容如下,含解释器python_d.exe和内核python38_d.dll,
接下来,将项目python设为启动项目(默认状态即是启动项目),点击调试,运行得到如下控制台,可以像平时使用python一样,与之交互。
如果想生成全部模块,需要运行PCbuild\get_externals.bat下载依赖,再编译,具体可参见Build CPython on Windows。
调试CPython
只要程序能运行起来,一切就好办了。凭借“宇宙最强IDE”,我们可以任性地设断点调试甚至修改代码。
F5重新启动调试,弹出控制台。在上面我们知道int类型位于Objects/longobject.c文件,打开文件,简单浏览后在函数PyObject * PyLong_FromLong(long ival)入口处打个断点。然后,在弹出的控制台中输入a = 1来创建int对象,回车,程序停在了断点处,查看变量ival的值为1——恰为我们输入的数值,这个函数会跟根据输入的C long int创建一个int对象,返回对象指针。
再来看看函数调用堆栈,如下图所示,
调用顺序从下至上,从中可以推断出,
- 从python_d.exe的入口main运行起来后,进入python38_d.dll
- 从标准输入stdin中读取键入的字符串
- 解析字符串,建立了语法树AST(abstract syntax tree)
- 解析语法树中的节点,判断字符为number,将字符串转化为C long int
- 由C long int创建Python的int对象
继续运行,弹出的控制台中光标前出现<<<,等待输入。这时如果我们点击调试中的停止按钮(全部中断),会发现程序停在Parser/myreadline.c文件_PyOS_WindowsConsoleReadline函数中的ReadConsoleW一行,
if (!ReadConsoleW(hStdIn, &wbuf[total_read], wbuflen - total_read, &n_read, NULL)) {
err = GetLastError();
goto exit;
}
ReadConsoleW为WINAPI,详见ReadConsole function,其等待并读取控制台的输入,读取的字符保存在wbuf中。如果有输入,则进入上面的流程,解析→建立语法树→……
小结
至此,我们揭开了Python面纱的一角——不过是一个可运行、可调试的程序而已(微笑)。
相关推荐
- 怎么查看电脑产品密钥(怎么查看自己电脑产品密钥)
-
准备工具:电脑1.打开电脑,在电脑中找到我的电脑选项,双击该选项打开我的电脑进入我的电脑主页面。2.在我的电脑主页面中找到磁盘下方的空白位置,鼠标右键单击该位置调出功能选项框。3.在功能选项框中找到下...
- 不知道密码怎么连接wifi网络
-
不知道WiFi密码怎么连接,如果你不知道WiFi密码的话,那我没有办法连接网络,你必须去找WiFi密码是主人,然后询问密码,只有你得到了最准确的密码以后,你才可以开启你的WiFi网络设置,然后输入正确...
- u盘写了保护怎么把保护删掉了
-
U盘写保护可以通过以下几种方法去除:1.取消U盘的写保护开关。有些U盘上面自带写保护的开关,如果被拨到写保护状态时,就会对U盘进行写保护,这种情况解决的办法最简单,直接将开关拨回原位即可。2.修复...
- 深度ghost精简xp(深度ghost文件)
-
windowsxp下运行ghost方法如下:1、首先把GHOST.EXE程序复制到你的硬盘某区上(不要是C区,假如是E区)。2、然后重新启动电脑,重启过程中按DEL键进入BIOS设置,设置为从光驱启...
- 固态硬盘如何安装(固态硬盘如何安装系统)
-
1、首先要在在机箱内找到固态硬盘安装的电源连接线,是从电脑的电源引出的一根线。形状是扁嘴形上面一般印着一个白色的“P4”2、然后要在主板上找固态硬盘的数据接口,用于数据输入输出,俗称SATA接口,再找...
- windows怎么打开注册表(windows怎么打开注册表管理器)
-
方法一、直接打开注册表1、点击屏幕左下角的“开始”按钮,再点击“运行”;2、或者直接按Win键+R键,打开“运行”对话框;3、在“运行”输入框中输入“regedit”命令;4、这样就能够打开注册表编辑...
- windows7安装windows10(windows7安装光盘下载)
-
在安装Win7时,出现提示“Windows无法安装到这个磁盘。这台计算机的硬件可能不支持启动到此磁盘。请确保在计算机的bios菜单中启用了磁盘的控制器。” 解决方法: 1.如果之前你做过BIOS设置,...
-
- 装机配置模拟器(装机配置模拟器教程)
-
装机模拟器2好装机模拟器2装系统方法1.在游戏PC装机模拟器里,有时候我们修理好电脑之后,发现电脑没有安装操作系统,这时候应该先安装系统。2.第一步,点击PC装机模拟器游戏,登录游戏。3.第二步,进入游戏之后,找到需要没有安装操作系统的电脑...
-
2025-11-10 21:51 off999
- 电脑网络正常但是上不了网(网络正常但电脑无法上网)
-
分析如下1、首先检查网卡的问题,打开电脑后,打开电脑右下角的WiFi连接,然后从里面的网络和共享中心检查,打开网络和共享中心后,出现对话框,在对话框左侧上方找到更改适配器设置,单击左键打开,就可以发现...
- vs2008安装包下载(vs2008下载官方下载)
-
vs2008是面向WindowsVista、Office2007、Web2.0的下一代开发工具,VS2008引入了250多个新特性,整合了对象、关系型数据、XML的访问方式,语言更加简洁。使用V...
- cad2018序列号(cad2018序列码)
-
AutoCAD2018序列号和密钥:序列号:356-72378422,666-69696969,667-98989898,400-45454545,066-66666666等密钥:001J1CA...
- ip检测网站(ip地址测试)
-
IP检测工具(IPNetChecker)V1.5.2是一个简易实用,功能强大的网络监控软件,使您可以检查互联网和局域网上的IP主机的网络状态。IP检测工具(IPNetChecker)V1.5....
- 云电脑app哪个好(手机云电脑app哪个最好)
-
答:以下是一些比较好的云电脑应用程序推荐:1.AnyDesk-支持Windows、MacOS、Linux、Android和iOS,可用于远程访问和控制PC或移动设备。2.Splashtop...
欢迎 你 发表评论:
- 一周热门
-
-
抖音上好看的小姐姐,Python给你都下载了
-
全网最简单易懂!495页Python漫画教程,高清PDF版免费下载
-
Python 3.14 的 UUIDv6/v7/v8 上新,别再用 uuid4 () 啦!
-
python入门到脱坑 输入与输出—str()函数
-
飞牛NAS部署TVGate Docker项目,实现内网一键转发、代理、jx
-
宝塔面板如何添加免费waf防火墙?(宝塔面板开启https)
-
Python三目运算基础与进阶_python三目运算符判断三个变量
-
(新版)Python 分布式爬虫与 JS 逆向进阶实战吾爱分享
-
慕ke 前端工程师2024「完整」
-
失业程序员复习python笔记——条件与循环
-
- 最近发表
- 标签列表
-
- python计时 (73)
- python安装路径 (56)
- python类型转换 (93)
- python进度条 (67)
- python吧 (67)
- python的for循环 (65)
- python格式化字符串 (61)
- python静态方法 (57)
- python列表切片 (59)
- python面向对象编程 (60)
- python 代码加密 (65)
- python串口编程 (77)
- python封装 (57)
- python写入txt (66)
- python读取文件夹下所有文件 (59)
- python操作mysql数据库 (66)
- python获取列表的长度 (64)
- python接口 (63)
- python调用函数 (57)
- python多态 (60)
- python匿名函数 (59)
- python打印九九乘法表 (65)
- python赋值 (62)
- python异常 (69)
- python元祖 (57)
