打算开始看 《Python源码剖析》, 这需要能够本地调试 CPython 的源码
虽然这本书是基于 CPython2.5 的,有点古老了,但大部分还是通用的
这里分别使用 CPython3.6 和 CPython2.7 的源码来调试
这样也能看出 Python2 与 Python3 在源码实现上的一些区别,下面是本次搭建的环境:
- src:CPython 3.6, CPython2.7
- os:Win10
- ide:VS2017
获取源码
从Github上分别下载 CPython3.6 的源码 和 CPython2.7 的源码 并解压
编译 CPython3.6 源码
我们并不调试 python 标准库的源码,所以这里直接跳过了依赖文件的下载而是直接编译:
使用 vs2017 打开 cpython-3.6\PCbuild\pcbuild.sln
在解决方案资源管理器中:右键 “python” -> 重定向项目 -> 选择 Windows SDK 版本为 10.0.17134.0 (或其他 Win10 版本的SDK即可)
对 “pythoncore” 重复上一条操作
在解决方案资源管理器中:右键 “pythoncore” -> 属性 -> 配置属性 -> C/C++ -> 预处理器 -> 右侧编辑“预处理器定义” -> 添加
“_X86_”
点击 “本地windows调试器” 开始编译源码,方案为 Debug Win32
等待一会,弹出交互式命令行窗口,证明编译成功,可以开始愉快地调试了
编译成功后在 cpython-3.6\PCbuild\ 目录下会多出两个目录:obj 和 win32
其中 win32 目录中存放着编译好的 python 二进制可执行文件
由于我们的编译模式为 Debug,所以该文件名为 python_d.exe 而不是 python.exe
在 cpython-3.6\PCbuild\ 目录下还有一个文件 readme.txt,这是官方对 windows 下编译 CPython 源码的说明,可供参考
编译 CPython2.7 源码
步骤与 CPython3.6 差不多,但需要修改一些源码:
使用 vs2017 打开
cpython-2.7\PCbuild\pcbuild.sln
,会提示升级SDK,确定,这会帮我们自动重定向SDK直接编译会报错:
timemodule.c
下的标识符timezone
、daylight
和tzname
未定义,这是升级 SDK 的缘故需要修改两个文件:
首先把
cpython-2.7\Modules\posixmodule.c
下的_PyVerify_fd
函数内容替换为如下代码:
//a call to _get_osfhandle with invalid fd sets errno to EBADF
if (_get_osfhandle(fd) == INVALID_HANDLE_VALUE)
return 0;
else
return 1;
然后把 cpython-2.7\Modules\timemodule.c
中 inittimezone
函数中报错的变量 timezone
、daylight
和 tzname
分别改为 _timezone
、_daylight
和 _tzname
,即在原来的变量前面加单下划线,一共改动四行,分别是 811,819,822 和 824 行,记得保存所有修改
- 点击 “本地windows调试器” 开始编译源码,方案为 Debug Win32
注意:CPython2.7 编译后的二进制可执行文件就在 cpython-2.7\PCbuild
下,并没有 win32 这个目录
移除冗余目录
到这里已经搭建完成了,但我们只关心 pythoncore 目录下的源码
因此可以 在解决方案资源管理器中 把其他目录从管理器中移出,避免对后期搜索结果的影响
但要保留 python 目录,因为该目录下的 python.c 是程序入口
也就是说最后只保留 pythoncore 和 python 这两个目录在解决方案资源管理器中即可
后期所有的调试工作都在 pythoncore 目录下进行