极客工坊

 找回密码
 注册

QQ登录

只需一步,快速开始

查看: 16477|回复: 7

介绍一款调试Python的神器

[复制链接]
发表于 2013-10-23 09:02:17 | 显示全部楼层 |阅读模式
前段时间在Pi上用Python和gtk搞了个应用,到最后测试阶段一直被闪退折磨。闪退是我自己起的名词,比如你玩手机的时候,玩得正高兴的时候,游戏莫名其妙的闪退了,你郁闷不,开发者其实更郁闷,因为闪退嘛,死都不知道怎么死的。
经过一周的追踪,用尽各种手段,终于让我发现一款神奇。先来说说事情的起因。
先省略几个小时的log。。。

  1. batching times: 1
  2. thread batching starts...

  3. set,  ['?RD.EC', '9006.38']
  4. thread batching stopped.

  5. ('READDATA', ('COND', None, None), [('?RD.EC', None)])
  6. get ?RD.EC
  7. in {'?RD.EC': '9006.38'}
  8. batching times: 1
  9. thread batching starts...

  10. set,  ['OHM:5']
  11. thread batching stopped.

  12. *** glibc detected *** python: double free or corruption (fasttop): 0x01b73a28 ***
  13. 已放弃
  14. pi@raspberrypi ~/calibration/cali04a $
复制代码
看到了吧,重复了几个小时的代码,突然间闪退了,就给你这么点答案,释放空指针,靠,这前不着村后不着地的python,你让我去给你查指针释放去?经人介绍,用pydb(Extended Python Debugger)来跑,无功而返,对于这种Segment fault,根本跟没用差不多嘛,pydb也就能调调正常的程序。
  1. ('READDATA', ('COND', None, None), [('?RD.EC', None)])
  2. get ?RD.EC
  3. in {'?RD.EC': '225.04'}
  4. batching times: 1
  5. thread batching starts...

  6. set,  ['OHM:1000']
  7. thread batching stopped.

  8. batching times: 1
  9. thread batching starts...

  10. set,  ['?RD.EC', '450.25']
  11. thread batching stopped.

  12. ('READDATA', ('COND', None, None), [('?RD.EC', None)])
  13. get ?RD.EC
  14. in {'?RD.EC': '450.25'}
  15. *** glibc detected *** /usr/bin/python: double free or corruption (!prev)batching times: 1
  16. : 0x00c12800 ***
  17. 已放弃
  18. pi@raspberrypi ~/calibration/src_cali04a $
复制代码
好吧,逼急了上gdb吧,好歹知道是哪里的错误了。这里要吐槽下gtk用到的gdk,满篇的断言,真不知该夸你还是该扁你!
  1. ('READDATA', ('COND', None, None), [('?RD.EC', None)])
  2. get ?RD.EC
  3. in {'?RD.EC': '22.50'}
  4. batching times: 1
  5. thread batching starts...

  6. set,  ['OHM:10000']
  7. thread batching stopped.

  8. batching times: 1
  9. thread batching starts...

  10. set,  ['?RD.EC', '45.01']
  11. thread batching stopped.

  12. ('READDATA', ('COND', None, None), [('?RD.EC', None)])
  13. get ?RD.EC
  14. in {'?RD.EC': '45.01'}
  15. batching times: 1
  16. thread batching starts...

  17. **
  18. 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)
  19. bt





  20. [New Thread 0x47eff470 (LWP 15726)]
  21. [Thread 0x48eff470 (LWP 15725) exited]
  22. [New Thread 0x48eff470 (LWP 15727)]
  23. [Thread 0x47eff470 (LWP 15726) exited]
  24. [New Thread 0x47eff470 (LWP 15728)]
  25. [Thread 0x47eff470 (LWP 15728) exited]
  26. [New Thread 0x467bf470 (LWP 15729)]
  27. [Thread 0x48eff470 (LWP 15727) exited]
  28. [New Thread 0x48eff470 (LWP 15730)]

  29. Program received signal SIGABRT, Aborted.
  30. 0x40384bfc in raise () from /lib/arm-linux-gnueabihf/libc.so.6
  31. (gdb) bt
  32. #0  0x40384bfc in raise () from /lib/arm-linux-gnueabihf/libc.so.6
  33. #1  0x4038897c in abort () from /lib/arm-linux-gnueabihf/libc.so.6
  34. #2  0x4046bd2c in ?? () from /lib/arm-linux-gnueabihf/libc.so.6
  35. #3  0x4046bd2c in ?? () from /lib/arm-linux-gnueabihf/libc.so.6
  36. Backtrace stopped: previous frame identical to this frame (corrupt stack?)
  37. (gdb)
复制代码
上面报gdk error的地方已经被无数函数调用过,我用bt命令回溯stack,貌似也看不到啥有用的信息,谁让咱用的是多线程呢,好吧,接下来该大杀器出场了。
  1. set,  ['?RD.EC', '225.06']
  2. thread batching stopped.

  3. ('READDATA', ('COND', None, None), [('?RD.EC', None)])
  4. get ?RD.EC
  5. in {'?RD.EC': '225.06', '?NTC.T': 'None', 'ID': 'None'}
  6. batching times: 1
  7. thread batching starts...

  8. set,  ['OHM:1000']
  9. thread batching stopped.

  10. **
  11. Gdk:ERROR:/build/gtk+2.0-x7uJoT/gtk+2.0-2.24.10/gdk/gdkregion-generic.c:1110:miUnionNonO: assertion failed: (y1 < y2)
  12. Fatal Python error: Segmentation fault

  13. Thread 0x474a6470:

  14. Thread 0x486b9470:
  15.   File "/usr/lib/python2.7/threading.py", line 244 in wait
  16.   File "/usr/lib/python2.7/threading.py", line 404 in wait
  17.   File "/usr/lib/python2.7/threading.py", line 500 in start
  18.   File "d:/workspace/calibration/cali_test.py", line 43 in timer_event
  19.   File "/usr/lib/python2.7/threading.py", line 760 in run
  20.   File "/usr/lib/python2.7/threading.py", line 552 in __bootstrap_inner
  21.   File "/usr/lib/python2.7/threading.py", line 525 in __bootstrap

  22. Thread 0x4666f470:
  23.   File "d:/workspace/calibration/basinterp.py", line 476 in run
  24.   File "d:/workspace/calibration/cali_test.py", line 388 in plying
  25.   File "/usr/lib/python2.7/threading.py", line 505 in run
  26.   File "/usr/lib/python2.7/threading.py", line 552 in __bootstrap_inner
  27.   File "/usr/lib/python2.7/threading.py", line 525 in __bootstrap

  28. Thread 0x45de1470:
  29.   File "/usr/lib/python2.7/threading.py", line 244 in wait
  30.   File "/usr/lib/python2.7/threading.py", line 668 in join
  31.   File "d:/workspace/calibration/cali_test.py", line 255 in receiving
  32.   File "/usr/lib/python2.7/threading.py", line 505 in run
  33.   File "/usr/lib/python2.7/threading.py", line 552 in __bootstrap_inner
  34.   File "/usr/lib/python2.7/threading.py", line 525 in __bootstrap

  35. Current thread 0x400d7210:
  36.   File "d:/workspace/calibration/cali_test.py", line 127 in on_TextViewOfLog_size_allocate
  37.   File "d:/workspace/calibration/cali_test.py", line 786 in main
  38.   File "d:/workspace/calibration/cali_test.py", line 791 in <module>
  39. 段错误
  40. 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主程序启动前,加上如下代码,然后就等着兔子上门吧:
  1. import faulthandler
  2. faulthandler.enable()
复制代码
有什么问题欢迎加入QQ群讨论,号码:204148284(开源硬件)



回复

使用道具 举报

发表于 2013-10-24 12:57:40 | 显示全部楼层
感谢楼主分享
回复 支持 反对

使用道具 举报

 楼主| 发表于 2013-10-25 09:32:35 | 显示全部楼层
ddkangfu 发表于 2013-10-24 12:57
感谢楼主分享

大家在Pi上都用什么开发,用Python的多吗
回复 支持 反对

使用道具 举报

发表于 2013-10-31 18:05:28 | 显示全部楼层
感谢分享,mark备用哈
回复 支持 反对

使用道具 举报

发表于 2015-1-2 15:52:35 | 显示全部楼层
好东西,记下来备用
回复 支持 反对

使用道具 举报

发表于 2015-1-4 13:47:53 | 显示全部楼层
MAN 发表于 2013-10-25 09:32
大家在Pi上都用什么开发,用Python的多吗

只会C/C++的路过。其实要是Python熟的话,很多事情都用不着C了
回复 支持 反对

使用道具 举报

发表于 2015-1-6 19:13:16 | 显示全部楼层
我刚学习编程,怎么我的python老湿说,python离不开C/C++呢?
回复 支持 反对

使用道具 举报

发表于 2015-1-11 09:05:05 | 显示全部楼层
多谢分享,很实用
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 注册

本版积分规则 需要先绑定手机号

Archiver|联系我们|极客工坊

GMT+8, 2024-3-29 18:59 , Processed in 0.043348 second(s), 23 queries .

Powered by Discuz! X3.4 Licensed

Copyright © 2001-2021, Tencent Cloud.

快速回复 返回顶部 返回列表