SigQ eventually gets full
Some signals appear to be getting held up somewhere, causing an eventual segfault.
cat /proc/5497/status | grep Sig 23cfdd722a8d: Sun Dec 24 20:04:39 2023
SigQ: 48523/63519 <-- this should be 0-ish when idle
SigPnd: 0000000000000000
SigBlk: 0000000000000000
SigIgn: 0000000000000000
SigCgt: ffffffff7fc1feff
Once these are all used up, a segfault will be issued:
Could not create timer: Resource temporarily unavailable (11)
I haven't seen this in worker-mode, FWIW. Related to #366
I suspect these signals come in after the request is completed (thus, PHP has shutdown) but still need to be handled.
This is likely related to the memory leak. This means that the timer created by PHP to handle timeouts isn't cleaned properly. This code is quite new in PHP (I created it), I probably messed up something.
Would you be able to track where the code timer is created (eg using GDB) and why it isn't freed?
The timer is both created and destroyed @dunglas, I suspect this is important:
timer_delete() deletes the timer whose ID is given in timerid. If the timer was armed at the time of this call, it is disarmed before being deleted. The treatment of any pending signal generated by the deleted timer is unspecified.
From the looks of things, pending signals do not seem to be cleaned up (at least in my kernel) after the clock is deleted.
But what signals? Because calling timer_delete() should disarm the timer, so no signals should be send.
May https://github.com/php/php-src/pull/12539 help?
The signals in /proc/${ID}/timers... The timer is disarmed and not fired. However, pending signals are left hanging around (yay unspecified behavior).
To clear the timers, the signal must be ignored after the timer is deleted.
Opening a PR https://github.com/php/php-src/compare/master...bottledcode:php-src:fix/timers?expand=1
Just need to figure out how to get it backported to 8.2 + 8.3 + master.
So, I added some logic to that branch in php-src to detect if we create more than one timer per thread (because there was still a leak). It looks like ts_resource(0) creates a timer, as well as php_request_startup().
@dunglas any ideas on how we could fix this on the FrankenPHP side? Or perhaps in my branch, I just make it silently bail instead of emitting a warning?
I've no idea yet, but I'll be glad to take a look when I get back from vacation if you don't manage to find a fix before that (but I'm sure you will :D). Anyway, thanks for your research and commitment to fixing these issues, this is very promising!!
This is now fixed upstream and should be in the next patch release of 8.2 and 8.3.
The patch will land in PHP 8.3.3 and 8.2.1 (it is already available in the betas).