效果图

Bughole工具实现了PHPStorm中95%以上的debug功能。借助该工具在预发布调试:PHP的业务代码、API甚至任务脚本,都将变得极为方便!

试用

Bughole整套工具在预发9已经部署完备,以下步骤将分别演示:1)debug获取评价列表的API;2)debug PHP 任务

debug: 获取评价列表API - BeibeiItemRateGet

  1. 打开bughole UI:#(暂不对外开放) ,并且确认自己已经连上了预发9
  2. 添加断点。在断点模块,点击“Add”按钮,新增断点信息(可通过类似方式不断增加断点)
    1. 文件路径:***/***/api/ItemRateGet.php
    2. 断点行号:26
    3. 填好断点信息,点击确定
  3. 点击“建立连接”按钮。则服务端agent开始监听Xdebug的拦截信息
  4. 在新标签页访问:http://sapi.beibei.com/item/rate/0-27221145-1-10-1.html?preview=1&XDEBUG_SESSION_START=1 。这个访问也必须是预发9的!此时Xdebug会尝试拦截这个访问,具体表现为:页面hanging转圈不返回
  5. 回到bughole UI,点击页面顶端的“点我测试”按钮。如果一切正常,你将看到如下图所示信息,这表明Xdebug已经正确开始了
  6. 试试StepOver命令,StepInto命令,StepOut命令?当然你也可以使用RunToLine命令。
    想查看当前Context的变量信息,就在右侧的Context面板查找吧。右下方还有调用栈信息
    最后,一定要记得点击“Stop”按钮停止debug

debug: ProductTestTask任务(product-module) 

  1. 打开bughole UI:#(暂不对外开放) ,并且确认自己已经连上了预发9
  2. 添加断点。在断点模块,点击“Add”按钮,新增断点信息(可通过类似方式不断增加断点)
    1. 文件路径:***/***/src/task/ProductTestTask.php
    2. 断点行号:17
    3. 填好断点信息,点击确定
  3. 点击“建立连接”按钮。则服务端agent开始监听Xdebug的拦截信息
  4. 在预发9机器上依次执行:

    # 切换到root用户
    sudo su
    # 为root用户设置环境变量(设置后Xdebug会主动拦截PHP脚本的运行)
    export XDEBUG_CONFIG="idekey=bughole"
    # 执行任务(切记不要加sudo)
    bash /task/task_admin.sh start --module=product ProductTestTask 
  5. 回到bughole UI,点击页面顶端的“点我测试”按钮。如果一切正常,你将看到如上图所示信息,这表明Xdebug已经正确开始了
  6. 试试StepOver命令,StepInto命令,StepOut命令?当然你也可以使用RunToLine命令。
    想查看当前Context的变量信息,就在右侧的Context面板查找吧。右下方还有调用栈信息
    最后,一定要记得点击“Stop”按钮停止debug

说明:debug模式同一时间只允许一个人进行debug,如果有其他人也在debug,则可能出现错乱情况。解决办法:1)避免同时使用debug;2)如果debug已经不正常,尝试重启:kill这个任务(python bughole/agent.py);重新运行: python /tmp/tiny-scripts/bughole/agent.py (无需sudo)

实战

实战1:debug任意URL

详细步骤,请参考:debug获取评价列表API。

上方步骤4中触发Xdebug启动拦截的关键在于:URL后面要增加一个query(GET、POST皆可): XDEBUG_SESSION_START=1 即可触发调试模式

 

当然,很多API接口会对请求参数中的sign做安全校验,意即URL的GET参数不能随意增删,否则会报错:sign校验失败。遇到这种情况,可以通过在Cookie中添加参数触发Xdebug启动

情况1:如果你在Chrome浏览器中,可以通过Cookie管理工具为当前API域名添加Cookie: XDEBUG_SESSION = 1, HX-BETA = 9;或者直接在网页console中输入: document.cookie = 'HX-BETA=9; XDEBUG_SESSION=1;'   然后接着上述步骤4的指示继续即可

情况2:如果你在Charlse中,可以通过Rewrite工具为API添加Cookie,然后接着上述步骤4的指示继续即可

实战2:debug PHP任务(同上方debug ProductTestTask)

步骤参考debug ProductTestTask任务。触发Xdebug启动拦截的关键在于:当前用户的环境变量中设置了: XDEBUG_CONFIG=idekey=bughole 这个变量(使用env命令可以查看当前用户空间的变量)

由于通过sudo export命令设置环境变量会失败,所以需要切换到root用户运行任务脚本。

注意:多进程的任务(worker_num >= 2)在debug时会出现异常,解决办法:debug时将worker_num设为1,debug完成后再改回原值。

遇到问题要反馈?

遇到使用问题,烦请联系我qq: 379396993, 我会尽快帮忙查看问题

预发布如何部署

1)拉取agent代码。注意将 GitLab用户名 替换为自己的用户名

cd /tmp
git clone http://GitLab用户名@git.example.com/dongxu.lu/tiny-scripts.git

2)安装Xdebug(如果已安装请跳过本步)

# 查看是否安装Xdebug,如果已安装请跳过本步
/opt/php-7.1.9/bin/php -m |grep Xdebug
 
# copy编译好的扩展至PHP指定目录
cp /tmp/tiny-scripts/bughole/xdebug.so /opt/php-7.1.9/lib/php/extensions/no-debug-non-zts-20160303/
 
# 新建文件: /opt/php-7.1.9/etc/conf.d/xdebug.ini , 内容如下
zend_extension = xdebug.so
xdebug.remote_enable = 1
xdebug.remote_connect_back = 0
xdebug.remote_host = 127.0.0.1
xdebug.remote_port = 21733
xdebug.remote_handler = dbgp
xdebug.remote_mode = req
xdebug.remote_autostart = 0
xdebug.idekey = "bughole"
 
# 重启PHP-FPM
service php-fpm-7 restart

3)agent持久运行

python /tmp/tiny-scripts/bughole/agent.py > /tmp/bughole-agent.log 2>&1 &

4)部署已完成。确认agent已运行

# agent会返回OK
curl http://127.0.0.1:21734

Bughole原理

工程结构图

时序图

以最常用的StepOver(下一行)命令的执行时序作为示例

安全考虑

Bughole未提供eval接口,所有操作都为“读”操作,不会对线上业务数据造成污染

待本周发布上线试用几天后会及时更新使用和部署(Agent)文档

项目源码

https://github.com/HelloLyfing/bughole