Bump version to 19.1.0 (final)
[llvm-project.git] / lldb / tools / lldb-dap / DAP.h
blob57562a14983519772f57cb1356e391d1f4b08558
1 //===-- DAP.h ---------------------------------------------------*- C++ -*-===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
9 #ifndef LLDB_TOOLS_LLDB_DAP_DAP_H
10 #define LLDB_TOOLS_LLDB_DAP_DAP_H
12 #include "llvm/Config/llvm-config.h" // for LLVM_ON_UNIX
14 #include <atomic>
15 #include <condition_variable>
16 #include <cstdio>
17 #include <future>
18 #include <iosfwd>
19 #include <map>
20 #include <optional>
21 #include <set>
22 #include <thread>
24 #include "llvm/ADT/DenseMap.h"
25 #include "llvm/ADT/DenseSet.h"
26 #include "llvm/ADT/StringMap.h"
27 #include "llvm/ADT/StringRef.h"
28 #include "llvm/Support/JSON.h"
29 #include "llvm/Support/Threading.h"
30 #include "llvm/Support/raw_ostream.h"
32 #include "lldb/API/SBAttachInfo.h"
33 #include "lldb/API/SBBreakpoint.h"
34 #include "lldb/API/SBBreakpointLocation.h"
35 #include "lldb/API/SBCommandInterpreter.h"
36 #include "lldb/API/SBCommandReturnObject.h"
37 #include "lldb/API/SBCommunication.h"
38 #include "lldb/API/SBDebugger.h"
39 #include "lldb/API/SBEvent.h"
40 #include "lldb/API/SBFormat.h"
41 #include "lldb/API/SBHostOS.h"
42 #include "lldb/API/SBInstruction.h"
43 #include "lldb/API/SBInstructionList.h"
44 #include "lldb/API/SBLanguageRuntime.h"
45 #include "lldb/API/SBLaunchInfo.h"
46 #include "lldb/API/SBLineEntry.h"
47 #include "lldb/API/SBListener.h"
48 #include "lldb/API/SBProcess.h"
49 #include "lldb/API/SBStream.h"
50 #include "lldb/API/SBStringList.h"
51 #include "lldb/API/SBTarget.h"
52 #include "lldb/API/SBThread.h"
54 #include "ExceptionBreakpoint.h"
55 #include "FunctionBreakpoint.h"
56 #include "IOStream.h"
57 #include "ProgressEvent.h"
58 #include "RunInTerminal.h"
59 #include "SourceBreakpoint.h"
61 #define VARREF_LOCALS (int64_t)1
62 #define VARREF_GLOBALS (int64_t)2
63 #define VARREF_REGS (int64_t)3
64 #define VARREF_FIRST_VAR_IDX (int64_t)4
65 #define NO_TYPENAME "<no-type>"
67 namespace lldb_dap {
69 typedef llvm::DenseMap<uint32_t, SourceBreakpoint> SourceBreakpointMap;
70 typedef llvm::StringMap<FunctionBreakpoint> FunctionBreakpointMap;
71 enum class OutputType { Console, Stdout, Stderr, Telemetry };
73 enum DAPBroadcasterBits {
74 eBroadcastBitStopEventThread = 1u << 0,
75 eBroadcastBitStopProgressThread = 1u << 1
78 typedef void (*RequestCallback)(const llvm::json::Object &command);
79 typedef void (*ResponseCallback)(llvm::Expected<llvm::json::Value> value);
81 enum class PacketStatus {
82 Success = 0,
83 EndOfFile,
84 JSONMalformed,
85 JSONNotObject
88 enum class ReplMode { Variable = 0, Command, Auto };
90 /// The detected context of an expression based off the current repl mode.
91 enum class ExpressionContext {
92 Variable = 0,
93 Command,
96 struct Variables {
97 /// Variable_reference start index of permanent expandable variable.
98 static constexpr int64_t PermanentVariableStartIndex = (1ll << 32);
100 lldb::SBValueList locals;
101 lldb::SBValueList globals;
102 lldb::SBValueList registers;
104 int64_t next_temporary_var_ref{VARREF_FIRST_VAR_IDX};
105 int64_t next_permanent_var_ref{PermanentVariableStartIndex};
107 /// Expandable variables that are alive in this stop state.
108 /// Will be cleared when debuggee resumes.
109 llvm::DenseMap<int64_t, lldb::SBValue> expandable_variables;
110 /// Expandable variables that persist across entire debug session.
111 /// These are the variables evaluated from debug console REPL.
112 llvm::DenseMap<int64_t, lldb::SBValue> expandable_permanent_variables;
114 /// Check if \p var_ref points to a variable that should persist for the
115 /// entire duration of the debug session, e.g. repl expandable variables
116 static bool IsPermanentVariableReference(int64_t var_ref);
118 /// \return a new variableReference.
119 /// Specify is_permanent as true for variable that should persist entire
120 /// debug session.
121 int64_t GetNewVariableReference(bool is_permanent);
123 /// \return the expandable variable corresponding with variableReference
124 /// value of \p value.
125 /// If \p var_ref is invalid an empty SBValue is returned.
126 lldb::SBValue GetVariable(int64_t var_ref) const;
128 /// Insert a new \p variable.
129 /// \return variableReference assigned to this expandable variable.
130 int64_t InsertExpandableVariable(lldb::SBValue variable, bool is_permanent);
132 /// Clear all scope variables and non-permanent expandable variables.
133 void Clear();
136 struct StartDebuggingRequestHandler : public lldb::SBCommandPluginInterface {
137 bool DoExecute(lldb::SBDebugger debugger, char **command,
138 lldb::SBCommandReturnObject &result) override;
141 struct ReplModeRequestHandler : public lldb::SBCommandPluginInterface {
142 bool DoExecute(lldb::SBDebugger debugger, char **command,
143 lldb::SBCommandReturnObject &result) override;
146 struct DAP {
147 std::string debug_adaptor_path;
148 InputStream input;
149 OutputStream output;
150 lldb::SBDebugger debugger;
151 lldb::SBTarget target;
152 Variables variables;
153 lldb::SBBroadcaster broadcaster;
154 std::thread event_thread;
155 std::thread progress_event_thread;
156 std::unique_ptr<std::ofstream> log;
157 llvm::StringMap<SourceBreakpointMap> source_breakpoints;
158 FunctionBreakpointMap function_breakpoints;
159 std::optional<std::vector<ExceptionBreakpoint>> exception_breakpoints;
160 llvm::once_flag init_exception_breakpoints_flag;
161 std::vector<std::string> pre_init_commands;
162 std::vector<std::string> init_commands;
163 std::vector<std::string> pre_run_commands;
164 std::vector<std::string> post_run_commands;
165 std::vector<std::string> exit_commands;
166 std::vector<std::string> stop_commands;
167 std::vector<std::string> terminate_commands;
168 // Map step in target id to list of function targets that user can choose.
169 llvm::DenseMap<lldb::addr_t, std::string> step_in_targets;
170 // A copy of the last LaunchRequest or AttachRequest so we can reuse its
171 // arguments if we get a RestartRequest.
172 std::optional<llvm::json::Object> last_launch_or_attach_request;
173 lldb::tid_t focus_tid;
174 bool disconnecting = false;
175 llvm::once_flag terminated_event_flag;
176 bool stop_at_entry;
177 bool is_attach;
178 bool enable_auto_variable_summaries;
179 bool enable_synthetic_child_debugging;
180 // The process event thread normally responds to process exited events by
181 // shutting down the entire adapter. When we're restarting, we keep the id of
182 // the old process here so we can detect this case and keep running.
183 lldb::pid_t restarting_process_id;
184 bool configuration_done_sent;
185 std::map<std::string, RequestCallback> request_handlers;
186 bool waiting_for_run_in_terminal;
187 ProgressEventReporter progress_event_reporter;
188 // Keep track of the last stop thread index IDs as threads won't go away
189 // unless we send a "thread" event to indicate the thread exited.
190 llvm::DenseSet<lldb::tid_t> thread_ids;
191 uint32_t reverse_request_seq;
192 std::mutex call_mutex;
193 std::map<int /* request_seq */, ResponseCallback /* reply handler */>
194 inflight_reverse_requests;
195 StartDebuggingRequestHandler start_debugging_request_handler;
196 ReplModeRequestHandler repl_mode_request_handler;
197 ReplMode repl_mode;
198 std::string command_escape_prefix = "`";
199 lldb::SBFormat frame_format;
200 lldb::SBFormat thread_format;
202 DAP();
203 ~DAP();
204 DAP(const DAP &rhs) = delete;
205 void operator=(const DAP &rhs) = delete;
206 ExceptionBreakpoint *GetExceptionBreakpoint(const std::string &filter);
207 ExceptionBreakpoint *GetExceptionBreakpoint(const lldb::break_id_t bp_id);
209 // Serialize the JSON value into a string and send the JSON packet to
210 // the "out" stream.
211 void SendJSON(const llvm::json::Value &json);
213 std::string ReadJSON();
215 void SendOutput(OutputType o, const llvm::StringRef output);
217 void SendProgressEvent(uint64_t progress_id, const char *message,
218 uint64_t completed, uint64_t total);
220 void __attribute__((format(printf, 3, 4)))
221 SendFormattedOutput(OutputType o, const char *format, ...);
223 static int64_t GetNextSourceReference();
225 ExceptionBreakpoint *GetExceptionBPFromStopReason(lldb::SBThread &thread);
227 lldb::SBThread GetLLDBThread(const llvm::json::Object &arguments);
229 lldb::SBFrame GetLLDBFrame(const llvm::json::Object &arguments);
231 llvm::json::Value CreateTopLevelScopes();
233 void PopulateExceptionBreakpoints();
235 /// \return
236 /// Attempt to determine if an expression is a variable expression or
237 /// lldb command using a hueristic based on the first term of the
238 /// expression.
239 ExpressionContext DetectExpressionContext(lldb::SBFrame frame,
240 std::string &expression);
242 /// \return
243 /// \b false if a fatal error was found while executing these commands,
244 /// according to the rules of \a LLDBUtils::RunLLDBCommands.
245 bool RunLLDBCommands(llvm::StringRef prefix,
246 llvm::ArrayRef<std::string> commands);
248 llvm::Error RunAttachCommands(llvm::ArrayRef<std::string> attach_commands);
249 llvm::Error RunLaunchCommands(llvm::ArrayRef<std::string> launch_commands);
250 llvm::Error RunPreInitCommands();
251 llvm::Error RunInitCommands();
252 llvm::Error RunPreRunCommands();
253 void RunPostRunCommands();
254 void RunStopCommands();
255 void RunExitCommands();
256 void RunTerminateCommands();
258 /// Create a new SBTarget object from the given request arguments.
259 /// \param[in] arguments
260 /// Launch configuration arguments.
262 /// \param[out] error
263 /// An SBError object that will contain an error description if
264 /// function failed to create the target.
266 /// \return
267 /// An SBTarget object.
268 lldb::SBTarget CreateTargetFromArguments(const llvm::json::Object &arguments,
269 lldb::SBError &error);
271 /// Set given target object as a current target for lldb-dap and start
272 /// listeing for its breakpoint events.
273 void SetTarget(const lldb::SBTarget target);
275 const std::map<std::string, RequestCallback> &GetRequestHandlers();
277 PacketStatus GetNextObject(llvm::json::Object &object);
278 bool HandleObject(const llvm::json::Object &object);
280 llvm::Error Loop();
282 /// Send a Debug Adapter Protocol reverse request to the IDE.
284 /// \param[in] command
285 /// The reverse request command.
287 /// \param[in] arguments
288 /// The reverse request arguements.
290 /// \param[in] callback
291 /// A callback to execute when the response arrives.
292 void SendReverseRequest(llvm::StringRef command, llvm::json::Value arguments,
293 ResponseCallback callback);
295 /// Registers a callback handler for a Debug Adapter Protocol request
297 /// \param[in] request
298 /// The name of the request following the Debug Adapter Protocol
299 /// specification.
301 /// \param[in] callback
302 /// The callback to execute when the given request is triggered by the
303 /// IDE.
304 void RegisterRequestCallback(std::string request, RequestCallback callback);
306 /// Debuggee will continue from stopped state.
307 void WillContinue() { variables.Clear(); }
309 /// Poll the process to wait for it to reach the eStateStopped state.
311 /// Wait for the process hit a stopped state. When running a launch with
312 /// "launchCommands", or attach with "attachCommands", the calls might take
313 /// some time to stop at the entry point since the command is asynchronous. We
314 /// need to sync up with the process and make sure it is stopped before we
315 /// proceed to do anything else as we will soon be asked to set breakpoints
316 /// and other things that require the process to be stopped. We must use
317 /// polling because "attachCommands" or "launchCommands" may or may not send
318 /// process state change events depending on if the user modifies the async
319 /// setting in the debugger. Since both "attachCommands" and "launchCommands"
320 /// could end up using any combination of LLDB commands, we must ensure we can
321 /// also catch when the process stops, so we must poll the process to make
322 /// sure we handle all cases.
324 /// \param[in] seconds
325 /// The number of seconds to poll the process to wait until it is stopped.
327 /// \return Error if waiting for the process fails, no error if succeeds.
328 lldb::SBError WaitForProcessToStop(uint32_t seconds);
330 void SetFrameFormat(llvm::StringRef format);
332 void SetThreadFormat(llvm::StringRef format);
334 private:
335 // Send the JSON in "json_str" to the "out" stream. Correctly send the
336 // "Content-Length:" field followed by the length, followed by the raw
337 // JSON bytes.
338 void SendJSON(const std::string &json_str);
341 extern DAP g_dap;
343 } // namespace lldb_dap
345 #endif