-
Notifications
You must be signed in to change notification settings - Fork 30k
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
inspector: add contexts when using vm module #9272
Conversation
Adds all Contexts created by the vm module to the inspector. This does permanent tracking of Contexts and syncing the Contexts whenever a new inspector is created. Fixes: nodejs#7593
1906d5f
to
2e4b318
Compare
/cc @bnoordhuis |
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.
Thanks for looking into it. Some comments - mostly about keeping as much gory inspector details within inspector itself.
src/env-inl.h
Outdated
@@ -356,6 +356,25 @@ inline IsolateData* Environment::isolate_data() const { | |||
return isolate_data_; | |||
} | |||
|
|||
inline void Environment::context_created(v8_inspector::V8ContextInfo info) { | |||
contexts()->push_back(info); | |||
if (inspector_agent()->IsStarted()) { |
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.
Should this be enclosed in #if HAVE_INSPECTOR check?
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.
good find
src/env-inl.h
Outdated
inline void Environment::context_created(v8_inspector::V8ContextInfo info) { | ||
contexts()->push_back(info); | ||
if (inspector_agent()->IsStarted()) { | ||
inspector_agent()->ContextCreated(info); |
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 would suggest to always call ContextCreated/ContextDestroyed - and then let inspector_agent check the IsStarted. This way in this header it will be a single line call (also, contexts vector will live in inspector then).
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.
@eugeneo the way the inspector_agent is setup, it is unsafe to call prior to it being started since platform_ does not exist.
@@ -7,6 +7,7 @@ | |||
#include "debug-agent.h" | |||
#if HAVE_INSPECTOR | |||
#include "inspector_agent.h" | |||
#include <vector> |
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.
Including STL header on the high level header used to cause some problems with the memory allocation on AIX (it was using a "wrong" alloc). I do not know if they were fixed...
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.
these includes are also present in existing inspector files
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.
Yes, I had to make sure they do not leak outside of inspector_agent translation unit. This issue might've been fixed since.
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 see it all over https://github.com/nodejs/node/search?utf8=%E2%9C%93&q=path%3Asrc+%22include+%3Cvector%3E%22&type=Code , presuming this is fixed.
src/inspector_agent.h
Outdated
@@ -33,6 +35,9 @@ class Agent { | |||
// Stop the inspector agent | |||
void Stop(); | |||
|
|||
void ContextCreated(const v8_inspector::V8ContextInfo& info); |
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 believe it would be better if this call accepted v8::Context (and, optionally, a string) rather then V8ContextInfo. This would allow us no to leak inspector API to the bigger Node.
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.
possible, but there is some complexity here since the v8 inspector is already tightly bound in inspector_agent.cc, if we had a generic API I would agree, but I don't see that currently.
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.
There's still some churn in inspector API (e.g. #9028 is quite major) so I feel like it would be safer to only rely on v8 namespace.
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 saw the Threads bit in the new devtools, is that the purpose of the contextGroupId
? Should we be including that as well?
src/env.h
Outdated
@@ -564,6 +571,7 @@ class Environment { | |||
debugger::Agent debugger_agent_; | |||
#if HAVE_INSPECTOR | |||
inspector::Agent inspector_agent_; | |||
std::vector<v8_inspector::V8ContextInfo> contexts_; |
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 think V8ContextInfo is safe to use here because it doesn't look like it's supposed to outlive a HandleScope. The context is stored as a v8::Local<v8::Context>
and Locals are clobbered when the HandleScope is destroyed.
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 can do it and match the other request to limit usage of v8_inspector namespace usage
src/env.h
Outdated
@@ -528,6 +529,12 @@ class Environment { | |||
inline inspector::Agent* inspector_agent() { | |||
return &inspector_agent_; | |||
} | |||
|
|||
inline void context_created(v8_inspector::V8ContextInfo context); | |||
inline void context_destroyed(v8::Local<v8::Context> context); |
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.
Can you call these ContextCreated() and ContextDestroyed()?
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.
sounds good
change context_created to ContextCreated on Environment create node specific class instead of exposing v8_inspector for Context tracking
@bnoordhuis @eugeneo fixed, please review when you find the time :) |
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.
Thanks for doing this. I still strongly feel like majority of this code should remain private to the inspector. I wonder if there is a way (or should be one) to be notified of context creation/destruction so the inspector could somehow subscribe to it.
Please notice that I've updates the V8 inspector version, now the API is the same as in inspector that is in the V8 repository.
@@ -528,6 +529,12 @@ class Environment { | |||
inline inspector::Agent* inspector_agent() { | |||
return &inspector_agent_; | |||
} | |||
|
|||
inline void ContextCreated(node::inspector::ContextInfo* info); |
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 still have an issue with the parameter asymmetry - especially, considering that ContextInfo is instantiated in call side in both cases (and will likely be for all future uses).
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.
unclear on what you suggest as an alternative?
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 am suggesting not to expose ContextInfo outside of inspector-agent.cc
src/env.cc
Outdated
new node::inspector::ContextInfo(context(), 1, "NodeJS Main Context")); | ||
#endif | ||
|
||
isolate()->SetAutorunMicrotasks(false); |
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.
Is this related to this change?
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.
unclear how this got in here, should be removed.
@@ -564,6 +571,7 @@ class Environment { | |||
debugger::Agent debugger_agent_; | |||
#if HAVE_INSPECTOR | |||
inspector::Agent inspector_agent_; | |||
std::vector<node::inspector::ContextInfo*> contexts_; |
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.
IMHO, this vector should be a member of inspector::AgentImpl.
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.
disagree since inspector isn't really usable until it starts
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.
But you're calling IsStarted - so it is usable, just not started.
I'm wondering if there's some way to introduce some sort of context registry that is not inspector specific. There might already be one in v8...
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.
IsStarted just checks if things are usable, platform_ being uninitialized resulted in segfaults when I tried to call contextCreated early on
@bmeck The "tests and/or benchmarks are included" box is checked, but I'm not seeing any tests or benchmarks. Did they just get omitted accidentally? Or should that box not be checked? |
@Trott accident |
return; | ||
} | ||
} | ||
} |
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.
You could simplify this with std::find
or std::find_if
.
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.
the erase needs an index not value.
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.
find() and find_if() return iterators, not values.
src/env-inl.h
Outdated
} | ||
} | ||
} | ||
#endif |
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.
Can you write this as #endif // HAVE_INSPECTOR
? Note the two spaces after #endif
.
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.
fixing, but copy paste only shows
#endif [<= one space?]// HAVE_INSPECTOR
src/env.cc
Outdated
@@ -30,6 +34,11 @@ void Environment::Start(int argc, | |||
HandleScope handle_scope(isolate()); | |||
Context::Scope context_scope(context()); | |||
|
|||
#if HAVE_INSPECTOR | |||
ContextCreated( | |||
new node::inspector::ContextInfo(context(), 1, "NodeJS Main Context")); |
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.
Line continuations should have four spaces of indent. (Ditto in other files, I won't point them out separately.)
src/inspector_agent.cc
Outdated
inspector_->contextCreated( | ||
v8_inspector::V8ContextInfo(env->context(), 1, "NodeJS Main Context")); | ||
v8::HandleScope handles(env_->isolate()); | ||
for (auto it : *(env->contexts())) { |
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.
You don't need parens around env->contexts()
.
src/inspector_agent.h
Outdated
context_.Reset(context->GetIsolate(), context); | ||
} | ||
~ContextInfo() { | ||
context_.Reset(); |
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.
Not necessary, ~Persistent()
resets by default.
src/inspector_agent.h
Outdated
const char* name() const { return name_; } | ||
private: | ||
v8::Persistent<v8::Context> context_; | ||
int groupId_; |
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.
Can you snake_case it to group_id_
? If it never changes, consider making it const (same for name_
.)
So glad this is being worked on! @bmeck do you have any ETA when this will make it into a version of node? :) |
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.
Left some comments, nothing substantial. I think @eugeneo should do the final sign-off because he understands the inspector code better than I do.
return; | ||
} | ||
} | ||
} |
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.
find() and find_if() return iterators, not values.
inspector_->contextCreated( | ||
v8_inspector::V8ContextInfo(env->context(), 1, "NodeJS Main Context")); | ||
v8::HandleScope handles(env_->isolate()); | ||
for (auto it : *env->contexts()) { |
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.
Somewhat inconsistent use of env
vs. env_
.
void AgentImpl::ContextCreated(const node::inspector::ContextInfo* info) { | ||
inspector_->contextCreated(info); | ||
} | ||
void AgentImpl::ContextDestroyed(v8::Local<v8::Context> context) { |
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.
Can you insert a blank line here and on line 894?
} | ||
void Agent::ContextDestroyed(v8::Local<v8::Context> context) { | ||
impl->ContextDestroyed(context); | ||
} |
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.
Out of curiosity, is the two or three levels of forwarding strictly necessary?
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.
in order to pass things to the right place and get through all the levels of abstraction, yes.
@@ -23,6 +25,25 @@ namespace inspector { | |||
|
|||
class AgentImpl; | |||
|
|||
class ContextInfo { | |||
public: | |||
explicit ContextInfo(v8::Local<v8::Context> context, const int groupId, |
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.
s/groupId/group_id/
inline v8::Local<v8::Context> context(v8::Isolate* isolate) const { | ||
return context_.Get(isolate); | ||
} | ||
int groupId() const { return group_id_; } |
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, idiomatic core code would spell this as group_id()
.
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.
is there a style guide on this or reason why linting doesn't pick these things up?
Stalled/blocked but still needed
…On Mar 24, 2017 5:37 PM, "James M Snell" ***@***.***> wrote:
Ping @bmeck <https://github.com/bmeck> ... does this still make sense? Is
it needed? /cc @eugeneo <https://github.com/eugeneo>
—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
<#9272 (comment)>, or mute
the thread
<https://github.com/notifications/unsubscribe-auth/AAOUozedBnlrGvn1o0ivT9QOOAlEJuyIks5rpEWkgaJpZM4KgGfw>
.
|
Can I get updates on : If the If the asymmetry is still a blocker. Guessing such an API is not in the works. |
@bmeck please take a look at https://github.com/eugeneo/node/tree/contexts_crashing - this is my suggested implementation, it is very similar to yours. I had to cut a corner or two - but the real problem is that it is crashing in test/parallel/test-vm-run-in-new-context.js |
@bmeck one thing I have been looking into (and I hope to go back to) is for the inspector to have its own WeakCallback on a context so there's no need to report to Inspector contexts going away. |
Is there any way React community could help with pushing this through? It’s affecting Jest pretty badly and I’m sure somebody could pick it up if you are busy with other things. |
I'm removing the |
Im super excited about this. I haven't written c/c++ since college, but I'd be willing to at least pair as a sounding board for anyone who can keep this going! |
This enables inspector support for contexts created using the vm module. Fixes: nodejs#7593 Fixes: nodejs#12096 Refs: nodejs#9272
Based on work by Bradley Farias <bradley.meck@gmail.com> and Eugene Ostroukhov <eostroukhov@chromium.org>. TODO: V8's console is injected unconditionally, which may be not desirable. Fixes: nodejs#7593 Refs: nodejs#9272
Yes, #14465 should have obviated this one. I'll close it out, thanks. |
Checklist
make -j8 test
(UNIX), orvcbuild test nosign
(Windows) passesAffected core subsystem(s)
inspector
Description of change
Tracks all
vm
module contexts for usage in v8_inspector. These are tracked even when the inspector is not running so that they are visible when the inspector is started up.Fixes: #7593