未加星标

跨平台PHP调试器设计及使用方法――探索和设计

字体大小 | |
[开发(php) 所属分类 开发(php) | 发布者 店小二05 | 时间 2016 | 作者 红领巾 ] 0人收藏点击收藏
跨平php调试器设计及使用方法――探索和设计

2小时前来源:CSDN博客

在《跨平台PHP调试器设计及使用方法――立项》一文中,我确定了使用xdebug作为调试器插件部分的基础组件。xdebug提供了一个远程调试的功能(相关资料可以详见https://xdebug.org/docs/remote),我们这个项目便是基于这个功能实现的。(转载请指明出于breaksoftware的csdn博客)

远程调试是基于网络传输方式进行交互的一种调试方式,那么其必定有服务端和客户端两部分组成。这儿的服务端和客户端都是相对的,因为一个客户端可能在和服务器通信后就变成了一个服务端,而服务端则在一次通信后就变成了客户端。xdebug在这个模型中属于服务端,因为它是嵌入到PHP执行器内部,影响PHP执行流程的部分,这些核心功能肯定是作为服务端的一部分而存在。同时它也应该有接收和响应请求的功能。

xdebug提供了两种连接的方式,一种是固定地址单线连接。一种是未知地址多线连接。

我们先看下固定地址单线连接,它的执行流程如下图


跨平台PHP调试器设计及使用方法――探索和设计
嵌入在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调试器设计及使用方法――探索和设计

嵌入在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的交互过程


跨平台PHP调试器设计及使用方法――探索和设计

第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在不同平台上(windowslinux)对这种方式存在兼容问题。这也是迫使我在项目后期老老实实使用标准socket去通信,还好我之前代码耦合做的比较好,替代方案很快就用上了。这儿感慨下,一些事情想时总是美好的样子,而现实往往是曲折的样子。当然随着阅历的增多,想像也会越来越靠谱,这就是经验的作用。 Xdebug给我们提供了很多调试的基础功能。但是作为调试器,我们应该在这些基础之上开发出更多组合性的功能,这样可以帮助使用者更快的发现问题。所以我们还需要对这些功能进行一些高阶封装组合,这些内容我们会在之后介绍。还有就是有些功能可能不是需要调试器提供的,比如日志文件监控,所以这块也将是我们调试器的一些辅助功能。于是我们调试器的结构是这样的
跨平台PHP调试器设计及使用方法――探索和设计

本文开发(php)相关术语:php代码审计工具 php开发工程师 移动开发者大会 移动互联网开发 web开发工程师 软件开发流程 软件开发工程师

主题: PHPXML探索服务器SDN数据博客Python其实流程图
分页:12
转载请注明
本文标题:跨平台PHP调试器设计及使用方法――探索和设计
本站链接:http://www.codesec.net/view/482215.html
分享请点击:


1.凡CodeSecTeam转载的文章,均出自其它媒体或其他官网介绍,目的在于传递更多的信息,并不代表本站赞同其观点和其真实性负责;
2.转载的文章仅代表原创作者观点,与本站无关。其原创性以及文中陈述文字和内容未经本站证实,本站对该文以及其中全部或者部分内容、文字的真实性、完整性、及时性,不作出任何保证或承若;
3.如本站转载稿涉及版权等问题,请作者及时联系本站,我们会及时处理。
登录后可拥有收藏文章、关注作者等权限...
技术大类 技术大类 | 开发(php) | 评论(0) | 阅读(51)