请教各位在 Windows 下 Python 3 出 segfault 时如何有效地找错。
Linux 下有 gdb。Windows 下 MinGW 的 gdb-python 好像只能用在 Python 2 上。我的程序是用 Python 3 写的,很多自己写的函数,2to3 应付不了,手动改要花很多时间。有在 qq 群里问过,有人建议用二分法删源码,直到 segment fault 不再出现就找到错了。这种方法好像效率太低,而且如果 segment fault 不是固定出现在某的地方不可用。
GUI 下用个 thread、pubsub 什么的,出 segfault 还是比较常见的,而且 GUI ( pyqt,wxpython 之类的)程序的 Test 测试好像也没有什么好的办法,unitest、pytes 派不太上用场。各路高手用什么方法找导致 segfault 的错误?请分享一下,先感谢。
1
dbow 2017-07-01 10:34:39 +08:00 1
完整的错误信息贴出来看看。
|
3
ipwx 2017-07-01 10:42:56 +08:00 1
Python 出 Segment Fault 一般不是 Python 写的代码的问题。
你写的、或者你引用的 native package 有问题。删掉整个 Python 3 重新安装一下吧?另外二进制的包如果用 Anaconda 装,一般会降低出问题的概率。 |
4
dbow 2017-07-01 10:47:45 +08:00 1
gdb --args ./app ..... 跑一遍, 出了 segment fault, 用 bt 命令, 输出 stack trace
|
5
yucongo OP |
8
ipwx 2017-07-01 11:22:47 +08:00
@yucongo 你把你装的依赖包列一下我们看看吧。很可能某个第三方库的二进制包和你的 Python 二进制不太兼容…… 或者你的代码使用第三方库时导致了它内部二进制包的异常。
另外最后的出错信息打出来看看也很重要。第三方库的二进制包出问题的 stack trace 和 Python 自己的二进制包出错,信息还是不一样的。 |
9
congeec 2017-07-01 11:39:58 +08:00 1
gdb-python 可以用于 python 3,不过你得自己编译安装。我试过,挺麻烦
|
11
yucongo OP certifi==2017.4.17
chardet==3.0.2 colorama==0.3.9 configobj==5.0.6 cx-Freeze==5.0.2 future==0.16.0 googletrans==2.1.3 html2text==2016.9.19 langdetect==1.0.7 langid==1.1.6 lxml==3.7.3 nltk==3.2.2 nose==1.3.7 numpy==1.13.0 pandas==0.20.2 py==1.4.34 pycountry==17.1.8 pysrt==1.1.1 pysubs2==0.2.1 pytest==3.1.2 python-dateutil==2.6.0 python-docx==0.8.6 pytz==2017.2 pywin32==221 PyYAML==3.12 regex==2017.4.29 requests==2.13.0 requests-cache==0.4.13 segtok==1.5.5 six==1.10.0 textblob==0.12.0 tqdm==4.11.2 wxPython==4.0.0a2.dev3016+2645796 xlrd==1.0.0 yandex.translate==0.3.5 @ipwx Python 3.5 venv 下 pip freeze 的包 因为看不懂 stack trace,所以一直在整 gdb-python,不过我试着用 gdb 在 Python 3 下获取 stack trace,成功的话在贴上来。 |
12
zk8802 2017-07-01 12:11:54 +08:00 via iPhone 1
用 WinDBG 跑 Python,挂了之后输入 k 看一下调用栈,一般就知道是哪个库的问题了。如果问题不复杂,这可能是最快的方法。
|
14
congeec 2017-07-01 13:06:40 +08:00
@yucongo https://github.com/fedora-python/python3/blob/master/python-gdb.py
https://wiki.python.org/moin/DebuggingWithGdb https://docs.python.org/devguide/gdb.html 你需要单独编译 gdb 和 CPython。编译 gdb 的时候,加--with-python="${the directory in which your python3 binary is installed}"。编译一份 CPython,记得用 debug 模式,这样调试时 step 到标准库,也会显示源码的 |
15
ipwx 2017-07-01 13:55:41 +08:00
库我认不全,不过我认知的库里面,NumPy, wxPython 和 lxml 都有 native binary。也许应该注意一下。
|
16
yucongo OP 貌似 Windows 下 Python 3 要找 segfault 出错的地方没有什么办法。再加上我的程序还是 wxpython GUI,完全没辙。我试过 Windbg,winpdb,trepan3k,pudb, 都不行。
Windbg 里用 pykd 可以运行 python 非 GUI 程序,运行 wxpython 写的 gui 程序就出不来 gui。也可以在 python 下运行 wxpython 写的 gui 程序后 attach 到 Windbg, 但 attach 后 wxpython gui 就没有反应了, 也就是说没法 gui 里的交互(点击、载入文件啊什么的)。 最后还是靠 logging …… 找到 python 一个 bug: os.startfile("") python ( 2.7, 3.4, 3.5 )直接死掉。try... except ... 没有用…… 花掉我一整天 ……&¥……%¥# |
17
nickr 2017-07-02 08:00:56 +08:00 via iPhone
” Windbg 里用 pykd 可以运行 python 非 GUI 程序,运行 wxpython 写的 gui 程序就出不来 gui。“
这个尝试完全是晕了头. pykd 是 windbg 的一个插件. 在 windbg 里跑起来一个 python vm, 用来和 windbg 交互. 和 op 现在遇到的 python crash 八杆子打不着. |
18
yucongo OP 这个 os.startfile("") 导致 python.exe 崩溃其实只在 ConEmu 下才出现(我的是 32 位 Windows 7,ConEmu 161002 ),所以可能要算 ConEmu 的 bug 吧……
|
19
yucongo OP @nickr 感谢回答。
我搞不太清楚。不过 Windbg 里 如果不 !load pykd.dll 是运行不了 !py 的。 Windbg 里 Alt-1: 0:000> !py -3.4 No export py found 0:000> !load pykd.dll 0:000> !py -3.4 Python 3.4.4 (v3.4.4:737efcadf5a6, Dec 20 2015, 19:28:18) [MSC v.1600 32 bit (Intel)] on win32 Type "help", "copyright", "credits" or "license" for more information. (InteractiveConsole) >>> |
20
hasdream 2017-07-02 21:11:37 +08:00
segfault 报错很多是 C 扩展不支持多线程操作, 比如多线程对一个 mysql(mysqldb)连接发起查询请求就会这样(每个线程开一个连接去查询就可以解决这个问题)。 大部分是 C 扩展一个回话不支持多线程操作 或者操作需要加锁
|