-
Notifications
You must be signed in to change notification settings - Fork 30.1k
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
debug: activate inspector with _debugProcess #11431
Conversation
CI: https://ci.nodejs.org/job/node-test-pull-request/6457/ ARM failures are parallel/test-dgram-address that does not seem to be influenced by this change. |
/cc @nodejs/diagnostics @jkrems |
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 a few comments … the size of the diff makes it quite difficult to tell code that was just moved around from actual changes, by the way. I don’t know if splitting into several commits would have been a possibility here, but that would make reviewing a lot easier…
src/inspector_agent.cc
Outdated
size_t len = string_value->Length(); | ||
std::vector<uint16_t> buffer(len, '\0'); | ||
string_value->Write(buffer.data(), 0, len); | ||
return StringBuffer::create(StringView(buffer.data(), len)); |
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.
Could you use a TwoByteValue
for the above couple of lines?
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. Thanks!
src/inspector_agent.cc
Outdated
|
||
std::unique_ptr<StringBuffer> ToProtocolString(Local<Value> value) { | ||
if (value.IsEmpty() || value->IsNull() || value->IsUndefined() || | ||
!value->IsString()) { |
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.
Why not just value.IsEmpty() || !value->IsString()
?
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 switched to TwoByteValue and removed this check.
src/inspector_agent.h
Outdated
class InspectorSessionDelegate { | ||
public: | ||
virtual bool WaitForFrontendMessage() = 0; | ||
virtual void OnMessage(const v8_inspector::StringView message) = 0; |
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 any reason why this can’t be const v8_inspector::StringView&
?
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.
Fixed
src/inspector_agent.h
Outdated
|
||
void Connect(InspectorSessionDelegate* delegate); | ||
void Disconnect(); | ||
void Dispatch(const v8_inspector::StringView message); |
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 for const v8_inspector::StringView&
)
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.
Fixed
src/inspector_io.cc
Outdated
using v8_inspector::StringView; | ||
|
||
template<typename Transport> | ||
using IoAndTransport = std::pair<Transport*, InspectorIo*>; |
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.
nit: I’m tempted to say this might better be called TransportAndIo
. 😄
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.
Right... :) Thanks, I fixed it!
CI: https://ci.nodejs.org/job/node-test-pull-request/6527/ I do not see ARM failures through the Hudson - I think GitHub integration might be glitchy. |
Tried this change against |
What's the status on this? |
@jasnell I am not sure. Code-wise it is ready for the review. A decision needs to be made when the old debugger stops handling the signal - is this something that needs to be discussed by @nodejs/diagnostics? |
@joshgav Can we pull this into tomorrow's meeting? I think it boils down to a unified "master plan" for doing the switch and when to land what and where. |
@jkrems sure, just added label. |
@jkrems, @joshgav - how can I join the meeting? I tried looking through the https://github.com/nodejs/diagnostics but did not find details about the upcoming meeting. |
@eugeneo This is the meta issue for the meeting: nodejs/diagnostics#89 |
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.
Mea culpa, looks like I reviewed this back in February but forgot to submit the comments. Re-reviewed; needs a rebase but the conflicts look minor.
src/inspector_agent.cc
Outdated
bool waiting_; | ||
}; | ||
static int GetDebugSignalHandlerMappingName(DWORD pid, wchar_t* buf, | ||
size_t buf_len) { |
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 line up the arguments?
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
src/inspector_agent.cc
Outdated
inspector_->contextCreated(info); | ||
} | ||
|
||
void runMessageLoopOnPause(int context_group_id) override { | ||
CHECK(channel_); |
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 CHECK_NE(channel, nullptr)
?
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
src/inspector_agent.cc
Outdated
void connectFrontend() { | ||
session_ = inspector_->connect(1, new ChannelImpl(agent_), StringView()); | ||
void connectFrontend(InspectorSessionDelegate* delegate) { | ||
CHECK(!channel_); |
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.
Likewise but with CHECK_EQ. I'll stop pointing it out.
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
src/inspector_agent.cc
Outdated
} | ||
|
||
InspectorSessionDelegate* delegate() { | ||
if (!channel_) |
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.
Prefer channel_ == nullptr
over bool coercion.
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
src/inspector_agent.cc
Outdated
int err = uv_thread_join(&thread_); | ||
CHECK_EQ(err, 0); | ||
delete inspector_; | ||
if (io_) |
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.
Likewise. I'll stop pointing it out.
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
src/inspector_agent.cc
Outdated
std::string InspectorAgentDelegate::GetTargetTitle(const std::string& id) { | ||
return script_name_.empty() ? GetProcessTitle() : script_name_; | ||
InspectorSessionDelegate* Agent::delegate() { | ||
return impl->client()->delegate(); |
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 explain why you sometimes CHECK(impl->client())
and sometimes not?
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
src/inspector_io.cc
Outdated
OneByteString(env->isolate(), str), \ | ||
var, \ | ||
v8::ReadOnly).FromJust(); \ | ||
} while (0) |
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.
Unused macro?
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.
Removed.
src/inspector_io.cc
Outdated
if (!script_name_.empty()) { | ||
uv_fs_t req; | ||
if (0 == uv_fs_realpath(&loop, &req, script_name_.c_str(), nullptr)) | ||
script_path = std::string(reinterpret_cast<char*>(req.ptr)); |
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.
static_cast?
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
src/inspector_io.cc
Outdated
if (!server.Start(&loop)) { | ||
state_ = State::kError; // Safe, main thread is waiting on semaphore | ||
uv_close(reinterpret_cast<uv_handle_t*>(&io_thread_req_), nullptr); | ||
uv_loop_close(&loop); |
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 CHECK_EQ(0, uv_loop_close(&loop))
? I'm pretty sure this won't work on account of the closing 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 changed the code to spin until the callback is called.
src/node_debug_options.cc
Outdated
@@ -141,7 +141,8 @@ int DebugOptions::port() const { | |||
int port = port_; | |||
if (port < 0) { | |||
#if HAVE_INSPECTOR | |||
port = inspector_enabled_ ? default_inspector_port : default_debugger_port; | |||
port = (debugger_enabled_ && !inspector_enabled_) ? default_debugger_port | |||
: default_inspector_port; |
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 make this an if statement for legibility? You could also simplify it to this:
if (port < 0) {
port = default_debugger_port;
#if HAVE_INSPECTOR
if (inspector_enabled_)
port = default_inspector_port;
#endif // HAVE_INSPECTOR
}
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
Thank you for the review. Please take another look. |
I did a rebase to account for the latest changes. Please review. |
Looks like there's one stray lint error:
|
@jkrems thanks for pointing that out, I fixed it. |
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 sans some final comments. Have you checked if ./configure --without-inspector
still builds?
src/inspector_agent.cc
Outdated
|
||
class AgentImpl { | ||
public: | ||
explicit AgentImpl(node::Environment* env); | ||
~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.
Out of curiosity, what is the purpose of this destructor?
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.
Removed.
src/inspector_agent.cc
Outdated
void WaitForFrontendMessage(); | ||
void NotifyMessageReceived(); | ||
bool StartIoThread(); | ||
static void InspectorWrapConsoleCall( | ||
const v8::FunctionCallbackInfo<Value>& args); |
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.
Four space indent.
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
src/inspector_agent.cc
Outdated
Local<Value> config_value = args->Get(context, 2).ToLocalChecked(); | ||
CHECK(config_value->IsObject()); | ||
Local<Object> config_object = config_value.As<Object>(); | ||
Local<String> in_call_key = OneByteString(isolate, "in_call"); |
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 use FIXED_ONE_BYTE_STRING here.
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, did search/replace for all invocations
src/inspector_agent.cc
Outdated
static_cast<void>(node_method.As<Function>()->Call(context, | ||
info.Holder(), | ||
call_args.size(), | ||
call_args.data())); | ||
if (try_catch.HasCaught()) | ||
try_catch.ReThrow(); |
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 point to creating the TryCatch when it just rethrows the exception?
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.
Removed.
src/inspector_agent.cc
Outdated
Local<Object> process = parent_env_->process_object(); | ||
Local<Object> inspector = Object::New(parent_env_->isolate()); | ||
process->DefineOwnProperty(parent_env_->context(), | ||
OneByteString(parent_env_->isolate(), "inspector"), |
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 use FIXED_ONE_BYTE_STRING here.
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.
src/inspector_io.cc
Outdated
} | ||
|
||
bool InspectorIo::IsStarted() { | ||
return !!platform_; |
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.
platform_ != nullptr
?
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
src/inspector_io.cc
Outdated
InspectorIo::MainThreadAsyncCb)); | ||
uv_unref(reinterpret_cast<uv_handle_t*>(&main_thread_req_)); | ||
CHECK_EQ(0, uv_sem_init(&start_sem_, 0)); | ||
memset(&io_thread_req_, 0, sizeof(io_thread_req_)); |
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 wrong but you could also io_thread_req_()
in the initializer list.
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
src/inspector_io.cc
Outdated
StringView message = std::get<2>(task)->string(); | ||
switch (std::get<0>(task)) { | ||
case InspectorAction::kStartSession: | ||
CHECK(!session_delegate_); |
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.
CHECK_EQ
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
src/inspector_io.cc
Outdated
parent_env_->inspector_agent()->Connect(session_delegate_.get()); | ||
break; | ||
case InspectorAction::kEndSession: | ||
CHECK(session_delegate_); |
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.
CHECK_NE
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
src/node.cc
Outdated
@@ -270,7 +270,7 @@ static struct { | |||
bool StartInspector(Environment *env, const char* script_path, | |||
const node::DebugOptions& options) { | |||
env->ThrowError("Node compiled with NODE_USE_V8_PLATFORM=0"); | |||
return false; // make compiler happy | |||
return true; // make compiler happy |
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 change suggests it's not just about the compiler?
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 removed outdated comment.
@bnoordhuis I moved the _debugProcess code back to node.cc so the node built with --without-inspector would still be able to send signal/do the weird Windows stuff to another Node instance. What do you think? |
@eugeneo Did you forget to push? I still see RegisterDebugSignalHandler() and friends in inspector_agent.cc, not node.cc. (Happy to hear I'm not the only one who thinks the Windows code is weird. I'm not even sure why it works.) |
Signal handler remains there, it is only the code that sends the signal that was moved back. (I see CI failures, looking into them) |
CI is passing: https://ci.nodejs.org/job/node-test-pull-request/7217/ |
CI: https://ci.nodejs.org/job/node-test-pull-request/7219/ - OS X is passing, even though its status is not properly reported. |
Landed as 7599b0e |
This pull request switches the signal handler to start inspector socket
server instead of the legacy V8 debug protocol.
Fixes: #8464
CC: @ofrobots