Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 4 additions & 1 deletion src/inspector_agent.cc
Original file line number Diff line number Diff line change
Expand Up @@ -747,7 +747,10 @@ bool Agent::StartIoThread() {

CHECK_NOT_NULL(client_);

io_ = InspectorIo::Start(client_->getThreadHandle(), path_, host_port_);
io_ = InspectorIo::Start(client_->getThreadHandle(),
path_,
host_port_,
debug_options_.inspect_store);
if (io_ == nullptr) {
return false;
}
Expand Down
31 changes: 27 additions & 4 deletions src/inspector_io.cc
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,25 @@ std::string ScriptPath(uv_loop_t* loop, const std::string& script_name) {
return script_path;
}

std::string StorePath(uv_loop_t* loop,
const std::string& inspector_store,
const std::string& id) {
std::string store_path;

if (!inspector_store.empty()) {
store_path = ScriptPath(loop, inspector_store);
if (!store_path.empty()) {
char sep = '/';
#ifdef _WIN32
sep = '\\';
#endif
store_path = store_path + sep + id;
}
}

return store_path;
}

// UUID RFC: https://www.ietf.org/rfc/rfc4122.txt
// Used ver 4 - with numbers
std::string GenerateID() {
Expand Down Expand Up @@ -243,9 +262,10 @@ class InspectorIoDelegate: public node::inspector::SocketServerDelegate {
std::unique_ptr<InspectorIo> InspectorIo::Start(
std::shared_ptr<MainThreadHandle> main_thread,
const std::string& path,
std::shared_ptr<HostPort> host_port) {
std::shared_ptr<HostPort> host_port,
const std::string& inspector_store) {
auto io = std::unique_ptr<InspectorIo>(
new InspectorIo(main_thread, path, host_port));
new InspectorIo(main_thread, path, host_port, inspector_store));
if (io->request_queue_->Expired()) { // Thread is not running
return nullptr;
}
Expand All @@ -254,11 +274,13 @@ std::unique_ptr<InspectorIo> InspectorIo::Start(

InspectorIo::InspectorIo(std::shared_ptr<MainThreadHandle> main_thread,
const std::string& path,
std::shared_ptr<HostPort> host_port)
std::shared_ptr<HostPort> host_port,
const std::string& inspector_store)
: main_thread_(main_thread),
host_port_(host_port),
thread_(),
script_name_(path),
inspector_store_(inspector_store),
id_(GenerateID()) {
Mutex::ScopedLock scoped_lock(thread_start_lock_);
CHECK_EQ(uv_thread_create(&thread_, InspectorIo::ThreadMain, this), 0);
Expand Down Expand Up @@ -294,7 +316,8 @@ void InspectorIo::ThreadMain() {
InspectorSocketServer server(std::move(delegate),
&loop,
host_port_->host(),
host_port_->port());
host_port_->port(),
StorePath(&loop, inspector_store_, id_));
request_queue_ = queue->handle();
// Its lifetime is now that of the server delegate
queue.reset();
Expand Down
7 changes: 5 additions & 2 deletions src/inspector_io.h
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,8 @@ class InspectorIo {
static std::unique_ptr<InspectorIo> Start(
std::shared_ptr<MainThreadHandle> main_thread,
const std::string& path,
std::shared_ptr<HostPort> host_port);
std::shared_ptr<HostPort> host_port,
const std::string& inspector_store);

// Will block till the transport thread shuts down
~InspectorIo();
Expand All @@ -61,7 +62,8 @@ class InspectorIo {
private:
InspectorIo(std::shared_ptr<MainThreadHandle> handle,
const std::string& path,
std::shared_ptr<HostPort> host_port);
std::shared_ptr<HostPort> host_port,
const std::string& inspector_store);

// Wrapper for agent->ThreadMain()
static void ThreadMain(void* agent);
Expand All @@ -85,6 +87,7 @@ class InspectorIo {
Mutex thread_start_lock_;
ConditionVariable thread_start_condition_;
std::string script_name_;
std::string inspector_store_;
// May be accessed from any thread
const std::string id_;
};
Expand Down
45 changes: 37 additions & 8 deletions src/inspector_socket_server.cc
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
#include "inspector_socket_server.h"

#include "node.h"
#include "node_internals.h"
#include "uv.h"
#include "zlib.h"

Expand Down Expand Up @@ -238,11 +239,29 @@ void PrintDebuggerReadyMessage(
fflush(out);
}

void WriteJsonListToFile(const std::string& filename,
std::string json_list_content) {
uv_buf_t data;
data.base = &json_list_content[0];
data.len = json_list_content.length();
WriteFileSync(filename.c_str(), data);
}

void RemoveStoreFileIfNeeded(uv_loop_t* loop, std::string* filename) {
if (!filename->empty()) {
uv_fs_t req;
req.ptr = nullptr;
uv_fs_unlink(loop, &req, filename->c_str(), nullptr);
uv_fs_req_cleanup(&req);
filename->clear();
}
}

InspectorSocketServer::InspectorSocketServer(
std::unique_ptr<SocketServerDelegate> delegate, uv_loop_t* loop,
const std::string& host, int port, FILE* out)
const std::string& host, int port, const std::string& inspector_store, FILE* out)
: loop_(loop), delegate_(std::move(delegate)), host_(host), port_(port),
next_session_id_(0), out_(out) {
inspector_store_(inspector_store), next_session_id_(0), out_(out) {
delegate_->AssignServer(this);
state_ = ServerState::kNew;
}
Expand Down Expand Up @@ -313,6 +332,15 @@ bool InspectorSocketServer::HandleGetRequest(int session_id,
void InspectorSocketServer::SendListResponse(InspectorSocket* socket,
const std::string& host,
SocketSession* session) {
std::string detected_host = host;
if (detected_host.empty()) {
detected_host = FormatHostPort(socket->GetHost(),
session->server_port());
}
SendHttpResponse(socket, GetListResponse(detected_host));
}

std::string InspectorSocketServer::GetListResponse(const std::string& detected_host) {
std::vector<std::map<std::string, std::string>> response;
for (const std::string& id : delegate_->GetTargetIds()) {
response.push_back(std::map<std::string, std::string>());
Expand All @@ -328,11 +356,6 @@ void InspectorSocketServer::SendListResponse(InspectorSocket* socket,
target_map["url"] = delegate_->GetTargetUrl(id);
Escape(&target_map["url"]);

std::string detected_host = host;
if (detected_host.empty()) {
detected_host = FormatHostPort(socket->GetHost(),
session->server_port());
}
std::string formatted_address = FormatAddress(detected_host, id, false);
target_map["devtoolsFrontendUrl"] = GetFrontendURL(false,
formatted_address);
Expand All @@ -341,7 +364,7 @@ void InspectorSocketServer::SendListResponse(InspectorSocket* socket,
formatted_address);
target_map["webSocketDebuggerUrl"] = FormatAddress(detected_host, id, true);
}
SendHttpResponse(socket, MapsToString(response));
return MapsToString(response);
}

std::string InspectorSocketServer::GetFrontendURL(bool is_compat,
Expand Down Expand Up @@ -396,6 +419,10 @@ bool InspectorSocketServer::Start() {
}
delegate_.swap(delegate_holder);
state_ = ServerState::kRunning;
if (!inspector_store_.empty()) {
WriteJsonListToFile(inspector_store_, GetListResponse(
FormatHostPort(host_, port_)));
}
PrintDebuggerReadyMessage(host_, server_sockets_,
delegate_->GetTargetIds(), out_);
return true;
Expand All @@ -409,11 +436,13 @@ void InspectorSocketServer::Stop() {
server_sockets_.clear();
if (done())
delegate_.reset();
RemoveStoreFileIfNeeded(loop_, &inspector_store_);
}

void InspectorSocketServer::TerminateConnections() {
for (const auto& key_value : connected_sessions_)
key_value.second.second->Close();
RemoveStoreFileIfNeeded(loop_, &inspector_store_);
}

bool InspectorSocketServer::TargetExists(const std::string& id) {
Expand Down
3 changes: 3 additions & 0 deletions src/inspector_socket_server.h
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ class InspectorSocketServer {
uv_loop_t* loop,
const std::string& host,
int port,
const std::string& inspector_store,
FILE* out = stderr);
~InspectorSocketServer();

Expand Down Expand Up @@ -79,6 +80,7 @@ class InspectorSocketServer {
private:
void SendListResponse(InspectorSocket* socket, const std::string& host,
SocketSession* session);
std::string GetListResponse(const std::string& host);
std::string GetFrontendURL(bool is_compat,
const std::string &formatted_address);
bool TargetExists(const std::string& id);
Expand All @@ -88,6 +90,7 @@ class InspectorSocketServer {
std::unique_ptr<SocketServerDelegate> delegate_;
const std::string host_;
int port_;
std::string inspector_store_;
std::vector<ServerSocketPtr> server_sockets_;
std::map<int, std::pair<std::string, std::unique_ptr<SocketSession>>>
connected_sessions_;
Expand Down
7 changes: 7 additions & 0 deletions src/node_options.cc
Original file line number Diff line number Diff line change
Expand Up @@ -260,6 +260,13 @@ DebugOptionsParser::DebugOptionsParser() {
Implies("--inspect-brk-node", "--inspect");
AddAlias("--inspect-brk-node=", { "--inspect-port", "--inspect-brk-node" });

AddOption("--inspect-store",
"experimental force inspector to put information available on /json/list "
"to file inside given folder",
&DebugOptions::inspect_store,
kAllowedInEnvironment);
Implies("--inspect-store", "--inspect");

AddOption("--debug-brk", "", &DebugOptions::break_first_line);
Implies("--debug-brk", "--debug");
AddAlias("--debug-brk=", { "--inspect-port", "--debug-brk" });
Expand Down
2 changes: 2 additions & 0 deletions src/node_options.h
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,8 @@ class DebugOptions : public Options {
bool break_first_line = false;
// --inspect-brk-node
bool break_node_first_line = false;
// --inspect-store
std::string inspect_store;

enum { kDefaultInspectorPort = 9229 };

Expand Down
2 changes: 1 addition & 1 deletion test/cctest/test_inspector_socket_server.cc
Original file line number Diff line number Diff line change
Expand Up @@ -358,7 +358,7 @@ ServerHolder::ServerHolder(bool has_targets, uv_loop_t* loop,
std::unique_ptr<TestSocketServerDelegate> delegate(
new TestSocketServerDelegate(this, targets));
server_ = std::make_unique<InspectorSocketServer>(
std::move(delegate), loop, host, port, out);
std::move(delegate), loop, host, port, std::string(), out);
}

static void TestHttpRequest(int port, const std::string& path,
Expand Down