Page MenuHomePhabricator

Replace wmerrors PHP extension with functionality built into PHP itself
Open, Needs TriagePublic

Description

The reason wmerrors is long and complicated is because PHP handled request timeout errors by trying to write out the error message from a signal handler. This was extremely unsafe and frequently crashed or deadlocked. In PHP 7.1, this issue was fixed: it now only calls signal-safe functions from the signal handler, setting a flag in the VM for graceful exit and setting a second "hard" timeout to abort the process if the VM doesn't terminate quickly enough.

I've confirmed in gdb just now that PHP 7.0 does indeed exit a signal handler using longjmp(). It then proceeds to run functions registered with register_shutdown_function(). I don't think it's advisable to do this since it will certainly crash or deadlock on occasion. In PHP 7.1 it should be possible to do this without generating segfaults.

The other tricky case is OOM errors. These still longjmp() directly out of the emalloc() call as of PHP git master. This leaves the calling code in an undefined state, but it's not as bad as timeouts since there are fewer possible calling locations. Maybe you could get away with running userspace code after this, as long as you keep the code very simple and avoid accessing any state which was being written at the time of the OOM. But in my testing of php-fpm, output from a shutdown function after OOM is discarded, so it's not possible to write out an OOM error page with this trick. This is probably because (gdb shows) a second OOM is inevitably triggered when you try to do anything in userspace. The memory usage is equal to the limit.

In summary, I think using a simple port of wmerrors would be advisable for PHP 7.0. wmerrors will routinely segfault but at least it has a timer to guard against deadlocks.

In PHP 7.1+, it should be possible to handle timeouts in userspace, but OOMs remain problematic.

In the long term, we should probably develop a patch for the PHP core which meets our needs for error reporting. We do have a contractor budget.

This ticket is to track that in the long-term we do not want to keep maintaining the wmerrors extension, and supposedly do have some budget for a contractor who could implement our needs upstream in PHP itself. Even though the original phab comment is a bit old now, we discussed this a few weeks ago on IRC and the situation is still the same.