首页IT科技vscode运行php到浏览器打不开(使用vscode调试PHP底层C源码)

vscode运行php到浏览器打不开(使用vscode调试PHP底层C源码)

时间2025-06-20 09:30:24分类IT科技浏览5391
导读:使用vscode调试PHP底层C源码 一直想着有机会调试一下php底层代码来着,这周正好心血来潮,就跟着教程配置了一下。本篇文章是基于macOS,可能在编译php源码之前的步骤对使用windows的师傅没啥可参考的。...

使用vscode调试PHP底层C源码

一直想着有机会调试一下php底层代码来着             ,这周正好心血来潮                    ,就跟着教程配置了一下             。本篇文章是基于macOS       ,可能在编译php源码之前的步骤对使用windows的师傅没啥可参考的                    。

windows下比较麻烦      ,主要是在编译php源码这一步                    ,最方便的办法是用docker来远程调试       。具体可以参考这篇文章vscode远程调试php底层代码      。使用p牛的dockerfile来自己建一个调试用docker                    。

说回mac下调试PHP源码需要的准备

下载并编译PHP

使用git来下载源码              ,这样切换PHP版本会较为方便              。(不过我现在应该不会这么做      ,因为下载下来的源码并不能直接编译成功                   ,需要自己修改      。改完的源码不舍得切换了)

git clone https://github.com/php/php-src cd php-src/ git checkout PHP-7.3.67

当然              ,不排除个人环境的原因,通过checkout切换分支                   ,重新编译一下还是很方便的                    ,如果编译不出错的话                   。

如果是mac,编译PHP前需要安装一下最新版的bison             ,mac自带的版本太老              。

brew install bison # bison的具体路径可以通过brew list bison来查看 export PATH=/opt/homebrew/Cellar/bison/3.8.2/bin:$PATH

编译需要调试的PHP。像我这里就开启了debug模式                    ,开启了phar扩展       ,如果需要开启别的扩展             ,需要再./configure命令后面自行指定                   。

./buildconf ./configure --disable-all --enable-debug --enable-phar --prefix=/source/php7.3.6/ make make install

编译完后                    ,编译结果都在/source/php7.3.6/文件夹下       ,/source/php7.3.6/bin/php为可执行文件                    。

编译好的PHP      ,执行./php -v 会显示NTS DEBUG。

编译过程中的错误

在进行make编译的时候                    ,碰到了两次报错             。

第一个报错:

/Users/niushaogang/jkbPhpPackage/php-5.4.45/main/reentrancy.c:139:23: error: too few arguments to function call, expected 3, have 2 readdir_r(dirp, entry); ~~~~~~~~~ ^ /Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/usr/include/dirent.h:110:5: note: readdir_r declared here int readdir_r(DIR *, struct dirent *, struct dirent **) __DARWIN_INODE64(readdir_r); ^ 1 error generated. make: *** [main/reentrancy.lo] Error 1

根据网上的教程              ,了解到这是php源码调用readdir_r函数的时候少传了一个参数                    。

查看php-src/main/reentrancy.c

函数定义:

​ int readdir_r(DIR *, struct dirent *, struct dirent **)

php调用:

​ readdir_r(dirp, entry)

readdir_r(dirp, entry) 修改为 readdir_r(dirp, entry,&entry)即可编译通过

第二个报错:

/Users/dre0m1/CTF/学习笔记/PHP源码/php-src/Zend/zend_language_parser.y:1317:5: error: implicit declaration of function yystpcpy is invalid in C99 [-Werror,-Wimplicit-function-declaration] yystpcpy(yyres, "end of file"); ^ /Users/dre0m1/CTF/学习笔记/PHP源码/php-src/Zend/zend_language_parser.y:1317:5: note: did you mean stpcpy? /Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/usr/include/string.h:130:7: note: stpcpy declared here char *stpcpy(char *__dst, const char *__src); ^ /Users/dre0m1/CTF/学习笔记/PHP源码/php-src/Zend/zend_language_parser.y:1324:29: error: implicit declaration of function yystrlen is invalid in C99 [-Werror,-Wimplicit-function-declaration] yystr_len = (unsigned int)yystrlen(yystr); ^ /Users/dre0m1/CTF/学习笔记/PHP源码/php-src/Zend/zend_language_parser.y:1324:29: note: did you mean strlen? /Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/usr/include/string.h:82:9: note: strlen declared here size_t strlen(const char *__s); ^ /Users/dre0m1/CTF/学习笔记/PHP源码/php-src/Zend/zend_language_parser.y:1345:4: error: implicit declaration of function yystpcpy is invalid in C99 [-Werror,-Wimplicit-function-declaration] yystpcpy(yyres, buffer); ^ /Users/dre0m1/CTF/学习笔记/PHP源码/php-src/Zend/zend_language_parser.y:1352:10: error: implicit declaration of function yystrlen is invalid in C99 [-Werror,-Wimplicit-function-declaration] return yystrlen(yystr) - (*yystr == " ? 2 : 0); ^ /Users/dre0m1/CTF/学习笔记/PHP源码/php-src/Zend/zend_language_parser.y:1365:2: error: implicit declaration of function yystpcpy is invalid in C99 [-Werror,-Wimplicit-function-declaration] yystpcpy(yyres, yystr); ^ 5 errors generated. make: *** [Zend/zend_language_parser.lo] Error 1

报错内容较多      ,出现在Zend/zend_language_parser.lo位置       。当时查找了好久的资料                   ,都没有找到相关的内容             。只知道implicit declaration of function yystrlen is invalid in C99这种报错类型是因为缺少相应的定义              ,由报错中的提示可以看出应该是缺少了yystpcpy这个函数                    。

访问文件php-src/Zend/zend_language_parser.c,可以看到这样一段代码

格式和yystpcpy还有yystrlen异常的统一,我当时就怀疑应该是在这个c文件中进行了函数重命名       。

代码中出现yystpcpy函数的位置一共有三处:

if (yyres) { yystpcpy(yyres, "end of file"); } return sizeof("end of file")-1; } yystpcpy(yyres, buffer); yystpcpy(yyres, yystr);

看样子应该就是stpcpy函数没错了                   ,试着在上面的#define处加入yystpcpy与yystrlen的定义:

#define yystpcpy zendstpcpy #define yystrlen zenddtrlen

依旧报错                    ,这边是我没动脑子了,光想着和上面的define内容结构统一             ,但是strlen和stpcpy这两个函数前面其实是不需要zend前缀的      。

修改之后重新编译                    ,make成功                    。

vscode调试

用vscode打开PHP源码       ,增加一个调试的配置:

选择环境c++(GDB/LLDB)-> Default Configuration,然后会生成一个配置文件:

{ // 使用 IntelliSense 了解相关属性              。 // 悬停以查看现有属性的描述      。 // 欲了解更多信息             ,请访问: https://go.microsoft.com/fwlink/?linkid=830387 "version": "0.2.0", "configurations": [ { "name": "debuug php source", "type": "cppdbg", "request": "launch", "program": "/Users/dre0m1/CTF/学习笔记/PHP源码/source/bin/php", "args": ["-f","/Users/dre0m1/CTF/学习笔记/PHP源码/1.php"], "stopAtEntry": true, "cwd": "${fileDirname}", "environment": [], "externalConsole": false, "MIMode": "lldb" } ] }

参数详解:

program 可执行的PHP文件的路径(编译生成的php文件) args 传给php的参数列表                    ,像我上面所填写的执行的就是php -f /Users/dre0m1/CTF/学习笔记/PHP源码/1.php cwd 当前目录       ,如果调试web应用      ,可以改成web根目录的路径 stopAtEntry 是否在main函数的时候断下

之后就可以正常调试了                   。

创心域SEO版权声明:以上内容作者已申请原创保护,未经允许不得转载,侵权必究!授权事宜、对本内容有异议或投诉,敬请联系网站管理员,我们将尽快回复您,谢谢合作!

展开全文READ MORE
linux返回命令行界面(linux怎么使用命令返回上一级目录?)