Skip to content
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

Merged
merged 0 commits into from
Apr 6, 2017
Merged

debug: activate inspector with _debugProcess #11431

merged 0 commits into from
Apr 6, 2017

Conversation

eugeneo
Copy link
Contributor

@eugeneo eugeneo commented Feb 16, 2017

This pull request switches the signal handler to start inspector socket
server instead of the legacy V8 debug protocol.

Fixes: #8464

CC: @ofrobots

@nodejs-github-bot nodejs-github-bot added build Issues and PRs related to build files or the CI. c++ Issues and PRs that require attention from people who are familiar with C++. dont-land-on-v4.x inspector Issues and PRs related to the V8 inspector protocol labels Feb 16, 2017
@eugeneo
Copy link
Contributor Author

eugeneo commented Feb 16, 2017

Ref: nodejs/diagnostics#67

@eugeneo
Copy link
Contributor Author

eugeneo commented Feb 17, 2017

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.

@ofrobots
Copy link
Contributor

/cc @nodejs/diagnostics @jkrems

@ofrobots ofrobots added the semver-major PRs that contain breaking changes and should be released in the next major version. label Feb 17, 2017
Copy link
Member

@addaleax addaleax left a 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…

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));
Copy link
Member

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?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done. Thanks!


std::unique_ptr<StringBuffer> ToProtocolString(Local<Value> value) {
if (value.IsEmpty() || value->IsNull() || value->IsUndefined() ||
!value->IsString()) {
Copy link
Member

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()?

Copy link
Contributor Author

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.

class InspectorSessionDelegate {
public:
virtual bool WaitForFrontendMessage() = 0;
virtual void OnMessage(const v8_inspector::StringView message) = 0;
Copy link
Member

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&?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed


void Connect(InspectorSessionDelegate* delegate);
void Disconnect();
void Dispatch(const v8_inspector::StringView message);
Copy link
Member

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&)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed

using v8_inspector::StringView;

template<typename Transport>
using IoAndTransport = std::pair<Transport*, InspectorIo*>;
Copy link
Member

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. 😄

Copy link
Contributor Author

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!

@eugeneo
Copy link
Contributor Author

eugeneo commented Feb 21, 2017

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.

@jkrems
Copy link
Contributor

jkrems commented Mar 16, 2017

Tried this change against node-inspect and it worked as expected.

@jasnell
Copy link
Member

jasnell commented Mar 22, 2017

What's the status on this?

@eugeneo
Copy link
Contributor Author

eugeneo commented Mar 22, 2017

@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?

@jkrems
Copy link
Contributor

jkrems commented Mar 22, 2017

@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.

@joshgav joshgav added the diag-agenda Issues and PRs to discuss during the meetings of the diagnostics working group. label Mar 22, 2017
@joshgav
Copy link
Contributor

joshgav commented Mar 22, 2017

@jkrems sure, just added label.

@eugeneo
Copy link
Contributor Author

eugeneo commented Mar 22, 2017

@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.

@jkrems
Copy link
Contributor

jkrems commented Mar 22, 2017

@eugeneo This is the meta issue for the meeting: nodejs/diagnostics#89

Copy link
Member

@bnoordhuis bnoordhuis left a 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.

bool waiting_;
};
static int GetDebugSignalHandlerMappingName(DWORD pid, wchar_t* buf,
size_t buf_len) {
Copy link
Member

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?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

inspector_->contextCreated(info);
}

void runMessageLoopOnPause(int context_group_id) override {
CHECK(channel_);
Copy link
Member

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)?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

void connectFrontend() {
session_ = inspector_->connect(1, new ChannelImpl(agent_), StringView());
void connectFrontend(InspectorSessionDelegate* delegate) {
CHECK(!channel_);
Copy link
Member

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.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

}

InspectorSessionDelegate* delegate() {
if (!channel_)
Copy link
Member

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.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

int err = uv_thread_join(&thread_);
CHECK_EQ(err, 0);
delete inspector_;
if (io_)
Copy link
Member

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.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

std::string InspectorAgentDelegate::GetTargetTitle(const std::string& id) {
return script_name_.empty() ? GetProcessTitle() : script_name_;
InspectorSessionDelegate* Agent::delegate() {
return impl->client()->delegate();
Copy link
Member

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?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

OneByteString(env->isolate(), str), \
var, \
v8::ReadOnly).FromJust(); \
} while (0)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Unused macro?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Removed.

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));
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

static_cast?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

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);
Copy link
Member

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.

Copy link
Contributor Author

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.

@@ -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;
Copy link
Member

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
}

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

@eugeneo
Copy link
Contributor Author

eugeneo commented Mar 29, 2017

Thank you for the review. Please take another look.

@eugeneo
Copy link
Contributor Author

eugeneo commented Mar 31, 2017

I did a rebase to account for the latest changes. Please review.

@jkrems
Copy link
Contributor

jkrems commented Apr 3, 2017

Looks like there's one stray lint error:

src/inspector_io.h:119:  Lines should be <= 80 characters long  [whitespace/line_length] [2]

@jkrems jkrems mentioned this pull request Apr 3, 2017
4 tasks
@eugeneo
Copy link
Contributor Author

eugeneo commented Apr 3, 2017

@jkrems thanks for pointing that out, I fixed it.

@eugeneo
Copy link
Contributor Author

eugeneo commented Apr 3, 2017

Copy link
Member

@bnoordhuis bnoordhuis left a 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?


class AgentImpl {
public:
explicit AgentImpl(node::Environment* env);
~AgentImpl() { }
Copy link
Member

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?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Removed.

void WaitForFrontendMessage();
void NotifyMessageReceived();
bool StartIoThread();
static void InspectorWrapConsoleCall(
const v8::FunctionCallbackInfo<Value>& args);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Four space indent.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

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");
Copy link
Member

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.

Copy link
Contributor Author

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

static_cast<void>(node_method.As<Function>()->Call(context,
info.Holder(),
call_args.size(),
call_args.data()));
if (try_catch.HasCaught())
try_catch.ReThrow();
Copy link
Member

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?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Removed.

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"),
Copy link
Member

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.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done.

}

bool InspectorIo::IsStarted() {
return !!platform_;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

platform_ != nullptr?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

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_));
Copy link
Member

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.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

StringView message = std::get<2>(task)->string();
switch (std::get<0>(task)) {
case InspectorAction::kStartSession:
CHECK(!session_delegate_);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

CHECK_EQ

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

parent_env_->inspector_agent()->Connect(session_delegate_.get());
break;
case InspectorAction::kEndSession:
CHECK(session_delegate_);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

CHECK_NE

Copy link
Contributor Author

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
Copy link
Member

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?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I removed outdated comment.

@eugeneo
Copy link
Contributor Author

eugeneo commented Apr 4, 2017

@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?

@bnoordhuis
Copy link
Member

@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.)

@eugeneo
Copy link
Contributor Author

eugeneo commented Apr 4, 2017

Signal handler remains there, it is only the code that sends the signal that was moved back. (I see CI failures, looking into them)

@eugeneo
Copy link
Contributor Author

eugeneo commented Apr 5, 2017

@eugeneo
Copy link
Contributor Author

eugeneo commented Apr 5, 2017

CI: https://ci.nodejs.org/job/node-test-pull-request/7219/ - OS X is passing, even though its status is not properly reported.

@eugeneo eugeneo closed this Apr 6, 2017
@eugeneo eugeneo deleted the inspector-signal branch April 6, 2017 16:12
@eugeneo eugeneo merged commit 7599b0e into nodejs:master Apr 6, 2017
@eugeneo
Copy link
Contributor Author

eugeneo commented Apr 6, 2017

Landed as 7599b0e

@addaleax addaleax removed the diag-agenda Issues and PRs to discuss during the meetings of the diagnostics working group. label May 10, 2017
@jasnell jasnell mentioned this pull request May 11, 2017
@refack refack mentioned this pull request Jun 11, 2017
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
build Issues and PRs related to build files or the CI. c++ Issues and PRs that require attention from people who are familiar with C++. inspector Issues and PRs related to the V8 inspector protocol semver-major PRs that contain breaking changes and should be released in the next major version.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

9 participants