1 #pragma once 2 3 #if defined(NODE_WANT_INTERNALS) && NODE_WANT_INTERNALS 4 5 #if !HAVE_INSPECTOR 6 #error("This header can only be used when inspector is enabled") 7 #endif 8 9 #include "node_options.h" 10 #include "v8.h" 11 12 #include <cstddef> 13 #include <memory> 14 15 namespace v8_inspector { 16 class StringView; 17 } // namespace v8_inspector 18 19 namespace node { 20 // Forward declaration to break recursive dependency chain with src/env.h. 21 class Environment; 22 struct ContextInfo; 23 24 namespace inspector { 25 class InspectorIo; 26 class ParentInspectorHandle; 27 class NodeInspectorClient; 28 class WorkerManager; 29 30 class InspectorSession { 31 public: 32 virtual ~InspectorSession() = default; 33 virtual void Dispatch(const v8_inspector::StringView& message) = 0; 34 }; 35 36 class InspectorSessionDelegate { 37 public: 38 virtual ~InspectorSessionDelegate() = default; 39 virtual void SendMessageToFrontend(const v8_inspector::StringView& message) 40 = 0; 41 }; 42 43 class Agent { 44 public: 45 explicit Agent(node::Environment* env); 46 ~Agent(); 47 48 // Create client_, may create io_ if option enabled 49 bool Start(const std::string& path, 50 const DebugOptions& options, 51 std::shared_ptr<ExclusiveAccess<HostPort>> host_port, 52 bool is_main); 53 // Stop and destroy io_ 54 void Stop(); 55 IsListening()56 bool IsListening() { return io_ != nullptr; } 57 // Returns true if the Node inspector is actually in use. It will be true 58 // if either the user explicitly opted into inspector (e.g. with the 59 // --inspect command line flag) or if inspector JS API had been used. 60 bool IsActive(); 61 62 // Blocks till frontend connects and sends "runIfWaitingForDebugger" 63 void WaitForConnect(); 64 // Blocks till all the sessions with "WaitForDisconnectOnShutdown" disconnect 65 void WaitForDisconnect(); 66 void ReportUncaughtException(v8::Local<v8::Value> error, 67 v8::Local<v8::Message> message); 68 69 // Async stack traces instrumentation. 70 void AsyncTaskScheduled(const v8_inspector::StringView& taskName, void* task, 71 bool recurring); 72 void AsyncTaskCanceled(void* task); 73 void AsyncTaskStarted(void* task); 74 void AsyncTaskFinished(void* task); 75 void AllAsyncTasksCanceled(); 76 77 void RegisterAsyncHook(v8::Isolate* isolate, 78 v8::Local<v8::Function> enable_function, 79 v8::Local<v8::Function> disable_function); 80 void EnableAsyncHook(); 81 void DisableAsyncHook(); 82 83 void SetParentHandle(std::unique_ptr<ParentInspectorHandle> parent_handle); 84 std::unique_ptr<ParentInspectorHandle> GetParentHandle( 85 uint64_t thread_id, const std::string& url); 86 87 // Called to create inspector sessions that can be used from the same thread. 88 // The inspector responds by using the delegate to send messages back. 89 std::unique_ptr<InspectorSession> Connect( 90 std::unique_ptr<InspectorSessionDelegate> delegate, 91 bool prevent_shutdown); 92 93 // Called from the worker to create inspector sessions that is connected 94 // to the main thread. 95 // The inspector responds by using the delegate to send messages back. 96 std::unique_ptr<InspectorSession> ConnectToMainThread( 97 std::unique_ptr<InspectorSessionDelegate> delegate, 98 bool prevent_shutdown); 99 100 void PauseOnNextJavascriptStatement(const std::string& reason); 101 102 std::string GetWsUrl() const; 103 104 // Can only be called from the main thread. 105 bool StartIoThread(); 106 107 // Calls StartIoThread() from off the main thread. 108 void RequestIoThreadStart(); 109 options()110 const DebugOptions& options() { return debug_options_; } host_port()111 std::shared_ptr<ExclusiveAccess<HostPort>> host_port() { return host_port_; } 112 void ContextCreated(v8::Local<v8::Context> context, const ContextInfo& info); 113 114 // Interface for interacting with inspectors in worker threads 115 std::shared_ptr<WorkerManager> GetWorkerManager(); 116 env()117 inline Environment* env() const { return parent_env_; } 118 119 private: 120 void ToggleAsyncHook(v8::Isolate* isolate, v8::Local<v8::Function> fn); 121 122 node::Environment* parent_env_; 123 // Encapsulates majority of the Inspector functionality 124 std::shared_ptr<NodeInspectorClient> client_; 125 // Interface for transports, e.g. WebSocket server 126 std::unique_ptr<InspectorIo> io_; 127 std::unique_ptr<ParentInspectorHandle> parent_handle_; 128 std::string path_; 129 130 // This is a copy of the debug options parsed from CLI in the Environment. 131 // Do not use the host_port in that, instead manipulate the shared host_port_ 132 // pointer which is meant to store the actual host and port of the inspector 133 // server. 134 DebugOptions debug_options_; 135 std::shared_ptr<ExclusiveAccess<HostPort>> host_port_; 136 137 bool pending_enable_async_hook_ = false; 138 bool pending_disable_async_hook_ = false; 139 }; 140 141 } // namespace inspector 142 } // namespace node 143 144 #endif // defined(NODE_WANT_INTERNALS) && NODE_WANT_INTERNALS 145