-
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: fix async hooks crashing when there is no node context #19134
Changes from 15 commits
6b76017
84a1822
5e9128f
9690b86
0e4fda8
c938269
70169d3
9f69beb
96a53db
cb3bba1
51257ed
361d425
704b418
bca7fd1
0577c29
54bf6dc
3c4d991
4d20b72
d9214a7
23fa418
c2b9b32
4437f90
436919e
6b095d7
85cf945
76df613
077c7a5
92ec8c1
39b5c1f
9c72574
e91cdc0
6ef891e
5ac8e62
aaa53b1
3a54578
634a63e
10b280e
e394201
af69d52
927d984
290b627
93d7670
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -3,6 +3,7 @@ | |
#include "node_buffer.h" | ||
#include "node_platform.h" | ||
#include "node_file.h" | ||
#include "node_context_data.h" | ||
#include "tracing/agent.h" | ||
|
||
#include <stdio.h> | ||
|
@@ -24,6 +25,11 @@ using v8::StackTrace; | |
using v8::String; | ||
using v8::Value; | ||
|
||
const int kNodeContextTag = 0x6e6f64; | ||
void* kNodeContextTagPtr = const_cast<void*>( | ||
static_cast<const void*>(&kNodeContextTag) | ||
); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Style nit: Left-leaning pointers (i.e. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. done |
||
|
||
IsolateData::IsolateData(Isolate* isolate, | ||
uv_loop_t* event_loop, | ||
MultiIsolatePlatform* platform, | ||
|
@@ -195,6 +201,10 @@ void Environment::Start(int argc, | |
set_process_object(process_object); | ||
|
||
SetupProcessObject(this, argc, argv, exec_argc, exec_argv); | ||
|
||
// Used by EnvPromiseHook to know that we are on a node context. | ||
context()->SetAlignedPointerInEmbedderData(ContextEmbedderIndex::kContextTag, kNodeContextTagPtr); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This should probably be happening in There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. that one might take a while. I'd need to clone the whole repo again, etc etc. |
||
|
||
LoadAsyncWrapperInfo(this); | ||
|
||
static uv_once_t init_once = UV_ONCE_INIT; | ||
|
@@ -364,7 +374,20 @@ bool Environment::RemovePromiseHook(promise_hook_func fn, void* arg) { | |
void Environment::EnvPromiseHook(v8::PromiseHookType type, | ||
v8::Local<v8::Promise> promise, | ||
v8::Local<v8::Value> parent) { | ||
Environment* env = Environment::GetCurrent(promise->CreationContext()); | ||
Local<v8::Context> context = promise->CreationContext(); | ||
|
||
// Grow the embedder data if necessary to make sure we are not out of bounds | ||
// when reading the magic number. | ||
context->SetAlignedPointerInEmbedderData(ContextEmbedderIndex::kContextTagBoundary, nullptr); | ||
int* magicNumberPtr = reinterpret_cast<int*>( | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Style: If you |
||
context->GetAlignedPointerFromEmbedderData(ContextEmbedderIndex::kContextTag) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. nit: four space indentation. You can move the ) on the next line to this line. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. done (the parenthesis part, the indent used looks like 2 spaces to me? or is 4 a special rule for these cases?) |
||
); | ||
if (magicNumberPtr != kNodeContextTagPtr || *magicNumberPtr != kNodeContextTag) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think the first condition implies the second one :) There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. there might be the reaaaaally tiny small chance that the pointer might actually point to the "random" memory location yet that this random location does not contain the expected value? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I mean, if There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. That's assuming that the context is actually created by node, maybe there could be the chance that: I mean, it is a failsafe, but I can just remove it and set the magic number to 0 and just rely on the pointer address if you want. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @xaviergonz Yeah, but if they manage to get the same pointer into the same internal field, then we still won’t be able to distinguish these. :)
I think it’s good to use a magic value here so that it’s easier to recognize – just saying that the second condition here will currently never be true if the first one was false. :) There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Actually upon thinking about it a bit more you are right :) The same memory location cannot be shared, so I'll just remove the second check There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. done |
||
return; | ||
} | ||
|
||
Environment* env = Environment::GetCurrent(context); | ||
|
||
for (const PromiseHookCallback& hook : env->promise_hooks_) { | ||
hook.cb_(type, promise, parent, hook.arg_); | ||
} | ||
|
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.
Ditto.
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.
done (the parenthesis part, the indent used looks like 2 spaces to me? or is 4 a special rule for these cases?)
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.
If it’s a block/conditional body/function body, 2 spaces, otherwise 4 for statement continuations.
We try to document this at https://github.com/nodejs/node/blob/master/CPP_STYLE_GUIDE.md, if you have any suggestions for improving the clarity of that document please say so :)
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.
ah thanks, missed that one. fixed!