xref: /third_party/node/src/inspector_agent.h (revision 1cb0ef41)
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
15namespace v8_inspector {
16class StringView;
17}  // namespace v8_inspector
18
19namespace node {
20// Forward declaration to break recursive dependency chain with src/env.h.
21class Environment;
22struct ContextInfo;
23
24namespace inspector {
25class InspectorIo;
26class ParentInspectorHandle;
27class NodeInspectorClient;
28class WorkerManager;
29
30class InspectorSession {
31 public:
32  virtual ~InspectorSession() = default;
33  virtual void Dispatch(const v8_inspector::StringView& message) = 0;
34};
35
36class InspectorSessionDelegate {
37 public:
38  virtual ~InspectorSessionDelegate() = default;
39  virtual void SendMessageToFrontend(const v8_inspector::StringView& message)
40                                     = 0;
41};
42
43class 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  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  const DebugOptions& options() { return debug_options_; }
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
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