A tool that uses eBPF to monitor PHP compile events and track file execution within a specified directory. Useful for detecting dead code (unused PHP files).
This project uses USDT (User-level Statically Defined Tracing) probes to track PHP compile__file__return events. An eBPF program runs in kernel space and stores compiled PHP file paths with timestamps in a BPF MAP. The Go application periodically reads this map and provides reports via HTTP API.
- Linux kernel 5.4 or later (eBPF CO-RE support)
- Root privileges
- Go 1.24 or later
- clang 10 or later
- libbpf
- bpftool
- Linux headers
sudo apt-get update
sudo apt-get install -y \
clang \
llvm \
libbpf-dev \
linux-headers-$(uname -r) \
bpftool- Clone the repository:
git clone <repository-url>
cd php-dcr- Download dependencies:
go mod download- Build:
make buildThis will:
- Generate
vmlinux.hfrom kernel BTF - Compile the eBPF program (
bpf/php.bpf.o) - Build the Go binary (
php-dcr)
The target PHP process must have the USE_ZEND_DTRACE=1 environment variable set. This enables USDT probes in the PHP runtime, which php-dcr uses to trace file compilation events.
Create /etc/systemd/system/apache2.service.d/dtrace.conf:
[Service]
Environment=USE_ZEND_DTRACE=1You may need to preserve another variable that already set (like Ubuntu setting)
[Service]
Environment=APACHE_STARTED_BY_SYSTEMD=true USE_ZEND_DTRACE=1Then reload and restart:
sudo systemctl daemon-reload
sudo systemctl restart apache2Create /etc/systemd/system/php-fpm.service.d/dtrace.conf (or php8.3-fpm.service.d etc. depending on your version):
[Service]
Environment=USE_ZEND_DTRACE=1Then reload and restart:
sudo systemctl daemon-reload
sudo systemctl restart php-fpmRun the program (requires root, --target-dir is required):
sudo ./php-dcr --target-dir /var/www/htmlOnly PHP files within the --target-dir directory will be tracked.
After starting, an HTTP server runs on port 8080 by default (configurable via --listen) with the following endpoints:
Returns a report of PHP files in the target directory and their compilation status.
{
"script": {
"start_time_unix": 1733500000,
"start_time_rfc3339": "2024-12-06T12:00:00+09:00"
},
"report": [
{
"filepath": "/var/www/html/index.php",
"compiled_time_unix": 1733500100,
"compiled_time_rfc3339": "2024-12-06T12:01:40+09:00"
},
{
"filepath": "/var/www/html/unused.php",
"compiled_time_unix": -1,
"compiled_time_rfc3339": ""
}
]
}compiled_time_unix: -1indicates the file was never compiled (potential dead code)
Returns a mapping of compiled PHP file paths to their compilation timestamps.
{
"/var/www/html/index.php": 1733500100,
"/var/www/html/config.php": 1733500105
}Returns a list of all PHP files in the target directory.
[
"/var/www/html/index.php",
"/var/www/html/config.php",
"/var/www/html/unused.php"
]Press Ctrl+C to exit.
-
eBPF Program (
bpf/php.bpf.c):- Attaches to PHP's
compile__file__returnUSDT probe - Captures compiled file names and timestamps
- Stores data in LRU HASH map
php_compile_file
- Attaches to PHP's
-
Go Program (
main.go):- Loads embedded eBPF object file
- Auto-discovers PHP binaries and attaches USDT probes
- Reads BPF MAP every 5 seconds and records compilation info
- Periodically updates the PHP file list in the target directory
- Provides reports via HTTP API
-
PHP Binary Auto-Discovery: Automatically searches for PHP binaries in:
/usr/lib/apache2/modules(libphp*)/usr/bin(php,php-fpm)
- Ensure running with root privileges
- Verify kernel supports eBPF CO-RE (5.4+)
- Check BTF is enabled:
ls /sys/kernel/btf/vmlinux
- Ensure PHP was built with USDT support
- Check available probes:
sudo bpftool probe | grep php
- Verify PHP application is actually running
- Check that PHP is compiling files (opcache may be caching)
- Ensure
--target-dirpoints to the correct path
Remove build artifacts:
make cleanApache License 2.0
Note: The eBPF program (bpf/*) declares "GPL" license for kernel compatibility.