/src/node/src/inspector_agent.h
Line | Count | Source (jump to first uncovered line) |
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 | 0 | virtual ~InspectorSession() = default; |
33 | | virtual void Dispatch(const v8_inspector::StringView& message) = 0; |
34 | | }; |
35 | | |
36 | | class InspectorSessionDelegate { |
37 | | public: |
38 | 0 | 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 | | |
56 | 222k | 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, const std::string& name); |
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 | | |
110 | 134k | const DebugOptions& options() { return debug_options_; } |
111 | 0 | 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 | | |
117 | 0 | 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 |