-
Notifications
You must be signed in to change notification settings - Fork 29.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
src: return static buffer on malloc(0) #8658
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.
LGTM
b91833a
to
49851f5
Compare
It might put people on the wrong foot because it deviates from what normal malloc does. If you think performance is at stake, then it's arguably better to teach callers to handle zero-sized allocations explicitly. |
Oh, another thing: there are at least one or two places in the source code where we pass a heap-allocated buffer to an external library (openssl), with the library responsible for freeing the memory again. I don't think we normally pass zero-sized buffers but it would fail badly if we did. |
@bnoordhuis Handling the Allowing a |
// a nullptr. | ||
// nullptr for zero-sized allocation requests. Normalize by always using | ||
// a static buffer. | ||
static void* fake_mem = malloc(1); |
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.
Are you sure this works as it is? Having fake_mem
as a static
variable means that every object file is going to end up with its own instance of that, meaning that e.g. the Free()
from node_crypto.cc
can’t handle Malloc()
ed buffers from node_buffer.cc
.
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.
Changed. Does it look better now?
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.
@mscdex Yeah, that should work, but it may come with a bit of overhead and it’s not technically thread-safe.
Something that might be a bit faster would be using a compile-time static buffer, i.e. extern char fake_mem[1];
in util-inl.h
and char fake_mem[1];
in util.cc
, because that should enable the compiler to inline the memory address (which may become an actual constant).
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.
Updated.
49851f5
to
c4996a0
Compare
c4996a0
to
070e10d
Compare
CI again after recent changes: https://ci.nodejs.org/job/node-test-pull-request/4150/ |
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.
LGTM
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.
LGTM
I'm going to go out on a limb and say this does not LGTM. The potential for subtle bugs outweighs any benefits, IMO. |
That's fair. Is this a "don't do this at all" or a "there's a better way" type of thing? |
I think the “better way” would basically be #8572? I’m reopening that because it seems like a solution that can get to consensus pretty easily, and anything else can be discussed later. |
Checklist
make -j4 test
(UNIX), orvcbuild test nosign
(Windows) passesAffected core subsystem(s)
Description of change
This is an alternate approach to #8572 that reuses a static buffer for
malloc(0)
requests to restore pre-node v6.6.0 behavior. This requires the addition of a newnode::Free()
for all buffers created vianode::Malloc()
/node::Calloc()
.Fixes: #8571