fix: don't segfault when the PHP CLI is executed while FrankenPHP is running - #2593
fix: don't segfault when the PHP CLI is executed while FrankenPHP is running#2593ousamabenyounes wants to merge 3 commits into
Conversation
…running ExecuteScriptCLI and ExecutePHPCode start the embedded PHP CLI SAPI via php_embed_init(). When FrankenPHP is already running in the same process (Init has been called), booting the embedded SAPI on top of the running FrankenPHP SAPI corrupts the PHP engine and crashes the whole process with a segmentation fault. Refuse the call cleanly instead: when FrankenPHP is running, log an error and return a non-zero exit status rather than crashing. The standalone CLI path (no prior Init) is unchanged. Fixes php#2342 Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
staticcheck QF1008: exec.ExitError embeds *os.ProcessState, so Exited() is promoted (as ExitCode() is already used on the next line).
|
But this can never happen? There's no code wiring to create this scenario. |
The godoc already noted that ExecuteScriptCLI/ExecutePHPCode must not run while FrankenPHP is up. Spell out the actionable alternatives: run the CLI before Init(), after Shutdown(), or in a separate process (the same binary in "php-cli" mode), which gives a real CLI SAPI and process isolation. Refs php#2342 Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
|
You're right that nothing in-tree chains But both are exported public API, so an external embedder can create the sequence — which is what @burgesQ did. My argument for the guard: an exported function that SIGSEGVs the whole process on misuse should fail loudly instead. Reproduced on PHP 8.5 ZTS ( Root cause as @burgesQ analysed: a second The guard logs an explicit error and returns a non-zero exit status — this keeps the exported I did look at making the call actually run while the server is up — executing the script on the FrankenPHP SAPI instead of a second embed SAPI — and I don't think it's a safe fix: I've spelled out the lifecycle constraint in the godoc of both functions (run CLI execution before |
|
For the love of god, @ousamabenyounes please stop slopping the slop responses everywhere. I don't want to read that. |
|
Really sorry i had a bug on my agent workflow...i ll do my best to fix it .... |
What
frankenphp.ExecuteScriptCLI()(andExecutePHPCode()) crash the whole processwith a segmentation fault when called after
frankenphp.Init()in the sameprocess (issue #2342):
Why
Both functions start the embedded PHP CLI SAPI through
php_embed_init(). Thatruns
sapi_startup()+php_module_startup()for the embed SAPI. When FrankenPHPis already running, its own SAPI and the PHP engine are already started, so
booting a second SAPI on top corrupts global engine state and the process
crashes.
What this PR does
The minimal, safe fix: prevent the crash. When FrankenPHP is already running,
ExecuteScriptCLI/ExecutePHPCodenow log an error and return a non-zero exitstatus instead of booting the embedded CLI SAPI and segfaulting. The standalone
CLI path (no prior
Init) is untouched.This intentionally does not add a new way to run CLI scripts inside a running
server (the broader idea discussed on the issue, e.g. running on a dedicated
thread/child process); it only turns an undefined-behaviour crash into a defined,
recoverable error. That larger feature can be built on top later.
Thread-safety note: the guard reads
isRunning(andglobalLogger) without anextra lock, consistent with how
Init/Shutdownalready manageisRunningandhow these globals are read elsewhere in the package. CLI-after-
Initis asequential misuse, not concurrent access.
Test verification (RED → GREEN)
Run in the dev image (
dev.Dockerfile), PHP 8.5 ZTS,-tags nowatcher.RED — unmodified
main(only the repro/test applied):(A standalone
Init()+ExecuteScriptCLI()program likewise crashes withsignal: segmentation fault, exit 139.)GREEN — with the fix (
go test -race):Existing standalone CLI tests still pass (no regression).
refuseCLIWhileRunningshows 100% coverage;
go build,go vet,gofmt, the Caddy module build andgo mod tidy -diffare all clean.