summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEugene Ostroukhov <eostroukhov@chromium.org>2016-06-09 18:00:08 -0700
committerAli Ijaz Sheikh <ofrobots@google.com>2016-09-02 13:47:10 -0700
commit609a265aebd89c93e5499363cc2b0bef9e24008b (patch)
tree334c2b762bfe1bcc50b921454229fdbed6bc7b1e
parent9826a79f54f83cf67c258ffbe34bfca121394f35 (diff)
downloadandroid-node-v8-609a265aebd89c93e5499363cc2b0bef9e24008b.tar.gz
android-node-v8-609a265aebd89c93e5499363cc2b0bef9e24008b.tar.bz2
android-node-v8-609a265aebd89c93e5499363cc2b0bef9e24008b.zip
inspector: use script name for target title
Changes inspector integration to use Node.js script file name as target title (reported in JSON and shown in developer tools UIs). It will also report file:// URL for the script as some tools seem to use that field to open the script in the editor. PR-URL: https://github.com/nodejs/node/pull/8243 Reviewed-By: bnoordhuis - Ben Noordhuis <info@bnoordhuis.nl>
-rw-r--r--src/inspector_agent.cc124
-rw-r--r--src/inspector_agent.h2
-rw-r--r--src/node.cc20
3 files changed, 101 insertions, 45 deletions
diff --git a/src/inspector_agent.cc b/src/inspector_agent.cc
index 32899600ac..d1c12d6e5a 100644
--- a/src/inspector_agent.cc
+++ b/src/inspector_agent.cc
@@ -51,7 +51,14 @@ void PrintDebuggerReadyMessage(int port) {
}
bool AcceptsConnection(inspector_socket_t* socket, const std::string& path) {
- return 0 == path.compare(0, sizeof(DEVTOOLS_PATH) - 1, DEVTOOLS_PATH);
+ return StringEqualNoCaseN(path.c_str(), DEVTOOLS_PATH,
+ sizeof(DEVTOOLS_PATH) - 1);
+}
+
+void Escape(std::string* string) {
+ for (char& c : *string) {
+ c = (c == '\"' || c == '\\') ? '_' : c;
+ }
}
void DisposeInspector(inspector_socket_t* socket, int status) {
@@ -98,7 +105,21 @@ void SendVersionResponse(inspector_socket_t* socket) {
SendHttpResponse(socket, buffer, len);
}
-void SendTargentsListResponse(inspector_socket_t* socket, int port) {
+std::string GetProcessTitle() {
+ // uv_get_process_title will trim the title if it is too long.
+ char title[2048];
+ int err = uv_get_process_title(title, sizeof(title));
+ if (err == 0) {
+ return title;
+ } else {
+ return "Node.js";
+ }
+}
+
+void SendTargentsListResponse(inspector_socket_t* socket,
+ const std::string& script_name_,
+ const std::string& script_path_,
+ int port) {
const char LIST_RESPONSE_TEMPLATE[] =
"[ {"
" \"description\": \"node.js instance\","
@@ -110,45 +131,60 @@ void SendTargentsListResponse(inspector_socket_t* socket, int port) {
" \"id\": \"%d\","
" \"title\": \"%s\","
" \"type\": \"node\","
+ " \"url\": \"%s\","
" \"webSocketDebuggerUrl\": \"ws://localhost:%d%s\""
"} ]";
- char buffer[sizeof(LIST_RESPONSE_TEMPLATE) + 4096];
- char title[2048]; // uv_get_process_title trims the title if too long
- int err = uv_get_process_title(title, sizeof(title));
- if (err != 0) {
- snprintf(title, sizeof(title), "Node.js");
- }
- char* c = title;
- while (*c != '\0') {
- if (*c < ' ' || *c == '\"') {
- *c = '_';
- }
- c++;
+ std::string title = script_name_.empty() ? GetProcessTitle() : script_name_;
+
+ // This attribute value is a "best effort" URL that is passed as a JSON
+ // string. It is not guaranteed to resolve to a valid resource.
+ std::string url = "file://" + script_path_;
+
+ Escape(&title);
+ Escape(&url);
+
+ const int NUMERIC_FIELDS_LENGTH = 5 * 2 + 20; // 2 x port + 1 x pid (64 bit)
+
+ int buf_len = sizeof(LIST_RESPONSE_TEMPLATE) + sizeof(DEVTOOLS_HASH) +
+ sizeof(DEVTOOLS_PATH) * 2 + title.length() +
+ url.length() + NUMERIC_FIELDS_LENGTH;
+ std::string buffer(buf_len, '\0');
+
+ int len = snprintf(&buffer[0], buf_len, LIST_RESPONSE_TEMPLATE,
+ DEVTOOLS_HASH, port, DEVTOOLS_PATH, getpid(),
+ title.c_str(), url.c_str(),
+ port, DEVTOOLS_PATH);
+ buffer.resize(len);
+ ASSERT_LT(len, buf_len); // Buffer should be big enough!
+ SendHttpResponse(socket, buffer.data(), len);
+}
+
+const char* match_path_segment(const char* path, const char* expected) {
+ size_t len = strlen(expected);
+ if (StringEqualNoCaseN(path, expected, len)) {
+ if (path[len] == '/') return path + len + 1;
+ if (path[len] == '\0') return path + len;
}
- size_t len = snprintf(buffer, sizeof(buffer), LIST_RESPONSE_TEMPLATE,
- DEVTOOLS_HASH, port, DEVTOOLS_PATH, getpid(),
- title, port, DEVTOOLS_PATH);
- ASSERT_LT(len, sizeof(buffer));
- SendHttpResponse(socket, buffer, len);
+ return nullptr;
}
-bool RespondToGet(inspector_socket_t* socket, const std::string& path,
+bool RespondToGet(inspector_socket_t* socket, const std::string& script_name_,
+ const std::string& script_path_, const std::string& path,
int port) {
- const char PATH[] = "/json";
- const char PATH_LIST[] = "/json/list";
- const char PATH_VERSION[] = "/json/version";
- const char PATH_ACTIVATE[] = "/json/activate/";
- if (0 == path.compare(0, sizeof(PATH_VERSION) - 1, PATH_VERSION)) {
+ const char* command = match_path_segment(path.c_str(), "/json");
+ if (command == nullptr)
+ return false;
+
+ if (match_path_segment(command, "list") || command[0] == '\0') {
+ SendTargentsListResponse(socket, script_name_, script_path_, port);
+ } else if (match_path_segment(command, "version")) {
SendVersionResponse(socket);
- } else if (0 == path.compare(0, sizeof(PATH_LIST) - 1, PATH_LIST) ||
- 0 == path.compare(0, sizeof(PATH) - 1, PATH)) {
- SendTargentsListResponse(socket, port);
- } else if (0 == path.compare(0, sizeof(PATH_ACTIVATE) - 1, PATH_ACTIVATE) &&
- atoi(path.substr(sizeof(PATH_ACTIVATE) - 1).c_str()) == getpid()) {
+ } else {
+ const char* pid = match_path_segment(command, "activate");
+ if (pid == nullptr || atoi(pid) != getpid())
+ return false;
const char TARGET_ACTIVATED[] = "Target activated";
SendHttpResponse(socket, TARGET_ACTIVATED, sizeof(TARGET_ACTIVATED) - 1);
- } else {
- return false;
}
return true;
}
@@ -166,7 +202,7 @@ class AgentImpl {
~AgentImpl();
// Start the inspector agent thread
- bool Start(v8::Platform* platform, int port, bool wait);
+ bool Start(v8::Platform* platform, const char* path, int port, bool wait);
// Stop the inspector agent
void Stop();
@@ -227,6 +263,9 @@ class AgentImpl {
int frontend_session_id_;
int backend_session_id_;
+ std::string script_name_;
+ std::string script_path_;
+
friend class ChannelImpl;
friend class DispatchOnInspectorBackendTask;
friend class SetConnectedTask;
@@ -442,10 +481,13 @@ void InspectorWrapConsoleCall(const v8::FunctionCallbackInfo<v8::Value>& args) {
array).ToLocalChecked());
}
-bool AgentImpl::Start(v8::Platform* platform, int port, bool wait) {
+bool AgentImpl::Start(v8::Platform* platform, const char* path,
+ int port, bool wait) {
auto env = parent_env_;
inspector_ = new V8NodeInspector(this, env, platform);
platform_ = platform;
+ if (path != nullptr)
+ script_name_ = path;
InstallInspectorOnProcess();
@@ -566,7 +608,8 @@ bool AgentImpl::OnInspectorHandshakeIO(inspector_socket_t* socket,
AgentImpl* agent = static_cast<AgentImpl*>(socket->data);
switch (state) {
case kInspectorHandshakeHttpGet:
- return RespondToGet(socket, path, agent->port_);
+ return RespondToGet(socket, agent->script_name_, agent->script_path_, path,
+ agent->port_);
case kInspectorHandshakeUpgrading:
return AcceptsConnection(socket, path);
case kInspectorHandshakeUpgraded:
@@ -635,6 +678,12 @@ void AgentImpl::WorkerRunIO() {
err = uv_async_init(&child_loop_, &io_thread_req_, AgentImpl::WriteCbIO);
CHECK_EQ(err, 0);
io_thread_req_.data = this;
+ if (!script_name_.empty()) {
+ uv_fs_t req;
+ if (0 == uv_fs_realpath(&child_loop_, &req, script_name_.c_str(), nullptr))
+ script_path_ = std::string(reinterpret_cast<char*>(req.ptr));
+ uv_fs_req_cleanup(&req);
+ }
uv_tcp_init(&child_loop_, &server);
uv_ip4_addr("0.0.0.0", port_, &addr);
server.data = this;
@@ -752,8 +801,9 @@ Agent::~Agent() {
delete impl;
}
-bool Agent::Start(v8::Platform* platform, int port, bool wait) {
- return impl->Start(platform, port, wait);
+bool Agent::Start(v8::Platform* platform, const char* path,
+ int port, bool wait) {
+ return impl->Start(platform, path, port, wait);
}
void Agent::Stop() {
diff --git a/src/inspector_agent.h b/src/inspector_agent.h
index 43433fdc6e..3607cffba5 100644
--- a/src/inspector_agent.h
+++ b/src/inspector_agent.h
@@ -29,7 +29,7 @@ class Agent {
~Agent();
// Start the inspector agent thread
- bool Start(v8::Platform* platform, int port, bool wait);
+ bool Start(v8::Platform* platform, const char* path, int port, bool wait);
// Stop the inspector agent
void Stop();
diff --git a/src/node.cc b/src/node.cc
index 9dc66f907f..d048bd03c8 100644
--- a/src/node.cc
+++ b/src/node.cc
@@ -207,9 +207,10 @@ static struct {
platform_ = nullptr;
}
- bool StartInspector(Environment *env, int port, bool wait) {
+ bool StartInspector(Environment *env, const char* script_path,
+ int port, bool wait) {
#if HAVE_INSPECTOR
- return env->inspector_agent()->Start(platform_, port, wait);
+ return env->inspector_agent()->Start(platform_, script_path, port, wait);
#else
return true;
#endif // HAVE_INSPECTOR
@@ -220,7 +221,8 @@ static struct {
void Initialize(int thread_pool_size) {}
void PumpMessageLoop(Isolate* isolate) {}
void Dispose() {}
- bool StartInspector(Environment *env, int port, bool wait) {
+ bool StartInspector(Environment *env, const char* script_path,
+ int port, bool wait) {
env->ThrowError("Node compiled with NODE_USE_V8_PLATFORM=0");
return false; // make compiler happy
}
@@ -3766,10 +3768,11 @@ static void DispatchMessagesDebugAgentCallback(Environment* env) {
}
-static void StartDebug(Environment* env, bool wait) {
+static void StartDebug(Environment* env, const char* path, bool wait) {
CHECK(!debugger_running);
if (use_inspector) {
- debugger_running = v8_platform.StartInspector(env, inspector_port, wait);
+ debugger_running = v8_platform.StartInspector(env, path, inspector_port,
+ wait);
} else {
env->debugger_agent()->set_dispatch_handler(
DispatchMessagesDebugAgentCallback);
@@ -3831,7 +3834,7 @@ static void DispatchDebugMessagesAsyncCallback(uv_async_t* handle) {
Environment* env = Environment::GetCurrent(isolate);
Context::Scope context_scope(env->context());
- StartDebug(env, false);
+ StartDebug(env, nullptr, false);
EnableDebug(env);
}
@@ -4396,7 +4399,10 @@ static void StartNodeInstance(void* arg) {
// Start debug agent when argv has --debug
if (instance_data->use_debug_agent()) {
- StartDebug(&env, debug_wait_connect);
+ const char* path = instance_data->argc() > 1
+ ? instance_data->argv()[1]
+ : nullptr;
+ StartDebug(&env, path, debug_wait_connect);
if (use_inspector && !debugger_running) {
exit(12);
}