Skip to content
Permalink

Comparing changes

Choose two branches to see what’s changed or to start a new pull request. If you need to, you can also or learn more about diff comparisons.

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also . Learn more about diff comparisons here.
base repository: php-debugger/php-debugger
Failed to load repositories. Confirm that selected base ref is valid, then try again.
Loading
base: main
Choose a base ref
...
head repository: php-debugger/php-debugger
Failed to load repositories. Confirm that selected head ref is valid, then try again.
Loading
compare: fix/frankenphp-observer-cache
Choose a head ref
Checking mergeability… Don’t worry, you can still create the pull request.
  • 3 commits
  • 20 files changed
  • 1 contributor

Commits on May 3, 2026

  1. Add FrankenPHP worker mode support to the debugger

    - Introduced `frankenphp.c` and `frankenphp.h` to hook into FrankenPHP's per-request lifecycle using `sapi_module.activate` and `sapi_module.deactivate`.
    - Integrated per-request debugger resets, trigger detection, and breakpoint polling mechanism for FrankenPHP workers.
    - Updated existing modules (e.g., `handler_dbgp`, `debugger.c`) to support queued command handling and lifecycle management.
    - Adjusted build files to include new FrankenPHP-specific sources.
    pronskiy committed May 3, 2026
    Configuration menu
    Copy the full SHA
    51c0478 View commit details
    Browse the repository at this point in the history
  2. Add Docker-based manual test for FrankenPHP worker mode

    Provides a self-contained reproducer for the new sapi_module.activate /
    deactivate hooks added in src/debugger/frankenphp.c.
    
    - tests/frankenphp/Dockerfile: multi-stage build that compiles
      php_debugger.so against FrankenPHP's bundled ZTS PHP and installs it
      as a Zend extension with xdebug.mode=debug and start_with_request=trigger.
    - tests/frankenphp/Caddyfile: minimal config registering /app/worker.php
      as the FrankenPHP worker, with explicit http:// scheme to avoid the
      default auto-https redirect.
    - tests/frankenphp/app/{worker.php,index.php}: long-lived
      frankenphp_handle_request() loop and a sample request script with an
      obvious breakpoint location.
    - tests/frankenphp/entrypoint.sh: rewrites xdebug.client_host /
      xdebug.client_port from XDEBUG_CLIENT_HOST / XDEBUG_CLIENT_PORT env
      vars before exec'ing FrankenPHP (PHP INI has no native fallback
      syntax for env-var defaults).
    - tests/frankenphp/README.md: build/run instructions, one-time PhpStorm
      Server + path-mapping setup, the four verification scenarios
      (no-trigger skip, trigger pause, multi-request worker reuse, and the
      xdebug_dbgp_poll_pending breakpoint-between-requests test), and a
      troubleshooting table.
    - .dockerignore: keeps host build artifacts (Makefile, *.dep, *.lo,
      .libs, ...) out of the build context — without this, absolute host
      paths baked into the local Makefile break the in-container build.
    - .gitignore: adds tests/frankenphp/**/*.{php,sh} allowlist exceptions
      so the test files aren't swallowed by the blanket *.php / *.sh rules
      used to ignore stray test artifacts.
    pronskiy committed May 3, 2026
    Configuration menu
    Copy the full SHA
    5920eab View commit details
    Browse the repository at this point in the history
  3. Fix observer cache poisoning in FrankenPHP worker mode (#63)

    Three coupled changes are needed for line breakpoints to fire on
    functions called by trigger requests after non-trigger requests have run
    in the same worker:
    
    1. xdebug_observer_init: always return real handlers. The Zend engine
       caches the result per zend_function the first time the function is
       observed, so returning {NULL, NULL} when observer_active=false
       permanently blacklists that function — even after a debugger
       connects in a later request that reuses the cached op_array. The
       handlers themselves already fast-path on \!observer_active, so the
       no-debug overhead remains a single load+branch.
    
    2. xdebug_frankenphp_sapi_activate: re-arm observer_active per request.
       FrankenPHP runs PHP_RINIT only once at worker startup; per-request
       only sapi_activate fires. Without this, a worker that started with
       no IDE leaves observer_active=false for the rest of its life, so
       xdebug_execute_begin fast-paths out, no fse is pushed, and
       xdebug_debugger_statement_call bails on its empty-stack check.
    
    3. xdebug_frankenphp_minit: force ZEND_COMPILE_EXTENDED_STMT and
       disable the opcache optimizer at MINIT. The normal RINIT path skips
       this when no IDE is connected at startup, but in the worker flow
       user files are compiled later — by trigger requests that need
       EXT_STMT opcodes already present. Without this, breakpoint_set sees
       an empty "set of executable lines" for the target file.
    
    The `tests/frankenphp/app` workload (`workload()` defined in `lib.php`,
    called from `index.php`) plus `dbgp_listener.py` reproduce the failure
    deterministically: 200 no-trigger requests followed by 5 trigger
    requests previously yielded 0/5 breakpoint hits; with the fix all 5
    hit lib.php:4.
    pronskiy committed May 3, 2026
    Configuration menu
    Copy the full SHA
    eded249 View commit details
    Browse the repository at this point in the history
Loading