-
Notifications
You must be signed in to change notification settings - Fork 7.8k
Close file_handle in fpm_main #10707
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
sapi/fpm/fpm/fpm_main.c
Outdated
@@ -1918,6 +1920,8 @@ consult the installation file that came with this distribution, or visit \n\ | |||
|
|||
php_execute_script(&file_handle); | |||
|
|||
zend_destroy_file_handle(&file_handle); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I might be missing something but from the code this seems to me like a serious leak that this is fixing. If I read it correctly, the filename and file fd is leaked on every request. We might need to do some testing to confirm it as I can't believe this could be happening for so long without noticing.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I didn't use a tool or anything to find this. I just stumbled upon this and saw there was no freeing. Do you have suggestions on how to test it reliably?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Running FPM with 1 pool with static pm and one child and the hit it with mulitple requests. Just GDB (requires setting set follow-fork-mode child
) might show if it's getting freed or maybe trying to use Valgrind or other tools might show it as well. I had some issues with Valgrind in past when trying to debug child but it was for callgrind. Memcheck might work though.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't see an increase in entries in /proc/<pid of FPM>/
. I guess this is due to the file handle using a stream instead of a FILE*, but I'm not sure to how it all works internally and I didn't look that far into it tbh.
But I do see a memory leak report even without using Valgrind, but only when using opcache starting from the second request to the same file. The script name is being leaked (at least) every time I reload the webpage. Possibly other resources (that aren't being reported?) could be leaked as well, idk for sure. When I apply this PR I no longer see the leak.
That leak looks like:
[Sun Mar 12 00:54:15 2023] Script: '-'
/home/niels/php-src/Zend/zend_string.h(150) : Freeing 0x00007fbaca65f4e0 (64 bytes), script=-
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I just noted in the main comment some reasoning for this. Just to answer why the /prod/<child_pid>/fd
is not increasing - it is because with opcache, there is no fd
because accelerator overrides zend_stream_open_function
and does not create any fd in file handle. And without opcache it is being freed in shutdown as I mentioned.
a8dddad
to
918bd0b
Compare
Updated such that only the success path destroys the file handle. |
I have done some debugging and it is actually slightly more complicated. The thing is that without opcache, the file is added to
Then it is freed inside
That explains why you don't see the issue with opcache disabled. With opcache it obviously does not scan the file on subsequent executions so there is a leak. So it makes sense to do the destroy but maybe in slightly more optimized way (adding new suggestiong). |
Thanks for the extensive debugging and explanation, very interesting issue actually. |
If it's not in the CG(open_files) list, we need to destroy the file handle ourselves. Co-authored-by: Jakub Zelenka <[email protected]>
918bd0b
to
5620e27
Compare
Force pushed the suggestion, and added a comment, and added your co-authored-by. Thanks alot! |
The file handle wasn't destroyed/closed. I don't know if this really matters all too much but it seems to me that it should be destroyed, just like is the case for the cgi sapi.