背景
线上的项目是使用python3.6.15写的, 跑在docker下
问题
某个进程执行巨慢,通过日志定位到了 if else, 但是if下的代码有日志, else 处并没有打日志, 所以想看看else 处到底发生了什么.
问题解决
尝试方案一. gdb 调试.
安装 gdb
1 | 没权限记录加sudo |
gdb 无法附加, 可能是安全策略导致的.
尝试 echo 0 /proc/sys/kernel/yama/ptrace_scope
但报错 只读文件系统.
一番搜索后, 发现可以在进入容器命令中加个参数即可解决.
1 | docker exec --privileged -ti ebbed4cb3xxxx bash |
解决后再次附加进程, 结果如下
一番搜索后猜测是原因可能是 原进程是root用户启动的,或者该进程是root启动的. 暂时先忽略这个报错.
看看 bt 命令 打印一下堆栈
解释型语言, 这个堆栈,并不是我理想的样子.
随即尝试方案二, 真香.
同样需要安装 gdb、python3-dbg, 上面我们已经安装过了.
安装主次主角 pyrasite
1 | pip install pyrasite |
同样需要 echo 0 | sudo tee /proc/sys/kernel/yama/ptrace_scope, 如果是容器下, 只需要 docker exec 时候, 加上 –privileged 命令就好.
然后执行 pyrasite-shell pid 附加到你要调试的进程中
1 | pyrasite-shell your_need_attach_process_id |
可以看到已经成功附加到了原进程中, 并且打印Pid, 已经是原进程的pid.
查看一下本地变量还有全局变量,打印一下本地变量 i的值,发现是变化的. 如果你的程序中有 redis_conn 这些,也应该可以执行 redis_conn.exist() 等复杂操作.
调试完成后, Use quit() or Ctrl-D (i.e. EOF) to exit, 这种退出方式不会影响原进程, 原进程健壮地活着. 手动狗头.jpg
done!!!