python pdb 转载:https://www.linuxidc.com/Linux/2017-11/148329.htm
最近在为一个监控系统开发agent,需要支持Linux、FreeBSD及Windows等操作系统。复杂的线上环境,带来了一系列诡异的问题,尽管代码上线前在为数不少的测试机器验证过。
Python程序吐coredump文件怎么办?很多人都会想到gdb加载coredump文件,然后查看信号及堆栈信息,以此分析原因。堆栈信息在调试中非常有用,但是别忘了,你写的是Python代码,但是gdb给你的是C堆栈信息!似乎没啥鸟用!难道要撸Python源码然后分析各种核心数据结构吗?有什么方式可以查看到Python堆栈信息吗?
还遇到过另一个问题,一个Python进程突然间陷入死循环,所有其他线程都调度不到。遇到这种情况,首先可能需要知道死循环到底在干什么。如何获悉呢?可能用strace跟一下系统调用可以看出一点端倪。但是一个堆栈信息更为具体更有说服力,就算是只有C堆栈信息有时也是足以说明问题的。
gdb就可以解决以上难题(其实远不止),接下来,我们一起看看具体要怎么操作吧~
准备
首先得有gdb吧,这个就不细说了,debian系发行版上运行以下命令完成安装:
apt-get install gdb
其次,还需要装一个包——python-dbg。这个包有什么作用呢?前面不是抱怨过C堆栈对于调试一个Python有何用?我们更需要的是Python堆栈信息,python-dbg就是为了完成这个使命。
运行
全新启动一个Python程序并进行调试,可以采用交互式方式,先启动gdb然后在gdb shell中启动Python程序:
$ gdb python
...
(gdb) run <programname>.py <arguments>
当然了,也可以一步到位,一条命令搞定这两步:
gdb -ex r --args python <programname>.py <arguments>
遗憾的是,现实中往往是这样的情景——一个正在运行的程序突然异常了,你需要调试它!这时为之奈何?
有一种方法你可以给它发一个信号,出一个coredump文件,然后用gdb来调试coredump文件:
gdb <coredump_file>
显然易见,这并不是一种很好的方式,那么有没有什么办法可以捕获进程并调试呢?你想得到的很有可能都有人实现了——
gdb python <process id>
gdb attach <process id>
这两种方式都可以让gdb捕获一个进程。因此,我们需要做的只是确定问题进程的pid,这个总该没有难度了吧——top、ps等等一系列命令都可以做到。
堆栈查看
查看C堆栈信息,用过gdb命令的估计都知道怎么做:
(gdb) bt
#0 0x0000002a95b3b705 in raise () from /lib/libc.so.6
#1 0x0000002a95b3ce8e in abort () from /lib/libc.so.6
#2 0x00000000004c164f in posix_abort (self=0x0, noargs=0x0) at ../Modules/posixmodule.c:7158
#3 0x0000000000489fac in call_function (pp_stack=0x7fbffff110, oparg=0) at ../Python/ceval.c:3531
#4 0x0000000000485fc2 in PyEval_EvalFrame (f=0x66ccd8) at ../Python/ceval.c:2163
...
那么,怎么查看Python堆栈呢。安装python-gdb之后,gdb会提供若干相关的操作。其中py-bt就是用来查看Python堆栈的:
(gdb) py-bt
线程查看
调试多线程程序,首先总得搞清楚到底有哪些线程吧:
(gdb) info threads
Id Target Id Frame
37 Thread 0xa29feb40 (LWP 17914) "NotificationThr" 0xb7fdd424 in __kernel_vsyscall ()
36 Thread 0xa03fcb40 (LWP 17913) "python2.7" 0xb7fdd424 in __kernel_vsyscall ()
35 Thread 0xa0bfdb40 (LWP 17911) "QProcessManager" 0xb7fdd424 in __kernel_vsyscall ()
34 Thread 0xa13feb40 (LWP 17910) "python2.7" 0xb7fdd424 in __kernel_vsyscall ()
33 Thread 0xa1bffb40 (LWP 17909) "python2.7" 0xb7fdd424 in __kernel_vsyscall ()
31 Thread 0xa31ffb40 (LWP 17907) "QFileInfoGather" 0xb7fdd424 in __kernel_vsyscall ()
30 Thread 0xa3fdfb40 (LWP 17906) "QInotifyFileSys" 0xb7fdd424 in __kernel_vsyscall ()
29 Thread 0xa481cb40 (LWP 17905) "QFileInfoGather" 0xb7fdd424 in __kernel_vsyscall ()
7 Thread 0xa508db40 (LWP 17883) "QThread" 0xb7fdd424 in __kernel_vsyscall ()
6 Thread 0xa5cebb40 (LWP 17882) "python2.7" 0xb7fdd424 in __kernel_vsyscall ()
5 Thread 0xa660cb40 (LWP 17881) "python2.7" 0xb7fdd424 in __kernel_vsyscall ()
3 Thread 0xabdffb40 (LWP 17876) "gdbus" 0xb7fdd424 in __kernel_vsyscall ()
2 Thread 0xac7b7b40 (LWP 17875) "dconf worker" 0xb7fdd424 in __kernel_vsyscall ()
* 1 Thread 0xb7d876c0 (LWP 17863) "python2.7" 0xb7fdd424 in __kernel_vsyscall ()
请注意*号哦——它标识的是当前线程。
那么如何切换线程呢?
(gdb) thread 37
这样就将37号线程设置为当前线程进行调试了。
好,那么怎么查看当前线程的相关信息呢?上节中,py-bt可以帮上忙——至少知道线程的执行堆栈。还有一个操作py-list,可以清楚看到当前执行到代码的第几行,还有前后若干行的代码可以对照哦:
(gdb) py-list
2025 # Open external files with our Mac app
2026 if sys.platform == "darwin" and 'Spyder.app' in __file__:
2027 main.connect(app, SIGNAL('open_external_file(QString)'),
2028 lambda fname: main.open_external_file(fname))
2029
>2030 app.exec_()
2031 return main
2032
2033
2034 def __remove_temp_session():
2035 if osp.isfile(TEMP_SESSION_PATH):
还有更6的,查看所有进程执行位置,非常方便有木有:
(gdb) thread apply all py-list
...
200
201 def accept(self):
>202 sock, addr = self._sock.accept()
203 return _socketobject(_sock=sock), addr
204 accept.__doc__ = _realsocket.accept.__doc__
205
206 def dup(self):
207 """dup() -> socket object
Thread 35 (Thread 0xa0bfdb40 (LWP 17911)):
Unable to locate python frame
Thread 34 (Thread 0xa13feb40 (LWP 17910)):
197 for method in _delegate_methods:
198 setattr(self, method, dummy)
199 close.__doc__ = _realsocket.close.__doc__
200
201 def accept(self):
>202 sock, addr = self._sock.accept()
203 return _socketobject(_sock=sock), addr...
参考资料
https://wiki.python.org/moin/DebuggingWithGdb
GDB调试命令 http://www.linuxidc.com/Linux/2017-01/139028.htm
强大的C/C++ 程序调试工具GDB http://www.linuxidc.com/Linux/2016-09/135171.htm
Linux GDB调试 详述 http://www.linuxidc.com/Linux/2016-11/137505.htm
使用 GDB 恢复堆栈信息 http://www.linuxidc.com/Linux/2017-07/145508.htm
使用GDB命令行调试器调试C/C++程序 http://www.linuxidc.com/Linux/2014-11/109845.htm
GDB调试命令总结 http://www.linuxidc.com/Linux/2016-08/133988.htm
GDB调试工具入门 http://www.linuxidc.com/Linux/2016-09/135168.htm
python pdb 转载:https://www.linuxidc.com/Linux/2017-11/148329.htm的更多相关文章
- 法语Linux NuTyX 11 RC2 发布
读 NuTyX是一个法语Linux发行版(具有多语言支持),由Linux From Scratch和Beyond Linux From Scratch构建,带有一个名为“cards”的自定义包管理器. ...
- Ubuntu 14.04 下搭建SVN服务器 (转载自 http://www.linuxidc.com/Linux/2015-01/111956.htm)-------------我所用到是红色字体
http://www.linuxidc.com/Linux/2015-01/111956.htm Ubuntu 14.04 下搭建SVN服务器 svn:// 安装软件包: sudo apt-get i ...
- SUSE Linux Enterprise 11 离线安装 DLIB python机器学习模块
python机器学习模块安装 环境:SUSE Linux Enterprise 11 sp4 离线安装 说明:在安装dlib时依赖的基础 环境较多,先升级gcc,以适应c++ 11的使用:需要用到c ...
- Python深入:Distutils发布Python模块--转载
https://blog.csdn.net/gqtcgq/article/details/49255995 Distutils可以用来在Python环境中构建和安装额外的模块.新的模块可以是纯Pyth ...
- Python classes to extract information from the Linux kernel /proc files.
python/python-linux-procfs/python-linux-procfs.git - Python classes to extract information from the ...
- SUSE Linux Enterprise 11 离线安装 DLIB 人脸识别 python机器学习模块
python机器学习模块安装 我的博客:http://www.cnblogs.com/wglIT/p/7525046.html 环境:SUSE Linux Enterprise 11 sp4 离线安 ...
- 使用python+xpath 获取https://pypi.python.org/pypi/lxml/2.3/的下载链接
使用python+xpath 获取https://pypi.python.org/pypi/lxml/2.3/的下载链接: 使用requests获取html后,分析html中的标签发现所需要的链接在& ...
- Hadoop 的部署适用性(网上资料http://www.linuxidc.com/Linux/2013-10/92141.htm)
近些年,Hadoop和“走向大数据分析引擎”一样,受到颇多赞誉.对很多人来说,Hadoop就意味着大数据技术.但其实开源的分布式处理框架未必能解决所有的大数据问题.这就要求想要部署Hadoop的公司慎 ...
- http://www.linuxidc.com/Linux/2007-09/7399.htm
http://www.linuxidc.com/Linux/2007-09/7399.htm
随机推荐
- Python学习笔记--gevent嵌套使用
这篇主要是接着上篇的,实验gevent嵌套使用,看情况如何.还是先上代码. #!/usr/bin/env python # -*- coding: utf-8 -*- # @Date : 2020-0 ...
- python列表解析补充:
python列表解析补充: # 补充: f = [x + y for x in 'ABCDE' for y in '1234567'] print(f) test = [] for x in 'ABC ...
- GoLand 设置与配置
1. 将 tab 改为 4个空格 2. GoLand 取消 import 自动导入
- AOP面试知识整理,^_^-包括spring Aop
讲到java企业级开发框架,就不可避免的讲到 IOC,AOP,MCV 今天面试时被问到AOP,讲的很乱,这里整理笔记,包括AOP,spring-AOP的部分知识,错误的地方请小伙伴指出来. 谈谈你对A ...
- 动态构造任意复杂的 Linq Where 表达式
前言 Linq 是 C# 中一个非常好用的集合处理库,用好了能帮我们简化大量又臭又长的嵌套循环,使处理逻辑清晰可见.EF 查询主要也是依赖 Linq.但是 Linq 相对 sql 也存在一些缺点,最主 ...
- python 深浅拷贝 元组 字典 集合操作
深浅拷贝 :值拷贝 :ls = [,,] res = ls 则print(res)就是[,,] 浅拷贝 :ls.copy() 深拷贝:ls3 = deepcopy(ls) # 新开辟列表空间,ls列表 ...
- Redis系列五 - 哨兵、持久化、主从
问:骚年,都说Redis很快,那你知道这是为什么吗? 答:英俊潇洒的面试官,您好.我们可以先看一下 关系型数据库 和 Redis 本质上的区别. Redis采用的是基于内存的,采用的是单进程单线程模型 ...
- 学习ConcurrentHashMap1.7分段锁原理
1. 概述 接上一篇 学习 ConcurrentHashMap1.8 并发写机制, 本文主要学习 Segment分段锁 的实现原理. 虽然 JDK1.7 在生产环境已逐渐被 JDK1.8 替代,然而一 ...
- 01.UNIX基础知识
1.UNIX体系结构 什么叫做内核? 内核是一种软件,它控制计算机硬件资源,并提供程序的运行环境. 什么叫操作系统? 在广义上,操作系统包括了内核和一些其他软件,这些软件使得计算机能够发挥作用,如可以 ...
- webpack学习(一):webpack的安装和命令行
本教程可以学习到如下内容: 1.webpack的安装 2.利用webpack命令打包js文件 3.如何在js文件里面引用css并将css文件在页面里面生效 4.学习webpack相关的高级的一些参数, ...