-
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: use final API #9028
inspector: use final API #9028
Conversation
I'll be looking into CI failures - CI UI seems to be down, so this might take some 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.
Rubber stamp LGTM once CI is good.
view.length()); | ||
|
||
// Reserve 1 character for terminator. | ||
std::string result(view.length() * sizeof(UChar) + 1, '\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.
sizeof(UChar)
doesn't look self-evidently correct. I assume it's shorthand for sizeof(*view.characters16())
(which is sizeof(uint16_t)
) but code points >= 0x800 encode to more than two bytes.
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. I changed the sizeof & allowed the code to resize the buffer if need be.
public: | ||
explicit ChannelImpl(AgentImpl* agent): agent_(agent) {} | ||
virtual ~ChannelImpl() {} | ||
private: | ||
void sendProtocolResponse(int callId, const String16& message) override { | ||
void sendProtocolResponse(int callId, | ||
const v8_inspector::StringView& message) override { |
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.
Style nit: can you line break at the (
or line up the second argument?
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 no longer need for a line break here.
const char CONTEXT_NAME[] = "NodeJS Main Context"; | ||
inspector_->contextCreated(v8_inspector::V8ContextInfo(env->context(), 1, | ||
StringView(reinterpret_cast<const uint8_t*>(CONTEXT_NAME), | ||
sizeof(CONTEXT_NAME) - 1))); |
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.
Style nit: can you line up arguments more 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.
I rearranged the code.
size_t len = string_value->Length(); | ||
std::basic_string<uint16_t> buffer(len, '\0'); | ||
string_value->Write(&buffer[0], 0, len); | ||
return StringBuffer::create(StringView(buffer.c_str(), 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.
For my own curiosity, is .c_str()
rather than .data()
necessary here if you also pass 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.
Coding mistake.
if (wait_) { | ||
std::string message(buf->base, read); | ||
if (message.find("\"Runtime.runIfWaitingForDebugger\"") | ||
!= std::string::npos) { |
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 put the operator on the line before?
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
if (AppendMessage(&incoming_message_queue_, frontend_session_id_, message)) { | ||
void AgentImpl::PostIncomingMessage(const char* message, size_t len) { | ||
if (AppendMessage(&incoming_message_queue_, frontend_session_id_, | ||
Utf8ToStringView(message, 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.
Style nit: 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
AppendMessage(&outgoing_message_queue_, session_id, message); | ||
void AgentImpl::Write(int session_id, const StringView& inspector_message) { | ||
AppendMessage(&outgoing_message_queue_, session_id, | ||
StringBuffer::create(inspector_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.
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
std::string tag; | ||
if (message.length() <= sizeof(TAG_CONNECT) || | ||
message.length() <= sizeof(TAG_DISCONNECT)) | ||
tag = StringViewToUtf8(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.
It's not exactly wrong but I'd wrap the body in braces for legibility.
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
@bnoordhuis I addressed your comments, please take another look. CI: https://ci.nodejs.org/job/node-test-pull-request/4506/ Linux ARM failure: exception in Hudson on one bot. |
c133999
to
83c7a88
Compare
@bnoordhuis Please take another look. |
#include "libplatform/libplatform.h" | ||
|
||
#include <unicode/unistr.h> |
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 you're taking a dependency on ICU, then configure should have a --with-intl=none
-> --without-inspector
implication.
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 modified configure
- now disabling either ICU or OpenSSL will also disable inspector.
std::string StringViewToUtf8(const StringView& view) { | ||
if (view.is8Bit()) | ||
return std::string(reinterpret_cast<const char*>(view.characters8()), | ||
view.length()); |
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 and maybe put braces around the block?
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
|
||
const uint16_t* source = view.characters16(); | ||
std::string result(view.length() * sizeof(*source), '\0'); | ||
UnicodeString utf16(reinterpret_cast<const UChar*>(source), view.length()); |
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 reinterpret_cast necessary? If for some reason UChar != uint16_t, then this line should arguably fail to compile instead of silently doing the wrong thing.
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.
Windows uses some different type for UChar (not clear from compiler messages - but probably wchar).
CheckedArrayByteSink sink(&result[0], result.length()); | ||
utf16.toUTF8(sink); | ||
result.resize(sink.NumberOfBytesAppended()); | ||
done = !sink.Overflowed(); |
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.
Does that mean this function may return partial strings? How bad is that?
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 sure what you mean here. This code makes sure string has enough capacity.
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.
Correct me if I'm wrong but CheckedArrayByteSink is instantiated every time with the same arguments in this loop so logically sink.Overflowed()
is either always true or always false. That means this loop either isn't (i.e., it's not a loop because it exits after the first iteration) or it's an infinite loop.
std::unique_ptr<StringBuffer> Utf8ToStringView(const char* source, | ||
size_t length) { | ||
UnicodeString utf16 = UnicodeString::fromUTF8(StringPiece(source, length)); | ||
StringView view(reinterpret_cast<const uint16_t*>(utf16.getBuffer()), |
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.
Same question as on line 212: is the reinterpret_cast necessary?
@@ -350,8 +373,10 @@ class V8NodeInspector : public v8_inspector::V8InspectorClient { | |||
terminated_(false), | |||
running_nested_loop_(false), | |||
inspector_(V8Inspector::create(env->isolate(), this)) { | |||
inspector_->contextCreated( | |||
v8_inspector::V8ContextInfo(env->context(), 1, "NodeJS Main Context")); | |||
const uint8_t CONTEXT_NAME[] = "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.
While you're here: s/NodeJS/Node.js/
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! Done.
String16::fromInteger(script_id) == stack_trace->topScriptId()) { | ||
v8::Local<v8::StackTrace> stack_trace = message->GetStackTrace(); | ||
|
||
if (!stack_trace.IsEmpty() && stack_trace->GetFrameCount() && |
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 put each clause on its own line?
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
StringView message = pair.second->string(); | ||
std::string tag; | ||
if (message.length() <= sizeof(TAG_CONNECT) || | ||
message.length() <= sizeof(TAG_DISCONNECT)) { |
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 ==
?
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
@bnoordhuis Thank you for the review. I've updated the code, please take another look. |
@bnoordhuis Please, take another look. |
def configure_inspector(o): | ||
o['variables']['v8_inspector'] = b(not options.without_inspector | ||
and o['variables']['v8_enable_i18n_support'] | ||
and o['variables']['node_use_openssl'] == 'true') |
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 use options
here? That way it won't depend on the order in which the configure_intl an/configure_openssl/configure_inspector functions are executed.
Also, please keep lines <= 80 columns.
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.
CheckedArrayByteSink sink(&result[0], result.length()); | ||
utf16.toUTF8(sink); | ||
result.resize(sink.NumberOfBytesAppended()); | ||
done = !sink.Overflowed(); |
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.
Correct me if I'm wrong but CheckedArrayByteSink is instantiated every time with the same arguments in this loop so logically sink.Overflowed()
is either always true or always false. That means this loop either isn't (i.e., it's not a loop because it exits after the first iteration) or it's an infinite loop.
v8::Local<v8::StackTrace> stack_trace = message->GetStackTrace(); | ||
|
||
if (!stack_trace.IsEmpty() && | ||
stack_trace->GetFrameCount() && |
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 stack_trace->GetFrameCount() > 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.
Done
@bnoordhuis thank you for the review, I uploaded a new version - please take a look. GitHub Ui is not allowing me to answer this comment (does not show the reply entry field for some reason):
The code was relying on string length, that was updated in the loop. I changed the code to make it more obvious. |
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 with some final comments. I think I understand how sinking works now.
def configure_inspector(o): | ||
disable_inspector = (options.without_inspector | ||
or options.with_intl in (None, 'none') | ||
or options.without_ssl) |
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 realize this is nitpicking but since we put operators at the end of the line everywhere else can you do it here too?
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
@@ -1250,6 +1255,8 @@ configure_v8(output) | |||
configure_openssl(output) | |||
configure_intl(output) | |||
configure_static(output) | |||
# should come after configure_openssl and configure_intl |
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 comment is no longer 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.
Done.
const uint16_t* source = view.characters16(); | ||
size_t result_length = view.length() * sizeof(*source); | ||
std::string result(result_length, '\0'); | ||
UnicodeString utf16(reinterpret_cast<const UChar*>(source), view.length()); |
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 the reinterpret_cast is non-optional here, can you at least add a static_assert that checks the pointed-to types are of the same size? See #9280 for an example of what I mean.
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, I addressed the comments and submitted to CI: https://ci.nodejs.org/job/node-test-pull-request/4674/ |
Landed as 8f00455 |
This implementation switches to V8 inspector from the V8 repository. The new inspector integration is now using final APIs and exposes a stable wire protocol, removing the need for pointing the users to specific devtools version. PR-URL: #9028 Reviewed-By: James M Snell <jasnell@gmail.com> Reviewed-By: Ben Noordhuis <info@bnoordhuis.nl>
hey @eugeneo this seemed to break configure on v6.x Would you be willing to manually backport |
Let me take a look. On Fri, Nov 18, 2016 at 1:50 PM Myles Borins notifications@github.com
|
@thealphanerd backporting this inspector to V8 5.1 is a significant effort. Can we opt out of it? I am not familiar with the process. |
@eugeneo we absolutely can opt out. Considering that v6.x has over 2 years of support left I'd like to get something as up to date as possible though. At what point will we no longer be able to update the inspector that we ship in v6? |
I guess this is the point inspector stops getting updated... The new On Fri, Nov 18, 2016 at 4:08 PM Myles Borins notifications@github.com
|
nodejs#9028 made Node.js use the V8 inspector bundled with the deps/v8 and removed the third party dependency. We can safely omit the non-existent license file.
Checklist
make -j8 test
(UNIX), orvcbuild test nosign
(Windows) passesAffected core subsystem(s)
deps: new version of the v8_inspector dependency
inspector: updated the code to use the new API
Description of change
This implementation switches to V8 inspector from the V8 repository. The
new inspector integration is now using final APIs and exposes a stable
wire protocol, removing the need for pointing the users to specific
devtools version.
CC: @ofrobots