pycharm远程调试openstack
准备
开发机器信息:
- pycharm 版本:2021.1.3
虚拟机信息:
- devstack 版本:queens
- devstack openstack 版本:queens
- python 版本:2.7.12
基本原理
- Python 远程调试模型其实是一个典型的Server/Client模型。
- 本地 PyCharm 有两个作用:
- 方便在本地编辑远程机器上的源代码。
- 启动 Python Debug Server,监听本地的某个端口,等待 Client 的接入。
- 远程机器运行的 Python 程序调用 pydevd_pycharm 库,连接到服务端。
- 断点是打在远程机器的源代码上,只是我们使用了远程开发的模式,所以看上去是写在本地的,实际上确实也是写在本地的,只是代码会被同步到远程。但实际上我们要保证的是远程源码打上了断点。
配置过程
创建本地工程
此步主要完成本地代码与远程代码的同步,可以将远程代码下载到本地,也可以将本地在 Pycharm 中修改的代码很快部署到远程环境中。
- 解释器选择远程解释器
- 不要自动创建 main.py
- 这里我使用了先前配置的解释器
- 新建一个远程解释器如下:
- 【设置】中选择【添加】
- 远程解释器配置
- 取消自动上传项目文件到服务器,因为一开始是空项目,我们要从远程下载代码,而不是从本地同步代码到远程
- 同步文件映射:本地项目目录 —> 远程项目目录
- 下载远程代码到本地,这样我们本地就有了一份和远程一模一样的源代码了
Debug Server配置
Debug Server 由 pycharm 负责启动,配置如下:
- 在本地利用 PyCharm 启动了一个Debug Server
- 上述配置的 ip 是本机的,端口也是本地端口
开始调试
准备工作
PyCharm 很好的一点是,他在配置debug server 的时候给你提示了怎么使用,如上图,步骤如下:
- 在远程环境安装debug client 的包:
1
pip install pydevd-pycharm~=211.7628.24
- 在源码中需要打断点的地方引用库
1
2import pydevd_pycharm
pydevd_pycharm.settrace('172.25.5.233', port=12345, stdoutToServer=True, stderrToServer=True)打断点
启动Debug Server
- 只能感叹,PyCharm的用户体验做的是真好,写的是真清楚,生怕你不知道
远端重启服务
- 查看服务启动命令
systemctl cat devstack@n-api
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20# 查看服务启动命令
systemctl cat devstack@n-api
# /etc/systemd/system/devstack@n-api.service
[Unit]
Description = Devstack devstack@n-api.service
[Service]
RestartForceExitStatus = 100
NotifyAccess = all
Restart = always
KillMode = process
Type = notify
ExecReload = /bin/kill -HUP $MAINPID
ExecStart = /usr/local/bin/uwsgi --procname-prefix nova-api --ini /etc/nova/nova-api-uwsgi.ini
User = stack
SyslogIdentifier = devstack@n-api.service
[Install]
WantedBy = multi-user.target - 停掉服务
systemctl stop devstack@n-api
- 用 bash 启动
/usr/local/bin/uwsgi --procname-prefix nova-api --ini /etc/
- 用
nova flavor-list
触发断点, 就能开始调试咯,如下图: - 调试变量:
通用的debug方法
pycharm 在测试环境 debug 固然方便,但是一旦遇到线上环境网络不通畅的情况,就没法进行debug了。因此还是很有必要掌握通用的debug方法。
pdb
pdb 调试时必须要手动启动服务的场景。如果服务是 systemd 管理的方式,那么需要先把服务停掉,然后手动启动,比如在 devstack 环境下调试时:
- 查看服务启动命令
1
systemctl show devstack@n-sch.service -p ExecStart
- 停止服务
1
systemctl stop devstack@n-sch.service
- 设置断点
1
import pdb; pdb.set_trace()
- 手动启动
1
/usr/local/bin/nova-scheduler --config-file /etc/nova/nova.conf
- 有些服务,是在某些 Group 中启动的(比如nova-compute),那么执行方式不一样,先查看 Group
1
2systemctl cat devstack@n-cpu.service | grep Group
Group = libvirt - 用 sg 工具执行
1
sg libvirt -c '/usr/local/bin/nova-compute --config-file /etc/nova/nova-cpu.conf'
remote-pdb
remote-pdb
不在乎程序是用什么方式运行的,只要能够能连接到程序就行(源码执行环境能够 pip 安装依赖)。 - 源码环境安装依赖
1
pip install remote-pdb
- 打上断点
1
from remote_pdb import RemotePdb; RemotePdb('127.0.0.1', 4444).set_trace()
- telnet 连接
1
telnet 127.0.0.1 4444
pdb 常用命令
1、查看源代码
- 命令:l
2、添加断点
- 命令:b
1
2
3
4
5
6
7
8
9
10
11
12# 参数:
# filename文件名,断点添加到哪个文件,如test.py
# lineno断点添加到哪一行
# function:函数名,在该函数执行的第一行设置断点
# 说明:
# 1.不带参数表示查看断点设置
# 2.带参则在指定位置设置一个断点
b lineno
b filename:lineno
b functionname
3、添加临时断点
- 命令:tbreak
1
2
3
4
5
6
7
8
9# 参数:
# 同b
# 说明:
# 执行一次后时自动删除(这就是它被称为临时断点的原因)
tbreak lineno
tbreak filename:lineno
tbreak functionname
4、清除断点
- 命令:cl
1
2
3
4
5
6
7
8
9# 参数:
# bpnumber 断点序号(多个以空格分隔)
# 说明:
# 1.不带参数用于清除所有断点,会提示确认(包括临时断点)
# 2.带参数则清除指定文件行或当前文件指定序号的断点
cl filename:lineno
cl bpnumber [bpnumber ...]
5、打印变量值
- 命令:p expression
1
2# 参数:
# expression Python表达式
6、逐行调试命令
包括 s ,n , r 这3个相似的命令,区别在如何对待函数上
- 命令1:s
1 |
|
命令2:n
1
2# 说明:
# 执行下一行(不会进入函数体)命令3:r
1
2# 说明:
# 执行下一行(在函数中时会直接执行到函数返回处)7、非逐行调试命令
命令1:c1
2# 说明:
# 持续执行下去,直到遇到一个断点
命令2:unt lineno
1 |
|
- 命令3:j lineno
1
2# 说明:
# 直接跳转到指定行(注意,被跳过的代码不执行)
8、查看函数参数
- 命令:a
1
2# 说明:
# 在函数中时打印函数的参数和参数的值
9、打印变量类型
- 命令:whatis expression
1
2# 说明:
# 打印表达式的类型,常用来打印变量值
10、启动交互式解释器
- 命令:interact
1
2# 说明:
# 启动一个python的交互式解释器,使用当前代码的全局命名空间(使用ctrl+d返回pdb)
11、打印堆栈信息
- 命令:w
1
2# 说明:
# 打印堆栈信息,最新的帧在最底部。箭头表示当前帧。
12、退出pdb
- 命令:q
pycharm远程调试openstack
http://mybestcheng.site/2022/12/07/openstack/misc/remote_debug/