-
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: fix process._debugEnd() for inspector #12777
Conversation
This needs a rebase, and what is the nature of |
I need it |
@TimothyGu this is not a new API - it was working with the old debugger. I did not know about this API until #12559 - so now I am fixing the issues. There are some genuine bugs that this API uncovered - those really need to be fixed. |
(I am looking into CI failures, looks like some new bugs were introduced) |
While I agree that we should at the minimum make the function working again under Inspector, I think we should consider making it fully public (document it and rename it to |
As this PR is not introducing/altering existing API, I would like to proceed with it in its current form (well, after I figure out how to fix intermittent issues :) ) Feel free to open a separate issue about the public API. I expect a lot of discussions there... |
All issues seem to be resolved. CI run: https://ci.nodejs.org/job/node-test-pull-request/7810/ |
src/inspector_agent.cc
Outdated
static_cast<Agent*>(handle->data)->StartIoThread(false); | ||
} | ||
|
||
void StartIoCallback(Isolate* isolate, void* agent) { |
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 is there an Isolate* isolate
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.
That's "InterruptCallback" typedef - https://github.com/nodejs/node/blob/master/deps/v8/include/v8.h#L5994
test/inspector/inspector-helper.js
Outdated
}).on('close', () => assert(this.expectClose_, 'Socket closed prematurely')); | ||
}).on('close', () => { | ||
assert(this.expectClose_, 'Socket closed prematurely'); | ||
this.closeCallback_ && this.closeCallback_(); |
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'm just trying to grok the code...
Who will set this.closeCallback_
?
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.
This test "framework" is really messy - I am trying to clean it up, but have not yet achieved the stage to create a pull request...
Currently the callback is set in sendCommandsAndExpectClose, e.g. when there's a need to handle connection closing and not just assert.
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 need another run through the code, it's been 3 years since I was there this...
Could you summarize the change in 3-4 sentences
src/inspector_io.cc
Outdated
@@ -89,13 +90,18 @@ void HandleSyncCloseCb(uv_handle_t* handle) { | |||
int CloseAsyncAndLoop(uv_async_t* async) { | |||
bool is_closed = false; | |||
async->data = &is_closed; | |||
uv_close(reinterpret_cast<uv_handle_t*>(async), HandleSyncCloseCb); |
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.
Help me here.
What happened to HandleSyncCloseCb
?
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.
Great catch! Thank you. I removed it by mistake together with debug statements when debugging the intermittent test failures :/
If I get the jist, we need to stop the |
test/inspector/test-on-off.js
Outdated
]).expectShutDown(0); | ||
} | ||
|
||
const script = 'process._debugEnd();' + |
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 a new functionality? detaching and reattaching?
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.
It is not a new functionality. Both APIs were already there (_debugProcess is meant to attach to other processes - but looks like it can be made to work on self just fine).
_debugProcess sends a signal on Posix systems. It is the function used to attach to processes that were not started with --inspect.
__debugEnd stops the agent. Looks like it had been there for ages, personally I am not sure why it is needed :)
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.
personally I am not sure why it is needed :)
Which one _debugProcess
, I assume?
Or am I missing something?
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.
_debugProcess is useful, frontends use it to attach to running instances.
__debugEnd, on the other hand, can only be called on self so the application needs to explicitly "want" to make itself undebuggable. I am not sure why...
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 the complex script
?
Run once with just _debugEnd
since this is the change.
We want to know if just this is failing, now it could fail on any of the two.
You can do a second run with this script.
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, but, but, that is what you're fixing.... 😕
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're just doing it for @823639792?
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.
- Complex script - I noticed that starting inspector after it had been stopped crashed the Node, so some test coverage definitely helps.
- _debugEnd - the goal here is to ensure that inspector can cleanly stop. There were some genuine bugs and race conditions that need to be addressed.
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.
Sure, so do two tests...
@refack Right. Initial inspector prototype was a fork of the debug_agent.cc - so it compiled but I did not pay much attention to Stop (e.g. the assumption was it is only called during the shutdown). |
@eugeneo can you rename this PR to |
@refack I updated commit message and PR title. I also added a test case that only stops the inspector. |
harness.expectShutDown(42); | ||
} | ||
|
||
helper.startNodeForInspectorTest(testStop, '--inspect', |
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.
shouldn't it be '--inspect-brk'
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.
No. That test does not wait for the session. The tests cover shutting down the inspector with or without the session.
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.
Just wondering because of the failures....
Do You have any idea why is fails only on aix & feeBSD? |
|
||
const script = 'process._debugEnd();' + | ||
'process._debugProcess(process.pid);' + | ||
'process._debugEnd();' + |
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.
it this line new?
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 testing if this fixes the failures. Server is starting (and printing out the message) on a background thread so I suspect the reason test fails is because process shuts down too fast. _debugEnd synchronizes the threads.
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.
That was my guess...
@refack looks like process exits before the stdio buffers are flushed - adding console.log fixes the failure (this is BSD stress test - https://ci.nodejs.org/job/node-stress-single-test/1192/nodes=freebsd10-64/) I uploaded updated test. |
Still failing on AIX: https://ci.nodejs.org/job/node-stress-single-test/1193/nodes=aix61-ppc64/console, investigating... |
Looks like the only way to fix the test once and for all would be to add the delay - which I won't do as it increases duration of the test run for little gain. This is AIX stress test with arbitrary delay added: https://ci.nodejs.org/job/node-stress-single-test/nodes=aix61-ppc64/1198/ What I uploaded here is to stop checking for the inspector startup message. If the inspector actually fails to start there will be crash so checking the process exit code should be enough. |
Sounds reasonable. There's an explicit test for that in #11207 |
CI all green: https://ci.nodejs.org/job/node-test-pull-request/7903/ |
@refack, @sam-github please let me know if I have not addressed any of your comments - I'm a bit confused with the GitHub UI... CI is green: https://ci.nodejs.org/job/node-test-pull-request/7974/ |
@eugeneo you didn't respond to #12777 (comment), and yes, the new review UI has some problems. |
True, these are the legacy APIs. The closest way to (re)start debugger is process._debugProcess(process.pid). It uses IPC (signals on *nix and debug API on Windows) but seems to work well if called on self.
API design is out of scope for this PR. #12263 also deals with the JS bindings for the session management - but it will be trivial to add some nicer start/stop APIs to inspector module, if need be. |
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.
A couple small nits, but basically LGTM
src/inspector_agent.cc
Outdated
io_->Stop(); | ||
io_.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.
I have trouble understanding Node core C++ conventions, does it makes sense that Stop()
is upper case, and reset()
is lower case @addaleax ?
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.
Node core is usually more UpperSnakeCase() for methods, but reset()
doesn’t come from Node core. I think this is okay.
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.
Stop is InspectorIo::Stop which is Node.
reset is std::unique_ptr::reset which is STL...
src/inspector_io.cc
Outdated
@@ -96,6 +97,12 @@ int CloseAsyncAndLoop(uv_async_t* async) { | |||
return uv_loop_close(async->loop); | |||
} | |||
|
|||
void ReleasePairOnAsyncClose(uv_handle_t* async) { | |||
AsyncAndAgent* pair = node::ContainerOf(&AsyncAndAgent::first, | |||
reinterpret_cast<uv_async_t*>(async)); |
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 think this line is supposed to be indented to line up after the parentheses (that you have to do this after changing the name of the type in the line before is why I don't like this style, but its the node style)
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_io.cc
Outdated
DispatchMessages(); | ||
} | ||
return true; | ||
} | ||
|
||
void InspectorIo::Stop() { | ||
CHECK(state_ == State::kAccepting || state_ == State::kConnected); |
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.
+1
LGTM, @refack PTAL |
@refack - gentle ping, please take another look :) |
@refack PTAL |
Sorry, for some reason your pings got filtered out from my email list. |
@eugeneo noticed a typo in the commit 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.
LGTM, pending CI and commit message nits.
Failures displayed in the PR may not be accurate, check @refack 's build on ci (I started a build 30 seconds after, and cancelled it, so I think the cancelled status is what is showing up in the github view). |
PS |
I forgot to update the commit message to include PR-URL and Reviewed by. Does this justify revert? |
Force push, and apologize in the IRC (that's the procedure) |
Done, thanks! Will push the proper commit. |
Landed as 5c26378 |
|
This change ensures that the WebSocket server can be stopped (and restarted if needed) buy calling process._debugEnd. PR-URL: #12777 Fixes: #12559 Reviewed-By: Sam Roberts <[email protected]> Reviewed-By: Refael Ackermann <[email protected]>
@sam-github it actually gets freed in ReleasePairOnAsyncClose that is called asynchronously after the request is closed from InspectorIo::~InspectorIo |
This change ensures that the WebSocket server can be stopped (and restarted if needed) buy calling process._debugEnd. PR-URL: #12777 Fixes: #12559 Reviewed-By: Sam Roberts <[email protected]> Reviewed-By: Refael Ackermann <[email protected]>
This change ensures that the WebSocket server can be stopped
(and restarted if needed) buy calling process._debugEnd.
Fixes: #12559
Checklist
make -j4 test
(UNIX), orvcbuild test
(Windows) passesAffected core subsystem(s)
inspector: fixes around WS server stopping and (re)starting.