src: remove debugger dead code
PR-URL: https://github.com/nodejs/node/pull/12621 Reviewed-By: Colin Ihrig <cjihrig@gmail.com> Reviewed-By: Ben Noordhuis <info@bnoordhuis.nl> Reviewed-By: Gibson Fahnestock <gibfahn@gmail.com> Reviewed-By: James M Snell <jasnell@gmail.com> Reviewed-By: Refael Ackermann <refack@gmail.com> Reviewed-By: Anna Henningsen <anna@addaleax.net>
This commit is contained in:
parent
d5db4d25dc
commit
719247ff95
3
node.gyp
3
node.gyp
@ -159,7 +159,6 @@
|
|||||||
'src/cares_wrap.cc',
|
'src/cares_wrap.cc',
|
||||||
'src/connection_wrap.cc',
|
'src/connection_wrap.cc',
|
||||||
'src/connect_wrap.cc',
|
'src/connect_wrap.cc',
|
||||||
'src/debug-agent.cc',
|
|
||||||
'src/env.cc',
|
'src/env.cc',
|
||||||
'src/fs_event_wrap.cc',
|
'src/fs_event_wrap.cc',
|
||||||
'src/handle_wrap.cc',
|
'src/handle_wrap.cc',
|
||||||
@ -211,7 +210,6 @@
|
|||||||
'src/base-object-inl.h',
|
'src/base-object-inl.h',
|
||||||
'src/connection_wrap.h',
|
'src/connection_wrap.h',
|
||||||
'src/connect_wrap.h',
|
'src/connect_wrap.h',
|
||||||
'src/debug-agent.h',
|
|
||||||
'src/env.h',
|
'src/env.h',
|
||||||
'src/env-inl.h',
|
'src/env-inl.h',
|
||||||
'src/handle_wrap.h',
|
'src/handle_wrap.h',
|
||||||
@ -612,7 +610,6 @@
|
|||||||
'<(OBJ_PATH)/node_buffer.<(OBJ_SUFFIX)',
|
'<(OBJ_PATH)/node_buffer.<(OBJ_SUFFIX)',
|
||||||
'<(OBJ_PATH)/node_i18n.<(OBJ_SUFFIX)',
|
'<(OBJ_PATH)/node_i18n.<(OBJ_SUFFIX)',
|
||||||
'<(OBJ_PATH)/node_url.<(OBJ_SUFFIX)',
|
'<(OBJ_PATH)/node_url.<(OBJ_SUFFIX)',
|
||||||
'<(OBJ_PATH)/debug-agent.<(OBJ_SUFFIX)',
|
|
||||||
'<(OBJ_PATH)/util.<(OBJ_SUFFIX)',
|
'<(OBJ_PATH)/util.<(OBJ_SUFFIX)',
|
||||||
'<(OBJ_PATH)/string_bytes.<(OBJ_SUFFIX)',
|
'<(OBJ_PATH)/string_bytes.<(OBJ_SUFFIX)',
|
||||||
'<(OBJ_PATH)/string_search.<(OBJ_SUFFIX)',
|
'<(OBJ_PATH)/string_search.<(OBJ_SUFFIX)',
|
||||||
|
@ -1,332 +0,0 @@
|
|||||||
// Copyright Fedor Indutny and other Node contributors.
|
|
||||||
//
|
|
||||||
// Permission is hereby granted, free of charge, to any person obtaining a
|
|
||||||
// copy of this software and associated documentation files (the
|
|
||||||
// "Software"), to deal in the Software without restriction, including
|
|
||||||
// without limitation the rights to use, copy, modify, merge, publish,
|
|
||||||
// distribute, sublicense, and/or sell copies of the Software, and to permit
|
|
||||||
// persons to whom the Software is furnished to do so, subject to the
|
|
||||||
// following conditions:
|
|
||||||
//
|
|
||||||
// The above copyright notice and this permission notice shall be included
|
|
||||||
// in all copies or substantial portions of the Software.
|
|
||||||
//
|
|
||||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
|
||||||
// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
|
||||||
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
|
|
||||||
// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
|
|
||||||
// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
|
|
||||||
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
|
|
||||||
// USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
||||||
|
|
||||||
#include "debug-agent.h"
|
|
||||||
|
|
||||||
#include "node.h"
|
|
||||||
#include "node_internals.h" // arraysize
|
|
||||||
#include "env.h"
|
|
||||||
#include "env-inl.h"
|
|
||||||
#include "v8.h"
|
|
||||||
#include "v8-debug.h"
|
|
||||||
#include "util.h"
|
|
||||||
#include "util-inl.h"
|
|
||||||
|
|
||||||
#include <string.h>
|
|
||||||
|
|
||||||
namespace node {
|
|
||||||
namespace debugger {
|
|
||||||
|
|
||||||
using v8::Context;
|
|
||||||
using v8::FunctionCallbackInfo;
|
|
||||||
using v8::FunctionTemplate;
|
|
||||||
using v8::HandleScope;
|
|
||||||
using v8::Integer;
|
|
||||||
using v8::Isolate;
|
|
||||||
using v8::Local;
|
|
||||||
using v8::Locker;
|
|
||||||
using v8::NewStringType;
|
|
||||||
using v8::Object;
|
|
||||||
using v8::String;
|
|
||||||
using v8::Value;
|
|
||||||
|
|
||||||
|
|
||||||
Agent::Agent(Environment* env) : state_(kNone),
|
|
||||||
wait_(false),
|
|
||||||
parent_env_(env),
|
|
||||||
child_env_(nullptr),
|
|
||||||
dispatch_handler_(nullptr) {
|
|
||||||
CHECK_EQ(0, uv_sem_init(&start_sem_, 0));
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
Agent::~Agent() {
|
|
||||||
Stop();
|
|
||||||
|
|
||||||
uv_sem_destroy(&start_sem_);
|
|
||||||
|
|
||||||
while (AgentMessage* msg = messages_.PopFront())
|
|
||||||
delete msg;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
bool Agent::Start(const DebugOptions& options) {
|
|
||||||
int err;
|
|
||||||
|
|
||||||
if (state_ == kRunning)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
err = uv_loop_init(&child_loop_);
|
|
||||||
if (err != 0)
|
|
||||||
goto loop_init_failed;
|
|
||||||
|
|
||||||
// Interruption signal handler
|
|
||||||
err = uv_async_init(&child_loop_, &child_signal_, ChildSignalCb);
|
|
||||||
if (err != 0)
|
|
||||||
goto async_init_failed;
|
|
||||||
uv_unref(reinterpret_cast<uv_handle_t*>(&child_signal_));
|
|
||||||
|
|
||||||
options_ = options;
|
|
||||||
wait_ = options_.wait_for_connect();
|
|
||||||
|
|
||||||
err = uv_thread_create(&thread_,
|
|
||||||
reinterpret_cast<uv_thread_cb>(ThreadCb),
|
|
||||||
this);
|
|
||||||
if (err != 0)
|
|
||||||
goto thread_create_failed;
|
|
||||||
|
|
||||||
uv_sem_wait(&start_sem_);
|
|
||||||
|
|
||||||
state_ = kRunning;
|
|
||||||
|
|
||||||
return true;
|
|
||||||
|
|
||||||
thread_create_failed:
|
|
||||||
uv_close(reinterpret_cast<uv_handle_t*>(&child_signal_), nullptr);
|
|
||||||
|
|
||||||
async_init_failed:
|
|
||||||
err = uv_loop_close(&child_loop_);
|
|
||||||
CHECK_EQ(err, 0);
|
|
||||||
|
|
||||||
loop_init_failed:
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void Agent::Enable() {
|
|
||||||
v8::Debug::SetMessageHandler(parent_env()->isolate(), MessageHandler);
|
|
||||||
|
|
||||||
// Assign environment to the debugger's context
|
|
||||||
// NOTE: The debugger context is created after `SetMessageHandler()` call
|
|
||||||
auto debug_context = v8::Debug::GetDebugContext(parent_env()->isolate());
|
|
||||||
parent_env()->AssignToContext(debug_context);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void Agent::Stop() {
|
|
||||||
int err;
|
|
||||||
|
|
||||||
if (state_ != kRunning) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
v8::Debug::SetMessageHandler(parent_env()->isolate(), nullptr);
|
|
||||||
|
|
||||||
// Send empty message to terminate things
|
|
||||||
EnqueueMessage(new AgentMessage(nullptr, 0));
|
|
||||||
|
|
||||||
// Signal worker thread to make it stop
|
|
||||||
err = uv_async_send(&child_signal_);
|
|
||||||
CHECK_EQ(err, 0);
|
|
||||||
|
|
||||||
err = uv_thread_join(&thread_);
|
|
||||||
CHECK_EQ(err, 0);
|
|
||||||
|
|
||||||
uv_close(reinterpret_cast<uv_handle_t*>(&child_signal_), nullptr);
|
|
||||||
uv_run(&child_loop_, UV_RUN_NOWAIT);
|
|
||||||
|
|
||||||
err = uv_loop_close(&child_loop_);
|
|
||||||
CHECK_EQ(err, 0);
|
|
||||||
|
|
||||||
state_ = kNone;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void Agent::WorkerRun() {
|
|
||||||
static const char* argv[] = { "node", "--debug-agent" };
|
|
||||||
Isolate::CreateParams params;
|
|
||||||
ArrayBufferAllocator array_buffer_allocator;
|
|
||||||
params.array_buffer_allocator = &array_buffer_allocator;
|
|
||||||
Isolate* isolate = Isolate::New(params);
|
|
||||||
{
|
|
||||||
Locker locker(isolate);
|
|
||||||
Isolate::Scope isolate_scope(isolate);
|
|
||||||
|
|
||||||
HandleScope handle_scope(isolate);
|
|
||||||
IsolateData isolate_data(isolate, &child_loop_,
|
|
||||||
array_buffer_allocator.zero_fill_field());
|
|
||||||
Local<Context> context = Context::New(isolate);
|
|
||||||
|
|
||||||
Context::Scope context_scope(context);
|
|
||||||
Environment env(&isolate_data, context);
|
|
||||||
|
|
||||||
const bool start_profiler_idle_notifier = false;
|
|
||||||
env.Start(arraysize(argv), argv,
|
|
||||||
arraysize(argv), argv,
|
|
||||||
start_profiler_idle_notifier);
|
|
||||||
|
|
||||||
child_env_ = &env;
|
|
||||||
|
|
||||||
// Expose API
|
|
||||||
InitAdaptor(&env);
|
|
||||||
LoadEnvironment(&env);
|
|
||||||
|
|
||||||
CHECK_EQ(&child_loop_, env.event_loop());
|
|
||||||
uv_run(&child_loop_, UV_RUN_DEFAULT);
|
|
||||||
|
|
||||||
// Clean-up persistent
|
|
||||||
api_.Reset();
|
|
||||||
|
|
||||||
env.CleanupHandles();
|
|
||||||
}
|
|
||||||
isolate->Dispose();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void Agent::InitAdaptor(Environment* env) {
|
|
||||||
Isolate* isolate = env->isolate();
|
|
||||||
HandleScope scope(isolate);
|
|
||||||
|
|
||||||
// Create API adaptor
|
|
||||||
Local<FunctionTemplate> t = FunctionTemplate::New(isolate);
|
|
||||||
t->InstanceTemplate()->SetInternalFieldCount(1);
|
|
||||||
t->SetClassName(String::NewFromUtf8(isolate, "DebugAPI"));
|
|
||||||
|
|
||||||
NODE_SET_PROTOTYPE_METHOD(t, "notifyListen", NotifyListen);
|
|
||||||
NODE_SET_PROTOTYPE_METHOD(t, "notifyWait", NotifyWait);
|
|
||||||
NODE_SET_PROTOTYPE_METHOD(t, "sendCommand", SendCommand);
|
|
||||||
|
|
||||||
Local<Object> api =
|
|
||||||
t->GetFunction()->NewInstance(env->context()).ToLocalChecked();
|
|
||||||
api->SetAlignedPointerInInternalField(0, this);
|
|
||||||
|
|
||||||
api->Set(String::NewFromUtf8(isolate, "host",
|
|
||||||
NewStringType::kNormal).ToLocalChecked(),
|
|
||||||
String::NewFromUtf8(isolate, options_.host_name().data(),
|
|
||||||
NewStringType::kNormal,
|
|
||||||
options_.host_name().size()).ToLocalChecked());
|
|
||||||
api->Set(String::NewFromUtf8(isolate, "port"),
|
|
||||||
Integer::New(isolate, options_.port()));
|
|
||||||
|
|
||||||
env->process_object()->Set(String::NewFromUtf8(isolate, "_debugAPI"), api);
|
|
||||||
api_.Reset(env->isolate(), api);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
Agent* Agent::Unwrap(const v8::FunctionCallbackInfo<v8::Value>& args) {
|
|
||||||
void* ptr = args.Holder()->GetAlignedPointerFromInternalField(0);
|
|
||||||
return reinterpret_cast<Agent*>(ptr);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void Agent::NotifyListen(const FunctionCallbackInfo<Value>& args) {
|
|
||||||
Agent* a = Unwrap(args);
|
|
||||||
|
|
||||||
// Notify other thread that we are ready to process events
|
|
||||||
uv_sem_post(&a->start_sem_);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void Agent::NotifyWait(const FunctionCallbackInfo<Value>& args) {
|
|
||||||
Agent* a = Unwrap(args);
|
|
||||||
|
|
||||||
a->wait_ = false;
|
|
||||||
|
|
||||||
int err = uv_async_send(&a->child_signal_);
|
|
||||||
CHECK_EQ(err, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void Agent::SendCommand(const FunctionCallbackInfo<Value>& args) {
|
|
||||||
Agent* a = Unwrap(args);
|
|
||||||
Environment* env = a->child_env();
|
|
||||||
HandleScope scope(env->isolate());
|
|
||||||
|
|
||||||
String::Value v(args[0]);
|
|
||||||
|
|
||||||
v8::Debug::SendCommand(a->parent_env()->isolate(), *v, v.length());
|
|
||||||
if (a->dispatch_handler_ != nullptr)
|
|
||||||
a->dispatch_handler_(a->parent_env());
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void Agent::ThreadCb(Agent* agent) {
|
|
||||||
agent->WorkerRun();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void Agent::ChildSignalCb(uv_async_t* signal) {
|
|
||||||
Agent* a = ContainerOf(&Agent::child_signal_, signal);
|
|
||||||
Isolate* isolate = a->child_env()->isolate();
|
|
||||||
|
|
||||||
HandleScope scope(isolate);
|
|
||||||
Local<Object> api = PersistentToLocal(isolate, a->api_);
|
|
||||||
|
|
||||||
Mutex::ScopedLock scoped_lock(a->message_mutex_);
|
|
||||||
while (AgentMessage* msg = a->messages_.PopFront()) {
|
|
||||||
// Time to close everything
|
|
||||||
if (msg->data() == nullptr) {
|
|
||||||
delete msg;
|
|
||||||
|
|
||||||
MakeCallback(isolate, api, "onclose", 0, nullptr);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Waiting for client, do not send anything just yet
|
|
||||||
if (a->wait_) {
|
|
||||||
a->messages_.PushFront(msg); // Push message back into the ready queue.
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
Local<Value> argv[] = {
|
|
||||||
String::NewFromTwoByte(isolate,
|
|
||||||
msg->data(),
|
|
||||||
String::kNormalString,
|
|
||||||
msg->length())
|
|
||||||
};
|
|
||||||
|
|
||||||
// Emit message
|
|
||||||
MakeCallback(isolate,
|
|
||||||
api,
|
|
||||||
"onmessage",
|
|
||||||
arraysize(argv),
|
|
||||||
argv);
|
|
||||||
delete msg;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void Agent::EnqueueMessage(AgentMessage* message) {
|
|
||||||
Mutex::ScopedLock scoped_lock(message_mutex_);
|
|
||||||
messages_.PushBack(message);
|
|
||||||
uv_async_send(&child_signal_);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void Agent::MessageHandler(const v8::Debug::Message& message) {
|
|
||||||
Isolate* isolate = message.GetIsolate();
|
|
||||||
Environment* env = Environment::GetCurrent(isolate);
|
|
||||||
if (env == nullptr)
|
|
||||||
return; // Called from a non-node context.
|
|
||||||
Agent* a = env->debugger_agent();
|
|
||||||
CHECK_NE(a, nullptr);
|
|
||||||
CHECK_EQ(isolate, a->parent_env()->isolate());
|
|
||||||
|
|
||||||
HandleScope scope(isolate);
|
|
||||||
Local<String> json = message.GetJSON();
|
|
||||||
String::Value v(json);
|
|
||||||
|
|
||||||
AgentMessage* msg = new AgentMessage(*v, v.length());
|
|
||||||
a->EnqueueMessage(msg);
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace debugger
|
|
||||||
} // namespace node
|
|
@ -1,142 +0,0 @@
|
|||||||
// Copyright Fedor Indutny and other Node contributors.
|
|
||||||
//
|
|
||||||
// Permission is hereby granted, free of charge, to any person obtaining a
|
|
||||||
// copy of this software and associated documentation files (the
|
|
||||||
// "Software"), to deal in the Software without restriction, including
|
|
||||||
// without limitation the rights to use, copy, modify, merge, publish,
|
|
||||||
// distribute, sublicense, and/or sell copies of the Software, and to permit
|
|
||||||
// persons to whom the Software is furnished to do so, subject to the
|
|
||||||
// following conditions:
|
|
||||||
//
|
|
||||||
// The above copyright notice and this permission notice shall be included
|
|
||||||
// in all copies or substantial portions of the Software.
|
|
||||||
//
|
|
||||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
|
||||||
// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
|
||||||
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
|
|
||||||
// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
|
|
||||||
// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
|
|
||||||
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
|
|
||||||
// USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
||||||
|
|
||||||
#ifndef SRC_DEBUG_AGENT_H_
|
|
||||||
#define SRC_DEBUG_AGENT_H_
|
|
||||||
|
|
||||||
#if defined(NODE_WANT_INTERNALS) && NODE_WANT_INTERNALS
|
|
||||||
|
|
||||||
#include "node_mutex.h"
|
|
||||||
#include "node_debug_options.h"
|
|
||||||
#include "util.h"
|
|
||||||
#include "util-inl.h"
|
|
||||||
#include "uv.h"
|
|
||||||
#include "v8.h"
|
|
||||||
#include "v8-debug.h"
|
|
||||||
|
|
||||||
#include <string.h>
|
|
||||||
#include <string>
|
|
||||||
|
|
||||||
// Forward declaration to break recursive dependency chain with src/env.h.
|
|
||||||
namespace node {
|
|
||||||
class Environment;
|
|
||||||
} // namespace node
|
|
||||||
|
|
||||||
namespace node {
|
|
||||||
namespace debugger {
|
|
||||||
|
|
||||||
class AgentMessage {
|
|
||||||
public:
|
|
||||||
AgentMessage(uint16_t* val, int length) : length_(length) {
|
|
||||||
if (val == nullptr) {
|
|
||||||
data_ = val;
|
|
||||||
} else {
|
|
||||||
data_ = new uint16_t[length];
|
|
||||||
memcpy(data_, val, length * sizeof(*data_));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
~AgentMessage() {
|
|
||||||
delete[] data_;
|
|
||||||
data_ = nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
inline const uint16_t* data() const { return data_; }
|
|
||||||
inline int length() const { return length_; }
|
|
||||||
|
|
||||||
ListNode<AgentMessage> member;
|
|
||||||
|
|
||||||
private:
|
|
||||||
uint16_t* data_;
|
|
||||||
int length_;
|
|
||||||
};
|
|
||||||
|
|
||||||
class Agent {
|
|
||||||
public:
|
|
||||||
explicit Agent(node::Environment* env);
|
|
||||||
~Agent();
|
|
||||||
|
|
||||||
typedef void (*DispatchHandler)(node::Environment* env);
|
|
||||||
|
|
||||||
// Start the debugger agent thread
|
|
||||||
bool Start(const DebugOptions& options);
|
|
||||||
// Listen for debug events
|
|
||||||
void Enable();
|
|
||||||
// Stop the debugger agent
|
|
||||||
void Stop();
|
|
||||||
|
|
||||||
inline void set_dispatch_handler(DispatchHandler handler) {
|
|
||||||
dispatch_handler_ = handler;
|
|
||||||
}
|
|
||||||
|
|
||||||
inline node::Environment* parent_env() const { return parent_env_; }
|
|
||||||
inline node::Environment* child_env() const { return child_env_; }
|
|
||||||
|
|
||||||
protected:
|
|
||||||
void InitAdaptor(Environment* env);
|
|
||||||
|
|
||||||
// Worker body
|
|
||||||
void WorkerRun();
|
|
||||||
|
|
||||||
static void ThreadCb(Agent* agent);
|
|
||||||
static void ParentSignalCb(uv_async_t* signal);
|
|
||||||
static void ChildSignalCb(uv_async_t* signal);
|
|
||||||
static void MessageHandler(const v8::Debug::Message& message);
|
|
||||||
|
|
||||||
// V8 API
|
|
||||||
static Agent* Unwrap(const v8::FunctionCallbackInfo<v8::Value>& args);
|
|
||||||
static void NotifyListen(const v8::FunctionCallbackInfo<v8::Value>& args);
|
|
||||||
static void NotifyWait(const v8::FunctionCallbackInfo<v8::Value>& args);
|
|
||||||
static void SendCommand(const v8::FunctionCallbackInfo<v8::Value>& args);
|
|
||||||
|
|
||||||
void EnqueueMessage(AgentMessage* message);
|
|
||||||
|
|
||||||
enum State {
|
|
||||||
kNone,
|
|
||||||
kRunning
|
|
||||||
};
|
|
||||||
|
|
||||||
State state_;
|
|
||||||
DebugOptions options_;
|
|
||||||
|
|
||||||
bool wait_;
|
|
||||||
|
|
||||||
uv_sem_t start_sem_;
|
|
||||||
node::Mutex message_mutex_;
|
|
||||||
uv_async_t child_signal_;
|
|
||||||
|
|
||||||
uv_thread_t thread_;
|
|
||||||
node::Environment* parent_env_;
|
|
||||||
node::Environment* child_env_;
|
|
||||||
uv_loop_t child_loop_;
|
|
||||||
v8::Persistent<v8::Object> api_;
|
|
||||||
|
|
||||||
ListHead<AgentMessage, &AgentMessage::member> messages_;
|
|
||||||
|
|
||||||
DispatchHandler dispatch_handler_;
|
|
||||||
};
|
|
||||||
|
|
||||||
} // namespace debugger
|
|
||||||
} // namespace node
|
|
||||||
|
|
||||||
#endif // defined(NODE_WANT_INTERNALS) && NODE_WANT_INTERNALS
|
|
||||||
|
|
||||||
#endif // SRC_DEBUG_AGENT_H_
|
|
@ -193,7 +193,6 @@ inline Environment::Environment(IsolateData* isolate_data,
|
|||||||
trace_sync_io_(false),
|
trace_sync_io_(false),
|
||||||
makecallback_cntr_(0),
|
makecallback_cntr_(0),
|
||||||
async_wrap_uid_(0),
|
async_wrap_uid_(0),
|
||||||
debugger_agent_(this),
|
|
||||||
#if HAVE_INSPECTOR
|
#if HAVE_INSPECTOR
|
||||||
inspector_agent_(this),
|
inspector_agent_(this),
|
||||||
#endif
|
#endif
|
||||||
|
@ -25,7 +25,6 @@
|
|||||||
#if defined(NODE_WANT_INTERNALS) && NODE_WANT_INTERNALS
|
#if defined(NODE_WANT_INTERNALS) && NODE_WANT_INTERNALS
|
||||||
|
|
||||||
#include "ares.h"
|
#include "ares.h"
|
||||||
#include "debug-agent.h"
|
|
||||||
#if HAVE_INSPECTOR
|
#if HAVE_INSPECTOR
|
||||||
#include "inspector_agent.h"
|
#include "inspector_agent.h"
|
||||||
#endif
|
#endif
|
||||||
@ -554,10 +553,6 @@ class Environment {
|
|||||||
ENVIRONMENT_STRONG_PERSISTENT_PROPERTIES(V)
|
ENVIRONMENT_STRONG_PERSISTENT_PROPERTIES(V)
|
||||||
#undef V
|
#undef V
|
||||||
|
|
||||||
inline debugger::Agent* debugger_agent() {
|
|
||||||
return &debugger_agent_;
|
|
||||||
}
|
|
||||||
|
|
||||||
#if HAVE_INSPECTOR
|
#if HAVE_INSPECTOR
|
||||||
inline inspector::Agent* inspector_agent() {
|
inline inspector::Agent* inspector_agent() {
|
||||||
return &inspector_agent_;
|
return &inspector_agent_;
|
||||||
@ -599,7 +594,6 @@ class Environment {
|
|||||||
size_t makecallback_cntr_;
|
size_t makecallback_cntr_;
|
||||||
int64_t async_wrap_uid_;
|
int64_t async_wrap_uid_;
|
||||||
std::vector<int64_t> destroy_ids_list_;
|
std::vector<int64_t> destroy_ids_list_;
|
||||||
debugger::Agent debugger_agent_;
|
|
||||||
#if HAVE_INSPECTOR
|
#if HAVE_INSPECTOR
|
||||||
inspector::Agent inspector_agent_;
|
inspector::Agent inspector_agent_;
|
||||||
#endif
|
#endif
|
||||||
|
88
src/node.cc
88
src/node.cc
@ -230,7 +230,6 @@ bool v8_initialized = false;
|
|||||||
// process-relative uptime base, initialized at start-up
|
// process-relative uptime base, initialized at start-up
|
||||||
static double prog_start_time;
|
static double prog_start_time;
|
||||||
static bool debugger_running;
|
static bool debugger_running;
|
||||||
static uv_async_t dispatch_debug_messages_async;
|
|
||||||
|
|
||||||
static Mutex node_isolate_mutex;
|
static Mutex node_isolate_mutex;
|
||||||
static v8::Isolate* node_isolate;
|
static v8::Isolate* node_isolate;
|
||||||
@ -3974,72 +3973,12 @@ static void ParseArgs(int* argc,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// Called from V8 Debug Agent TCP thread.
|
|
||||||
static void DispatchMessagesDebugAgentCallback(Environment* env) {
|
|
||||||
// TODO(indutny): move async handle to environment
|
|
||||||
uv_async_send(&dispatch_debug_messages_async);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static void StartDebug(Environment* env, const char* path,
|
static void StartDebug(Environment* env, const char* path,
|
||||||
DebugOptions debug_options) {
|
DebugOptions debug_options) {
|
||||||
CHECK(!debugger_running);
|
CHECK(!debugger_running);
|
||||||
if (debug_options.debugger_enabled()) {
|
|
||||||
env->debugger_agent()->set_dispatch_handler(
|
|
||||||
DispatchMessagesDebugAgentCallback);
|
|
||||||
debugger_running = env->debugger_agent()->Start(debug_options);
|
|
||||||
if (debugger_running == false) {
|
|
||||||
fprintf(stderr, "Starting debugger on %s:%d failed\n",
|
|
||||||
debug_options.host_name().c_str(), debug_options.port());
|
|
||||||
fflush(stderr);
|
|
||||||
}
|
|
||||||
#if HAVE_INSPECTOR
|
#if HAVE_INSPECTOR
|
||||||
} else {
|
debugger_running = v8_platform.StartInspector(env, path, debug_options);
|
||||||
debugger_running = v8_platform.StartInspector(env, path, debug_options);
|
|
||||||
#endif // HAVE_INSPECTOR
|
#endif // HAVE_INSPECTOR
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// Called from the main thread.
|
|
||||||
static void EnableDebug(Environment* env) {
|
|
||||||
CHECK(debugger_running);
|
|
||||||
|
|
||||||
// Send message to enable debug in workers
|
|
||||||
HandleScope handle_scope(env->isolate());
|
|
||||||
|
|
||||||
Local<Object> message = Object::New(env->isolate());
|
|
||||||
message->Set(FIXED_ONE_BYTE_STRING(env->isolate(), "cmd"),
|
|
||||||
FIXED_ONE_BYTE_STRING(env->isolate(), "NODE_DEBUG_ENABLED"));
|
|
||||||
Local<Value> argv[] = {
|
|
||||||
FIXED_ONE_BYTE_STRING(env->isolate(), "internalMessage"),
|
|
||||||
message
|
|
||||||
};
|
|
||||||
MakeCallback(env, env->process_object(), "emit", arraysize(argv), argv);
|
|
||||||
|
|
||||||
// Enabled debugger, possibly making it wait on a semaphore
|
|
||||||
env->debugger_agent()->Enable();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// Called from the main thread.
|
|
||||||
static void DispatchDebugMessagesAsyncCallback(uv_async_t* handle) {
|
|
||||||
Mutex::ScopedLock scoped_lock(node_isolate_mutex);
|
|
||||||
if (auto isolate = node_isolate) {
|
|
||||||
if (debugger_running == false) {
|
|
||||||
fprintf(stderr, "Starting debugger agent.\n");
|
|
||||||
|
|
||||||
HandleScope scope(isolate);
|
|
||||||
Environment* env = Environment::GetCurrent(isolate);
|
|
||||||
Context::Scope context_scope(env->context());
|
|
||||||
debug_options.EnableDebugAgent(DebugAgentType::kDebugger);
|
|
||||||
StartDebug(env, nullptr, debug_options);
|
|
||||||
EnableDebug(env);
|
|
||||||
}
|
|
||||||
|
|
||||||
Isolate::Scope isolate_scope(isolate);
|
|
||||||
v8::Debug::ProcessDebugMessages(isolate);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -4184,15 +4123,9 @@ static void DebugPause(const FunctionCallbackInfo<Value>& args) {
|
|||||||
|
|
||||||
static void DebugEnd(const FunctionCallbackInfo<Value>& args) {
|
static void DebugEnd(const FunctionCallbackInfo<Value>& args) {
|
||||||
if (debugger_running) {
|
if (debugger_running) {
|
||||||
|
#if HAVE_INSPECTOR
|
||||||
Environment* env = Environment::GetCurrent(args);
|
Environment* env = Environment::GetCurrent(args);
|
||||||
#if HAVE_INSPECTOR
|
env->inspector_agent()->Stop();
|
||||||
if (!debug_options.debugger_enabled()) {
|
|
||||||
env->inspector_agent()->Stop();
|
|
||||||
} else {
|
|
||||||
#endif
|
|
||||||
env->debugger_agent()->Stop();
|
|
||||||
#if HAVE_INSPECTOR
|
|
||||||
}
|
|
||||||
#endif
|
#endif
|
||||||
debugger_running = false;
|
debugger_running = false;
|
||||||
}
|
}
|
||||||
@ -4339,13 +4272,6 @@ void Init(int* argc,
|
|||||||
// Make inherited handles noninheritable.
|
// Make inherited handles noninheritable.
|
||||||
uv_disable_stdio_inheritance();
|
uv_disable_stdio_inheritance();
|
||||||
|
|
||||||
// init async debug messages dispatching
|
|
||||||
// Main thread uses uv_default_loop
|
|
||||||
CHECK_EQ(0, uv_async_init(uv_default_loop(),
|
|
||||||
&dispatch_debug_messages_async,
|
|
||||||
DispatchDebugMessagesAsyncCallback));
|
|
||||||
uv_unref(reinterpret_cast<uv_handle_t*>(&dispatch_debug_messages_async));
|
|
||||||
|
|
||||||
#if defined(NODE_HAVE_I18N_SUPPORT)
|
#if defined(NODE_HAVE_I18N_SUPPORT)
|
||||||
// Set the ICU casing flag early
|
// Set the ICU casing flag early
|
||||||
// so the user can disable a flag --foo at run-time by passing
|
// so the user can disable a flag --foo at run-time by passing
|
||||||
@ -4536,9 +4462,7 @@ inline int Start(Isolate* isolate, IsolateData* isolate_data,
|
|||||||
const char* path = argc > 1 ? argv[1] : nullptr;
|
const char* path = argc > 1 ? argv[1] : nullptr;
|
||||||
StartDebug(&env, path, debug_options);
|
StartDebug(&env, path, debug_options);
|
||||||
|
|
||||||
bool debugger_enabled =
|
if (debug_options.inspector_enabled() && !debugger_running)
|
||||||
debug_options.debugger_enabled() || debug_options.inspector_enabled();
|
|
||||||
if (debugger_enabled && !debugger_running)
|
|
||||||
return 12; // Signal internal error.
|
return 12; // Signal internal error.
|
||||||
|
|
||||||
{
|
{
|
||||||
@ -4548,10 +4472,6 @@ inline int Start(Isolate* isolate, IsolateData* isolate_data,
|
|||||||
|
|
||||||
env.set_trace_sync_io(trace_sync_io);
|
env.set_trace_sync_io(trace_sync_io);
|
||||||
|
|
||||||
// Enable debugger
|
|
||||||
if (debug_options.debugger_enabled())
|
|
||||||
EnableDebug(&env);
|
|
||||||
|
|
||||||
if (load_napi_modules) {
|
if (load_napi_modules) {
|
||||||
ProcessEmitWarning(&env, "N-API is an experimental feature "
|
ProcessEmitWarning(&env, "N-API is an experimental feature "
|
||||||
"and could change at any time.");
|
"and could change at any time.");
|
||||||
|
@ -25,6 +25,7 @@
|
|||||||
#include "node_crypto.h"
|
#include "node_crypto.h"
|
||||||
#include "node_crypto_bio.h"
|
#include "node_crypto_bio.h"
|
||||||
#include "node_crypto_groups.h"
|
#include "node_crypto_groups.h"
|
||||||
|
#include "node_mutex.h"
|
||||||
#include "tls_wrap.h" // TLSWrap
|
#include "tls_wrap.h" // TLSWrap
|
||||||
|
|
||||||
#include "async-wrap.h"
|
#include "async-wrap.h"
|
||||||
|
@ -8,7 +8,6 @@
|
|||||||
namespace node {
|
namespace node {
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
const int default_debugger_port = 5858;
|
|
||||||
#if HAVE_INSPECTOR
|
#if HAVE_INSPECTOR
|
||||||
const int default_inspector_port = 9229;
|
const int default_inspector_port = 9229;
|
||||||
#endif // HAVE_INSPECTOR
|
#endif // HAVE_INSPECTOR
|
||||||
@ -56,29 +55,13 @@ std::pair<std::string, int> split_host_port(const std::string& arg) {
|
|||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
DebugOptions::DebugOptions() : debugger_enabled_(false),
|
DebugOptions::DebugOptions() :
|
||||||
#if HAVE_INSPECTOR
|
#if HAVE_INSPECTOR
|
||||||
inspector_enabled_(false),
|
inspector_enabled_(false),
|
||||||
#endif // HAVE_INSPECTOR
|
#endif // HAVE_INSPECTOR
|
||||||
wait_connect_(false), http_enabled_(false),
|
wait_connect_(false), http_enabled_(false),
|
||||||
host_name_("127.0.0.1"), port_(-1) { }
|
host_name_("127.0.0.1"), port_(-1) { }
|
||||||
|
|
||||||
void DebugOptions::EnableDebugAgent(DebugAgentType tool) {
|
|
||||||
switch (tool) {
|
|
||||||
#if HAVE_INSPECTOR
|
|
||||||
case DebugAgentType::kInspector:
|
|
||||||
inspector_enabled_ = true;
|
|
||||||
debugger_enabled_ = true;
|
|
||||||
break;
|
|
||||||
#endif // HAVE_INSPECTOR
|
|
||||||
case DebugAgentType::kDebugger:
|
|
||||||
debugger_enabled_ = true;
|
|
||||||
break;
|
|
||||||
case DebugAgentType::kNone:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
bool DebugOptions::ParseOption(const std::string& option) {
|
bool DebugOptions::ParseOption(const std::string& option) {
|
||||||
bool enable_inspector = false;
|
bool enable_inspector = false;
|
||||||
bool has_argument = false;
|
bool has_argument = false;
|
||||||
@ -95,10 +78,8 @@ bool DebugOptions::ParseOption(const std::string& option) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (option_name == "--inspect") {
|
if (option_name == "--inspect") {
|
||||||
debugger_enabled_ = true;
|
|
||||||
enable_inspector = true;
|
enable_inspector = true;
|
||||||
} else if (option_name == "--inspect-brk") {
|
} else if (option_name == "--inspect-brk") {
|
||||||
debugger_enabled_ = true;
|
|
||||||
enable_inspector = true;
|
enable_inspector = true;
|
||||||
wait_connect_ = true;
|
wait_connect_ = true;
|
||||||
} else if ((option_name != "--debug-port" &&
|
} else if ((option_name != "--debug-port" &&
|
||||||
@ -136,10 +117,8 @@ bool DebugOptions::ParseOption(const std::string& option) {
|
|||||||
int DebugOptions::port() const {
|
int DebugOptions::port() const {
|
||||||
int port = port_;
|
int port = port_;
|
||||||
if (port < 0) {
|
if (port < 0) {
|
||||||
port = default_debugger_port;
|
|
||||||
#if HAVE_INSPECTOR
|
#if HAVE_INSPECTOR
|
||||||
if (!debugger_enabled_ || inspector_enabled_)
|
port = default_inspector_port;
|
||||||
port = default_inspector_port;
|
|
||||||
#endif // HAVE_INSPECTOR
|
#endif // HAVE_INSPECTOR
|
||||||
}
|
}
|
||||||
return port;
|
return port;
|
||||||
|
@ -6,21 +6,10 @@
|
|||||||
// Forward declaration to break recursive dependency chain with src/env.h.
|
// Forward declaration to break recursive dependency chain with src/env.h.
|
||||||
namespace node {
|
namespace node {
|
||||||
|
|
||||||
enum class DebugAgentType {
|
|
||||||
kNone,
|
|
||||||
kDebugger,
|
|
||||||
#if HAVE_INSPECTOR
|
|
||||||
kInspector
|
|
||||||
#endif // HAVE_INSPECTOR
|
|
||||||
};
|
|
||||||
|
|
||||||
class DebugOptions {
|
class DebugOptions {
|
||||||
public:
|
public:
|
||||||
DebugOptions();
|
DebugOptions();
|
||||||
bool ParseOption(const std::string& option);
|
bool ParseOption(const std::string& option);
|
||||||
bool debugger_enabled() const {
|
|
||||||
return debugger_enabled_ && !inspector_enabled();
|
|
||||||
}
|
|
||||||
bool inspector_enabled() const {
|
bool inspector_enabled() const {
|
||||||
#if HAVE_INSPECTOR
|
#if HAVE_INSPECTOR
|
||||||
return inspector_enabled_;
|
return inspector_enabled_;
|
||||||
@ -28,7 +17,6 @@ class DebugOptions {
|
|||||||
return false;
|
return false;
|
||||||
#endif // HAVE_INSPECTOR
|
#endif // HAVE_INSPECTOR
|
||||||
}
|
}
|
||||||
void EnableDebugAgent(DebugAgentType type);
|
|
||||||
bool ToolsServerEnabled();
|
bool ToolsServerEnabled();
|
||||||
bool wait_for_connect() const { return wait_connect_; }
|
bool wait_for_connect() const { return wait_connect_; }
|
||||||
std::string host_name() const { return host_name_; }
|
std::string host_name() const { return host_name_; }
|
||||||
@ -36,7 +24,6 @@ class DebugOptions {
|
|||||||
void set_port(int port) { port_ = port; }
|
void set_port(int port) { port_ = port; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
bool debugger_enabled_;
|
|
||||||
#if HAVE_INSPECTOR
|
#if HAVE_INSPECTOR
|
||||||
bool inspector_enabled_;
|
bool inspector_enabled_;
|
||||||
#endif // HAVE_INSPECTOR
|
#endif // HAVE_INSPECTOR
|
||||||
|
Loading…
x
Reference in New Issue
Block a user