HacKerQWQ的博客空间

vscode远程调试php底层代码

Word count: 1.2kReading time: 6 min
2021/11/05 Share

环境配置

这里以P神的DockerFile为例,https://github.com/phith0n/phpsrc-debug-docker/blob/master/7.4/Dockerfile

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
FROM phusion/baseimage:master

LABEL maintainer="phithon <root@leavesongs.com>"

# dependencies required for running "phpize"
# (see persistent deps below)
ENV PHPIZE_DEPS \
autoconf \
dpkg-dev \
file \
g++ \
gcc \
libc-dev \
make \
pkg-config \
re2c \
bison

# persistent / runtime deps
RUN set -eux; \
apt-get update; \
apt-get install -y --no-install-recommends \
$PHPIZE_DEPS \
ca-certificates \
curl \
wget \
xz-utils \
unzip \
gdb \
libargon2-dev \
libcurl4-openssl-dev \
libedit-dev \
libonig-dev \
libsodium-dev \
libsqlite3-dev \
libssl-dev \
libxml2-dev \
zlib1g-dev \
libfreetype6-dev \
libjpeg-turbo8-dev \
libpng-dev

ARG PHP_INI_DIR="/usr/local/etc/php"
RUN set -eux; \
mkdir -p "$PHP_INI_DIR/conf.d"; \
# allow running as an arbitrary user (https://github.com/docker-library/php/issues/743)
[ ! -d /var/www/html ]; \
mkdir -p /var/www/html; \
chown www-data:www-data /var/www/html; \
chmod 777 /var/www/html

ARG PHP_URL="https://www.php.net/distributions/php-7.4.15.tar.gz"

RUN set -eux \
&& mkdir -p /usr/src/php \
&& cd /usr/src \
&& curl -fsSL -o php.tar.gz "$PHP_URL" \
&& tar -zxf php.tar.gz -C /usr/src/php --strip-components=1 \
&& rm -rf php.tar.gz

RUN set -eux; \
cd /usr/src/php; \
gnuArch="$(dpkg-architecture --query DEB_BUILD_GNU_TYPE)"; \
debMultiarch="$(dpkg-architecture --query DEB_BUILD_MULTIARCH)"; \
# https://bugs.php.net/bug.php?id=74125
if [ ! -d /usr/include/curl ]; then \
ln -sT "/usr/include/$debMultiarch/curl" /usr/local/include/curl; \
fi; \
./configure \
--build="$gnuArch" \
--with-config-file-path="$PHP_INI_DIR" \
--with-config-file-scan-dir="$PHP_INI_DIR/conf.d" \
\
# make sure invalid --configure-flags are fatal errors instead of just warnings
--enable-option-checking=fatal \
\
# https://github.com/docker-library/php/issues/439
--with-mhash \
\
# https://github.com/docker-library/php/issues/822
--with-pic \
\
# --enable-ftp is included here because ftp_ssl_connect() needs ftp to be compiled statically (see https://github.com/docker-library/php/issues/236)
--enable-ftp \
# --enable-mbstring is included here because otherwise there's no way to get pecl to use it properly (see https://github.com/docker-library/php/issues/195)
--enable-mbstring \
# --enable-mysqlnd is included here because it's harder to compile after the fact than extensions are (since it's a plugin for several extensions, not an extension in itself)
--enable-mysqlnd \
# https://wiki.php.net/rfc/argon2_password_hash (7.2+)
\
# As of PHP 7.4.0, --with-gd becomes --enable-gd
--enable-gd \
--with-freetype \
--with-jpeg \
--with-password-argon2 \
# https://wiki.php.net/rfc/libsodium
--with-sodium=shared \
# always build against system sqlite3 (https://github.com/php/php-src/commit/6083a387a81dbbd66d6316a3a12a63f06d5f7109)
--with-pdo-sqlite=/usr \
--with-sqlite3=/usr \
--with-pdo-mysql \
--with-mysqli \
\
--with-curl \
--with-libedit \
--with-openssl \
--with-zlib \
\
# in PHP 7.4+, the pecl/pear installers are officially deprecated (requiring an explicit "--with-pear")
--with-pear \
\
# bundled pcre does not support JIT on s390x
# https://manpages.debian.org/stretch/libpcre3-dev/pcrejit.3.en.html#AVAILABILITY_OF_JIT_SUPPORT
$(test "$gnuArch" = 's390x-linux-gnu' && echo '--without-pcre-jit') \
--with-libdir="lib/$debMultiarch" \
\
--enable-embed \
--enable-debug \
; \
make -j "$(nproc)"; \
make install; \
make clean; \
find -type f -name '*.a' -delete; \
cp -v php.ini-* "$PHP_INI_DIR/"; \
\
cd /; \
\
# update pecl channel definitions https://github.com/docker-library/php/issues/443
pecl update-channels; \
rm -rf /tmp/pear ~/.pearrc; \
\
# smoke test
php --version


RUN rm -f /etc/service/sshd/down

ENTRYPOINT [ "/sbin/my_init", "--enable-insecure-key" ]

保存到Dockerfile,用如下命令构建docker镜像

1
2
# docker build -t docker_name /path/to/Dockerfile
docker build -t php7_debug .

第一次构建时间长一点,然后通过命令启动docker

1
docker run -it --rm --name debug -p 8080:80 -p 2222:22 php7_debug

会产生一个私钥文件

image-20211105124009912

将它的权限设置为当前用户专有(所有者以及访问权限),用以下命令连接

1
ssh -i d:/ssh/private.key -p2222 root@192.168.119.132

image-20211105124033653

  • 如果连接不了需要将当前用户目录下的known_hosts的主机指纹删除

在vscode中安装remote-ssh插件,添加连接

image-20211105124235511

在新窗口中连接主机并打开文件夹

image-20211105124415316

然后就可以在c文件中下断点了

image-20211105124451306

还需要在主机连接中安装c/c++ debug插件,配置如下

image-20211105124617636

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
{
// 使用 IntelliSense 了解相关属性。
// 悬停以查看现有属性的描述。
// 欲了解更多信息,请访问: https://go.microsoft.com/fwlink/?linkid=830387
"version": "0.2.0",
"configurations": [
{
"name": "(gdb) 启动",
"type": "cppdbg",
"request": "launch",
"program": "/usr/local/bin/php",
"args": ["-S","0.0.0.0:80","-t","/var/www/html"],
"stopAtEntry": false,
"cwd": "${fileDirname}",
"environment": [],
"externalConsole": false,
"MIMode": "gdb",
"setupCommands": [
{
"description": "为 gdb 启用整齐打印",
"text": "-enable-pretty-printing",
"ignoreFailures": true
}
]
}

]
}

program选择启动的二进制文件,args表示二进制文件的启动参数,这里-S表示启动一个简单的服务器,绑定端口是80,-t表示启动的目录

开始调试

首先将代码添加到/var/www/html

1
echo "<?php file_get_contents(__FILE__);" > /var/www/html/index.php

然后需要找到需要调试的php函数所对应的c文件中的函数

1
grep -rn "PHP_FUNCTION(file_get_contents)" /usr/src/php/ext

PHP_FUNCTION中填写需要查找的函数,就会返回函数所在的文件

image-20211105125747605

也可以试试在这网站上查找,https://heap.space/

在对应位置打上断点之后就可以启动调试,访问页面触发断点了

image-20211105125837040

CATALOG
  1. 1. 环境配置
  2. 2. 开始调试