-
Notifications
You must be signed in to change notification settings - Fork 7.8k
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
Add runtime-enabled heap debugging capabilities #18172
Conversation
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.
Thank you! I can confirm that the padding
option is particularly useful in catching refcounting bugs, since it will make the:
ZEND_ASSERT(p->refcount > 0);
in zend_gc_delref()
functional. Without the padding, the refcount would be overwritten by ZendMM metadata on free, thus preventing the assertion from ever triggering.
The check_freelists_on_shutdown
option would also detect this on shutdown, but that would happen much later.
I've got a few comments inline, but overall this looks very good and helpful in catching some of my past production bugs.
Co-authored-by: Tim Düsterhus <[email protected]>
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.
As far as this doesn't affect release build performance, I don't see any problems.
Debugging memory corruption issues in production can be difficult when it's not possible to use a debug build or ASAN/MSAN/Valgrind (e.g. for performance reasons).
This PR makes it possible to enable some basic heap debugging helpers without rebuilding PHP. This is controlled by the environment variable
ZEND_MM_DEBUG
. The env var takes a comma-separated list of parameters:poison_free=byte
: Override freed blocks with the specified byte value (represented as a number)poison_alloc=byte
: Override newly allocated blocks with the specified byte value (represented as a number)padding=bytes
: Pad allocated blocks with the specified amount of bytes (if non-zero, a value >= 16 is recommended to not break alignments)check_freelists_on_shutdown=0|1
: Enable checking freelist consistency on shutdownExample:
ZEND_MM_DEBUG=poison_free=0xbe,poison_alloc=0xeb,padding=16,check_freelists_on_shutdown=1 php ...
.This is based on an idea of @TimWolla.
Implementation
This is implemented by installing custom handlers when
ZEND_MM_DEBUG
is set.Overhead
This has zero overhead when
ZEND_MM_DEBUG
is not set. WhenZEND_MM_DEBUG
is set, the overhead is about 8.5% on the Symfony Demo benchmark.Goals:
Non-goals: