跨平台PHP调试器设计及使用方法——探索和设计
在《跨平台PHP调试器设计及使用方法——立项》一文中,我确定了使用xdebug作为调试器插件部分的基础组件。xdebug提供了一个远程调试的功能(相关资料可以详见https://xdebug.org/docs/remote),我们这个项目便是基于这个功能实现的。(转载请指明出于breaksoftware的csdn博客)
远程调试是基于网络传输方式进行交互的一种调试方式,那么其必定有服务端和客户端两部分组成。这儿的服务端和客户端都是相对的,因为一个客户端可能在和服务器通信后就变成了一个服务端,而服务端则在一次通信后就变成了客户端。xdebug在这个模型中属于服务端,因为它是嵌入到PHP执行器内部,影响PHP执行流程的部分,这些核心功能肯定是作为服务端的一部分而存在。同时它也应该有接收和响应请求的功能。
xdebug提供了两种连接的方式,一种是固定地址单线连接。一种是未知地址多线连接。
我们先看下固定地址单线连接,它的执行流程如下图
- 嵌入在PHP执行程序中的Xdebug开启了一个80端口
- 控制调试过程的IDE发起一次HTTP的调试请求
- Xdebug根据配置项中的remote_host和remote_port字段(也就是IDE所在机器的IP和IDE开放的端口),向IDE发起连接请求
- IDE和Xdebug建立连接,相互通信
- Xdebug应答2过程中的HTTP请求
上述方式存在一个问题,就是要在Xdebug里配置好IDE的IP和PORT,这样就只能有一台机器上的IDE可以与该Xdebug通信。为了可以支持多用户同时连接方式,Xdebug还提供了一种针对未知IP连接的方式,我们先看下流程图:
- 嵌入在PHP执行程序中的Xdebug开启一个80端口
- 控制调试过程的IDE发起一次HTTP的调试请求
- Xdebug的配置项中药配置remote_connect_back为1或者on,还要配置remote_port。Xdebug根据2中的请求解析出远端IDE的IP,然后通过该IP和remote_port发起一次连接请求
- IDE和Xdebug建立连接,相互通信
- Xdebug应答2过程中的HTTP请求
面对这两种方式,我们需要如何选择呢?首先我们看一个问题,如果配置过netbeans和Xdebug连接的朋友,肯定记得netbeans中要配置代码FTP地址。因为作为IDE需要能查看到远程机器上这些要被执行的文件(因为要展现给用户看执行到哪儿了,哪儿要下断点等)。虽然xdebug的source命令可以获取当前执行文件的内容,而对于一款调试器来说,我们往往需要很多尚未发生的内容。所以IDE要能访问远程文件是必要的。
但是这一步骤,也将影响用户配置调试器的进度。因为为了调试,我还要给远程机器开启一个FTP服务,还要配置服务对应的本地地址,这些似乎都和我们要进行调试的行为无关。所以为了解决这个问题,我们索性在调试器中不放开编辑源码的功能。同时我们将IDE和Xdebug放在同一台机器上,这样IDE可以读取本地的PHP执行的文件,这样也就不用开启FTP服务了。于是,我们就选择固定IP单线连接的方式。
这儿需要指出的是,我们在配置remote_host时肯定不能写死一个IP。因为我们代码和配置随时会被拷贝到其他环境,所以写死一些值将严重影响其适用性,于是我们可以使用localhost来代替固定IP
xdebug.remote_enable=On xdebug.remote_handler=dbgp xdebug.remote_host=localhost xdebug.remote_port=9000 |
通信方式解决后,我们便需要关注通信协议的问题。xdebug使用的是一个叫dpgp的协议,其协议文档见https://xdebug.org/docs-dbgp.php。
这份协议文档虽然比较长,但是还算简单。作为行为请求的发起方,需要向Xdebug发送command -a value -b value……这种类型的请求内容,而Xdebug会返回一个XML内容。对于这种看似不对称的请求类型造成的原因,文档中解释是说XML内容生成是容易的,但是解析却需要其他的库。然而作者明显不想引入这些并不太重要的第三方库。其实我觉得这种请求方式挺好的,它非常像我们使用的其他输入式调试器,比如windbg。
接下来我们看下调试的过程
- IDE获取Xdebug支持的一些属性(不同版本的Xdebug支持不同的功能,所以IDE要先探知它的支持什么不支持什么)
- IDE设置一些Xdebug属性、断点等信息
- Xdebug让代码运行起来,直到遇到断点或者运行结束
- 如果遇到断点,IDE可以向Xdebug询问一些变量值,堆栈信息,或者修改一些变量值等
我们再看下Xdebug文档中一段比较类似人通话的过程,它也展现了整个调试过程的样貌
IDE: feature_get supports_async DBG: yes IDE: stdin redirect DBG: ok IDE: stderr redirect DBG: ok IDE: run DBG: stdin data... DBG: stdin data... DBG: reached breakpoint, done running IDE: give me some variables DBG: ok, here they are IDE: evaluate this expression DBG: stderr data... DBG: ok, done IDE: run IDE: break DBG: ok, breaking DBG: at breakpoint, done running IDE: stop DBG: good bye |
虽然看似整个协议非常简单,但是我并没打算去实现一套发送请求并解析XML返回结果的库。我看了一下其他软件的Xdebug通信库基本上都是调用了一套名叫pydbgp的Python实现库,我也准备使用它。有时候还是非常必要站在巨人的肩膀上去实现一些事。
pydbgd的官方地址是http://jaredforsyth.com/pydbgp/。我们只需要取用下载包中的bin和dbgp两个目录下文件。因为这块的资料非常少,所以研究使用这套库也花费了我一定的时间。而且这套库实现中也存在不少缺陷,我也总是在不停探索和打patch中前行。好在经过一段努力,终于把它和Xdebug打通了。下面我展示一段pydbgp和Xdebug的交互过程
第1部分是告诉IDE,调试用的IDE-KEY是什么,要监听哪个端口的。因为我是以netbeans的调试作为模板,所以我的IDE-KEY也是Netbeans和Xdebug交互的IDE-Key:netbeans-xdebug。当然这个值可以改成别的,但是要和xdebug的配置文件的idekey值一样
xdebug.idekey="netbeans-xdebug"
然后我启动了监听本地9000端口。这个9000端口号也不是随便设置的,也要和Xdebug配置文件中的remote_port值一样
xdebug.remote_port=9000
此时我们可以在网页中发起一次请求,用于触发php执行。这种触发行为分为两种,我会在之后做介绍。
网页此时一直处在等待状态,这表示Xdebug已经把PHP的执行过程给中断了。于是我们可以进行下步操作。
我们执行sessions指令,用于查看目前有哪些连接已经建立过了。如上图,pydbgp返回了连接信息。当然这个展现不是Xdebug的原始数据——原始数据是XML的。
知道连接号后,我们使用select指令进入特定的连接。之后使用status查看调试的状态。第一次status执行后,表示调试器处在开始状态,这种状态是一种中断状态,它还没进入PHP代码层。我们执行“步过”——step over操作一次,这个时候PHP执行便进入代码了。使用stack_get指令查看当前的调用堆栈信息,这些信息中包括了栈号、文件路径、函数名。如果我们不关心之后的执行,就直接调用run指令,让程序跑到底。这个时候调用status命令,可以看到调试器处在stopping的状态。此时再run一下,本次调试就彻底结束了。结束后,我们使用quit指令退出当前调试。如果还有别的调试请求过来,则可以再调用sessions查看连接号,重复上述的调试过程。上图中4是这个过程的一个体现。
如果不想进行调试了,则可以调用quit退出整个pydbgp。
pydbgp帮助我们连接Xdebug,转发命令,解析返回的XML结果。但是它只提供了标准输入方式的请求接口,我们没法像直接调用API一样调用这些接口。而且我也无意于将这套接口改成API的形式。于是我决定采用父子进程通信的方式,父进程是我们的业务逻辑,子进程是pydbgp,父子进程通过重定向输入输出来进行通信。这是我最初的想法,但是最后重定向的方案也被否掉了,因为python在不同平台上(windows和linux)对这种方式存在兼容问题。这也是迫使我在项目后期老老实实使用标准socket去通信,还好我之前代码耦合做的比较好,替代方案很快就用上了。这儿感慨下,一些事情想时总是美好的样子,而现实往往是曲折的样子。当然随着阅历的增多,想像也会越来越靠谱,这就是经验的作用。
Xdebug给我们提供了很多调试的基础功能。但是作为调试器,我们应该在这些基础之上开发出更多组合性的功能,这样可以帮助使用者更快的发现问题。所以我们还需要对这些功能进行一些高阶封装组合,这些内容我们会在之后介绍。还有就是有些功能可能不是需要调试器提供的,比如日志文件监控,所以这块也将是我们调试器的一些辅助功能。于是我们调试器的结构是这样的
相关文章:

Ubuntu下允许Root用户直接登录图形界面
ubuntu root是默认禁用了,不允许用root登陆,所以先要设置root密码。 执行:sudo passwd root 接着输入密码和root密码,重复密码。再重新启动就可以用root登陆。 另外,默认情况下是不允许用root帐号直接登陆图形界面的。…

携程App for Apple Watch探索
在Apple Watch发布之后,很多App都针对它设计了相应的版本。旅行作为与Apple Watch时间管理特性契合度较高的场景,同时携程旅行作为国内领先的OTA行业App,也成为了首批适配Apple Watch并荣登Apple官网和App Store推荐的应用之一。InfoQ就App f…
跨平台PHP调试器设计及使用方法——通信
首先引用《跨平台PHP调试器设计及使用方法——探索和设计》中的结构图(转载请指明出于breaksoftware的csdn博客) 本文要介绍的是我们逻辑和pydbgp通信的实现(图中红框内内容)。 设计通信之前,我需要先设计一种通信协议…

MVP模式的相关知识
MVP 是从经典的模式MVC演变而来,它们的基本思想有相通的地方:Controller/Presenter负责逻辑的处理,Model提供数据,View负责显示。作为一种新的模式,MVP与MVC有着一个重大的区别:在MVP中View并不直接使用Mod…
“数学不行,还能干点啥?”面试官+CTO:干啥都费劲!
关于数学与程序员的“暧昧”关系,先看看网友的看法:同时编程圈也流传着一个段子:一流程序员靠数学,二流程序员靠算法,末端程序员靠百度,低端看高端就是黑魔法。想一想,我们日常学习、求职、工作…

CentOS7 yum 源的配置与使用
YUM:Yellowdog Updater Modified Yum(全称为 Yellow dog Updater, Modified)是一个在Fedora和RedHat以及CentOS中的Shell前端软件包管理器。基于RPM包管理,能够从指定的服务器自动下载RPM包并且安装,可以自动处理依赖…

跨平台PHP调试器设计及使用方法——协议解析
在《跨平台PHP调试器设计及使用方法——探索和设计》一文中,我介绍了将使用pydbgp作为和Xdebug的通信库,并让pydbgp以(孙)子进程的方式存在。《跨平台PHP调试器设计及使用方法——通信》解决了和pydbgp通信的问题,本文…

测试客户端发图图
转载于:https://blog.51cto.com/ericsong/116942
搜狐、美团、小米都在用的Apache Doris有什么好? | BDTC 2019
【导读】12 月 5-7 日,由中国计算机学会主办,CCF 大数据专家委员会承办,CSDN、中科天玑协办的中国大数据技术大会(BDTC 2019)在北京长城饭店隆重举行。100 顶尖技术专家、1000 大数据从业者齐聚于此,以“大…

cacti邮件告警设置
功能说明对指定流量图形(指定接口)设置最高或最低流量阀值,当流量出现异常偏高或偏低触发阀值,系统自动将异常信息以邮件形式通知指定收件人。如果收件人邮箱是139邮箱,还可以增设短信通知功能。设置前准备设置该功能之…
跨平台PHP调试器设计及使用方法——高阶封装
在《跨平台PHP调试器设计及使用方法——协议解析》一文中介绍了如何将pydbgp返回的数据转换成我们需要的数据。我们使用该问中的接口已经可以构建一个简单的调试器。但是由于pydbgp存在的一些问题,以及调试器需要的一些高级功能,我们还需要对这些接口进行…

Oracle的口令文件(passwordfile)的讲解(摘录)
初学oracle,很多概念迷糊,今天看到这文章,让我有一个比较清晰的认识。转载[url]http://www.itpub.net/viewthread.php?tid906008&extra&page1[/url]1、os认证oracle安装之后默认情况下是启用了os认证的,这里提到的os认证…
如何优雅地使用pdpipe与Pandas构建管道?
作者 | Tirthajyoti Sarkar译者 | 清儿爸编辑 | 夕颜出品 | AI科技大本营(ID: rgznai100) 【导读】Pandas 是 Python 生态系统中的一个了不起的库,用于数据分析和机器学习。它在 Excel/CSV 文件和 SQL 表所在的数据世界与 Scikit-learn 或 Te…

第 十 天 : 添 加 硬 盘 和 分 区 挂 载 等
小Q:狼若回头,必有缘由,不是报恩,就是***; 事不三思必有败,人能百忍则无忧。今天的进度虽然慢了,但是学习状态还是一如往常,只不过今天遇到了不少新的知识点,需要好好想想…
从4个月到7天,Netflix开源Python框架Metaflow有何提升性能的魔法?
作者 | Rupert Thomas译者 | 凯隐编辑 | Jane出品 | AI科技大本营(ID:rgznai100)【导语】Metaflow 是由 Netflix 开发,用在数据科学领域的 Python框架,于 2019 年 12 月正式对外开源。据介绍,Metaflow 解决…
SOA标准发展混乱 国内业务缺少经验
近年来,SOA已经成为国际及我国信息技术领域的重大热点之一。从2005年至今,SOA逐渐成为影响中国IT系统构建的主导思想。从2006年开始,SOA的建设方法已在我国部分行业信息化项目中开始得以越来越广泛的应用。 但热潮背后, SOA概念在…
跨平台PHP调试器设计及使用方法——界面设计和实现
一个优秀的交互设计往往会影响一个产品的命运。在设计这款调试器时,我一直在构思这款调试器该长什么样子。简单、好用是我设计的原则,于是在《跨平台PHP调试器设计及使用方法——立项》一文中,我给出了一个Demo。之后实现的效果也与之变化并不…

AJAX安全-Session做Token
个人思路,请大神看到了指点 个人理解token是防止扫号机或者恶意注册、恶意发表灌水,有些JS写的token算法,也会被抓出来被利用,个人感觉还是用会过期的Session做token更好,服务器存储,加载到客户端页面&…
跨平台PHP调试器设计及使用方法——使用
经过之前六篇博文的分析和介绍,大家应该对这套调试器有个初步的认识。本文我将讲解它的使用方法。(转载请指明出于breaksoftware的csdn博客) 上图是该软件界面的布局,我们之后的讲解也将围绕着这些功能展开。 文件夹管理 在查看一…
管理7k+工作流,月运行超10000万次,Lyft开源的Flyte平台意味着什么?
作者 | Allyson Gale译者 | 刘畅编辑 | Jane出品 | AI科技大本营(ID:rgznai100)【导读】Flyte 平台可以更容易的创建并发,可伸缩和可维护的工作流,从而进行机器学习和数据处理。Flyte 已有三年多的训练模型和数据处理经…

Jmeter组件执行顺序与作用域
一、Jmeter重要组件: 1)配置元件---Config Element: 用于初始化默认值和变量,以便后续采样器使用。配置元件大其作用域的初始阶段处理,配置元件仅对其所在的测试树分支有效,如,在同一个作用域…
跨平台PHP调试器设计及使用方法——拾遗
之前七篇博文讲解了跨平台PHP调试器从立项到实现的整个过程,并讲解了其使用方法。但是它们并不能全部涵盖所有重要内容,所以新开一片博文,用来讲述其中一些杂项。(转载请指明出于breaksoftware的csdn博客) 触发调试的…
召唤超参调优开源新神器:集XGBoost、TensorFlow、PyTorch、MXNet等十大模块于一身...
整理 | 凯隐编辑 | Jane出品 | AI科技大本营(ID:rgznai100)【导读】Optuna是一款为机器学习任务设计的自动超参数优化软件框架,是一款按运行定义(define-by-run) 原则设计的优化软件,允许用户动态地调整搜索空间&#…

Linux下的Silverlight:Moonlight 1.0 Beta 1发布了
Moonlight是微软Silverlight的一个开源实现,其目标平台是Linux与Unix/X11系统。自从2007年9月开始,Moonlight就在Mono项目下进行了开发,它是由Novell发起并资助的。现在,Moonlight 1.0 Beta 1已经向公众发布了。 Novell和Mono宣布…
在visual studio 2010中调用ffmpeg
转自:http://blog.sina.com.cn/s/blog_4178f4bf01018wqh.html 最近几天一直在折腾ffmpeg,在网上也查了许多资料,费了不少劲,现在在这里和大家分享一下。 一、准备工作本来是想自己在windows下编译ffmpeg生成lib、dll等库文件的&am…
无线路由器与无线AP的区别
摆脱线缆的羁绊,手捧一杯香醇的咖啡在家中的任何角落都可以无拘无束和网友谈天说地──这就是无线的魅力!在无线网络迅猛发展的今天,无线局域网(Wireless Local-Area Network,简称WLAN)已经成为许多SOHO家庭…

Simple Dynamic Strings(SDS)源码解析和使用说明一
SDS是Redis源码中一个独立的字符串管理库。它是由Redis作者Antirez设计和维护的。一开始,SDS只是Antirez为日常开发而实现的一套字符串库,它被使用在Redis、Disque和Hiredis等作者维护的项目中。但是作者觉得这块功能还是比较独立的,应该让其…
“不会Linux,到底有多危险?”骨灰级成程序员:基本等于自废武功!
说起程序员的必备技能,我想大家都可以说很多,比如:算法、数据结构、数学、编程语言等等。对于程序员来讲,这些底层能力固然重要,但是,工具同样也是如此,比如常被大家所忽视的:Linux。…

“Uncaught TypeError: string is not a function”
http://www.cnblogs.com/haitao-fan/archive/2013/11/08/3414678.html 今天在js中写了一个方法叫做search(),然后点击按钮的时候提示: “Uncaught TypeError: string is not a function” 百思不得其解啊,我的js木有问题啊啊.... 后来才发现酱…

关于Nikon Ai AF 28mm F1.4D遮光罩的问题
-- 好不容易找到百变妖,确实比较妖!!遮光罩不好找,原厂推荐的HK-7基本属于古董中的古董。 爬文很久,终于找到一篇国外的介绍,说可以用HK-4代替,比HK-7效果更好,而且可以用85mm 1.4D-…