专栏名称: Python之美
《Python web开发实战》作者的公众号。发现Python之美,主要包含Web开发、Python进阶、架构设计、Python开发招聘信息等方面内容
目录
相关文章推荐
Python爱好者社区  ·  确认裁员了,很严重,所有人做好准备吧! ·  2 天前  
Python爱好者社区  ·  python必备手册 ·  3 天前  
Python爱好者社区  ·  挑行李回家的高考女生火了!热心网友愿资助,多 ... ·  2 天前  
Python爱好者社区  ·  全球第二大成人网站,正在被打包出售。。。 ·  3 天前  
Python开发者  ·  震撼!美国卡脖子下,中国工程师拖 4 ... ·  3 天前  
51好读  ›  专栏  ›  Python之美

一次调试段错误(segmentation fault)的经验

Python之美  · 公众号  · Python  · 2019-12-11 17:47

正文

请到「今天看啥」查看全文


. py install

  • ... # 正常

  • Installed / Users / dongweiming / lyanna / venv / lib / python3 . 8 / site - packages / aiomcache - 0.6 . 0 - py3 . 8.egg

  • Processing dependencies for aiomcache == 0.6 . 0

  • Finished processing dependencies for aiomcache == 0.6 . 0

  • 那可以确定不是aiomemcache,这个时候我想到:

    • 是setuptools(在setup.py中会用到)及其依赖中的C扩展(在Python3.8下)问题

    • 最新的CPython代码问题

    怀疑最新的CPython代码问题

    等大家看完全文会发现这里偏了,因为按照几率来说肯定是第三方的库更不靠谱一点... 不过也是合理的,想尝鲜就是非常可能遇到各种还没有人踩到的坑。此时我心中一怔,顺便给CPython改C代码的机会来的,激动!!

    由于这种心情的撺掇,调试方向的天平倾向了CPython而不是看setuptools依赖链。

    接着我加了DEBUG标记重新编译了CPython:

    1. ./configure CFLAGS='-DPy_DEBUG' --with-pydebug && make && make install

    这次最终没有抛段错误,执行正常,很奇怪。接着我不带标记重新编译,上面的错误又重现了,不过我在调试过程发现直接用CPython源码目录下编译好的python执行正常:

    1. ~/cpython/python.exe /Users/dongweiming/lyanna/venv/src/aiomcache/setup.py develop

    也就是说 用什么都没做的裸Python正常,但是在虚拟环境中的Python本来也正常,但是安装了一堆依赖后就不正常

    直观上,我已经觉得和CPython 3.8的源码无关了(# ̄~ ̄#),但谁引起的段错误还不清楚。


    GDB大法

    对于调试Python代码,我基本上都会用print,连pdb也用的很少。如果是C接口有问题,就需要使用gdb了。另外gdb也可以用于调试正在运行的Python进程。

    在macOS下使用Homebrew安装gdb:

    1. brew install gdb

    不过此时GDB只有基本的Python支持,如果你自己编译GDB记得加上 -- with - python 选项。接着我们要把CPython项目中的libpython.py里面提供的命令加进来:

    1. gdb python3

    2. GNU gdb (GDB) 8.3

    3. ...

    4. (gdb) python # Python解释器

    5. >import sys # 和写Python代码一样

    6. >sys.path.insert(0, '/Users/dongweiming/cpython/Tools/gdb') # 把包含libpython.py文件的目录加到sys.path里

    7. >import libpython # 导入

    8. >end # 结束Python

    9. (gdb) py # 按Tab就可以看到支持多个py-开头的命令了

    10. py-bt py-down py-locals py-up python-interactive

    11. py-bt-full py-list py-print python

    导入libpython的缺点是每次进入gdb都得执行一次,另外一个方法是写入到GDB初始化文件 . gdbinit 中:

    1. source ~/cpython/Tools/gdb/libpython.py

    libpython的作用是让 PyObject * 的输出更容易理解,另外新加了上面看到的命令具体用法可以看延伸阅读链接2。

    另外CPython官方也维护了一个 Misc / gdbinit 文件(见延伸阅读链接3),其中提供了pystack、pyframe、lineno等命令,它们是针对gdb 7之前的版本,我安装的是当前最新的GDB 8.3,就不需要了

    这里要注意一个细节,加了配置后抛段错误前会卡住,需要在 . gdbinit 里面加这么一句:

    1. set startup-with-shell off

    Ok, 配置已经完成了,现在运行这个有问题的命令:

    1. gdb python3

    2. (gdb) run /Users/dongweiming/lyanna/venv/src/aiomcache/setup.py develop

    3. Starting program: /Users/dongweiming/lyanna/venv/bin/python3 /Users/dongweiming/lyanna/venv/src/aiomcache/setup.py develop

    4. Unable to find Mach task port for process-id 8888: (os/kern) failure (0x5).

    5. (please check gdb is codesigned - see taskgated(8))

    这是由于权限问题,需要给gdb签一个证书。步骤如下(也可以参考延伸阅读链接5里的内容):

    1. 启动Keychain Access应用程序

    2. 从菜单选择Certificate Assistant -> Create a Certificate

    3. 新加一个证书,名字就叫gdbcert(之后还要用到),身份类型self-signed root,证书类型Code Signing,「Let me override defaults」不用勾,然后create

    4. 创建一个XML文件(gdb.xml),内容如下:

    1. xml version="1.0" encoding="UTF-8"?>

    2. version="1.0">

    3. com.apple.security.cs.debugger

    1. 更新代码签名: codesign -- entitlements gdb . xml - fs gdbcert / usr / local / bin / gdb

    现在就可以正常使用了:

    1. cd ~/cpython

    2. (gdb) run /Users/dongweiming/lyanna/venv/src/aiomcache/setup.py develop

    3. Starting







    请到「今天看啥」查看全文