Back to home

打可调试的在线服务

初次发表于2051/10/23

某年某月的某一天,在xx云上运行的服务突然死锁而停止服务了。祭出gdb神器准备debug一番的时候,才发现我们的银河量产的云主机中安装的python也许当初为了性能的考虑,是不携带调试信息的。
当小概率的bug突然发生时,你却不能调试,身为码农,最痛苦的事情莫过如此。为了捕捉着稍纵即逝的幽灵,有必要打造一个可调式的线上服务环境。
1. 在你的工程中建立依赖环境的目录,如$project_home/env/python
2. 下载并安装合适版本的python,如
Python-2.7.11#./configure --with-pydebug --prefix=$project_home/env/python
Python-2.7.11#make && make install
3. 分离符号表
在服务正常运行中,为了性能应该不携带调试信息,而调试的时候有需要调试信息,所以把python的可执行文件中的调试信息单独保存,需要时动态加载即可。
env/python/bin#objcopy --only-keep-debug python python.dbg
env/python/bin#objcopy --strip-debug python
4. 安装gdb(可选)
确保你的gdb版本>=7
确认gdb连接的Python是所要debugPython,否则请重新编译gdb
5. 下载libpython.py
将其放置在sys.path能找到的的某个路径下
6. 下载并安装依赖的第三方库
你的代码中用到的第三方库,用env/python/bin/python xxx/setup.py install 安装即可;或者使用veritualenv也可以完成同样的功能,需要者自行放狗搜索。
7. 用自带的python环境运行你的代码
Chroot/virtualenv或者其它尽你所能的方式,反正就是用新安装的python运行你的代码
8. 尝试调试
#gdb –p $pid
>symbol-file /path/to/env/python/bin/python.dbg
>python
>import libpython
>end
>py-bt
确保没有错误且能看到当前运行的python源码

9. 耐心等待幽灵重现
遇见死锁,我不怕不怕了。。。
推而广之:
1. 无论你用什么编程语言,让你的服务高效运行,产品环境不要携带调试信息
2. 无论你用什么编程语言,让你的服务可调试,务必要有可动态加载的调试信息
3. 无论你用什么编程语言,如果以上条件不满足,学着自己动手打造可调式的产品环境