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 相关文章推荐
python中的闭包用法实例详解
May 05 Python
web.py 十分钟创建简易博客实现代码
Apr 22 Python
Python3使用SMTP发送带附件邮件
Jun 16 Python
对python中list的拷贝与numpy的array的拷贝详解
Jan 29 Python
python 应用之Pycharm 新建模板默认添加编码格式-作者-时间等信息【推荐】
Jun 17 Python
基于TensorFlow常量、序列以及随机值生成实例
Jan 04 Python
python递归调用中的坑:打印有值, 返回却None
Mar 16 Python
python 安装库几种方法之cmd,anaconda,pycharm详解
Apr 08 Python
Django配置Bootstrap, js实现过程详解
Oct 13 Python
基于python实现百度语音识别和图灵对话
Nov 02 Python
python将图片转为矢量图的方法步骤
Mar 30 Python
python Polars库的使用简介
Apr 21 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
PHP中在数据库中保存Checkbox数据(1)
2006/10/09 PHP
默默简单的写了一个模板引擎
2007/01/02 PHP
在PHP中设置、使用、删除Cookie的解决方法
2013/05/06 PHP
PHP FATAL ERROR: CALL TO UNDEFINED FUNCTION BCMUL()解决办法
2014/05/04 PHP
PHP中预定义的6种接口介绍
2015/05/12 PHP
PHP实现批量重命名某个文件夹下所有文件的方法
2017/09/04 PHP
php自动加载代码实例详解
2021/02/26 PHP
js编码、解码函数介绍及其使用示例
2013/09/05 Javascript
jQuery Form 页面表单提交的小例子
2013/11/15 Javascript
node.js中的console.trace方法使用说明
2014/12/09 Javascript
js面向对象之常见创建对象的几种方式(工厂模式、构造函数模式、原型模式)
2015/11/09 Javascript
ES6新特性之解构、参数、模块和记号用法示例
2017/04/01 Javascript
JavaScript数据结构之二叉查找树的定义与表示方法
2017/04/12 Javascript
微信小程序 本地数据存储实例详解
2017/04/13 Javascript
全站最详细的Vuex教程
2018/04/13 Javascript
JS中验证整数和小数的正则表达式
2018/10/08 Javascript
vue中v-for循环选中点击的元素并对该元素添加样式操作
2020/07/17 Javascript
如何通过Proxy实现JSBridge模块化封装
2020/10/22 Javascript
python list 合并连接字符串的方法
2013/03/09 Python
简单总结Python中序列与字典的相同和不同之处
2016/01/19 Python
Python中内置的日志模块logging用法详解
2016/07/12 Python
Python列表和元组的定义与使用操作示例
2017/07/26 Python
Python通过调用有道翻译api实现翻译功能示例
2018/07/19 Python
对python3中pathlib库的Path类的使用详解
2018/10/14 Python
在Python中将函数作为另一个函数的参数传入并调用的方法
2019/01/22 Python
Django缓存系统实现过程解析
2019/08/02 Python
python的Jenkins接口调用方式
2020/05/12 Python
python爬虫爬取淘宝商品比价(附淘宝反爬虫机制解决小办法)
2020/12/03 Python
实例讲解CSS3中的box-flex弹性盒属性布局
2016/06/09 HTML / CSS
韩国流行时尚女装网站:Dintchina(中文)
2018/07/19 全球购物
日本热销NO.1胶原蛋白冻:Aishitoto爱希特多
2019/06/20 全球购物
中文专业毕业生自荐信
2013/10/28 职场文书
企业总经理职责
2014/02/02 职场文书
行政副总岗位职责
2014/02/23 职场文书
python函数指定默认值的实例讲解
2021/03/29 Python
MySQL读取JSON转换的方式
2022/03/18 MySQL