Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 15 additions & 3 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -11,19 +11,31 @@ jobs:
tests:
name: Tests (PHP ${{ matrix.php }}, ${{ matrix.os }})
runs-on: ${{ matrix.os }}
# Experimental legs may fail without failing the workflow (see the matrix)
continue-on-error: ${{ matrix.experimental == true }}
strategy:
fail-fast: false
matrix:
include:
# PHP 8.6 is still in beta: setup-php installs the beta build and
# Composer resolves z-engine 8.6.x-dev (the master branch alias).
- { os: ubuntu-latest, php: '8.4' }
- { os: ubuntu-latest, php: '8.5' }
# z-engine ships darwin (x64 + arm64) definitions for both the 8.4
# and 8.5 lines (lisachenko/z-engine#58), so macOS runs the full PHP
- { os: ubuntu-latest, php: '8.6' }
# z-engine ships darwin (x64 + arm64) definitions for the 8.4, 8.5
# and 8.6 lines (lisachenko/z-engine#58), so macOS runs the full PHP
# matrix. macos-latest is arm64, macos-15-intel is x64.
- { os: macos-latest, php: '8.4' }
- { os: macos-latest, php: '8.5' }
# EXPERIMENTAL: Apple Silicon clang builds of PHP 8.6 use the new
# tail-call VM (ZEND_VM_KIND_TAILCALL), under which z-engine's user
# opcode handlers corrupt VM state (lisachenko/z-engine#280) - every
# instrumented debuggee crashes. The leg keeps running for visibility
# and turns required again once the upstream issue is resolved.
- { os: macos-latest, php: '8.6', experimental: true }
- { os: macos-15-intel, php: '8.4' }
- { os: macos-15-intel, php: '8.5' }
- { os: macos-15-intel, php: '8.6' }
steps:
- uses: actions/checkout@v4

Expand All @@ -50,7 +62,7 @@ jobs:
strategy:
fail-fast: false
matrix:
php: ['8.4', '8.5']
php: ['8.4', '8.5', '8.6']
steps:
- uses: actions/checkout@v4

Expand Down
9 changes: 5 additions & 4 deletions AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,13 +11,14 @@ split: prose says ZDebug, code says `zdebug`.

## Branch model

`main` supports PHP 8.4 and 8.5 in parallel. Engine memory layouts change between PHP
minors, so each minor rides its own z-engine line (`8.4.x-dev` on PHP 8.4, `8.5.x-dev`
on PHP 8.5) and Composer resolves the matching one for the running PHP.
`main` supports PHP 8.4, 8.5 and 8.6 (beta) in parallel. Engine memory layouts change
between PHP minors, so each minor rides its own z-engine line (`8.4.x-dev` on PHP 8.4,
`8.5.x-dev` on PHP 8.5, `8.6.x-dev` — the master branch alias — on PHP 8.6) and
Composer resolves the matching one for the running PHP.

## Environment requirements

- PHP `^8.4` (8.4 and 8.5 are tested in CI), **NTS, linux-x64 or darwin-x64/arm64** (the platforms z-engine ships definitions for).
- PHP `^8.4` (8.4, 8.5 and the 8.6 beta are tested in CI), **NTS, linux-x64 or darwin-x64/arm64** (the platforms z-engine ships definitions for). Exception: 8.6 on darwin-arm64 is broken by PHP 8.6's tail-call VM (lisachenko/z-engine#280) — that CI leg is experimental until the upstream issue is resolved.
- `ffi.enable=1` and **JIT off** (`opcache.jit=off`) — the JIT rewrites the executor
internals the statement hook plugs into. Both must come from `php.ini`/`-d`.
- The debuggee's code must be compiled **after** the debugger initializes; the
Expand Down
6 changes: 3 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
**ZDebug** is an Xdebug-compatible step debugger with **no C extension**. Your IDE attaches over DBGp — Xdebug's own protocol — while pure PHP code drives the Zend VM through FFI, courtesy of [z-engine](https://github.com/lisachenko/z-engine). Set breakpoints, step through code, inspect and edit the stack and variables in PhpStorm or VS Code, with nothing compiled and nothing installed but Composer packages.

[![CI](https://img.shields.io/github/actions/workflow/status/lisachenko/zdebug/ci.yml?branch=main&label=CI)](https://github.com/lisachenko/zdebug/actions/workflows/ci.yml)
[![PHP Version](https://img.shields.io/badge/php-8.4%20%7C%208.5-8892BF.svg)](https://php.net/)
[![PHP Version](https://img.shields.io/badge/php-8.4%20%7C%208.5%20%7C%208.6-8892BF.svg)](https://php.net/)
[![License](https://img.shields.io/badge/license-MIT-blue.svg)](LICENSE)
[![PHPStan](https://img.shields.io/badge/PHPStan-level%20max-brightgreen.svg)](https://phpstan.org/)
[![Status](https://img.shields.io/badge/status-experimental-orange.svg)](#status)
Expand Down Expand Up @@ -161,13 +161,13 @@ Precedence, lowest to highest: built-in defaults → Xdebug ini/env → `ZDEBUG_

## Requirements

- PHP **8.4 or 8.5** (supported in parallel), **NTS**, **linux-x64 or macOS x64/arm64** (platforms z-engine ships definitions for); Composer resolves the matching z-engine line per minor
- PHP **8.4, 8.5 or 8.6 (beta)** (supported in parallel), **NTS**, **linux-x64 or macOS x64/arm64** (platforms z-engine ships definitions for); Composer resolves the matching z-engine line per minor. On 8.6, macOS **arm64** is not usable yet: Apple Silicon clang builds select PHP 8.6's new tail-call VM, which breaks z-engine's engine hooks ([lisachenko/z-engine#280](https://github.com/lisachenko/z-engine/issues/280))
- `ffi.enable=1` and **`opcache.jit=off`** (the JIT rewrites the executor internals the hook plugs into)
- Your app's code must load **after** ZDebug attaches — `auto_prepend_file` guarantees this

## Status

The debugger is complete enough to use as one: an IDE attaches, sets line, conditional, call, return and exception breakpoints, steps over/into/out, walks the stack, reads and writes variables, evaluates expressions, fetches source and detaches — all of it proven end-to-end by a test suite that plays a fake IDE against a real spawned child process, on PHP 8.4 and 8.5 across linux-x64 and macOS (x64 + arm64).
The debugger is complete enough to use as one: an IDE attaches, sets line, conditional, call, return and exception breakpoints, steps over/into/out, walks the stack, reads and writes variables, evaluates expressions, fetches source and detaches — all of it proven end-to-end by a test suite that plays a fake IDE against a real spawned child process, on PHP 8.4 and 8.5 across linux-x64 and macOS (x64 + arm64), and on the PHP 8.6 beta on linux-x64 and macOS x64 (macOS arm64 awaits lisachenko/z-engine#280).

What is left is a short list, and most of it is the engine's doing rather than unfinished plumbing:

Expand Down
2 changes: 1 addition & 1 deletion composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
"require": {
"php": "^8.4",
"ext-ffi": "*",
"lisachenko/z-engine": "8.4.x-dev || 8.5.x-dev"
"lisachenko/z-engine": "8.4.x-dev || 8.5.x-dev || 8.6.x-dev"
},
"require-dev": {
"phpunit/phpunit": "^12.2",
Expand Down
Loading