Pycharm远程调试原理及具体配置详解


Posted in Python onAugust 08, 2019

前言

工作中使用Pycharm作为python开发的IDE,作为专业的python集成开发环境,其功能之强大令人折服。开发过程中Debug是必不可少的。平时经常使用Pycharm的remote debug功能,非常好用。但是刚开始的时候并不了解该过程的原理,只是按部就班的配置。于是抽空了解了一下相关知识,期待能够了解其原理,今后能够在需要的时候自己独立的配置调试环境。本文将以浅显易懂的方式讲解一下相关过程。

1.应用环境

常见的IDE基本都具有Local Debugger功能。一般只需要简单的配置,直接加断点并使用Debug方式运行即可使用断点调试。这是对于本地调试开发而言。如果项目已经完成并上线部署到服务端,或者是本地需要在IDE之外单独配置并启动程序,那么显然不能使用本地调试。如果能够配合日志并使用断点定位分析问题,将会事半功倍。那么如何使用本地安装的Pycharm远程调试程序?

2.远程调试原理

如果程序部署在远端,要在本地获取程序运行状态并进行断点调试,必然需要连接到程序并进行通讯。利用Pycharm进行远程调试过程中,Pycharm充当服务器的角色。

首先,对Pycharm Run/Debug Configures进行配置,指定Pycharm安装端的一些属性,比如Pycharm所在主机的IP地址和端口号等。

然后,启动Pycharm的远程调试。这时Pycharm处于监听状态,等待独立于IDE之外运行的程序的连接。

其次,在远端程序刚启动时,需要根据Pycharm Debug Configures中的配置信息,连接到Pycharm。

最后,连接成功之后,当远程客户端运行到本地Pycharm中设置的断点处时,便会在断点处暂停程序的执行,而在本地Pycharm命中断点处能够看到远端程序当前运行的状态和调用栈等信息并进行下一步跟踪和逐步调试。

本地Pycharm中调试的源代码工程应和远端运行的程序源代码保持一致。Pycharm中Remote Debug Configure的配置要保证能够被远程连接。

由于远程客户端使用Pycharm提供的pydevd模块连接到本地的Pycharm remote Debug,两者通讯链接均遵循Pycharm自定义的协议。因此我们不必关心Pycharm设置断点和远程客户端命中断点过程中两端具体的实现和处理过程,只要保证我们的Debug Configure有效即可。然后在需要的地方通过断点暂定程序,分析当前程序状态找出问题所在。

3.Pycharm具体配置

下面是当前的操作环境,原理和步骤都是想通的,可根据实际情况进行配置配即可。

当前环境:

  • Win7
  • Python 2.7.12
  • PyCharm Professional 2017.1.4 (community版本 好像没有remote debug 功能)

本地完成Pycharm的安装,在安装目录找到debug-eggs文件夹,里面有两个文件:

  • pycharm-debug.egg
  • pycharm-debug-py3k.egg

分别对应本地python解释器为python2和python3的情况。

解压pycharm-debug.egg文件,得到的文件夹pycharm-debug中包含的是remote debug相关的模块。

远程客户端便是通过该文件夹中pydevd文件的settrace方法连接到指定的debug server的。

客户端配置:

为方便起见,我们将客户端也放置到本地。(远端的只需要将下面的localhost改为Pycharm所在端的IP即可)

工程中添加刚才解压得到的远程调试模块:

./pycharm-debug

下面还需要封装一个连接到Remote Debug Server的文件

./PycharmRemoteDebug.py

import sys
sys.path.append('./Pycharm_debug')
import pydevd
if __name__ != '__main__':
 pydevd.settrace('localhost', port=23456, stdoutToServer=True, stderrToServer=True, suspend=False)

当前待调试程序:./Main.py

# -*- coding:utf-8 -*-
import PycharmRemoteDebug

class Singleton(object):
 _INSTANCE = {}
 def __init__(self, cls):
  self.cls = cls

 def __call__(self, *args, **kwargs):
  instance = self._INSTANCE.get(self.cls, None)
  if not instance:
   instance = self.cls(*args, **kwargs)
   self._INSTANCE[self.cls] = instance
  return instance

 def __getattr__(self, key):
  return getattr(self.cls, key, None)
@Singleton
class MyClass(object):
 def __init__(self):
  self.init_attr = "init_attr"
 def __getattr__(self, key):
  return self.__dict__.get(key, 1212)
if __name__ == "__main__":
 mcls1 = MyClass()
 mcls2 = MyClass()
 print mcls1 is mcls2

注意调试模块pycharm-debug和链接文件PycharmRemoteDebug.py可以放置到任意的路径和位置,只需要调整模块引用的路径即可。

当前工程目录:

Pycharm远程调试原理及具体配置详解

Pycharm Remote Debug 配置:

打开Run/Debug Configures

Pycharm远程调试原理及具体配置详解

新建配置 Add New Configuration --> Python Remote Debug

Pycharm远程调试原理及具体配置详解

上面的名字可以自己随便命名,端口号可以随便改,只要可用即可。

上面截图绿色部分的标记也告诉了我们客户端连接Debug Server的步骤方法,注意第三步中使用的命令就是我们客户端配置中的PycharmRemoteDebug.py文件中的连接命令。

4.使用步骤

选择刚才新建的Debug模式 Remote_Debug,点击绿色甲壳虫Debug按钮:

Pycharm远程调试原理及具体配置详解

Debug Console 显示如下信息,说明本地Debug Server已经开启并在监听状态:

Starting debug server at port 23456
Use the following code to connect to the debugger:
import pydevd
pydevd.settrace('localhost', port=23456, stdoutToServer=True, stderrToServer=True, suspend=False)
Waiting for process connection...

然后在Pycharm中设置断点。

最后启动客户端(运行Main.py,并非在IDE中,直接双击该文件或者使用命令行执行)

Pycharm中命中断点:

Pycharm远程调试原理及具体配置详解

Watch程序当前状态以及调用栈等信息:

Pycharm远程调试原理及具体配置详解

5.注意事项

  • 如果将程序部署到远端,那么需要Remote Debug配置中的localhost修改为安装Pycharm主机的IP地址,同时将PycharmRemoteDebug.py中的localhost改为同样的IP地址;
  • 使用Pycharm的Deployment功能映射远程和本地代码;
  • 断点命中时,客户端程序处于暂定状态;
  • 如果没有开启Remote Debug Server,运行客户端会卡住;
  • 不需要使用Remote Debug时一定不要在程序启动的时候import PycharmRemoteDebug模块;
  • 添加remote debug 配置文件后,注意区分启动本地和远程两种不同的调试模式;

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Python 相关文章推荐
在GitHub Pages上使用Pelican搭建博客的教程
Apr 25 Python
Python写入数据到MP3文件中的方法
Jul 10 Python
发布你的Python模块详解
Sep 15 Python
python面向对象_详谈类的继承与方法的重载
Jun 07 Python
python实现朴素贝叶斯分类器
Mar 28 Python
利用Anaconda简单安装scrapy框架的方法
Jun 13 Python
Django admin.py 在修改/添加表单界面显示额外字段的方法
Aug 22 Python
一行Python代码制作动态二维码的实现
Sep 09 Python
python随机生成库faker库api实例详解
Nov 28 Python
Python文件夹批处理操作代码实例
Jul 21 Python
Python 忽略文件名编码的方法
Aug 01 Python
一文带你掌握Pyecharts地理数据可视化的方法
Feb 06 Python
Python IDE Pycharm中的快捷键列表用法
Aug 08 #Python
python多线程与多进程及其区别详解
Aug 08 #Python
python PIL和CV对 图片的读取,显示,裁剪,保存实现方法
Aug 07 #Python
python实现对图片进行旋转,放缩,裁剪的功能
Aug 07 #Python
Django 实现前端图片压缩功能的方法
Aug 07 #Python
Django 后台获取文件列表 InMemoryUploadedFile的例子
Aug 07 #Python
python 直接赋值和copy的区别详解
Aug 07 #Python
You might like
PHP4实际应用经验篇(8)
2006/10/09 PHP
header导出Excel应用示例
2014/01/24 PHP
PHP实现支持GET,POST,Multipart/form-data的HTTP请求类
2014/09/24 PHP
Yii2中关联查询简单用法示例
2016/08/10 PHP
php外部执行命令函数用法小结
2016/10/11 PHP
PHP CURL与java http使用方法详解
2018/01/26 PHP
不用AJAX和IFRAME,说说真正意义上的ASP+JS无刷新技术
2008/09/25 Javascript
JS获取dom 对象 ajax操作 读写cookie函数
2009/11/18 Javascript
圣诞节Merry Christmas给博客添加浪漫的下雪效果基于jquery实现
2012/12/27 Javascript
node.js中的events.emitter.listeners方法使用说明
2014/12/10 Javascript
JS实现超过长度限制后自动跳转下一款文本框的方法
2015/02/23 Javascript
js淡入淡出焦点图幻灯片效果代码分享
2015/09/08 Javascript
Angular中$compile源码分析
2016/01/28 Javascript
AngularJS入门教程之Select(选择框)详解
2016/07/27 Javascript
jQuery实现jQuery-form.js实现异步上传文件
2017/04/28 jQuery
Vue.js组件间的循环引用方法示例
2017/12/27 Javascript
jQuery获取随机颜色的实例代码
2018/05/21 jQuery
基于mpvue的小程序项目搭建的步骤
2018/05/22 Javascript
微信小程序实现红包雨功能
2018/07/11 Javascript
[38:39]完美世界DOTA2联赛循环赛 IO vs GXR BO2第二场 11.04
2020/11/05 DOTA
一个计算身份证号码校验位的Python小程序
2014/08/15 Python
python正则表达式及使用正则表达式的例子
2018/01/22 Python
使用Python从零开始撸一个区块链
2018/03/14 Python
python实现批量处理将图片粘贴到另一张图片上并保存
2019/12/12 Python
Python 解析pymysql模块操作数据库的方法
2020/02/18 Python
HTML5的download属性详细介绍和使用实例
2014/04/23 HTML / CSS
美赞臣营养马来西亚旗舰店:Enfagrow马来西亚
2019/07/26 全球购物
令人啧啧称赞的经理推荐信
2013/11/07 职场文书
军校本科大学生自我评价
2014/01/14 职场文书
12月小学生校园广播稿
2014/02/04 职场文书
党务公开方案
2014/05/06 职场文书
县长“四风”对照检查材料思想汇报
2014/10/05 职场文书
2015元旦家电促销活动策划方案
2014/12/09 职场文书
学习商务礼仪心得体会
2016/01/22 职场文书
美甲店的创业计划书模板
2019/08/23 职场文书
SONY AN-LP1 短波有源天线放大器图
2022/04/05 无线电