介绍一款调试Python的神器
前段时间在Pi上用Python和gtk搞了个应用,到最后测试阶段一直被闪退折磨。闪退是我自己起的名词,比如你玩手机的时候,玩得正高兴的时候,游戏莫名其妙的闪退了,你郁闷不,开发者其实更郁闷,因为闪退嘛,死都不知道怎么死的。经过一周的追踪,用尽各种手段,终于让我发现一款神奇。先来说说事情的起因。
先省略几个小时的log。。。
batching times: 1
thread batching starts...
set,['?RD.EC', '9006.38']
thread batching stopped.
('READDATA', ('COND', None, None), [('?RD.EC', None)])
get ?RD.EC
in {'?RD.EC': '9006.38'}
batching times: 1
thread batching starts...
set,['OHM:5']
thread batching stopped.
*** glibc detected *** python: double free or corruption (fasttop): 0x01b73a28 ***
已放弃
pi@raspberrypi ~/calibration/cali04a $看到了吧,重复了几个小时的代码,突然间闪退了,就给你这么点答案,释放空指针,靠,这前不着村后不着地的python,你让我去给你查指针释放去?经人介绍,用pydb(Extended Python Debugger)来跑,无功而返,对于这种Segment fault,根本跟没用差不多嘛,pydb也就能调调正常的程序。('READDATA', ('COND', None, None), [('?RD.EC', None)])
get ?RD.EC
in {'?RD.EC': '225.04'}
batching times: 1
thread batching starts...
set,['OHM:1000']
thread batching stopped.
batching times: 1
thread batching starts...
set,['?RD.EC', '450.25']
thread batching stopped.
('READDATA', ('COND', None, None), [('?RD.EC', None)])
get ?RD.EC
in {'?RD.EC': '450.25'}
*** glibc detected *** /usr/bin/python: double free or corruption (!prev)batching times: 1
: 0x00c12800 ***
已放弃
pi@raspberrypi ~/calibration/src_cali04a $好吧,逼急了上gdb吧,好歹知道是哪里的错误了。这里要吐槽下gtk用到的gdk,满篇的断言,真不知该夸你还是该扁你!('READDATA', ('COND', None, None), [('?RD.EC', None)])
get ?RD.EC
in {'?RD.EC': '22.50'}
batching times: 1
thread batching starts...
set,['OHM:10000']
thread batching stopped.
batching times: 1
thread batching starts...
set,['?RD.EC', '45.01']
thread batching stopped.
('READDATA', ('COND', None, None), [('?RD.EC', None)])
get ?RD.EC
in {'?RD.EC': '45.01'}
batching times: 1
thread batching starts...
**
Gdk:ERROR:/build/gtk+2.0-x7uJoT/gtk+2.0-2.24.10/gdk/gdkregion-generic.c:1206:miUnionO: assertion failed: (pReg->numRects<=pReg->size)
bt
Program received signal SIGABRT, Aborted.
0x40384bfc in raise () from /lib/arm-linux-gnueabihf/libc.so.6
(gdb) bt
#00x40384bfc in raise () from /lib/arm-linux-gnueabihf/libc.so.6
#10x4038897c in abort () from /lib/arm-linux-gnueabihf/libc.so.6
#20x4046bd2c in ?? () from /lib/arm-linux-gnueabihf/libc.so.6
#30x4046bd2c in ?? () from /lib/arm-linux-gnueabihf/libc.so.6
Backtrace stopped: previous frame identical to this frame (corrupt stack?)
(gdb)上面报gdk error的地方已经被无数函数调用过,我用bt命令回溯stack,貌似也看不到啥有用的信息,谁让咱用的是多线程呢,好吧,接下来该大杀器出场了。set,['?RD.EC', '225.06']
thread batching stopped.
('READDATA', ('COND', None, None), [('?RD.EC', None)])
get ?RD.EC
in {'?RD.EC': '225.06', '?NTC.T': 'None', 'ID': 'None'}
batching times: 1
thread batching starts...
set,['OHM:1000']
thread batching stopped.
**
Gdk:ERROR:/build/gtk+2.0-x7uJoT/gtk+2.0-2.24.10/gdk/gdkregion-generic.c:1110:miUnionNonO: assertion failed: (y1 < y2)
Fatal Python error: Segmentation fault
Thread 0x474a6470:
Thread 0x486b9470:
File "/usr/lib/python2.7/threading.py", line 244 in wait
File "/usr/lib/python2.7/threading.py", line 404 in wait
File "/usr/lib/python2.7/threading.py", line 500 in start
File "d:/workspace/calibration/cali_test.py", line 43 in timer_event
File "/usr/lib/python2.7/threading.py", line 760 in run
File "/usr/lib/python2.7/threading.py", line 552 in __bootstrap_inner
File "/usr/lib/python2.7/threading.py", line 525 in __bootstrap
Thread 0x4666f470:
File "d:/workspace/calibration/basinterp.py", line 476 in run
File "d:/workspace/calibration/cali_test.py", line 388 in plying
File "/usr/lib/python2.7/threading.py", line 505 in run
File "/usr/lib/python2.7/threading.py", line 552 in __bootstrap_inner
File "/usr/lib/python2.7/threading.py", line 525 in __bootstrap
Thread 0x45de1470:
File "/usr/lib/python2.7/threading.py", line 244 in wait
File "/usr/lib/python2.7/threading.py", line 668 in join
File "d:/workspace/calibration/cali_test.py", line 255 in receiving
File "/usr/lib/python2.7/threading.py", line 505 in run
File "/usr/lib/python2.7/threading.py", line 552 in __bootstrap_inner
File "/usr/lib/python2.7/threading.py", line 525 in __bootstrap
Current thread 0x400d7210:
File "d:/workspace/calibration/cali_test.py", line 127 in on_TextViewOfLog_size_allocate
File "d:/workspace/calibration/cali_test.py", line 786 in main
File "d:/workspace/calibration/cali_test.py", line 791 in <module>
段错误
pi@raspberrypi ~/calibration/cali04a $
看到这里爽伐?每个线程的stack都被完整的打印出来,找问题不跟玩似的,呵呵。问题就是出在最后这个on_TextViewOfLog_size_allocate,究其原因,我没有把gtk的窗口设成固定大小,又因为我有一个Frame在不停地变换长短不一的文字,所以整个窗体一会大一点一会小一点,gdk经过几个小时的折磨,终于不小心被自己的断言给干掉了gdkregion-generic.c:1110:miUnionNonO: assertion failed: (y1 < y2)
好了,就这样。对了,忘了说神器叫啥了,faulthandler,截至发帖版本是2.2,地址在:https://pypi.python.org/pypi/faulthandler,用法如下:
在你的python主程序启动前,加上如下代码,然后就等着兔子上门吧:import faulthandler
faulthandler.enable()有什么问题欢迎加入QQ群讨论,号码:204148284(开源硬件)
就是他了找了好久
页:
[1]