Luther Monson, Staff Software Engineer at SUSE

Luther Monson

Go by way of PHP · Containers · VMs · Windows · Kubernetes

The Bugs Were Our Own Linker Wraps: Making a PHP Timeout Actually Time Out

max_execution_time did nothing in ePHPm because we had wrapped zend_set_timeout to a no-op. The SDK already had per-thread timers. We just had to stop switching them off.

8-Minute Read

Side by side: a process-wide SIGPROF timer that can land on the wrong thread, versus a per-thread POSIX timer that delivers SIGRTMIN to the PHP thread that armed it

In the stack guard post the villain was a -Wl,--wrap linker flag that turned off PHP’s C-stack overflow guard. It wasn’t the only one. Until August, max_execution_time did nothing in ePHPm on Linux, for the same reason. We had wrapped the function that arms it to a no-op. A runaway script ran until the HTTP layer’s request timeout gave up on it and sent a 504. The PHP thread kept burning CPU after that.

We Disabled PHP's Stack Guard Ourselves: Containing Segfaults in a Single-Process PHP Server

How ePHPm went from dying silently on a segfault to containing stack overflows per thread. It also covers the linker flag that had turned off PHP's own guard.

12-Minute Read

Diagram of a PHP thread stack, the guard window below it, and which faults get contained versus which kill the process

php-fpm has a property nobody thinks about until they leave it. When a worker segfaults, you lose one request. The master forks a new child and life goes on. ePHPm runs every tenant’s PHP as threads inside one process. That’s where the memory and latency wins come from. It also means one tenant’s segfault takes down every other tenant on the box.

PHP Signal Safety - The Init Ordering Bug Nobody Warns You About

Embedding PHP in a multithreaded server means PHP's timeout signals can land on any thread. How ePHPm got that under control.

11-Minute Read

Thread timeline: the main thread installs PHP's signal handlers during php_embed_init, a PHP thread later arms ITIMER_PROF, and SIGPROF is delivered to a tokio worker that has no PHP state

Last week I wrote about why ePHPm embeds PHP from Rust and promised the signal bug its own post. Here it is. It’s the kind of bug where the fix is about ten lines and the explanation is the whole post. Nothing in PHP’s embed documentation (there’s barely any) tells you that initializing PHP has process-wide side effects. Those side effects assume PHP is the only thing in the process.

Recent Posts

Categories

About

Luther is a 20+ year software veteran specializing in backend APIs and architecting products. Employed at SUSE as the Team Lead for the Containers on Windows Team working on Rancher + Kubernetes