1 //===-- lldb-vscode.cpp -----------------------------------------*- 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 //===----------------------------------------------------------------------===//
8 
9 #include "VSCode.h"
10 
11 #include <cassert>
12 #include <climits>
13 #include <cstdarg>
14 #include <cstdio>
15 #include <cstdlib>
16 #include <cstring>
17 #include <sys/stat.h>
18 #include <sys/types.h>
19 #if defined(_WIN32)
20 // We need to #define NOMINMAX in order to skip `min()` and `max()` macro
21 // definitions that conflict with other system headers.
22 // We also need to #undef GetObject (which is defined to GetObjectW) because
23 // the JSON code we use also has methods named `GetObject()` and we conflict
24 // against these.
25 #define NOMINMAX
26 #include <windows.h>
27 #undef GetObject
28 #include <io.h>
29 #else
30 #include <netinet/in.h>
31 #include <sys/socket.h>
32 #include <unistd.h>
33 #endif
34 
35 #include <algorithm>
36 #include <chrono>
37 #include <fstream>
38 #include <map>
39 #include <memory>
40 #include <mutex>
41 #include <set>
42 #include <sstream>
43 #include <thread>
44 #include <vector>
45 
46 #include "llvm/ADT/ArrayRef.h"
47 #include "llvm/ADT/DenseMap.h"
48 #include "llvm/ADT/ScopeExit.h"
49 #include "llvm/Option/Arg.h"
50 #include "llvm/Option/ArgList.h"
51 #include "llvm/Option/Option.h"
52 #include "llvm/Support/Errno.h"
53 #include "llvm/Support/FileSystem.h"
54 #include "llvm/Support/InitLLVM.h"
55 #include "llvm/Support/Path.h"
56 #include "llvm/Support/PrettyStackTrace.h"
57 #include "llvm/Support/raw_ostream.h"
58 
59 #include "JSONUtils.h"
60 #include "LLDBUtils.h"
61 #include "OutputRedirector.h"
62 
63 #if defined(_WIN32)
64 #ifndef PATH_MAX
65 #define PATH_MAX MAX_PATH
66 #endif
67 typedef int socklen_t;
68 constexpr const char *dev_null_path = "nul";
69 
70 #else
71 constexpr const char *dev_null_path = "/dev/null";
72 
73 #endif
74 
75 using namespace lldb_vscode;
76 
77 namespace {
78 enum ID {
79   OPT_INVALID = 0, // This is not an option ID.
80 #define OPTION(PREFIX, NAME, ID, KIND, GROUP, ALIAS, ALIASARGS, FLAGS, PARAM,  \
81                HELPTEXT, METAVAR, VALUES)                                      \
82   OPT_##ID,
83 #include "Options.inc"
84 #undef OPTION
85 };
86 
87 #define PREFIX(NAME, VALUE) const char *const NAME[] = VALUE;
88 #include "Options.inc"
89 #undef PREFIX
90 
91 static const llvm::opt::OptTable::Info InfoTable[] = {
92 #define OPTION(PREFIX, NAME, ID, KIND, GROUP, ALIAS, ALIASARGS, FLAGS, PARAM,  \
93                HELPTEXT, METAVAR, VALUES)                                      \
94   {PREFIX,      NAME,      HELPTEXT,                                           \
95    METAVAR,     OPT_##ID,  llvm::opt::Option::KIND##Class,                     \
96    PARAM,       FLAGS,     OPT_##GROUP,                                        \
97    OPT_##ALIAS, ALIASARGS, VALUES},
98 #include "Options.inc"
99 #undef OPTION
100 };
101 class LLDBVSCodeOptTable : public llvm::opt::OptTable {
102 public:
103   LLDBVSCodeOptTable() : OptTable(InfoTable, true) {}
104 };
105 
106 typedef void (*RequestCallback)(const llvm::json::Object &command);
107 
108 enum LaunchMethod { Launch, Attach, AttachForSuspendedLaunch };
109 
110 lldb::SBValueList *GetTopLevelScope(int64_t variablesReference) {
111   switch (variablesReference) {
112   case VARREF_LOCALS:
113     return &g_vsc.variables.locals;
114   case VARREF_GLOBALS:
115     return &g_vsc.variables.globals;
116   case VARREF_REGS:
117     return &g_vsc.variables.registers;
118   default:
119     return nullptr;
120   }
121 }
122 
123 SOCKET AcceptConnection(int portno) {
124   // Accept a socket connection from any host on "portno".
125   SOCKET newsockfd = -1;
126   struct sockaddr_in serv_addr, cli_addr;
127   SOCKET sockfd = socket(AF_INET, SOCK_STREAM, 0);
128   if (sockfd < 0) {
129     if (g_vsc.log)
130       *g_vsc.log << "error: opening socket (" << strerror(errno) << ")"
131                  << std::endl;
132   } else {
133     memset((char *)&serv_addr, 0, sizeof(serv_addr));
134     serv_addr.sin_family = AF_INET;
135     // serv_addr.sin_addr.s_addr = htonl(INADDR_ANY);
136     serv_addr.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
137     serv_addr.sin_port = htons(portno);
138     if (bind(sockfd, (struct sockaddr *)&serv_addr, sizeof(serv_addr)) < 0) {
139       if (g_vsc.log)
140         *g_vsc.log << "error: binding socket (" << strerror(errno) << ")"
141                    << std::endl;
142     } else {
143       listen(sockfd, 5);
144       socklen_t clilen = sizeof(cli_addr);
145       newsockfd =
146           llvm::sys::RetryAfterSignal(static_cast<SOCKET>(-1), accept, sockfd,
147                                       (struct sockaddr *)&cli_addr, &clilen);
148       if (newsockfd < 0)
149         if (g_vsc.log)
150           *g_vsc.log << "error: accept (" << strerror(errno) << ")"
151                      << std::endl;
152     }
153 #if defined(_WIN32)
154     closesocket(sockfd);
155 #else
156     close(sockfd);
157 #endif
158   }
159   return newsockfd;
160 }
161 
162 std::vector<const char *> MakeArgv(const llvm::ArrayRef<std::string> &strs) {
163   // Create and return an array of "const char *", one for each C string in
164   // "strs" and terminate the list with a NULL. This can be used for argument
165   // vectors (argv) or environment vectors (envp) like those passed to the
166   // "main" function in C programs.
167   std::vector<const char *> argv;
168   for (const auto &s : strs)
169     argv.push_back(s.c_str());
170   argv.push_back(nullptr);
171   return argv;
172 }
173 
174 // Send a "exited" event to indicate the process has exited.
175 void SendProcessExitedEvent(lldb::SBProcess &process) {
176   llvm::json::Object event(CreateEventObject("exited"));
177   llvm::json::Object body;
178   body.try_emplace("exitCode", (int64_t)process.GetExitStatus());
179   event.try_emplace("body", std::move(body));
180   g_vsc.SendJSON(llvm::json::Value(std::move(event)));
181 }
182 
183 void SendThreadExitedEvent(lldb::tid_t tid) {
184   llvm::json::Object event(CreateEventObject("thread"));
185   llvm::json::Object body;
186   body.try_emplace("reason", "exited");
187   body.try_emplace("threadId", (int64_t)tid);
188   event.try_emplace("body", std::move(body));
189   g_vsc.SendJSON(llvm::json::Value(std::move(event)));
190 }
191 
192 // Send a "terminated" event to indicate the process is done being
193 // debugged.
194 void SendTerminatedEvent() {
195   // If an inferior exits prior to the processing of a disconnect request, then
196   // the threads executing EventThreadFunction and request_discontinue
197   // respectively may call SendTerminatedEvent simultaneously. Without any
198   // synchronization, the thread executing EventThreadFunction may set
199   // g_vsc.sent_terminated_event before the thread executing
200   // request_discontinue has had a chance to test it, in which case the latter
201   // would move ahead to issue a response to the disconnect request. Said
202   // response may get dispatched ahead of the terminated event compelling the
203   // client to terminate the debug session without consuming any console output
204   // that might've been generated by the execution of terminateCommands. So,
205   // synchronize simultaneous calls to SendTerminatedEvent.
206   static std::mutex mutex;
207   std::lock_guard<std::mutex> locker(mutex);
208   if (!g_vsc.sent_terminated_event) {
209     g_vsc.sent_terminated_event = true;
210     g_vsc.RunTerminateCommands();
211     // Send a "terminated" event
212     llvm::json::Object event(CreateEventObject("terminated"));
213     g_vsc.SendJSON(llvm::json::Value(std::move(event)));
214   }
215 }
216 
217 // Send a thread stopped event for all threads as long as the process
218 // is stopped.
219 void SendThreadStoppedEvent() {
220   lldb::SBProcess process = g_vsc.target.GetProcess();
221   if (process.IsValid()) {
222     auto state = process.GetState();
223     if (state == lldb::eStateStopped) {
224       llvm::DenseSet<lldb::tid_t> old_thread_ids;
225       old_thread_ids.swap(g_vsc.thread_ids);
226       uint32_t stop_id = process.GetStopID();
227       const uint32_t num_threads = process.GetNumThreads();
228 
229       // First make a pass through the threads to see if the focused thread
230       // has a stop reason. In case the focus thread doesn't have a stop
231       // reason, remember the first thread that has a stop reason so we can
232       // set it as the focus thread if below if needed.
233       lldb::tid_t first_tid_with_reason = LLDB_INVALID_THREAD_ID;
234       uint32_t num_threads_with_reason = 0;
235       bool focus_thread_exists = false;
236       for (uint32_t thread_idx = 0; thread_idx < num_threads; ++thread_idx) {
237         lldb::SBThread thread = process.GetThreadAtIndex(thread_idx);
238         const lldb::tid_t tid = thread.GetThreadID();
239         const bool has_reason = ThreadHasStopReason(thread);
240         // If the focus thread doesn't have a stop reason, clear the thread ID
241         if (tid == g_vsc.focus_tid) {
242           focus_thread_exists = true;
243           if (!has_reason)
244             g_vsc.focus_tid = LLDB_INVALID_THREAD_ID;
245         }
246         if (has_reason) {
247           ++num_threads_with_reason;
248           if (first_tid_with_reason == LLDB_INVALID_THREAD_ID)
249             first_tid_with_reason = tid;
250         }
251       }
252 
253       // We will have cleared g_vsc.focus_tid if he focus thread doesn't have
254       // a stop reason, so if it was cleared, or wasn't set, or doesn't exist,
255       // then set the focus thread to the first thread with a stop reason.
256       if (!focus_thread_exists || g_vsc.focus_tid == LLDB_INVALID_THREAD_ID)
257         g_vsc.focus_tid = first_tid_with_reason;
258 
259       // If no threads stopped with a reason, then report the first one so
260       // we at least let the UI know we stopped.
261       if (num_threads_with_reason == 0) {
262         lldb::SBThread thread = process.GetThreadAtIndex(0);
263         g_vsc.SendJSON(CreateThreadStopped(thread, stop_id));
264       } else {
265         for (uint32_t thread_idx = 0; thread_idx < num_threads; ++thread_idx) {
266           lldb::SBThread thread = process.GetThreadAtIndex(thread_idx);
267           g_vsc.thread_ids.insert(thread.GetThreadID());
268           if (ThreadHasStopReason(thread)) {
269             g_vsc.SendJSON(CreateThreadStopped(thread, stop_id));
270           }
271         }
272       }
273 
274       for (auto tid : old_thread_ids) {
275         auto end = g_vsc.thread_ids.end();
276         auto pos = g_vsc.thread_ids.find(tid);
277         if (pos == end)
278           SendThreadExitedEvent(tid);
279       }
280     } else {
281       if (g_vsc.log)
282         *g_vsc.log << "error: SendThreadStoppedEvent() when process"
283                       " isn't stopped ("
284                    << lldb::SBDebugger::StateAsCString(state) << ')'
285                    << std::endl;
286     }
287   } else {
288     if (g_vsc.log)
289       *g_vsc.log << "error: SendThreadStoppedEvent() invalid process"
290                  << std::endl;
291   }
292   g_vsc.RunStopCommands();
293 }
294 
295 // "ProcessEvent": {
296 //   "allOf": [
297 //     { "$ref": "#/definitions/Event" },
298 //     {
299 //       "type": "object",
300 //       "description": "Event message for 'process' event type. The event
301 //                       indicates that the debugger has begun debugging a
302 //                       new process. Either one that it has launched, or one
303 //                       that it has attached to.",
304 //       "properties": {
305 //         "event": {
306 //           "type": "string",
307 //           "enum": [ "process" ]
308 //         },
309 //         "body": {
310 //           "type": "object",
311 //           "properties": {
312 //             "name": {
313 //               "type": "string",
314 //               "description": "The logical name of the process. This is
315 //                               usually the full path to process's executable
316 //                               file. Example: /home/myproj/program.js."
317 //             },
318 //             "systemProcessId": {
319 //               "type": "integer",
320 //               "description": "The system process id of the debugged process.
321 //                               This property will be missing for non-system
322 //                               processes."
323 //             },
324 //             "isLocalProcess": {
325 //               "type": "boolean",
326 //               "description": "If true, the process is running on the same
327 //                               computer as the debug adapter."
328 //             },
329 //             "startMethod": {
330 //               "type": "string",
331 //               "enum": [ "launch", "attach", "attachForSuspendedLaunch" ],
332 //               "description": "Describes how the debug engine started
333 //                               debugging this process.",
334 //               "enumDescriptions": [
335 //                 "Process was launched under the debugger.",
336 //                 "Debugger attached to an existing process.",
337 //                 "A project launcher component has launched a new process in
338 //                  a suspended state and then asked the debugger to attach."
339 //               ]
340 //             }
341 //           },
342 //           "required": [ "name" ]
343 //         }
344 //       },
345 //       "required": [ "event", "body" ]
346 //     }
347 //   ]
348 // }
349 void SendProcessEvent(LaunchMethod launch_method) {
350   lldb::SBFileSpec exe_fspec = g_vsc.target.GetExecutable();
351   char exe_path[PATH_MAX];
352   exe_fspec.GetPath(exe_path, sizeof(exe_path));
353   llvm::json::Object event(CreateEventObject("process"));
354   llvm::json::Object body;
355   EmplaceSafeString(body, "name", std::string(exe_path));
356   const auto pid = g_vsc.target.GetProcess().GetProcessID();
357   body.try_emplace("systemProcessId", (int64_t)pid);
358   body.try_emplace("isLocalProcess", true);
359   const char *startMethod = nullptr;
360   switch (launch_method) {
361   case Launch:
362     startMethod = "launch";
363     break;
364   case Attach:
365     startMethod = "attach";
366     break;
367   case AttachForSuspendedLaunch:
368     startMethod = "attachForSuspendedLaunch";
369     break;
370   }
371   body.try_emplace("startMethod", startMethod);
372   event.try_emplace("body", std::move(body));
373   g_vsc.SendJSON(llvm::json::Value(std::move(event)));
374 }
375 
376 // Grab any STDOUT and STDERR from the process and send it up to VS Code
377 // via an "output" event to the "stdout" and "stderr" categories.
378 void SendStdOutStdErr(lldb::SBProcess &process) {
379   char buffer[1024];
380   size_t count;
381   while ((count = process.GetSTDOUT(buffer, sizeof(buffer))) > 0)
382     g_vsc.SendOutput(OutputType::Stdout, llvm::StringRef(buffer, count));
383   while ((count = process.GetSTDERR(buffer, sizeof(buffer))) > 0)
384     g_vsc.SendOutput(OutputType::Stderr, llvm::StringRef(buffer, count));
385 }
386 
387 void ProgressEventThreadFunction() {
388   lldb::SBListener listener("lldb-vscode.progress.listener");
389   g_vsc.debugger.GetBroadcaster().AddListener(
390       listener, lldb::SBDebugger::eBroadcastBitProgress);
391   g_vsc.broadcaster.AddListener(listener, eBroadcastBitStopProgressThread);
392   lldb::SBEvent event;
393   bool done = false;
394   while (!done) {
395     if (listener.WaitForEvent(1, event)) {
396       const auto event_mask = event.GetType();
397       if (event.BroadcasterMatchesRef(g_vsc.broadcaster)) {
398         if (event_mask & eBroadcastBitStopProgressThread) {
399           done = true;
400         }
401       } else {
402         uint64_t progress_id = 0;
403         uint64_t completed = 0;
404         uint64_t total = 0;
405         bool is_debugger_specific = false;
406         const char *message = lldb::SBDebugger::GetProgressFromEvent(
407             event, progress_id, completed, total, is_debugger_specific);
408         if (message)
409           g_vsc.SendProgressEvent(progress_id, message, completed, total);
410       }
411     }
412   }
413 }
414 
415 // All events from the debugger, target, process, thread and frames are
416 // received in this function that runs in its own thread. We are using a
417 // "FILE *" to output packets back to VS Code and they have mutexes in them
418 // them prevent multiple threads from writing simultaneously so no locking
419 // is required.
420 void EventThreadFunction() {
421   lldb::SBEvent event;
422   lldb::SBListener listener = g_vsc.debugger.GetListener();
423   bool done = false;
424   while (!done) {
425     if (listener.WaitForEvent(1, event)) {
426       const auto event_mask = event.GetType();
427       if (lldb::SBProcess::EventIsProcessEvent(event)) {
428         lldb::SBProcess process = lldb::SBProcess::GetProcessFromEvent(event);
429         if (event_mask & lldb::SBProcess::eBroadcastBitStateChanged) {
430           auto state = lldb::SBProcess::GetStateFromEvent(event);
431           switch (state) {
432           case lldb::eStateInvalid:
433             // Not a state event
434             break;
435           case lldb::eStateUnloaded:
436             break;
437           case lldb::eStateConnected:
438             break;
439           case lldb::eStateAttaching:
440             break;
441           case lldb::eStateLaunching:
442             break;
443           case lldb::eStateStepping:
444             break;
445           case lldb::eStateCrashed:
446             break;
447           case lldb::eStateDetached:
448             break;
449           case lldb::eStateSuspended:
450             break;
451           case lldb::eStateStopped:
452             // We launch and attach in synchronous mode then the first stop
453             // event will not be delivered. If we use "launchCommands" during a
454             // launch or "attachCommands" during an attach we might some process
455             // stop events which we do not want to send an event for. We will
456             // manually send a stopped event in request_configurationDone(...)
457             // so don't send any before then.
458             if (g_vsc.configuration_done_sent) {
459               // Only report a stopped event if the process was not restarted.
460               if (!lldb::SBProcess::GetRestartedFromEvent(event)) {
461                 SendStdOutStdErr(process);
462                 SendThreadStoppedEvent();
463               }
464             }
465             break;
466           case lldb::eStateRunning:
467             g_vsc.WillContinue();
468             break;
469           case lldb::eStateExited: {
470             // Run any exit LLDB commands the user specified in the
471             // launch.json
472             g_vsc.RunExitCommands();
473             SendProcessExitedEvent(process);
474             SendTerminatedEvent();
475             done = true;
476           } break;
477           }
478         } else if ((event_mask & lldb::SBProcess::eBroadcastBitSTDOUT) ||
479                    (event_mask & lldb::SBProcess::eBroadcastBitSTDERR)) {
480           SendStdOutStdErr(process);
481         }
482       } else if (lldb::SBBreakpoint::EventIsBreakpointEvent(event)) {
483         if (event_mask & lldb::SBTarget::eBroadcastBitBreakpointChanged) {
484           auto event_type =
485               lldb::SBBreakpoint::GetBreakpointEventTypeFromEvent(event);
486           auto bp = lldb::SBBreakpoint::GetBreakpointFromEvent(event);
487           // If the breakpoint was originated from the IDE, it will have the
488           // BreakpointBase::GetBreakpointLabel() label attached. Regardless
489           // of wether the locations were added or removed, the breakpoint
490           // ins't going away, so we the reason is always "changed".
491           if ((event_type & lldb::eBreakpointEventTypeLocationsAdded ||
492                event_type & lldb::eBreakpointEventTypeLocationsRemoved) &&
493               bp.MatchesName(BreakpointBase::GetBreakpointLabel())) {
494             auto bp_event = CreateEventObject("breakpoint");
495             llvm::json::Object body;
496             // As VSCode already knows the path of this breakpoint, we don't
497             // need to send it back as part of a "changed" event. This
498             // prevent us from sending to VSCode paths that should be source
499             // mapped. Note that CreateBreakpoint doesn't apply source mapping.
500             // Besides, the current implementation of VSCode ignores the
501             // "source" element of breakpoint events.
502             llvm::json::Value source_bp = CreateBreakpoint(bp);
503             source_bp.getAsObject()->erase("source");
504 
505             body.try_emplace("breakpoint", source_bp);
506             body.try_emplace("reason", "changed");
507             bp_event.try_emplace("body", std::move(body));
508             g_vsc.SendJSON(llvm::json::Value(std::move(bp_event)));
509           }
510         }
511       } else if (event.BroadcasterMatchesRef(g_vsc.broadcaster)) {
512         if (event_mask & eBroadcastBitStopEventThread) {
513           done = true;
514         }
515       }
516     }
517   }
518 }
519 
520 // Both attach and launch take a either a sourcePath or sourceMap
521 // argument (or neither), from which we need to set the target.source-map.
522 void SetSourceMapFromArguments(const llvm::json::Object &arguments) {
523   const char *sourceMapHelp =
524       "source must be be an array of two-element arrays, "
525       "each containing a source and replacement path string.\n";
526 
527   std::string sourceMapCommand;
528   llvm::raw_string_ostream strm(sourceMapCommand);
529   strm << "settings set target.source-map ";
530   auto sourcePath = GetString(arguments, "sourcePath");
531 
532   // sourceMap is the new, more general form of sourcePath and overrides it.
533   auto sourceMap = arguments.getArray("sourceMap");
534   if (sourceMap) {
535     for (const auto &value : *sourceMap) {
536       auto mapping = value.getAsArray();
537       if (mapping == nullptr || mapping->size() != 2 ||
538           (*mapping)[0].kind() != llvm::json::Value::String ||
539           (*mapping)[1].kind() != llvm::json::Value::String) {
540         g_vsc.SendOutput(OutputType::Console, llvm::StringRef(sourceMapHelp));
541         return;
542       }
543       auto mapFrom = GetAsString((*mapping)[0]);
544       auto mapTo = GetAsString((*mapping)[1]);
545       strm << "\"" << mapFrom << "\" \"" << mapTo << "\" ";
546     }
547   } else {
548     if (ObjectContainsKey(arguments, "sourceMap")) {
549       g_vsc.SendOutput(OutputType::Console, llvm::StringRef(sourceMapHelp));
550       return;
551     }
552     if (sourcePath.empty())
553       return;
554     // Do any source remapping needed before we create our targets
555     strm << "\".\" \"" << sourcePath << "\"";
556   }
557   strm.flush();
558   if (!sourceMapCommand.empty()) {
559     g_vsc.RunLLDBCommands("Setting source map:", {sourceMapCommand});
560   }
561 }
562 
563 // "AttachRequest": {
564 //   "allOf": [ { "$ref": "#/definitions/Request" }, {
565 //     "type": "object",
566 //     "description": "Attach request; value of command field is 'attach'.",
567 //     "properties": {
568 //       "command": {
569 //         "type": "string",
570 //         "enum": [ "attach" ]
571 //       },
572 //       "arguments": {
573 //         "$ref": "#/definitions/AttachRequestArguments"
574 //       }
575 //     },
576 //     "required": [ "command", "arguments" ]
577 //   }]
578 // },
579 // "AttachRequestArguments": {
580 //   "type": "object",
581 //   "description": "Arguments for 'attach' request.\nThe attach request has no
582 //   standardized attributes."
583 // },
584 // "AttachResponse": {
585 //   "allOf": [ { "$ref": "#/definitions/Response" }, {
586 //     "type": "object",
587 //     "description": "Response to 'attach' request. This is just an
588 //     acknowledgement, so no body field is required."
589 //   }]
590 // }
591 void request_attach(const llvm::json::Object &request) {
592   g_vsc.is_attach = true;
593   llvm::json::Object response;
594   lldb::SBError error;
595   FillResponse(request, response);
596   lldb::SBAttachInfo attach_info;
597   auto arguments = request.getObject("arguments");
598   const lldb::pid_t pid =
599       GetUnsigned(arguments, "pid", LLDB_INVALID_PROCESS_ID);
600   if (pid != LLDB_INVALID_PROCESS_ID)
601     attach_info.SetProcessID(pid);
602   const auto wait_for = GetBoolean(arguments, "waitFor", false);
603   attach_info.SetWaitForLaunch(wait_for, false /*async*/);
604   g_vsc.init_commands = GetStrings(arguments, "initCommands");
605   g_vsc.pre_run_commands = GetStrings(arguments, "preRunCommands");
606   g_vsc.stop_commands = GetStrings(arguments, "stopCommands");
607   g_vsc.exit_commands = GetStrings(arguments, "exitCommands");
608   g_vsc.terminate_commands = GetStrings(arguments, "terminateCommands");
609   auto attachCommands = GetStrings(arguments, "attachCommands");
610   llvm::StringRef core_file = GetString(arguments, "coreFile");
611   const uint64_t timeout_seconds = GetUnsigned(arguments, "timeout", 30);
612   g_vsc.stop_at_entry =
613       core_file.empty() ? GetBoolean(arguments, "stopOnEntry", false) : true;
614   std::vector<std::string> postRunCommands =
615       GetStrings(arguments, "postRunCommands");
616   const llvm::StringRef debuggerRoot = GetString(arguments, "debuggerRoot");
617 
618   // This is a hack for loading DWARF in .o files on Mac where the .o files
619   // in the debug map of the main executable have relative paths which require
620   // the lldb-vscode binary to have its working directory set to that relative
621   // root for the .o files in order to be able to load debug info.
622   if (!debuggerRoot.empty())
623     llvm::sys::fs::set_current_path(debuggerRoot);
624 
625   // Run any initialize LLDB commands the user specified in the launch.json
626   g_vsc.RunInitCommands();
627 
628   SetSourceMapFromArguments(*arguments);
629 
630   lldb::SBError status;
631   g_vsc.SetTarget(g_vsc.CreateTargetFromArguments(*arguments, status));
632   if (status.Fail()) {
633     response["success"] = llvm::json::Value(false);
634     EmplaceSafeString(response, "message", status.GetCString());
635     g_vsc.SendJSON(llvm::json::Value(std::move(response)));
636     return;
637   }
638 
639   // Run any pre run LLDB commands the user specified in the launch.json
640   g_vsc.RunPreRunCommands();
641 
642   if (pid == LLDB_INVALID_PROCESS_ID && wait_for) {
643     char attach_msg[256];
644     auto attach_msg_len = snprintf(attach_msg, sizeof(attach_msg),
645                                    "Waiting to attach to \"%s\"...",
646                                    g_vsc.target.GetExecutable().GetFilename());
647     g_vsc.SendOutput(OutputType::Console,
648                      llvm::StringRef(attach_msg, attach_msg_len));
649   }
650   if (attachCommands.empty()) {
651     // No "attachCommands", just attach normally.
652     // Disable async events so the attach will be successful when we return from
653     // the launch call and the launch will happen synchronously
654     g_vsc.debugger.SetAsync(false);
655     if (core_file.empty())
656       g_vsc.target.Attach(attach_info, error);
657     else
658       g_vsc.target.LoadCore(core_file.data(), error);
659     // Reenable async events
660     g_vsc.debugger.SetAsync(true);
661   } else {
662     // We have "attachCommands" that are a set of commands that are expected
663     // to execute the commands after which a process should be created. If there
664     // is no valid process after running these commands, we have failed.
665     g_vsc.RunLLDBCommands("Running attachCommands:", attachCommands);
666     // The custom commands might have created a new target so we should use the
667     // selected target after these commands are run.
668     g_vsc.target = g_vsc.debugger.GetSelectedTarget();
669 
670     // Make sure the process is attached and stopped before proceeding as the
671     // the launch commands are not run using the synchronous mode.
672     error = g_vsc.WaitForProcessToStop(timeout_seconds);
673   }
674 
675   if (error.Success() && core_file.empty()) {
676     auto attached_pid = g_vsc.target.GetProcess().GetProcessID();
677     if (attached_pid == LLDB_INVALID_PROCESS_ID) {
678       if (attachCommands.empty())
679         error.SetErrorString("failed to attach to a process");
680       else
681         error.SetErrorString("attachCommands failed to attach to a process");
682     }
683   }
684 
685   if (error.Fail()) {
686     response["success"] = llvm::json::Value(false);
687     EmplaceSafeString(response, "message", std::string(error.GetCString()));
688   } else {
689     g_vsc.RunLLDBCommands("Running postRunCommands:", postRunCommands);
690   }
691 
692   g_vsc.SendJSON(llvm::json::Value(std::move(response)));
693   if (error.Success()) {
694     SendProcessEvent(Attach);
695     g_vsc.SendJSON(CreateEventObject("initialized"));
696   }
697 }
698 
699 // "ContinueRequest": {
700 //   "allOf": [ { "$ref": "#/definitions/Request" }, {
701 //     "type": "object",
702 //     "description": "Continue request; value of command field is 'continue'.
703 //                     The request starts the debuggee to run again.",
704 //     "properties": {
705 //       "command": {
706 //         "type": "string",
707 //         "enum": [ "continue" ]
708 //       },
709 //       "arguments": {
710 //         "$ref": "#/definitions/ContinueArguments"
711 //       }
712 //     },
713 //     "required": [ "command", "arguments"  ]
714 //   }]
715 // },
716 // "ContinueArguments": {
717 //   "type": "object",
718 //   "description": "Arguments for 'continue' request.",
719 //   "properties": {
720 //     "threadId": {
721 //       "type": "integer",
722 //       "description": "Continue execution for the specified thread (if
723 //                       possible). If the backend cannot continue on a single
724 //                       thread but will continue on all threads, it should
725 //                       set the allThreadsContinued attribute in the response
726 //                       to true."
727 //     }
728 //   },
729 //   "required": [ "threadId" ]
730 // },
731 // "ContinueResponse": {
732 //   "allOf": [ { "$ref": "#/definitions/Response" }, {
733 //     "type": "object",
734 //     "description": "Response to 'continue' request.",
735 //     "properties": {
736 //       "body": {
737 //         "type": "object",
738 //         "properties": {
739 //           "allThreadsContinued": {
740 //             "type": "boolean",
741 //             "description": "If true, the continue request has ignored the
742 //                             specified thread and continued all threads
743 //                             instead. If this attribute is missing a value
744 //                             of 'true' is assumed for backward
745 //                             compatibility."
746 //           }
747 //         }
748 //       }
749 //     },
750 //     "required": [ "body" ]
751 //   }]
752 // }
753 void request_continue(const llvm::json::Object &request) {
754   llvm::json::Object response;
755   FillResponse(request, response);
756   lldb::SBProcess process = g_vsc.target.GetProcess();
757   auto arguments = request.getObject("arguments");
758   // Remember the thread ID that caused the resume so we can set the
759   // "threadCausedFocus" boolean value in the "stopped" events.
760   g_vsc.focus_tid = GetUnsigned(arguments, "threadId", LLDB_INVALID_THREAD_ID);
761   lldb::SBError error = process.Continue();
762   llvm::json::Object body;
763   body.try_emplace("allThreadsContinued", true);
764   response.try_emplace("body", std::move(body));
765   g_vsc.SendJSON(llvm::json::Value(std::move(response)));
766 }
767 
768 // "ConfigurationDoneRequest": {
769 //   "allOf": [ { "$ref": "#/definitions/Request" }, {
770 //             "type": "object",
771 //             "description": "ConfigurationDone request; value of command field
772 //             is 'configurationDone'.\nThe client of the debug protocol must
773 //             send this request at the end of the sequence of configuration
774 //             requests (which was started by the InitializedEvent).",
775 //             "properties": {
776 //             "command": {
777 //             "type": "string",
778 //             "enum": [ "configurationDone" ]
779 //             },
780 //             "arguments": {
781 //             "$ref": "#/definitions/ConfigurationDoneArguments"
782 //             }
783 //             },
784 //             "required": [ "command" ]
785 //             }]
786 // },
787 // "ConfigurationDoneArguments": {
788 //   "type": "object",
789 //   "description": "Arguments for 'configurationDone' request.\nThe
790 //   configurationDone request has no standardized attributes."
791 // },
792 // "ConfigurationDoneResponse": {
793 //   "allOf": [ { "$ref": "#/definitions/Response" }, {
794 //             "type": "object",
795 //             "description": "Response to 'configurationDone' request. This is
796 //             just an acknowledgement, so no body field is required."
797 //             }]
798 // },
799 void request_configurationDone(const llvm::json::Object &request) {
800   llvm::json::Object response;
801   FillResponse(request, response);
802   g_vsc.SendJSON(llvm::json::Value(std::move(response)));
803   g_vsc.configuration_done_sent = true;
804   if (g_vsc.stop_at_entry)
805     SendThreadStoppedEvent();
806   else
807     g_vsc.target.GetProcess().Continue();
808 }
809 
810 // "DisconnectRequest": {
811 //   "allOf": [ { "$ref": "#/definitions/Request" }, {
812 //     "type": "object",
813 //     "description": "Disconnect request; value of command field is
814 //                     'disconnect'.",
815 //     "properties": {
816 //       "command": {
817 //         "type": "string",
818 //         "enum": [ "disconnect" ]
819 //       },
820 //       "arguments": {
821 //         "$ref": "#/definitions/DisconnectArguments"
822 //       }
823 //     },
824 //     "required": [ "command" ]
825 //   }]
826 // },
827 // "DisconnectArguments": {
828 //   "type": "object",
829 //   "description": "Arguments for 'disconnect' request.",
830 //   "properties": {
831 //     "terminateDebuggee": {
832 //       "type": "boolean",
833 //       "description": "Indicates whether the debuggee should be terminated
834 //                       when the debugger is disconnected. If unspecified,
835 //                       the debug adapter is free to do whatever it thinks
836 //                       is best. A client can only rely on this attribute
837 //                       being properly honored if a debug adapter returns
838 //                       true for the 'supportTerminateDebuggee' capability."
839 //     },
840 //     "restart": {
841 //       "type": "boolean",
842 //       "description": "Indicates whether the debuggee should be restart
843 //                       the process."
844 //     }
845 //   }
846 // },
847 // "DisconnectResponse": {
848 //   "allOf": [ { "$ref": "#/definitions/Response" }, {
849 //     "type": "object",
850 //     "description": "Response to 'disconnect' request. This is just an
851 //                     acknowledgement, so no body field is required."
852 //   }]
853 // }
854 void request_disconnect(const llvm::json::Object &request) {
855   llvm::json::Object response;
856   FillResponse(request, response);
857   auto arguments = request.getObject("arguments");
858 
859   bool defaultTerminateDebuggee = g_vsc.is_attach ? false : true;
860   bool terminateDebuggee =
861       GetBoolean(arguments, "terminateDebuggee", defaultTerminateDebuggee);
862   lldb::SBProcess process = g_vsc.target.GetProcess();
863   auto state = process.GetState();
864   switch (state) {
865   case lldb::eStateInvalid:
866   case lldb::eStateUnloaded:
867   case lldb::eStateDetached:
868   case lldb::eStateExited:
869     break;
870   case lldb::eStateConnected:
871   case lldb::eStateAttaching:
872   case lldb::eStateLaunching:
873   case lldb::eStateStepping:
874   case lldb::eStateCrashed:
875   case lldb::eStateSuspended:
876   case lldb::eStateStopped:
877   case lldb::eStateRunning:
878     g_vsc.debugger.SetAsync(false);
879     lldb::SBError error = terminateDebuggee ? process.Kill() : process.Detach();
880     if (!error.Success())
881       response.try_emplace("error", error.GetCString());
882     g_vsc.debugger.SetAsync(true);
883     break;
884   }
885   SendTerminatedEvent();
886   g_vsc.SendJSON(llvm::json::Value(std::move(response)));
887   if (g_vsc.event_thread.joinable()) {
888     g_vsc.broadcaster.BroadcastEventByType(eBroadcastBitStopEventThread);
889     g_vsc.event_thread.join();
890   }
891   if (g_vsc.progress_event_thread.joinable()) {
892     g_vsc.broadcaster.BroadcastEventByType(eBroadcastBitStopProgressThread);
893     g_vsc.progress_event_thread.join();
894   }
895 }
896 
897 void request_exceptionInfo(const llvm::json::Object &request) {
898   llvm::json::Object response;
899   FillResponse(request, response);
900   auto arguments = request.getObject("arguments");
901   llvm::json::Object body;
902   lldb::SBThread thread = g_vsc.GetLLDBThread(*arguments);
903   if (thread.IsValid()) {
904     auto stopReason = thread.GetStopReason();
905     if (stopReason == lldb::eStopReasonSignal)
906       body.try_emplace("exceptionId", "signal");
907     else if (stopReason == lldb::eStopReasonBreakpoint) {
908       ExceptionBreakpoint *exc_bp = g_vsc.GetExceptionBPFromStopReason(thread);
909       if (exc_bp) {
910         EmplaceSafeString(body, "exceptionId", exc_bp->filter);
911         EmplaceSafeString(body, "description", exc_bp->label);
912       } else {
913         body.try_emplace("exceptionId", "exception");
914       }
915     } else {
916       body.try_emplace("exceptionId", "exception");
917     }
918     if (!ObjectContainsKey(body, "description")) {
919       char description[1024];
920       if (thread.GetStopDescription(description, sizeof(description))) {
921         EmplaceSafeString(body, "description", std::string(description));
922       }
923     }
924     body.try_emplace("breakMode", "always");
925     // auto excInfoCount = thread.GetStopReasonDataCount();
926     // for (auto i=0; i<excInfoCount; ++i) {
927     //   uint64_t exc_data = thread.GetStopReasonDataAtIndex(i);
928     // }
929   } else {
930     response["success"] = llvm::json::Value(false);
931   }
932   response.try_emplace("body", std::move(body));
933   g_vsc.SendJSON(llvm::json::Value(std::move(response)));
934 }
935 
936 // "CompletionsRequest": {
937 //   "allOf": [ { "$ref": "#/definitions/Request" }, {
938 //     "type": "object",
939 //     "description": "Returns a list of possible completions for a given caret
940 //     position and text.\nThe CompletionsRequest may only be called if the
941 //     'supportsCompletionsRequest' capability exists and is true.",
942 //     "properties": {
943 //       "command": {
944 //         "type": "string",
945 //         "enum": [ "completions" ]
946 //       },
947 //       "arguments": {
948 //         "$ref": "#/definitions/CompletionsArguments"
949 //       }
950 //     },
951 //     "required": [ "command", "arguments"  ]
952 //   }]
953 // },
954 // "CompletionsArguments": {
955 //   "type": "object",
956 //   "description": "Arguments for 'completions' request.",
957 //   "properties": {
958 //     "frameId": {
959 //       "type": "integer",
960 //       "description": "Returns completions in the scope of this stack frame.
961 //       If not specified, the completions are returned for the global scope."
962 //     },
963 //     "text": {
964 //       "type": "string",
965 //       "description": "One or more source lines. Typically this is the text a
966 //       user has typed into the debug console before he asked for completion."
967 //     },
968 //     "column": {
969 //       "type": "integer",
970 //       "description": "The character position for which to determine the
971 //       completion proposals."
972 //     },
973 //     "line": {
974 //       "type": "integer",
975 //       "description": "An optional line for which to determine the completion
976 //       proposals. If missing the first line of the text is assumed."
977 //     }
978 //   },
979 //   "required": [ "text", "column" ]
980 // },
981 // "CompletionsResponse": {
982 //   "allOf": [ { "$ref": "#/definitions/Response" }, {
983 //     "type": "object",
984 //     "description": "Response to 'completions' request.",
985 //     "properties": {
986 //       "body": {
987 //         "type": "object",
988 //         "properties": {
989 //           "targets": {
990 //             "type": "array",
991 //             "items": {
992 //               "$ref": "#/definitions/CompletionItem"
993 //             },
994 //             "description": "The possible completions for ."
995 //           }
996 //         },
997 //         "required": [ "targets" ]
998 //       }
999 //     },
1000 //     "required": [ "body" ]
1001 //   }]
1002 // },
1003 // "CompletionItem": {
1004 //   "type": "object",
1005 //   "description": "CompletionItems are the suggestions returned from the
1006 //   CompletionsRequest.", "properties": {
1007 //     "label": {
1008 //       "type": "string",
1009 //       "description": "The label of this completion item. By default this is
1010 //       also the text that is inserted when selecting this completion."
1011 //     },
1012 //     "text": {
1013 //       "type": "string",
1014 //       "description": "If text is not falsy then it is inserted instead of the
1015 //       label."
1016 //     },
1017 //     "sortText": {
1018 //       "type": "string",
1019 //       "description": "A string that should be used when comparing this item
1020 //       with other items. When `falsy` the label is used."
1021 //     },
1022 //     "type": {
1023 //       "$ref": "#/definitions/CompletionItemType",
1024 //       "description": "The item's type. Typically the client uses this
1025 //       information to render the item in the UI with an icon."
1026 //     },
1027 //     "start": {
1028 //       "type": "integer",
1029 //       "description": "This value determines the location (in the
1030 //       CompletionsRequest's 'text' attribute) where the completion text is
1031 //       added.\nIf missing the text is added at the location specified by the
1032 //       CompletionsRequest's 'column' attribute."
1033 //     },
1034 //     "length": {
1035 //       "type": "integer",
1036 //       "description": "This value determines how many characters are
1037 //       overwritten by the completion text.\nIf missing the value 0 is assumed
1038 //       which results in the completion text being inserted."
1039 //     }
1040 //   },
1041 //   "required": [ "label" ]
1042 // },
1043 // "CompletionItemType": {
1044 //   "type": "string",
1045 //   "description": "Some predefined types for the CompletionItem. Please note
1046 //   that not all clients have specific icons for all of them.", "enum": [
1047 //   "method", "function", "constructor", "field", "variable", "class",
1048 //   "interface", "module", "property", "unit", "value", "enum", "keyword",
1049 //   "snippet", "text", "color", "file", "reference", "customcolor" ]
1050 // }
1051 void request_completions(const llvm::json::Object &request) {
1052   llvm::json::Object response;
1053   FillResponse(request, response);
1054   llvm::json::Object body;
1055   auto arguments = request.getObject("arguments");
1056   std::string text = std::string(GetString(arguments, "text"));
1057   auto original_column = GetSigned(arguments, "column", text.size());
1058   auto actual_column = original_column - 1;
1059   llvm::json::Array targets;
1060   // NOTE: the 'line' argument is not needed, as multiline expressions
1061   // work well already
1062   // TODO: support frameID. Currently
1063   // g_vsc.debugger.GetCommandInterpreter().HandleCompletionWithDescriptions
1064   // is frame-unaware.
1065 
1066   if (!text.empty() && text[0] == '`') {
1067     text = text.substr(1);
1068     actual_column--;
1069   } else {
1070     text = "p " + text;
1071     actual_column += 2;
1072   }
1073   lldb::SBStringList matches;
1074   lldb::SBStringList descriptions;
1075   g_vsc.debugger.GetCommandInterpreter().HandleCompletionWithDescriptions(
1076       text.c_str(), actual_column, 0, -1, matches, descriptions);
1077   size_t count = std::min((uint32_t)100, matches.GetSize());
1078   targets.reserve(count);
1079   for (size_t i = 0; i < count; i++) {
1080     std::string match = matches.GetStringAtIndex(i);
1081     std::string description = descriptions.GetStringAtIndex(i);
1082 
1083     llvm::json::Object item;
1084 
1085     llvm::StringRef match_ref = match;
1086     for (llvm::StringRef commit_point : {".", "->"}) {
1087       if (match_ref.contains(commit_point)) {
1088         match_ref = match_ref.rsplit(commit_point).second;
1089       }
1090     }
1091     EmplaceSafeString(item, "text", match_ref);
1092 
1093     if (description.empty())
1094       EmplaceSafeString(item, "label", match);
1095     else
1096       EmplaceSafeString(item, "label", match + " -- " + description);
1097 
1098     targets.emplace_back(std::move(item));
1099   }
1100 
1101   body.try_emplace("targets", std::move(targets));
1102   response.try_emplace("body", std::move(body));
1103   g_vsc.SendJSON(llvm::json::Value(std::move(response)));
1104 }
1105 
1106 //  "EvaluateRequest": {
1107 //    "allOf": [ { "$ref": "#/definitions/Request" }, {
1108 //      "type": "object",
1109 //      "description": "Evaluate request; value of command field is 'evaluate'.
1110 //                      Evaluates the given expression in the context of the
1111 //                      top most stack frame. The expression has access to any
1112 //                      variables and arguments that are in scope.",
1113 //      "properties": {
1114 //        "command": {
1115 //          "type": "string",
1116 //          "enum": [ "evaluate" ]
1117 //        },
1118 //        "arguments": {
1119 //          "$ref": "#/definitions/EvaluateArguments"
1120 //        }
1121 //      },
1122 //      "required": [ "command", "arguments"  ]
1123 //    }]
1124 //  },
1125 //  "EvaluateArguments": {
1126 //    "type": "object",
1127 //    "description": "Arguments for 'evaluate' request.",
1128 //    "properties": {
1129 //      "expression": {
1130 //        "type": "string",
1131 //        "description": "The expression to evaluate."
1132 //      },
1133 //      "frameId": {
1134 //        "type": "integer",
1135 //        "description": "Evaluate the expression in the scope of this stack
1136 //                        frame. If not specified, the expression is evaluated
1137 //                        in the global scope."
1138 //      },
1139 //      "context": {
1140 //        "type": "string",
1141 //        "_enum": [ "watch", "repl", "hover" ],
1142 //        "enumDescriptions": [
1143 //          "evaluate is run in a watch.",
1144 //          "evaluate is run from REPL console.",
1145 //          "evaluate is run from a data hover."
1146 //        ],
1147 //        "description": "The context in which the evaluate request is run."
1148 //      },
1149 //      "format": {
1150 //        "$ref": "#/definitions/ValueFormat",
1151 //        "description": "Specifies details on how to format the Evaluate
1152 //                        result."
1153 //      }
1154 //    },
1155 //    "required": [ "expression" ]
1156 //  },
1157 //  "EvaluateResponse": {
1158 //    "allOf": [ { "$ref": "#/definitions/Response" }, {
1159 //      "type": "object",
1160 //      "description": "Response to 'evaluate' request.",
1161 //      "properties": {
1162 //        "body": {
1163 //          "type": "object",
1164 //          "properties": {
1165 //            "result": {
1166 //              "type": "string",
1167 //              "description": "The result of the evaluate request."
1168 //            },
1169 //            "type": {
1170 //              "type": "string",
1171 //              "description": "The optional type of the evaluate result."
1172 //            },
1173 //            "presentationHint": {
1174 //              "$ref": "#/definitions/VariablePresentationHint",
1175 //              "description": "Properties of a evaluate result that can be
1176 //                              used to determine how to render the result in
1177 //                              the UI."
1178 //            },
1179 //            "variablesReference": {
1180 //              "type": "number",
1181 //              "description": "If variablesReference is > 0, the evaluate
1182 //                              result is structured and its children can be
1183 //                              retrieved by passing variablesReference to the
1184 //                              VariablesRequest."
1185 //            },
1186 //            "namedVariables": {
1187 //              "type": "number",
1188 //              "description": "The number of named child variables. The
1189 //                              client can use this optional information to
1190 //                              present the variables in a paged UI and fetch
1191 //                              them in chunks."
1192 //            },
1193 //            "indexedVariables": {
1194 //              "type": "number",
1195 //              "description": "The number of indexed child variables. The
1196 //                              client can use this optional information to
1197 //                              present the variables in a paged UI and fetch
1198 //                              them in chunks."
1199 //            }
1200 //          },
1201 //          "required": [ "result", "variablesReference" ]
1202 //        }
1203 //      },
1204 //      "required": [ "body" ]
1205 //    }]
1206 //  }
1207 void request_evaluate(const llvm::json::Object &request) {
1208   llvm::json::Object response;
1209   FillResponse(request, response);
1210   llvm::json::Object body;
1211   auto arguments = request.getObject("arguments");
1212   lldb::SBFrame frame = g_vsc.GetLLDBFrame(*arguments);
1213   const auto expression = GetString(arguments, "expression");
1214   llvm::StringRef context = GetString(arguments, "context");
1215 
1216   if (!expression.empty() && expression[0] == '`') {
1217     auto result =
1218         RunLLDBCommands(llvm::StringRef(), {std::string(expression.substr(1))});
1219     EmplaceSafeString(body, "result", result);
1220     body.try_emplace("variablesReference", (int64_t)0);
1221   } else {
1222     // Always try to get the answer from the local variables if possible. If
1223     // this fails, then if the context is not "hover", actually evaluate an
1224     // expression using the expression parser.
1225     //
1226     // "frame variable" is more reliable than the expression parser in
1227     // many cases and it is faster.
1228     lldb::SBValue value = frame.GetValueForVariablePath(
1229         expression.data(), lldb::eDynamicDontRunTarget);
1230 
1231     // Freeze dry the value in case users expand it later in the debug console
1232     if (value.GetError().Success() && context == "repl")
1233       value = value.Persist();
1234 
1235     if (value.GetError().Fail() && context != "hover")
1236       value = frame.EvaluateExpression(expression.data());
1237 
1238     if (value.GetError().Fail()) {
1239       response["success"] = llvm::json::Value(false);
1240       // This error object must live until we're done with the pointer returned
1241       // by GetCString().
1242       lldb::SBError error = value.GetError();
1243       const char *error_cstr = error.GetCString();
1244       if (error_cstr && error_cstr[0])
1245         EmplaceSafeString(response, "message", std::string(error_cstr));
1246       else
1247         EmplaceSafeString(response, "message", "evaluate failed");
1248     } else {
1249       SetValueForKey(value, body, "result");
1250       auto value_typename = value.GetType().GetDisplayTypeName();
1251       EmplaceSafeString(body, "type",
1252                         value_typename ? value_typename : NO_TYPENAME);
1253       if (value.MightHaveChildren()) {
1254         auto variableReference = g_vsc.variables.InsertExpandableVariable(
1255             value, /*is_permanent=*/context == "repl");
1256         body.try_emplace("variablesReference", variableReference);
1257       } else {
1258         body.try_emplace("variablesReference", (int64_t)0);
1259       }
1260     }
1261   }
1262   response.try_emplace("body", std::move(body));
1263   g_vsc.SendJSON(llvm::json::Value(std::move(response)));
1264 }
1265 
1266 // "compileUnitsRequest": {
1267 //   "allOf": [ { "$ref": "#/definitions/Request" }, {
1268 //     "type": "object",
1269 //     "description": "Compile Unit request; value of command field is
1270 //                     'compileUnits'.",
1271 //     "properties": {
1272 //       "command": {
1273 //         "type": "string",
1274 //         "enum": [ "compileUnits" ]
1275 //       },
1276 //       "arguments": {
1277 //         "$ref": "#/definitions/compileUnitRequestArguments"
1278 //       }
1279 //     },
1280 //     "required": [ "command", "arguments" ]
1281 //   }]
1282 // },
1283 // "compileUnitsRequestArguments": {
1284 //   "type": "object",
1285 //   "description": "Arguments for 'compileUnits' request.",
1286 //   "properties": {
1287 //     "moduleId": {
1288 //       "type": "string",
1289 //       "description": "The ID of the module."
1290 //     }
1291 //   },
1292 //   "required": [ "moduleId" ]
1293 // },
1294 // "compileUnitsResponse": {
1295 //   "allOf": [ { "$ref": "#/definitions/Response" }, {
1296 //     "type": "object",
1297 //     "description": "Response to 'compileUnits' request.",
1298 //     "properties": {
1299 //       "body": {
1300 //         "description": "Response to 'compileUnits' request. Array of
1301 //                         paths of compile units."
1302 //       }
1303 //     }
1304 //   }]
1305 // }
1306 void request_compileUnits(const llvm::json::Object &request) {
1307   llvm::json::Object response;
1308   FillResponse(request, response);
1309   llvm::json::Object body;
1310   llvm::json::Array units;
1311   auto arguments = request.getObject("arguments");
1312   std::string module_id = std::string(GetString(arguments, "moduleId"));
1313   int num_modules = g_vsc.target.GetNumModules();
1314   for (int i = 0; i < num_modules; i++) {
1315     auto curr_module = g_vsc.target.GetModuleAtIndex(i);
1316     if (module_id == curr_module.GetUUIDString()) {
1317       int num_units = curr_module.GetNumCompileUnits();
1318       for (int j = 0; j < num_units; j++) {
1319         auto curr_unit = curr_module.GetCompileUnitAtIndex(j);
1320         units.emplace_back(CreateCompileUnit(curr_unit));
1321       }
1322       body.try_emplace("compileUnits", std::move(units));
1323       break;
1324     }
1325   }
1326   response.try_emplace("body", std::move(body));
1327   g_vsc.SendJSON(llvm::json::Value(std::move(response)));
1328 }
1329 
1330 // "modulesRequest": {
1331 //   "allOf": [ { "$ref": "#/definitions/Request" }, {
1332 //     "type": "object",
1333 //     "description": "Modules request; value of command field is
1334 //                     'modules'.",
1335 //     "properties": {
1336 //       "command": {
1337 //         "type": "string",
1338 //         "enum": [ "modules" ]
1339 //       },
1340 //     },
1341 //     "required": [ "command" ]
1342 //   }]
1343 // },
1344 // "modulesResponse": {
1345 //   "allOf": [ { "$ref": "#/definitions/Response" }, {
1346 //     "type": "object",
1347 //     "description": "Response to 'modules' request.",
1348 //     "properties": {
1349 //       "body": {
1350 //         "description": "Response to 'modules' request. Array of
1351 //                         module objects."
1352 //       }
1353 //     }
1354 //   }]
1355 // }
1356 void request_modules(const llvm::json::Object &request) {
1357   llvm::json::Object response;
1358   FillResponse(request, response);
1359 
1360   llvm::json::Array modules;
1361   for (size_t i = 0; i < g_vsc.target.GetNumModules(); i++) {
1362     lldb::SBModule module = g_vsc.target.GetModuleAtIndex(i);
1363     modules.emplace_back(CreateModule(module));
1364   }
1365 
1366   llvm::json::Object body;
1367   body.try_emplace("modules", std::move(modules));
1368   response.try_emplace("body", std::move(body));
1369   g_vsc.SendJSON(llvm::json::Value(std::move(response)));
1370 }
1371 
1372 // "InitializeRequest": {
1373 //   "allOf": [ { "$ref": "#/definitions/Request" }, {
1374 //     "type": "object",
1375 //     "description": "Initialize request; value of command field is
1376 //                     'initialize'.",
1377 //     "properties": {
1378 //       "command": {
1379 //         "type": "string",
1380 //         "enum": [ "initialize" ]
1381 //       },
1382 //       "arguments": {
1383 //         "$ref": "#/definitions/InitializeRequestArguments"
1384 //       }
1385 //     },
1386 //     "required": [ "command", "arguments" ]
1387 //   }]
1388 // },
1389 // "InitializeRequestArguments": {
1390 //   "type": "object",
1391 //   "description": "Arguments for 'initialize' request.",
1392 //   "properties": {
1393 //     "clientID": {
1394 //       "type": "string",
1395 //       "description": "The ID of the (frontend) client using this adapter."
1396 //     },
1397 //     "adapterID": {
1398 //       "type": "string",
1399 //       "description": "The ID of the debug adapter."
1400 //     },
1401 //     "locale": {
1402 //       "type": "string",
1403 //       "description": "The ISO-639 locale of the (frontend) client using
1404 //                       this adapter, e.g. en-US or de-CH."
1405 //     },
1406 //     "linesStartAt1": {
1407 //       "type": "boolean",
1408 //       "description": "If true all line numbers are 1-based (default)."
1409 //     },
1410 //     "columnsStartAt1": {
1411 //       "type": "boolean",
1412 //       "description": "If true all column numbers are 1-based (default)."
1413 //     },
1414 //     "pathFormat": {
1415 //       "type": "string",
1416 //       "_enum": [ "path", "uri" ],
1417 //       "description": "Determines in what format paths are specified. The
1418 //                       default is 'path', which is the native format."
1419 //     },
1420 //     "supportsVariableType": {
1421 //       "type": "boolean",
1422 //       "description": "Client supports the optional type attribute for
1423 //                       variables."
1424 //     },
1425 //     "supportsVariablePaging": {
1426 //       "type": "boolean",
1427 //       "description": "Client supports the paging of variables."
1428 //     },
1429 //     "supportsRunInTerminalRequest": {
1430 //       "type": "boolean",
1431 //       "description": "Client supports the runInTerminal request."
1432 //     }
1433 //   },
1434 //   "required": [ "adapterID" ]
1435 // },
1436 // "InitializeResponse": {
1437 //   "allOf": [ { "$ref": "#/definitions/Response" }, {
1438 //     "type": "object",
1439 //     "description": "Response to 'initialize' request.",
1440 //     "properties": {
1441 //       "body": {
1442 //         "$ref": "#/definitions/Capabilities",
1443 //         "description": "The capabilities of this debug adapter."
1444 //       }
1445 //     }
1446 //   }]
1447 // }
1448 void request_initialize(const llvm::json::Object &request) {
1449   g_vsc.debugger = lldb::SBDebugger::Create(true /*source_init_files*/);
1450   g_vsc.progress_event_thread = std::thread(ProgressEventThreadFunction);
1451 
1452   // Create an empty target right away since we might get breakpoint requests
1453   // before we are given an executable to launch in a "launch" request, or a
1454   // executable when attaching to a process by process ID in a "attach"
1455   // request.
1456   FILE *out = llvm::sys::RetryAfterSignal(nullptr, fopen, dev_null_path, "w");
1457   if (out) {
1458     // Set the output and error file handles to redirect into nothing otherwise
1459     // if any code in LLDB prints to the debugger file handles, the output and
1460     // error file handles are initialized to STDOUT and STDERR and any output
1461     // will kill our debug session.
1462     g_vsc.debugger.SetOutputFileHandle(out, true);
1463     g_vsc.debugger.SetErrorFileHandle(out, false);
1464   }
1465 
1466   // Start our event thread so we can receive events from the debugger, target,
1467   // process and more.
1468   g_vsc.event_thread = std::thread(EventThreadFunction);
1469 
1470   llvm::json::Object response;
1471   FillResponse(request, response);
1472   llvm::json::Object body;
1473   // The debug adapter supports the configurationDoneRequest.
1474   body.try_emplace("supportsConfigurationDoneRequest", true);
1475   // The debug adapter supports function breakpoints.
1476   body.try_emplace("supportsFunctionBreakpoints", true);
1477   // The debug adapter supports conditional breakpoints.
1478   body.try_emplace("supportsConditionalBreakpoints", true);
1479   // The debug adapter supports breakpoints that break execution after a
1480   // specified number of hits.
1481   body.try_emplace("supportsHitConditionalBreakpoints", true);
1482   // The debug adapter supports a (side effect free) evaluate request for
1483   // data hovers.
1484   body.try_emplace("supportsEvaluateForHovers", true);
1485   // Available filters or options for the setExceptionBreakpoints request.
1486   llvm::json::Array filters;
1487   for (const auto &exc_bp : g_vsc.exception_breakpoints) {
1488     filters.emplace_back(CreateExceptionBreakpointFilter(exc_bp));
1489   }
1490   body.try_emplace("exceptionBreakpointFilters", std::move(filters));
1491   // The debug adapter supports launching a debugee in intergrated VSCode
1492   // terminal.
1493   body.try_emplace("supportsRunInTerminalRequest", true);
1494   // The debug adapter supports stepping back via the stepBack and
1495   // reverseContinue requests.
1496   body.try_emplace("supportsStepBack", false);
1497   // The debug adapter supports setting a variable to a value.
1498   body.try_emplace("supportsSetVariable", true);
1499   // The debug adapter supports restarting a frame.
1500   body.try_emplace("supportsRestartFrame", false);
1501   // The debug adapter supports the gotoTargetsRequest.
1502   body.try_emplace("supportsGotoTargetsRequest", false);
1503   // The debug adapter supports the stepInTargetsRequest.
1504   body.try_emplace("supportsStepInTargetsRequest", false);
1505   // We need to improve the current implementation of completions in order to
1506   // enable it again. For some context, this is how VSCode works:
1507   // - VSCode sends a completion request whenever chars are added, the user
1508   //   triggers completion manually via CTRL-space or similar mechanisms, but
1509   //   not when there's a deletion. Besides, VSCode doesn't let us know which
1510   //   of these events we are handling. What is more, the use can paste or cut
1511   //   sections of the text arbitrarily.
1512   //   https://github.com/microsoft/vscode/issues/89531 tracks part of the
1513   //   issue just mentioned.
1514   // This behavior causes many problems with the current way completion is
1515   // implemented in lldb-vscode, as these requests could be really expensive,
1516   // blocking the debugger, and there could be many concurrent requests unless
1517   // the user types very slowly... We need to address this specific issue, or
1518   // at least trigger completion only when the user explicitly wants it, which
1519   // is the behavior of LLDB CLI, that expects a TAB.
1520   body.try_emplace("supportsCompletionsRequest", false);
1521   // The debug adapter supports the modules request.
1522   body.try_emplace("supportsModulesRequest", true);
1523   // The set of additional module information exposed by the debug adapter.
1524   //   body.try_emplace("additionalModuleColumns"] = ColumnDescriptor
1525   // Checksum algorithms supported by the debug adapter.
1526   //   body.try_emplace("supportedChecksumAlgorithms"] = ChecksumAlgorithm
1527   // The debug adapter supports the RestartRequest. In this case a client
1528   // should not implement 'restart' by terminating and relaunching the adapter
1529   // but by calling the RestartRequest.
1530   body.try_emplace("supportsRestartRequest", false);
1531   // The debug adapter supports 'exceptionOptions' on the
1532   // setExceptionBreakpoints request.
1533   body.try_emplace("supportsExceptionOptions", true);
1534   // The debug adapter supports a 'format' attribute on the stackTraceRequest,
1535   // variablesRequest, and evaluateRequest.
1536   body.try_emplace("supportsValueFormattingOptions", true);
1537   // The debug adapter supports the exceptionInfo request.
1538   body.try_emplace("supportsExceptionInfoRequest", true);
1539   // The debug adapter supports the 'terminateDebuggee' attribute on the
1540   // 'disconnect' request.
1541   body.try_emplace("supportTerminateDebuggee", true);
1542   // The debug adapter supports the delayed loading of parts of the stack,
1543   // which requires that both the 'startFrame' and 'levels' arguments and the
1544   // 'totalFrames' result of the 'StackTrace' request are supported.
1545   body.try_emplace("supportsDelayedStackTraceLoading", true);
1546   // The debug adapter supports the 'loadedSources' request.
1547   body.try_emplace("supportsLoadedSourcesRequest", false);
1548   // The debug adapter supports sending progress reporting events.
1549   body.try_emplace("supportsProgressReporting", true);
1550 
1551   response.try_emplace("body", std::move(body));
1552   g_vsc.SendJSON(llvm::json::Value(std::move(response)));
1553 }
1554 
1555 llvm::Error request_runInTerminal(const llvm::json::Object &launch_request) {
1556   g_vsc.is_attach = true;
1557   lldb::SBAttachInfo attach_info;
1558 
1559   llvm::Expected<std::shared_ptr<FifoFile>> comm_file_or_err =
1560       CreateRunInTerminalCommFile();
1561   if (!comm_file_or_err)
1562     return comm_file_or_err.takeError();
1563   FifoFile &comm_file = *comm_file_or_err.get();
1564 
1565   RunInTerminalDebugAdapterCommChannel comm_channel(comm_file.m_path);
1566 
1567   llvm::json::Object reverse_request = CreateRunInTerminalReverseRequest(
1568       launch_request, g_vsc.debug_adaptor_path, comm_file.m_path);
1569   llvm::json::Object reverse_response;
1570   lldb_vscode::PacketStatus status =
1571       g_vsc.SendReverseRequest(reverse_request, reverse_response);
1572   if (status != lldb_vscode::PacketStatus::Success)
1573     return llvm::createStringError(llvm::inconvertibleErrorCode(),
1574                                    "Process cannot be launched by the IDE. %s",
1575                                    comm_channel.GetLauncherError().c_str());
1576 
1577   if (llvm::Expected<lldb::pid_t> pid = comm_channel.GetLauncherPid())
1578     attach_info.SetProcessID(*pid);
1579   else
1580     return pid.takeError();
1581 
1582   g_vsc.debugger.SetAsync(false);
1583   lldb::SBError error;
1584   g_vsc.target.Attach(attach_info, error);
1585 
1586   if (error.Fail())
1587     return llvm::createStringError(llvm::inconvertibleErrorCode(),
1588                                    "Failed to attach to the target process. %s",
1589                                    comm_channel.GetLauncherError().c_str());
1590   // This will notify the runInTerminal launcher that we attached.
1591   // We have to make this async, as the function won't return until the launcher
1592   // resumes and reads the data.
1593   std::future<lldb::SBError> did_attach_message_success =
1594       comm_channel.NotifyDidAttach();
1595 
1596   // We just attached to the runInTerminal launcher, which was waiting to be
1597   // attached. We now resume it, so it can receive the didAttach notification
1598   // and then perform the exec. Upon continuing, the debugger will stop the
1599   // process right in the middle of the exec. To the user, what we are doing is
1600   // transparent, as they will only be able to see the process since the exec,
1601   // completely unaware of the preparatory work.
1602   g_vsc.target.GetProcess().Continue();
1603 
1604   // Now that the actual target is just starting (i.e. exec was just invoked),
1605   // we return the debugger to its async state.
1606   g_vsc.debugger.SetAsync(true);
1607 
1608   // If sending the notification failed, the launcher should be dead by now and
1609   // the async didAttach notification should have an error message, so we
1610   // return it. Otherwise, everything was a success.
1611   did_attach_message_success.wait();
1612   error = did_attach_message_success.get();
1613   if (error.Success())
1614     return llvm::Error::success();
1615   return llvm::createStringError(llvm::inconvertibleErrorCode(),
1616                                  error.GetCString());
1617 }
1618 
1619 // "LaunchRequest": {
1620 //   "allOf": [ { "$ref": "#/definitions/Request" }, {
1621 //     "type": "object",
1622 //     "description": "Launch request; value of command field is 'launch'.",
1623 //     "properties": {
1624 //       "command": {
1625 //         "type": "string",
1626 //         "enum": [ "launch" ]
1627 //       },
1628 //       "arguments": {
1629 //         "$ref": "#/definitions/LaunchRequestArguments"
1630 //       }
1631 //     },
1632 //     "required": [ "command", "arguments"  ]
1633 //   }]
1634 // },
1635 // "LaunchRequestArguments": {
1636 //   "type": "object",
1637 //   "description": "Arguments for 'launch' request.",
1638 //   "properties": {
1639 //     "noDebug": {
1640 //       "type": "boolean",
1641 //       "description": "If noDebug is true the launch request should launch
1642 //                       the program without enabling debugging."
1643 //     }
1644 //   }
1645 // },
1646 // "LaunchResponse": {
1647 //   "allOf": [ { "$ref": "#/definitions/Response" }, {
1648 //     "type": "object",
1649 //     "description": "Response to 'launch' request. This is just an
1650 //                     acknowledgement, so no body field is required."
1651 //   }]
1652 // }
1653 void request_launch(const llvm::json::Object &request) {
1654   g_vsc.is_attach = false;
1655   llvm::json::Object response;
1656   lldb::SBError error;
1657   FillResponse(request, response);
1658   auto arguments = request.getObject("arguments");
1659   g_vsc.init_commands = GetStrings(arguments, "initCommands");
1660   g_vsc.pre_run_commands = GetStrings(arguments, "preRunCommands");
1661   g_vsc.stop_commands = GetStrings(arguments, "stopCommands");
1662   g_vsc.exit_commands = GetStrings(arguments, "exitCommands");
1663   g_vsc.terminate_commands = GetStrings(arguments, "terminateCommands");
1664   auto launchCommands = GetStrings(arguments, "launchCommands");
1665   std::vector<std::string> postRunCommands =
1666       GetStrings(arguments, "postRunCommands");
1667   g_vsc.stop_at_entry = GetBoolean(arguments, "stopOnEntry", false);
1668   const llvm::StringRef debuggerRoot = GetString(arguments, "debuggerRoot");
1669   const uint64_t timeout_seconds = GetUnsigned(arguments, "timeout", 30);
1670 
1671   // This is a hack for loading DWARF in .o files on Mac where the .o files
1672   // in the debug map of the main executable have relative paths which require
1673   // the lldb-vscode binary to have its working directory set to that relative
1674   // root for the .o files in order to be able to load debug info.
1675   if (!debuggerRoot.empty())
1676     llvm::sys::fs::set_current_path(debuggerRoot);
1677 
1678   // Run any initialize LLDB commands the user specified in the launch.json.
1679   // This is run before target is created, so commands can't do anything with
1680   // the targets - preRunCommands are run with the target.
1681   g_vsc.RunInitCommands();
1682 
1683   SetSourceMapFromArguments(*arguments);
1684 
1685   lldb::SBError status;
1686   g_vsc.SetTarget(g_vsc.CreateTargetFromArguments(*arguments, status));
1687   if (status.Fail()) {
1688     response["success"] = llvm::json::Value(false);
1689     EmplaceSafeString(response, "message", status.GetCString());
1690     g_vsc.SendJSON(llvm::json::Value(std::move(response)));
1691     return;
1692   }
1693 
1694   // Instantiate a launch info instance for the target.
1695   auto launch_info = g_vsc.target.GetLaunchInfo();
1696 
1697   // Grab the current working directory if there is one and set it in the
1698   // launch info.
1699   const auto cwd = GetString(arguments, "cwd");
1700   if (!cwd.empty())
1701     launch_info.SetWorkingDirectory(cwd.data());
1702 
1703   // Extract any extra arguments and append them to our program arguments for
1704   // when we launch
1705   auto args = GetStrings(arguments, "args");
1706   if (!args.empty())
1707     launch_info.SetArguments(MakeArgv(args).data(), true);
1708 
1709   // Pass any environment variables along that the user specified.
1710   auto envs = GetStrings(arguments, "env");
1711   if (!envs.empty())
1712     launch_info.SetEnvironmentEntries(MakeArgv(envs).data(), true);
1713 
1714   auto flags = launch_info.GetLaunchFlags();
1715 
1716   if (GetBoolean(arguments, "disableASLR", true))
1717     flags |= lldb::eLaunchFlagDisableASLR;
1718   if (GetBoolean(arguments, "disableSTDIO", false))
1719     flags |= lldb::eLaunchFlagDisableSTDIO;
1720   if (GetBoolean(arguments, "shellExpandArguments", false))
1721     flags |= lldb::eLaunchFlagShellExpandArguments;
1722   const bool detatchOnError = GetBoolean(arguments, "detachOnError", false);
1723   launch_info.SetDetachOnError(detatchOnError);
1724   launch_info.SetLaunchFlags(flags | lldb::eLaunchFlagDebug |
1725                              lldb::eLaunchFlagStopAtEntry);
1726 
1727   // Run any pre run LLDB commands the user specified in the launch.json
1728   g_vsc.RunPreRunCommands();
1729 
1730   if (GetBoolean(arguments, "runInTerminal", false)) {
1731     if (llvm::Error err = request_runInTerminal(request))
1732       error.SetErrorString(llvm::toString(std::move(err)).c_str());
1733   } else if (launchCommands.empty()) {
1734     // Disable async events so the launch will be successful when we return from
1735     // the launch call and the launch will happen synchronously
1736     g_vsc.debugger.SetAsync(false);
1737     g_vsc.target.Launch(launch_info, error);
1738     g_vsc.debugger.SetAsync(true);
1739   } else {
1740     g_vsc.RunLLDBCommands("Running launchCommands:", launchCommands);
1741     // The custom commands might have created a new target so we should use the
1742     // selected target after these commands are run.
1743     g_vsc.target = g_vsc.debugger.GetSelectedTarget();
1744     // Make sure the process is launched and stopped at the entry point before
1745     // proceeding as the the launch commands are not run using the synchronous
1746     // mode.
1747     error = g_vsc.WaitForProcessToStop(timeout_seconds);
1748   }
1749 
1750   if (error.Fail()) {
1751     response["success"] = llvm::json::Value(false);
1752     EmplaceSafeString(response, "message", std::string(error.GetCString()));
1753   } else {
1754     g_vsc.RunLLDBCommands("Running postRunCommands:", postRunCommands);
1755   }
1756 
1757   g_vsc.SendJSON(llvm::json::Value(std::move(response)));
1758 
1759   if (g_vsc.is_attach)
1760     SendProcessEvent(Attach); // this happens when doing runInTerminal
1761   else
1762     SendProcessEvent(Launch);
1763   g_vsc.SendJSON(llvm::json::Value(CreateEventObject("initialized")));
1764 }
1765 
1766 // "NextRequest": {
1767 //   "allOf": [ { "$ref": "#/definitions/Request" }, {
1768 //     "type": "object",
1769 //     "description": "Next request; value of command field is 'next'. The
1770 //                     request starts the debuggee to run again for one step.
1771 //                     The debug adapter first sends the NextResponse and then
1772 //                     a StoppedEvent (event type 'step') after the step has
1773 //                     completed.",
1774 //     "properties": {
1775 //       "command": {
1776 //         "type": "string",
1777 //         "enum": [ "next" ]
1778 //       },
1779 //       "arguments": {
1780 //         "$ref": "#/definitions/NextArguments"
1781 //       }
1782 //     },
1783 //     "required": [ "command", "arguments"  ]
1784 //   }]
1785 // },
1786 // "NextArguments": {
1787 //   "type": "object",
1788 //   "description": "Arguments for 'next' request.",
1789 //   "properties": {
1790 //     "threadId": {
1791 //       "type": "integer",
1792 //       "description": "Execute 'next' for this thread."
1793 //     }
1794 //   },
1795 //   "required": [ "threadId" ]
1796 // },
1797 // "NextResponse": {
1798 //   "allOf": [ { "$ref": "#/definitions/Response" }, {
1799 //     "type": "object",
1800 //     "description": "Response to 'next' request. This is just an
1801 //                     acknowledgement, so no body field is required."
1802 //   }]
1803 // }
1804 void request_next(const llvm::json::Object &request) {
1805   llvm::json::Object response;
1806   FillResponse(request, response);
1807   auto arguments = request.getObject("arguments");
1808   lldb::SBThread thread = g_vsc.GetLLDBThread(*arguments);
1809   if (thread.IsValid()) {
1810     // Remember the thread ID that caused the resume so we can set the
1811     // "threadCausedFocus" boolean value in the "stopped" events.
1812     g_vsc.focus_tid = thread.GetThreadID();
1813     thread.StepOver();
1814   } else {
1815     response["success"] = llvm::json::Value(false);
1816   }
1817   g_vsc.SendJSON(llvm::json::Value(std::move(response)));
1818 }
1819 
1820 // "PauseRequest": {
1821 //   "allOf": [ { "$ref": "#/definitions/Request" }, {
1822 //     "type": "object",
1823 //     "description": "Pause request; value of command field is 'pause'. The
1824 //     request suspenses the debuggee. The debug adapter first sends the
1825 //     PauseResponse and then a StoppedEvent (event type 'pause') after the
1826 //     thread has been paused successfully.", "properties": {
1827 //       "command": {
1828 //         "type": "string",
1829 //         "enum": [ "pause" ]
1830 //       },
1831 //       "arguments": {
1832 //         "$ref": "#/definitions/PauseArguments"
1833 //       }
1834 //     },
1835 //     "required": [ "command", "arguments"  ]
1836 //   }]
1837 // },
1838 // "PauseArguments": {
1839 //   "type": "object",
1840 //   "description": "Arguments for 'pause' request.",
1841 //   "properties": {
1842 //     "threadId": {
1843 //       "type": "integer",
1844 //       "description": "Pause execution for this thread."
1845 //     }
1846 //   },
1847 //   "required": [ "threadId" ]
1848 // },
1849 // "PauseResponse": {
1850 //   "allOf": [ { "$ref": "#/definitions/Response" }, {
1851 //     "type": "object",
1852 //     "description": "Response to 'pause' request. This is just an
1853 //     acknowledgement, so no body field is required."
1854 //   }]
1855 // }
1856 void request_pause(const llvm::json::Object &request) {
1857   llvm::json::Object response;
1858   FillResponse(request, response);
1859   lldb::SBProcess process = g_vsc.target.GetProcess();
1860   lldb::SBError error = process.Stop();
1861   g_vsc.SendJSON(llvm::json::Value(std::move(response)));
1862 }
1863 
1864 // "ScopesRequest": {
1865 //   "allOf": [ { "$ref": "#/definitions/Request" }, {
1866 //     "type": "object",
1867 //     "description": "Scopes request; value of command field is 'scopes'. The
1868 //     request returns the variable scopes for a given stackframe ID.",
1869 //     "properties": {
1870 //       "command": {
1871 //         "type": "string",
1872 //         "enum": [ "scopes" ]
1873 //       },
1874 //       "arguments": {
1875 //         "$ref": "#/definitions/ScopesArguments"
1876 //       }
1877 //     },
1878 //     "required": [ "command", "arguments"  ]
1879 //   }]
1880 // },
1881 // "ScopesArguments": {
1882 //   "type": "object",
1883 //   "description": "Arguments for 'scopes' request.",
1884 //   "properties": {
1885 //     "frameId": {
1886 //       "type": "integer",
1887 //       "description": "Retrieve the scopes for this stackframe."
1888 //     }
1889 //   },
1890 //   "required": [ "frameId" ]
1891 // },
1892 // "ScopesResponse": {
1893 //   "allOf": [ { "$ref": "#/definitions/Response" }, {
1894 //     "type": "object",
1895 //     "description": "Response to 'scopes' request.",
1896 //     "properties": {
1897 //       "body": {
1898 //         "type": "object",
1899 //         "properties": {
1900 //           "scopes": {
1901 //             "type": "array",
1902 //             "items": {
1903 //               "$ref": "#/definitions/Scope"
1904 //             },
1905 //             "description": "The scopes of the stackframe. If the array has
1906 //             length zero, there are no scopes available."
1907 //           }
1908 //         },
1909 //         "required": [ "scopes" ]
1910 //       }
1911 //     },
1912 //     "required": [ "body" ]
1913 //   }]
1914 // }
1915 void request_scopes(const llvm::json::Object &request) {
1916   llvm::json::Object response;
1917   FillResponse(request, response);
1918   llvm::json::Object body;
1919   auto arguments = request.getObject("arguments");
1920   lldb::SBFrame frame = g_vsc.GetLLDBFrame(*arguments);
1921   // As the user selects different stack frames in the GUI, a "scopes" request
1922   // will be sent to the DAP. This is the only way we know that the user has
1923   // selected a frame in a thread. There are no other notifications that are
1924   // sent and VS code doesn't allow multiple frames to show variables
1925   // concurrently. If we select the thread and frame as the "scopes" requests
1926   // are sent, this allows users to type commands in the debugger console
1927   // with a backtick character to run lldb commands and these lldb commands
1928   // will now have the right context selected as they are run. If the user
1929   // types "`bt" into the debugger console and we had another thread selected
1930   // in the LLDB library, we would show the wrong thing to the user. If the
1931   // users switches threads with a lldb command like "`thread select 14", the
1932   // GUI will not update as there are no "event" notification packets that
1933   // allow us to change the currently selected thread or frame in the GUI that
1934   // I am aware of.
1935   if (frame.IsValid()) {
1936     frame.GetThread().GetProcess().SetSelectedThread(frame.GetThread());
1937     frame.GetThread().SetSelectedFrame(frame.GetFrameID());
1938   }
1939   g_vsc.variables.locals = frame.GetVariables(/*arguments=*/true,
1940                                               /*locals=*/true,
1941                                               /*statics=*/false,
1942                                               /*in_scope_only=*/true);
1943   g_vsc.variables.globals = frame.GetVariables(/*arguments=*/false,
1944                                                /*locals=*/false,
1945                                                /*statics=*/true,
1946                                                /*in_scope_only=*/true);
1947   g_vsc.variables.registers = frame.GetRegisters();
1948   body.try_emplace("scopes", g_vsc.CreateTopLevelScopes());
1949   response.try_emplace("body", std::move(body));
1950   g_vsc.SendJSON(llvm::json::Value(std::move(response)));
1951 }
1952 
1953 // "SetBreakpointsRequest": {
1954 //   "allOf": [ { "$ref": "#/definitions/Request" }, {
1955 //     "type": "object",
1956 //     "description": "SetBreakpoints request; value of command field is
1957 //     'setBreakpoints'. Sets multiple breakpoints for a single source and
1958 //     clears all previous breakpoints in that source. To clear all breakpoint
1959 //     for a source, specify an empty array. When a breakpoint is hit, a
1960 //     StoppedEvent (event type 'breakpoint') is generated.", "properties": {
1961 //       "command": {
1962 //         "type": "string",
1963 //         "enum": [ "setBreakpoints" ]
1964 //       },
1965 //       "arguments": {
1966 //         "$ref": "#/definitions/SetBreakpointsArguments"
1967 //       }
1968 //     },
1969 //     "required": [ "command", "arguments"  ]
1970 //   }]
1971 // },
1972 // "SetBreakpointsArguments": {
1973 //   "type": "object",
1974 //   "description": "Arguments for 'setBreakpoints' request.",
1975 //   "properties": {
1976 //     "source": {
1977 //       "$ref": "#/definitions/Source",
1978 //       "description": "The source location of the breakpoints; either
1979 //       source.path or source.reference must be specified."
1980 //     },
1981 //     "breakpoints": {
1982 //       "type": "array",
1983 //       "items": {
1984 //         "$ref": "#/definitions/SourceBreakpoint"
1985 //       },
1986 //       "description": "The code locations of the breakpoints."
1987 //     },
1988 //     "lines": {
1989 //       "type": "array",
1990 //       "items": {
1991 //         "type": "integer"
1992 //       },
1993 //       "description": "Deprecated: The code locations of the breakpoints."
1994 //     },
1995 //     "sourceModified": {
1996 //       "type": "boolean",
1997 //       "description": "A value of true indicates that the underlying source
1998 //       has been modified which results in new breakpoint locations."
1999 //     }
2000 //   },
2001 //   "required": [ "source" ]
2002 // },
2003 // "SetBreakpointsResponse": {
2004 //   "allOf": [ { "$ref": "#/definitions/Response" }, {
2005 //     "type": "object",
2006 //     "description": "Response to 'setBreakpoints' request. Returned is
2007 //     information about each breakpoint created by this request. This includes
2008 //     the actual code location and whether the breakpoint could be verified.
2009 //     The breakpoints returned are in the same order as the elements of the
2010 //     'breakpoints' (or the deprecated 'lines') in the
2011 //     SetBreakpointsArguments.", "properties": {
2012 //       "body": {
2013 //         "type": "object",
2014 //         "properties": {
2015 //           "breakpoints": {
2016 //             "type": "array",
2017 //             "items": {
2018 //               "$ref": "#/definitions/Breakpoint"
2019 //             },
2020 //             "description": "Information about the breakpoints. The array
2021 //             elements are in the same order as the elements of the
2022 //             'breakpoints' (or the deprecated 'lines') in the
2023 //             SetBreakpointsArguments."
2024 //           }
2025 //         },
2026 //         "required": [ "breakpoints" ]
2027 //       }
2028 //     },
2029 //     "required": [ "body" ]
2030 //   }]
2031 // },
2032 // "SourceBreakpoint": {
2033 //   "type": "object",
2034 //   "description": "Properties of a breakpoint or logpoint passed to the
2035 //   setBreakpoints request.", "properties": {
2036 //     "line": {
2037 //       "type": "integer",
2038 //       "description": "The source line of the breakpoint or logpoint."
2039 //     },
2040 //     "column": {
2041 //       "type": "integer",
2042 //       "description": "An optional source column of the breakpoint."
2043 //     },
2044 //     "condition": {
2045 //       "type": "string",
2046 //       "description": "An optional expression for conditional breakpoints."
2047 //     },
2048 //     "hitCondition": {
2049 //       "type": "string",
2050 //       "description": "An optional expression that controls how many hits of
2051 //       the breakpoint are ignored. The backend is expected to interpret the
2052 //       expression as needed."
2053 //     },
2054 //     "logMessage": {
2055 //       "type": "string",
2056 //       "description": "If this attribute exists and is non-empty, the backend
2057 //       must not 'break' (stop) but log the message instead. Expressions within
2058 //       {} are interpolated."
2059 //     }
2060 //   },
2061 //   "required": [ "line" ]
2062 // }
2063 void request_setBreakpoints(const llvm::json::Object &request) {
2064   llvm::json::Object response;
2065   lldb::SBError error;
2066   FillResponse(request, response);
2067   auto arguments = request.getObject("arguments");
2068   auto source = arguments->getObject("source");
2069   const auto path = GetString(source, "path");
2070   auto breakpoints = arguments->getArray("breakpoints");
2071   llvm::json::Array response_breakpoints;
2072 
2073   // Decode the source breakpoint infos for this "setBreakpoints" request
2074   SourceBreakpointMap request_bps;
2075   // "breakpoints" may be unset, in which case we treat it the same as being set
2076   // to an empty array.
2077   if (breakpoints) {
2078     for (const auto &bp : *breakpoints) {
2079       auto bp_obj = bp.getAsObject();
2080       if (bp_obj) {
2081         SourceBreakpoint src_bp(*bp_obj);
2082         request_bps[src_bp.line] = src_bp;
2083 
2084         // We check if this breakpoint already exists to update it
2085         auto existing_source_bps = g_vsc.source_breakpoints.find(path);
2086         if (existing_source_bps != g_vsc.source_breakpoints.end()) {
2087           const auto &existing_bp =
2088               existing_source_bps->second.find(src_bp.line);
2089           if (existing_bp != existing_source_bps->second.end()) {
2090             existing_bp->second.UpdateBreakpoint(src_bp);
2091             AppendBreakpoint(existing_bp->second.bp, response_breakpoints, path,
2092                              src_bp.line);
2093             continue;
2094           }
2095         }
2096         // At this point the breakpoint is new
2097         src_bp.SetBreakpoint(path.data());
2098         AppendBreakpoint(src_bp.bp, response_breakpoints, path, src_bp.line);
2099         g_vsc.source_breakpoints[path][src_bp.line] = std::move(src_bp);
2100       }
2101     }
2102   }
2103 
2104   // Delete any breakpoints in this source file that aren't in the
2105   // request_bps set. There is no call to remove breakpoints other than
2106   // calling this function with a smaller or empty "breakpoints" list.
2107   auto old_src_bp_pos = g_vsc.source_breakpoints.find(path);
2108   if (old_src_bp_pos != g_vsc.source_breakpoints.end()) {
2109     for (auto &old_bp : old_src_bp_pos->second) {
2110       auto request_pos = request_bps.find(old_bp.first);
2111       if (request_pos == request_bps.end()) {
2112         // This breakpoint no longer exists in this source file, delete it
2113         g_vsc.target.BreakpointDelete(old_bp.second.bp.GetID());
2114         old_src_bp_pos->second.erase(old_bp.first);
2115       }
2116     }
2117   }
2118 
2119   llvm::json::Object body;
2120   body.try_emplace("breakpoints", std::move(response_breakpoints));
2121   response.try_emplace("body", std::move(body));
2122   g_vsc.SendJSON(llvm::json::Value(std::move(response)));
2123 }
2124 
2125 // "SetExceptionBreakpointsRequest": {
2126 //   "allOf": [ { "$ref": "#/definitions/Request" }, {
2127 //     "type": "object",
2128 //     "description": "SetExceptionBreakpoints request; value of command field
2129 //     is 'setExceptionBreakpoints'. The request configures the debuggers
2130 //     response to thrown exceptions. If an exception is configured to break, a
2131 //     StoppedEvent is fired (event type 'exception').", "properties": {
2132 //       "command": {
2133 //         "type": "string",
2134 //         "enum": [ "setExceptionBreakpoints" ]
2135 //       },
2136 //       "arguments": {
2137 //         "$ref": "#/definitions/SetExceptionBreakpointsArguments"
2138 //       }
2139 //     },
2140 //     "required": [ "command", "arguments"  ]
2141 //   }]
2142 // },
2143 // "SetExceptionBreakpointsArguments": {
2144 //   "type": "object",
2145 //   "description": "Arguments for 'setExceptionBreakpoints' request.",
2146 //   "properties": {
2147 //     "filters": {
2148 //       "type": "array",
2149 //       "items": {
2150 //         "type": "string"
2151 //       },
2152 //       "description": "IDs of checked exception options. The set of IDs is
2153 //       returned via the 'exceptionBreakpointFilters' capability."
2154 //     },
2155 //     "exceptionOptions": {
2156 //       "type": "array",
2157 //       "items": {
2158 //         "$ref": "#/definitions/ExceptionOptions"
2159 //       },
2160 //       "description": "Configuration options for selected exceptions."
2161 //     }
2162 //   },
2163 //   "required": [ "filters" ]
2164 // },
2165 // "SetExceptionBreakpointsResponse": {
2166 //   "allOf": [ { "$ref": "#/definitions/Response" }, {
2167 //     "type": "object",
2168 //     "description": "Response to 'setExceptionBreakpoints' request. This is
2169 //     just an acknowledgement, so no body field is required."
2170 //   }]
2171 // }
2172 void request_setExceptionBreakpoints(const llvm::json::Object &request) {
2173   llvm::json::Object response;
2174   lldb::SBError error;
2175   FillResponse(request, response);
2176   auto arguments = request.getObject("arguments");
2177   auto filters = arguments->getArray("filters");
2178   // Keep a list of any exception breakpoint filter names that weren't set
2179   // so we can clear any exception breakpoints if needed.
2180   std::set<std::string> unset_filters;
2181   for (const auto &bp : g_vsc.exception_breakpoints)
2182     unset_filters.insert(bp.filter);
2183 
2184   for (const auto &value : *filters) {
2185     const auto filter = GetAsString(value);
2186     auto exc_bp = g_vsc.GetExceptionBreakpoint(std::string(filter));
2187     if (exc_bp) {
2188       exc_bp->SetBreakpoint();
2189       unset_filters.erase(std::string(filter));
2190     }
2191   }
2192   for (const auto &filter : unset_filters) {
2193     auto exc_bp = g_vsc.GetExceptionBreakpoint(filter);
2194     if (exc_bp)
2195       exc_bp->ClearBreakpoint();
2196   }
2197   g_vsc.SendJSON(llvm::json::Value(std::move(response)));
2198 }
2199 
2200 // "SetFunctionBreakpointsRequest": {
2201 //   "allOf": [ { "$ref": "#/definitions/Request" }, {
2202 //     "type": "object",
2203 //     "description": "SetFunctionBreakpoints request; value of command field is
2204 //     'setFunctionBreakpoints'. Sets multiple function breakpoints and clears
2205 //     all previous function breakpoints. To clear all function breakpoint,
2206 //     specify an empty array. When a function breakpoint is hit, a StoppedEvent
2207 //     (event type 'function breakpoint') is generated.", "properties": {
2208 //       "command": {
2209 //         "type": "string",
2210 //         "enum": [ "setFunctionBreakpoints" ]
2211 //       },
2212 //       "arguments": {
2213 //         "$ref": "#/definitions/SetFunctionBreakpointsArguments"
2214 //       }
2215 //     },
2216 //     "required": [ "command", "arguments"  ]
2217 //   }]
2218 // },
2219 // "SetFunctionBreakpointsArguments": {
2220 //   "type": "object",
2221 //   "description": "Arguments for 'setFunctionBreakpoints' request.",
2222 //   "properties": {
2223 //     "breakpoints": {
2224 //       "type": "array",
2225 //       "items": {
2226 //         "$ref": "#/definitions/FunctionBreakpoint"
2227 //       },
2228 //       "description": "The function names of the breakpoints."
2229 //     }
2230 //   },
2231 //   "required": [ "breakpoints" ]
2232 // },
2233 // "FunctionBreakpoint": {
2234 //   "type": "object",
2235 //   "description": "Properties of a breakpoint passed to the
2236 //   setFunctionBreakpoints request.", "properties": {
2237 //     "name": {
2238 //       "type": "string",
2239 //       "description": "The name of the function."
2240 //     },
2241 //     "condition": {
2242 //       "type": "string",
2243 //       "description": "An optional expression for conditional breakpoints."
2244 //     },
2245 //     "hitCondition": {
2246 //       "type": "string",
2247 //       "description": "An optional expression that controls how many hits of
2248 //       the breakpoint are ignored. The backend is expected to interpret the
2249 //       expression as needed."
2250 //     }
2251 //   },
2252 //   "required": [ "name" ]
2253 // },
2254 // "SetFunctionBreakpointsResponse": {
2255 //   "allOf": [ { "$ref": "#/definitions/Response" }, {
2256 //     "type": "object",
2257 //     "description": "Response to 'setFunctionBreakpoints' request. Returned is
2258 //     information about each breakpoint created by this request.",
2259 //     "properties": {
2260 //       "body": {
2261 //         "type": "object",
2262 //         "properties": {
2263 //           "breakpoints": {
2264 //             "type": "array",
2265 //             "items": {
2266 //               "$ref": "#/definitions/Breakpoint"
2267 //             },
2268 //             "description": "Information about the breakpoints. The array
2269 //             elements correspond to the elements of the 'breakpoints' array."
2270 //           }
2271 //         },
2272 //         "required": [ "breakpoints" ]
2273 //       }
2274 //     },
2275 //     "required": [ "body" ]
2276 //   }]
2277 // }
2278 void request_setFunctionBreakpoints(const llvm::json::Object &request) {
2279   llvm::json::Object response;
2280   lldb::SBError error;
2281   FillResponse(request, response);
2282   auto arguments = request.getObject("arguments");
2283   auto breakpoints = arguments->getArray("breakpoints");
2284   FunctionBreakpointMap request_bps;
2285   llvm::json::Array response_breakpoints;
2286   for (const auto &value : *breakpoints) {
2287     auto bp_obj = value.getAsObject();
2288     if (bp_obj == nullptr)
2289       continue;
2290     FunctionBreakpoint func_bp(*bp_obj);
2291     request_bps[func_bp.functionName] = std::move(func_bp);
2292   }
2293 
2294   std::vector<llvm::StringRef> remove_names;
2295   // Disable any function breakpoints that aren't in the request_bps.
2296   // There is no call to remove function breakpoints other than calling this
2297   // function with a smaller or empty "breakpoints" list.
2298   for (auto &pair : g_vsc.function_breakpoints) {
2299     auto request_pos = request_bps.find(pair.first());
2300     if (request_pos == request_bps.end()) {
2301       // This function breakpoint no longer exists delete it from LLDB
2302       g_vsc.target.BreakpointDelete(pair.second.bp.GetID());
2303       remove_names.push_back(pair.first());
2304     } else {
2305       // Update the existing breakpoint as any setting withing the function
2306       // breakpoint might have changed.
2307       pair.second.UpdateBreakpoint(request_pos->second);
2308       // Remove this breakpoint from the request breakpoints since we have
2309       // handled it here and we don't need to set a new breakpoint below.
2310       request_bps.erase(request_pos);
2311       // Add this breakpoint info to the response
2312       AppendBreakpoint(pair.second.bp, response_breakpoints);
2313     }
2314   }
2315   // Remove any breakpoints that are no longer in our list
2316   for (const auto &name : remove_names)
2317     g_vsc.function_breakpoints.erase(name);
2318 
2319   // Any breakpoints that are left in "request_bps" are breakpoints that
2320   // need to be set.
2321   for (auto &pair : request_bps) {
2322     pair.second.SetBreakpoint();
2323     // Add this breakpoint info to the response
2324     AppendBreakpoint(pair.second.bp, response_breakpoints);
2325     g_vsc.function_breakpoints[pair.first()] = std::move(pair.second);
2326   }
2327 
2328   llvm::json::Object body;
2329   body.try_emplace("breakpoints", std::move(response_breakpoints));
2330   response.try_emplace("body", std::move(body));
2331   g_vsc.SendJSON(llvm::json::Value(std::move(response)));
2332 }
2333 
2334 // "SourceRequest": {
2335 //   "allOf": [ { "$ref": "#/definitions/Request" }, {
2336 //     "type": "object",
2337 //     "description": "Source request; value of command field is 'source'. The
2338 //     request retrieves the source code for a given source reference.",
2339 //     "properties": {
2340 //       "command": {
2341 //         "type": "string",
2342 //         "enum": [ "source" ]
2343 //       },
2344 //       "arguments": {
2345 //         "$ref": "#/definitions/SourceArguments"
2346 //       }
2347 //     },
2348 //     "required": [ "command", "arguments"  ]
2349 //   }]
2350 // },
2351 // "SourceArguments": {
2352 //   "type": "object",
2353 //   "description": "Arguments for 'source' request.",
2354 //   "properties": {
2355 //     "source": {
2356 //       "$ref": "#/definitions/Source",
2357 //       "description": "Specifies the source content to load. Either
2358 //       source.path or source.sourceReference must be specified."
2359 //     },
2360 //     "sourceReference": {
2361 //       "type": "integer",
2362 //       "description": "The reference to the source. This is the same as
2363 //       source.sourceReference. This is provided for backward compatibility
2364 //       since old backends do not understand the 'source' attribute."
2365 //     }
2366 //   },
2367 //   "required": [ "sourceReference" ]
2368 // },
2369 // "SourceResponse": {
2370 //   "allOf": [ { "$ref": "#/definitions/Response" }, {
2371 //     "type": "object",
2372 //     "description": "Response to 'source' request.",
2373 //     "properties": {
2374 //       "body": {
2375 //         "type": "object",
2376 //         "properties": {
2377 //           "content": {
2378 //             "type": "string",
2379 //             "description": "Content of the source reference."
2380 //           },
2381 //           "mimeType": {
2382 //             "type": "string",
2383 //             "description": "Optional content type (mime type) of the source."
2384 //           }
2385 //         },
2386 //         "required": [ "content" ]
2387 //       }
2388 //     },
2389 //     "required": [ "body" ]
2390 //   }]
2391 // }
2392 void request_source(const llvm::json::Object &request) {
2393   llvm::json::Object response;
2394   FillResponse(request, response);
2395   llvm::json::Object body;
2396 
2397   auto arguments = request.getObject("arguments");
2398   auto source = arguments->getObject("source");
2399   auto sourceReference = GetSigned(source, "sourceReference", -1);
2400   auto pos = g_vsc.source_map.find((lldb::addr_t)sourceReference);
2401   if (pos != g_vsc.source_map.end()) {
2402     EmplaceSafeString(body, "content", pos->second.content);
2403   } else {
2404     response["success"] = llvm::json::Value(false);
2405   }
2406   EmplaceSafeString(body, "mimeType", "text/x-lldb.disassembly");
2407   response.try_emplace("body", std::move(body));
2408   g_vsc.SendJSON(llvm::json::Value(std::move(response)));
2409 }
2410 
2411 // "StackTraceRequest": {
2412 //   "allOf": [ { "$ref": "#/definitions/Request" }, {
2413 //     "type": "object",
2414 //     "description": "StackTrace request; value of command field is
2415 //     'stackTrace'. The request returns a stacktrace from the current execution
2416 //     state.", "properties": {
2417 //       "command": {
2418 //         "type": "string",
2419 //         "enum": [ "stackTrace" ]
2420 //       },
2421 //       "arguments": {
2422 //         "$ref": "#/definitions/StackTraceArguments"
2423 //       }
2424 //     },
2425 //     "required": [ "command", "arguments"  ]
2426 //   }]
2427 // },
2428 // "StackTraceArguments": {
2429 //   "type": "object",
2430 //   "description": "Arguments for 'stackTrace' request.",
2431 //   "properties": {
2432 //     "threadId": {
2433 //       "type": "integer",
2434 //       "description": "Retrieve the stacktrace for this thread."
2435 //     },
2436 //     "startFrame": {
2437 //       "type": "integer",
2438 //       "description": "The index of the first frame to return; if omitted
2439 //       frames start at 0."
2440 //     },
2441 //     "levels": {
2442 //       "type": "integer",
2443 //       "description": "The maximum number of frames to return. If levels is
2444 //       not specified or 0, all frames are returned."
2445 //     },
2446 //     "format": {
2447 //       "$ref": "#/definitions/StackFrameFormat",
2448 //       "description": "Specifies details on how to format the stack frames."
2449 //     }
2450 //  },
2451 //   "required": [ "threadId" ]
2452 // },
2453 // "StackTraceResponse": {
2454 //   "allOf": [ { "$ref": "#/definitions/Response" }, {
2455 //     "type": "object",
2456 //     "description": "Response to 'stackTrace' request.",
2457 //     "properties": {
2458 //       "body": {
2459 //         "type": "object",
2460 //         "properties": {
2461 //           "stackFrames": {
2462 //             "type": "array",
2463 //             "items": {
2464 //               "$ref": "#/definitions/StackFrame"
2465 //             },
2466 //             "description": "The frames of the stackframe. If the array has
2467 //             length zero, there are no stackframes available. This means that
2468 //             there is no location information available."
2469 //           },
2470 //           "totalFrames": {
2471 //             "type": "integer",
2472 //             "description": "The total number of frames available."
2473 //           }
2474 //         },
2475 //         "required": [ "stackFrames" ]
2476 //       }
2477 //     },
2478 //     "required": [ "body" ]
2479 //   }]
2480 // }
2481 void request_stackTrace(const llvm::json::Object &request) {
2482   llvm::json::Object response;
2483   FillResponse(request, response);
2484   lldb::SBError error;
2485   auto arguments = request.getObject("arguments");
2486   lldb::SBThread thread = g_vsc.GetLLDBThread(*arguments);
2487   llvm::json::Array stackFrames;
2488   llvm::json::Object body;
2489 
2490   if (thread.IsValid()) {
2491     const auto startFrame = GetUnsigned(arguments, "startFrame", 0);
2492     const auto levels = GetUnsigned(arguments, "levels", 0);
2493     const auto endFrame = (levels == 0) ? INT64_MAX : (startFrame + levels);
2494     for (uint32_t i = startFrame; i < endFrame; ++i) {
2495       auto frame = thread.GetFrameAtIndex(i);
2496       if (!frame.IsValid())
2497         break;
2498       stackFrames.emplace_back(CreateStackFrame(frame));
2499     }
2500     const auto totalFrames = thread.GetNumFrames();
2501     body.try_emplace("totalFrames", totalFrames);
2502   }
2503   body.try_emplace("stackFrames", std::move(stackFrames));
2504   response.try_emplace("body", std::move(body));
2505   g_vsc.SendJSON(llvm::json::Value(std::move(response)));
2506 }
2507 
2508 // "StepInRequest": {
2509 //   "allOf": [ { "$ref": "#/definitions/Request" }, {
2510 //     "type": "object",
2511 //     "description": "StepIn request; value of command field is 'stepIn'. The
2512 //     request starts the debuggee to step into a function/method if possible.
2513 //     If it cannot step into a target, 'stepIn' behaves like 'next'. The debug
2514 //     adapter first sends the StepInResponse and then a StoppedEvent (event
2515 //     type 'step') after the step has completed. If there are multiple
2516 //     function/method calls (or other targets) on the source line, the optional
2517 //     argument 'targetId' can be used to control into which target the 'stepIn'
2518 //     should occur. The list of possible targets for a given source line can be
2519 //     retrieved via the 'stepInTargets' request.", "properties": {
2520 //       "command": {
2521 //         "type": "string",
2522 //         "enum": [ "stepIn" ]
2523 //       },
2524 //       "arguments": {
2525 //         "$ref": "#/definitions/StepInArguments"
2526 //       }
2527 //     },
2528 //     "required": [ "command", "arguments"  ]
2529 //   }]
2530 // },
2531 // "StepInArguments": {
2532 //   "type": "object",
2533 //   "description": "Arguments for 'stepIn' request.",
2534 //   "properties": {
2535 //     "threadId": {
2536 //       "type": "integer",
2537 //       "description": "Execute 'stepIn' for this thread."
2538 //     },
2539 //     "targetId": {
2540 //       "type": "integer",
2541 //       "description": "Optional id of the target to step into."
2542 //     }
2543 //   },
2544 //   "required": [ "threadId" ]
2545 // },
2546 // "StepInResponse": {
2547 //   "allOf": [ { "$ref": "#/definitions/Response" }, {
2548 //     "type": "object",
2549 //     "description": "Response to 'stepIn' request. This is just an
2550 //     acknowledgement, so no body field is required."
2551 //   }]
2552 // }
2553 void request_stepIn(const llvm::json::Object &request) {
2554   llvm::json::Object response;
2555   FillResponse(request, response);
2556   auto arguments = request.getObject("arguments");
2557   lldb::SBThread thread = g_vsc.GetLLDBThread(*arguments);
2558   if (thread.IsValid()) {
2559     // Remember the thread ID that caused the resume so we can set the
2560     // "threadCausedFocus" boolean value in the "stopped" events.
2561     g_vsc.focus_tid = thread.GetThreadID();
2562     thread.StepInto();
2563   } else {
2564     response["success"] = llvm::json::Value(false);
2565   }
2566   g_vsc.SendJSON(llvm::json::Value(std::move(response)));
2567 }
2568 
2569 // "StepOutRequest": {
2570 //   "allOf": [ { "$ref": "#/definitions/Request" }, {
2571 //     "type": "object",
2572 //     "description": "StepOut request; value of command field is 'stepOut'. The
2573 //     request starts the debuggee to run again for one step. The debug adapter
2574 //     first sends the StepOutResponse and then a StoppedEvent (event type
2575 //     'step') after the step has completed.", "properties": {
2576 //       "command": {
2577 //         "type": "string",
2578 //         "enum": [ "stepOut" ]
2579 //       },
2580 //       "arguments": {
2581 //         "$ref": "#/definitions/StepOutArguments"
2582 //       }
2583 //     },
2584 //     "required": [ "command", "arguments"  ]
2585 //   }]
2586 // },
2587 // "StepOutArguments": {
2588 //   "type": "object",
2589 //   "description": "Arguments for 'stepOut' request.",
2590 //   "properties": {
2591 //     "threadId": {
2592 //       "type": "integer",
2593 //       "description": "Execute 'stepOut' for this thread."
2594 //     }
2595 //   },
2596 //   "required": [ "threadId" ]
2597 // },
2598 // "StepOutResponse": {
2599 //   "allOf": [ { "$ref": "#/definitions/Response" }, {
2600 //     "type": "object",
2601 //     "description": "Response to 'stepOut' request. This is just an
2602 //     acknowledgement, so no body field is required."
2603 //   }]
2604 // }
2605 void request_stepOut(const llvm::json::Object &request) {
2606   llvm::json::Object response;
2607   FillResponse(request, response);
2608   auto arguments = request.getObject("arguments");
2609   lldb::SBThread thread = g_vsc.GetLLDBThread(*arguments);
2610   if (thread.IsValid()) {
2611     // Remember the thread ID that caused the resume so we can set the
2612     // "threadCausedFocus" boolean value in the "stopped" events.
2613     g_vsc.focus_tid = thread.GetThreadID();
2614     thread.StepOut();
2615   } else {
2616     response["success"] = llvm::json::Value(false);
2617   }
2618   g_vsc.SendJSON(llvm::json::Value(std::move(response)));
2619 }
2620 
2621 // "ThreadsRequest": {
2622 //   "allOf": [ { "$ref": "#/definitions/Request" }, {
2623 //     "type": "object",
2624 //     "description": "Thread request; value of command field is 'threads'. The
2625 //     request retrieves a list of all threads.", "properties": {
2626 //       "command": {
2627 //         "type": "string",
2628 //         "enum": [ "threads" ]
2629 //       }
2630 //     },
2631 //     "required": [ "command" ]
2632 //   }]
2633 // },
2634 // "ThreadsResponse": {
2635 //   "allOf": [ { "$ref": "#/definitions/Response" }, {
2636 //     "type": "object",
2637 //     "description": "Response to 'threads' request.",
2638 //     "properties": {
2639 //       "body": {
2640 //         "type": "object",
2641 //         "properties": {
2642 //           "threads": {
2643 //             "type": "array",
2644 //             "items": {
2645 //               "$ref": "#/definitions/Thread"
2646 //             },
2647 //             "description": "All threads."
2648 //           }
2649 //         },
2650 //         "required": [ "threads" ]
2651 //       }
2652 //     },
2653 //     "required": [ "body" ]
2654 //   }]
2655 // }
2656 void request_threads(const llvm::json::Object &request) {
2657 
2658   lldb::SBProcess process = g_vsc.target.GetProcess();
2659   llvm::json::Object response;
2660   FillResponse(request, response);
2661 
2662   const uint32_t num_threads = process.GetNumThreads();
2663   llvm::json::Array threads;
2664   for (uint32_t thread_idx = 0; thread_idx < num_threads; ++thread_idx) {
2665     lldb::SBThread thread = process.GetThreadAtIndex(thread_idx);
2666     threads.emplace_back(CreateThread(thread));
2667   }
2668   if (threads.size() == 0) {
2669     response["success"] = llvm::json::Value(false);
2670   }
2671   llvm::json::Object body;
2672   body.try_emplace("threads", std::move(threads));
2673   response.try_emplace("body", std::move(body));
2674   g_vsc.SendJSON(llvm::json::Value(std::move(response)));
2675 }
2676 
2677 // "SetVariableRequest": {
2678 //   "allOf": [ { "$ref": "#/definitions/Request" }, {
2679 //     "type": "object",
2680 //     "description": "setVariable request; value of command field is
2681 //     'setVariable'. Set the variable with the given name in the variable
2682 //     container to a new value.", "properties": {
2683 //       "command": {
2684 //         "type": "string",
2685 //         "enum": [ "setVariable" ]
2686 //       },
2687 //       "arguments": {
2688 //         "$ref": "#/definitions/SetVariableArguments"
2689 //       }
2690 //     },
2691 //     "required": [ "command", "arguments"  ]
2692 //   }]
2693 // },
2694 // "SetVariableArguments": {
2695 //   "type": "object",
2696 //   "description": "Arguments for 'setVariable' request.",
2697 //   "properties": {
2698 //     "variablesReference": {
2699 //       "type": "integer",
2700 //       "description": "The reference of the variable container."
2701 //     },
2702 //     "name": {
2703 //       "type": "string",
2704 //       "description": "The name of the variable."
2705 //     },
2706 //     "value": {
2707 //       "type": "string",
2708 //       "description": "The value of the variable."
2709 //     },
2710 //     "format": {
2711 //       "$ref": "#/definitions/ValueFormat",
2712 //       "description": "Specifies details on how to format the response value."
2713 //     }
2714 //   },
2715 //   "required": [ "variablesReference", "name", "value" ]
2716 // },
2717 // "SetVariableResponse": {
2718 //   "allOf": [ { "$ref": "#/definitions/Response" }, {
2719 //     "type": "object",
2720 //     "description": "Response to 'setVariable' request.",
2721 //     "properties": {
2722 //       "body": {
2723 //         "type": "object",
2724 //         "properties": {
2725 //           "value": {
2726 //             "type": "string",
2727 //             "description": "The new value of the variable."
2728 //           },
2729 //           "type": {
2730 //             "type": "string",
2731 //             "description": "The type of the new value. Typically shown in the
2732 //             UI when hovering over the value."
2733 //           },
2734 //           "variablesReference": {
2735 //             "type": "number",
2736 //             "description": "If variablesReference is > 0, the new value is
2737 //             structured and its children can be retrieved by passing
2738 //             variablesReference to the VariablesRequest."
2739 //           },
2740 //           "namedVariables": {
2741 //             "type": "number",
2742 //             "description": "The number of named child variables. The client
2743 //             can use this optional information to present the variables in a
2744 //             paged UI and fetch them in chunks."
2745 //           },
2746 //           "indexedVariables": {
2747 //             "type": "number",
2748 //             "description": "The number of indexed child variables. The client
2749 //             can use this optional information to present the variables in a
2750 //             paged UI and fetch them in chunks."
2751 //           }
2752 //         },
2753 //         "required": [ "value" ]
2754 //       }
2755 //     },
2756 //     "required": [ "body" ]
2757 //   }]
2758 // }
2759 void request_setVariable(const llvm::json::Object &request) {
2760   llvm::json::Object response;
2761   FillResponse(request, response);
2762   llvm::json::Array variables;
2763   llvm::json::Object body;
2764   auto arguments = request.getObject("arguments");
2765   // This is a reference to the containing variable/scope
2766   const auto variablesReference =
2767       GetUnsigned(arguments, "variablesReference", 0);
2768   llvm::StringRef name = GetString(arguments, "name");
2769   bool is_duplicated_variable_name = name.contains(" @");
2770 
2771   const auto value = GetString(arguments, "value");
2772   // Set success to false just in case we don't find the variable by name
2773   response.try_emplace("success", false);
2774 
2775   lldb::SBValue variable;
2776   int64_t newVariablesReference = 0;
2777 
2778   // The "id" is the unique integer ID that is unique within the enclosing
2779   // variablesReference. It is optionally added to any "interface Variable"
2780   // objects to uniquely identify a variable within an enclosing
2781   // variablesReference. It helps to disambiguate between two variables that
2782   // have the same name within the same scope since the "setVariables" request
2783   // only specifies the variable reference of the enclosing scope/variable, and
2784   // the name of the variable. We could have two shadowed variables with the
2785   // same name in "Locals" or "Globals". In our case the "id" absolute index
2786   // of the variable within the g_vsc.variables list.
2787   const auto id_value = GetUnsigned(arguments, "id", UINT64_MAX);
2788   if (id_value != UINT64_MAX) {
2789     variable = g_vsc.variables.GetVariable(id_value);
2790   } else if (lldb::SBValueList *top_scope =
2791                  GetTopLevelScope(variablesReference)) {
2792     // variablesReference is one of our scopes, not an actual variable it is
2793     // asking for a variable in locals or globals or registers
2794     int64_t end_idx = top_scope->GetSize();
2795     // Searching backward so that we choose the variable in closest scope
2796     // among variables of the same name.
2797     for (int64_t i = end_idx - 1; i >= 0; --i) {
2798       lldb::SBValue curr_variable = top_scope->GetValueAtIndex(i);
2799       std::string variable_name = CreateUniqueVariableNameForDisplay(
2800           curr_variable, is_duplicated_variable_name);
2801       if (variable_name == name) {
2802         variable = curr_variable;
2803         break;
2804       }
2805     }
2806   } else {
2807     // This is not under the globals or locals scope, so there are no duplicated
2808     // names.
2809 
2810     // We have a named item within an actual variable so we need to find it
2811     // withing the container variable by name.
2812     lldb::SBValue container = g_vsc.variables.GetVariable(variablesReference);
2813     variable = container.GetChildMemberWithName(name.data());
2814     if (!variable.IsValid()) {
2815       if (name.startswith("[")) {
2816         llvm::StringRef index_str(name.drop_front(1));
2817         uint64_t index = 0;
2818         if (!index_str.consumeInteger(0, index)) {
2819           if (index_str == "]")
2820             variable = container.GetChildAtIndex(index);
2821         }
2822       }
2823     }
2824   }
2825 
2826   if (variable.IsValid()) {
2827     lldb::SBError error;
2828     bool success = variable.SetValueFromCString(value.data(), error);
2829     if (success) {
2830       SetValueForKey(variable, body, "value");
2831       EmplaceSafeString(body, "type", variable.GetType().GetDisplayTypeName());
2832 
2833       // We don't know the index of the variable in our g_vsc.variables
2834       // so always insert a new one to get its variablesReference.
2835       // is_permanent is false because debug console does not support
2836       // setVariable request.
2837       if (variable.MightHaveChildren())
2838         newVariablesReference = g_vsc.variables.InsertExpandableVariable(
2839             variable, /*is_permanent=*/false);
2840 
2841       body.try_emplace("variablesReference", newVariablesReference);
2842     } else {
2843       EmplaceSafeString(body, "message", std::string(error.GetCString()));
2844     }
2845     response["success"] = llvm::json::Value(success);
2846   } else {
2847     response["success"] = llvm::json::Value(false);
2848   }
2849 
2850   response.try_emplace("body", std::move(body));
2851   g_vsc.SendJSON(llvm::json::Value(std::move(response)));
2852 }
2853 
2854 // "VariablesRequest": {
2855 //   "allOf": [ { "$ref": "#/definitions/Request" }, {
2856 //     "type": "object",
2857 //     "description": "Variables request; value of command field is 'variables'.
2858 //     Retrieves all child variables for the given variable reference. An
2859 //     optional filter can be used to limit the fetched children to either named
2860 //     or indexed children.", "properties": {
2861 //       "command": {
2862 //         "type": "string",
2863 //         "enum": [ "variables" ]
2864 //       },
2865 //       "arguments": {
2866 //         "$ref": "#/definitions/VariablesArguments"
2867 //       }
2868 //     },
2869 //     "required": [ "command", "arguments"  ]
2870 //   }]
2871 // },
2872 // "VariablesArguments": {
2873 //   "type": "object",
2874 //   "description": "Arguments for 'variables' request.",
2875 //   "properties": {
2876 //     "variablesReference": {
2877 //       "type": "integer",
2878 //       "description": "The Variable reference."
2879 //     },
2880 //     "filter": {
2881 //       "type": "string",
2882 //       "enum": [ "indexed", "named" ],
2883 //       "description": "Optional filter to limit the child variables to either
2884 //       named or indexed. If ommited, both types are fetched."
2885 //     },
2886 //     "start": {
2887 //       "type": "integer",
2888 //       "description": "The index of the first variable to return; if omitted
2889 //       children start at 0."
2890 //     },
2891 //     "count": {
2892 //       "type": "integer",
2893 //       "description": "The number of variables to return. If count is missing
2894 //       or 0, all variables are returned."
2895 //     },
2896 //     "format": {
2897 //       "$ref": "#/definitions/ValueFormat",
2898 //       "description": "Specifies details on how to format the Variable
2899 //       values."
2900 //     }
2901 //   },
2902 //   "required": [ "variablesReference" ]
2903 // },
2904 // "VariablesResponse": {
2905 //   "allOf": [ { "$ref": "#/definitions/Response" }, {
2906 //     "type": "object",
2907 //     "description": "Response to 'variables' request.",
2908 //     "properties": {
2909 //       "body": {
2910 //         "type": "object",
2911 //         "properties": {
2912 //           "variables": {
2913 //             "type": "array",
2914 //             "items": {
2915 //               "$ref": "#/definitions/Variable"
2916 //             },
2917 //             "description": "All (or a range) of variables for the given
2918 //             variable reference."
2919 //           }
2920 //         },
2921 //         "required": [ "variables" ]
2922 //       }
2923 //     },
2924 //     "required": [ "body" ]
2925 //   }]
2926 // }
2927 void request_variables(const llvm::json::Object &request) {
2928   llvm::json::Object response;
2929   FillResponse(request, response);
2930   llvm::json::Array variables;
2931   auto arguments = request.getObject("arguments");
2932   const auto variablesReference =
2933       GetUnsigned(arguments, "variablesReference", 0);
2934   const int64_t start = GetSigned(arguments, "start", 0);
2935   const int64_t count = GetSigned(arguments, "count", 0);
2936   bool hex = false;
2937   auto format = arguments->getObject("format");
2938   if (format)
2939     hex = GetBoolean(format, "hex", false);
2940 
2941   if (lldb::SBValueList *top_scope = GetTopLevelScope(variablesReference)) {
2942     // variablesReference is one of our scopes, not an actual variable it is
2943     // asking for the list of args, locals or globals.
2944     int64_t start_idx = 0;
2945     int64_t num_children = 0;
2946 
2947     num_children = top_scope->GetSize();
2948     const int64_t end_idx = start_idx + ((count == 0) ? num_children : count);
2949 
2950     // We first find out which variable names are duplicated
2951     std::map<std::string, int> variable_name_counts;
2952     for (auto i = start_idx; i < end_idx; ++i) {
2953       lldb::SBValue variable = top_scope->GetValueAtIndex(i);
2954       if (!variable.IsValid())
2955         break;
2956       variable_name_counts[GetNonNullVariableName(variable)]++;
2957     }
2958 
2959     // Now we construct the result with unique display variable names
2960     for (auto i = start_idx; i < end_idx; ++i) {
2961       lldb::SBValue variable = top_scope->GetValueAtIndex(i);
2962 
2963       if (!variable.IsValid())
2964         break;
2965 
2966       int64_t var_ref = 0;
2967       if (variable.MightHaveChildren()) {
2968         var_ref = g_vsc.variables.InsertExpandableVariable(
2969             variable, /*is_permanent=*/false);
2970       }
2971       variables.emplace_back(CreateVariable(
2972           variable, var_ref, var_ref != 0 ? var_ref : UINT64_MAX, hex,
2973           variable_name_counts[GetNonNullVariableName(variable)] > 1));
2974     }
2975   } else {
2976     // We are expanding a variable that has children, so we will return its
2977     // children.
2978     lldb::SBValue variable = g_vsc.variables.GetVariable(variablesReference);
2979     if (variable.IsValid()) {
2980       const auto num_children = variable.GetNumChildren();
2981       const int64_t end_idx = start + ((count == 0) ? num_children : count);
2982       for (auto i = start; i < end_idx; ++i) {
2983         lldb::SBValue child = variable.GetChildAtIndex(i);
2984         if (!child.IsValid())
2985           break;
2986         if (child.MightHaveChildren()) {
2987           auto is_permanent =
2988               g_vsc.variables.IsPermanentVariableReference(variablesReference);
2989           auto childVariablesReferences =
2990               g_vsc.variables.InsertExpandableVariable(child, is_permanent);
2991           variables.emplace_back(CreateVariable(child, childVariablesReferences,
2992                                                 childVariablesReferences, hex));
2993         } else {
2994           variables.emplace_back(CreateVariable(child, 0, INT64_MAX, hex));
2995         }
2996       }
2997     }
2998   }
2999   llvm::json::Object body;
3000   body.try_emplace("variables", std::move(variables));
3001   response.try_emplace("body", std::move(body));
3002   g_vsc.SendJSON(llvm::json::Value(std::move(response)));
3003 }
3004 
3005 // A request used in testing to get the details on all breakpoints that are
3006 // currently set in the target. This helps us to test "setBreakpoints" and
3007 // "setFunctionBreakpoints" requests to verify we have the correct set of
3008 // breakpoints currently set in LLDB.
3009 void request__testGetTargetBreakpoints(const llvm::json::Object &request) {
3010   llvm::json::Object response;
3011   FillResponse(request, response);
3012   llvm::json::Array response_breakpoints;
3013   for (uint32_t i = 0; g_vsc.target.GetBreakpointAtIndex(i).IsValid(); ++i) {
3014     auto bp = g_vsc.target.GetBreakpointAtIndex(i);
3015     AppendBreakpoint(bp, response_breakpoints);
3016   }
3017   llvm::json::Object body;
3018   body.try_emplace("breakpoints", std::move(response_breakpoints));
3019   response.try_emplace("body", std::move(body));
3020   g_vsc.SendJSON(llvm::json::Value(std::move(response)));
3021 }
3022 
3023 void RegisterRequestCallbacks() {
3024   g_vsc.RegisterRequestCallback("attach", request_attach);
3025   g_vsc.RegisterRequestCallback("completions", request_completions);
3026   g_vsc.RegisterRequestCallback("continue", request_continue);
3027   g_vsc.RegisterRequestCallback("configurationDone", request_configurationDone);
3028   g_vsc.RegisterRequestCallback("disconnect", request_disconnect);
3029   g_vsc.RegisterRequestCallback("evaluate", request_evaluate);
3030   g_vsc.RegisterRequestCallback("exceptionInfo", request_exceptionInfo);
3031   g_vsc.RegisterRequestCallback("initialize", request_initialize);
3032   g_vsc.RegisterRequestCallback("launch", request_launch);
3033   g_vsc.RegisterRequestCallback("next", request_next);
3034   g_vsc.RegisterRequestCallback("pause", request_pause);
3035   g_vsc.RegisterRequestCallback("scopes", request_scopes);
3036   g_vsc.RegisterRequestCallback("setBreakpoints", request_setBreakpoints);
3037   g_vsc.RegisterRequestCallback("setExceptionBreakpoints",
3038                                 request_setExceptionBreakpoints);
3039   g_vsc.RegisterRequestCallback("setFunctionBreakpoints",
3040                                 request_setFunctionBreakpoints);
3041   g_vsc.RegisterRequestCallback("setVariable", request_setVariable);
3042   g_vsc.RegisterRequestCallback("source", request_source);
3043   g_vsc.RegisterRequestCallback("stackTrace", request_stackTrace);
3044   g_vsc.RegisterRequestCallback("stepIn", request_stepIn);
3045   g_vsc.RegisterRequestCallback("stepOut", request_stepOut);
3046   g_vsc.RegisterRequestCallback("threads", request_threads);
3047   g_vsc.RegisterRequestCallback("variables", request_variables);
3048   // Custom requests
3049   g_vsc.RegisterRequestCallback("compileUnits", request_compileUnits);
3050   g_vsc.RegisterRequestCallback("modules", request_modules);
3051   // Testing requests
3052   g_vsc.RegisterRequestCallback("_testGetTargetBreakpoints",
3053                                 request__testGetTargetBreakpoints);
3054 }
3055 
3056 } // anonymous namespace
3057 
3058 static void printHelp(LLDBVSCodeOptTable &table, llvm::StringRef tool_name) {
3059   std::string usage_str = tool_name.str() + " options";
3060   table.printHelp(llvm::outs(), usage_str.c_str(), "LLDB VSCode", false);
3061 
3062   std::string examples = R"___(
3063 EXAMPLES:
3064   The debug adapter can be started in two modes.
3065 
3066   Running lldb-vscode without any arguments will start communicating with the
3067   parent over stdio. Passing a port number causes lldb-vscode to start listening
3068   for connections on that port.
3069 
3070     lldb-vscode -p <port>
3071 
3072   Passing --wait-for-debugger will pause the process at startup and wait for a
3073   debugger to attach to the process.
3074 
3075     lldb-vscode -g
3076   )___";
3077   llvm::outs() << examples;
3078 }
3079 
3080 // If --launch-target is provided, this instance of lldb-vscode becomes a
3081 // runInTerminal launcher. It will ultimately launch the program specified in
3082 // the --launch-target argument, which is the original program the user wanted
3083 // to debug. This is done in such a way that the actual debug adaptor can
3084 // place breakpoints at the beginning of the program.
3085 //
3086 // The launcher will communicate with the debug adaptor using a fifo file in the
3087 // directory specified in the --comm-file argument.
3088 //
3089 // Regarding the actual flow, this launcher will first notify the debug adaptor
3090 // of its pid. Then, the launcher will be in a pending state waiting to be
3091 // attached by the adaptor.
3092 //
3093 // Once attached and resumed, the launcher will exec and become the program
3094 // specified by --launch-target, which is the original target the
3095 // user wanted to run.
3096 //
3097 // In case of errors launching the target, a suitable error message will be
3098 // emitted to the debug adaptor.
3099 void LaunchRunInTerminalTarget(llvm::opt::Arg &target_arg,
3100                                llvm::StringRef comm_file, char *argv[]) {
3101 #if defined(_WIN32)
3102   llvm::errs() << "runInTerminal is only supported on POSIX systems\n";
3103   exit(EXIT_FAILURE);
3104 #else
3105   RunInTerminalLauncherCommChannel comm_channel(comm_file);
3106   if (llvm::Error err = comm_channel.NotifyPid()) {
3107     llvm::errs() << llvm::toString(std::move(err)) << "\n";
3108     exit(EXIT_FAILURE);
3109   }
3110 
3111   // We will wait to be attached with a timeout. We don't wait indefinitely
3112   // using a signal to prevent being paused forever.
3113 
3114   // This env var should be used only for tests.
3115   const char *timeout_env_var = getenv("LLDB_VSCODE_RIT_TIMEOUT_IN_MS");
3116   int timeout_in_ms =
3117       timeout_env_var != nullptr ? atoi(timeout_env_var) : 20000;
3118   if (llvm::Error err = comm_channel.WaitUntilDebugAdaptorAttaches(
3119           std::chrono::milliseconds(timeout_in_ms))) {
3120     llvm::errs() << llvm::toString(std::move(err)) << "\n";
3121     exit(EXIT_FAILURE);
3122   }
3123 
3124   const char *target = target_arg.getValue();
3125   execvp(target, argv);
3126 
3127   std::string error = std::strerror(errno);
3128   comm_channel.NotifyError(error);
3129   llvm::errs() << error << "\n";
3130   exit(EXIT_FAILURE);
3131 #endif
3132 }
3133 
3134 /// used only by TestVSCode_redirection_to_console.py
3135 void redirection_test() {
3136   printf("stdout message\n");
3137   fprintf(stderr, "stderr message\n");
3138   fflush(stdout);
3139   fflush(stderr);
3140 }
3141 
3142 /// Redirect stdout and stderr fo the IDE's console output.
3143 ///
3144 /// Errors in this operation will be printed to the log file and the IDE's
3145 /// console output as well.
3146 ///
3147 /// \return
3148 ///     A fd pointing to the original stdout.
3149 int SetupStdoutStderrRedirection() {
3150   int new_stdout_fd = dup(fileno(stdout));
3151   auto stdout_err_redirector_callback = [&](llvm::StringRef data) {
3152     g_vsc.SendOutput(OutputType::Console, data);
3153   };
3154 
3155   for (int fd : {fileno(stdout), fileno(stderr)}) {
3156     if (llvm::Error err = RedirectFd(fd, stdout_err_redirector_callback)) {
3157       std::string error_message = llvm::toString(std::move(err));
3158       if (g_vsc.log)
3159         *g_vsc.log << error_message << std::endl;
3160       stdout_err_redirector_callback(error_message);
3161     }
3162   }
3163 
3164   /// used only by TestVSCode_redirection_to_console.py
3165   if (getenv("LLDB_VSCODE_TEST_STDOUT_STDERR_REDIRECTION") != nullptr)
3166     redirection_test();
3167   return new_stdout_fd;
3168 }
3169 
3170 int main(int argc, char *argv[]) {
3171   llvm::InitLLVM IL(argc, argv, /*InstallPipeSignalExitHandler=*/false);
3172   llvm::PrettyStackTraceProgram X(argc, argv);
3173 
3174   llvm::SmallString<256> program_path(argv[0]);
3175   llvm::sys::fs::make_absolute(program_path);
3176   g_vsc.debug_adaptor_path = program_path.str().str();
3177 
3178   LLDBVSCodeOptTable T;
3179   unsigned MAI, MAC;
3180   llvm::ArrayRef<const char *> ArgsArr = llvm::makeArrayRef(argv + 1, argc);
3181   llvm::opt::InputArgList input_args = T.ParseArgs(ArgsArr, MAI, MAC);
3182 
3183   if (input_args.hasArg(OPT_help)) {
3184     printHelp(T, llvm::sys::path::filename(argv[0]));
3185     return EXIT_SUCCESS;
3186   }
3187 
3188   if (llvm::opt::Arg *target_arg = input_args.getLastArg(OPT_launch_target)) {
3189     if (llvm::opt::Arg *comm_file = input_args.getLastArg(OPT_comm_file)) {
3190       int target_args_pos = argc;
3191       for (int i = 0; i < argc; i++)
3192         if (strcmp(argv[i], "--launch-target") == 0) {
3193           target_args_pos = i + 1;
3194           break;
3195         }
3196       LaunchRunInTerminalTarget(*target_arg, comm_file->getValue(),
3197                                 argv + target_args_pos);
3198     } else {
3199       llvm::errs() << "\"--launch-target\" requires \"--comm-file\" to be "
3200                       "specified\n";
3201       return EXIT_FAILURE;
3202     }
3203   }
3204 
3205   // stdout/stderr redirection to the IDE's console
3206   int new_stdout_fd = SetupStdoutStderrRedirection();
3207 
3208   // Initialize LLDB first before we do anything.
3209   lldb::SBDebugger::Initialize();
3210 
3211   // Terminate the debugger before the C++ destructor chain kicks in.
3212   auto terminate_debugger =
3213       llvm::make_scope_exit([] { lldb::SBDebugger::Terminate(); });
3214 
3215   RegisterRequestCallbacks();
3216 
3217   int portno = -1;
3218 
3219   if (auto *arg = input_args.getLastArg(OPT_port)) {
3220     auto optarg = arg->getValue();
3221     char *remainder;
3222     portno = strtol(optarg, &remainder, 0);
3223     if (remainder == optarg || *remainder != '\0') {
3224       fprintf(stderr, "'%s' is not a valid port number.\n", optarg);
3225       return EXIT_FAILURE;
3226     }
3227   }
3228 
3229 #if !defined(_WIN32)
3230   if (input_args.hasArg(OPT_wait_for_debugger)) {
3231     printf("Paused waiting for debugger to attach (pid = %i)...\n", getpid());
3232     pause();
3233   }
3234 #endif
3235   if (portno != -1) {
3236     printf("Listening on port %i...\n", portno);
3237     SOCKET socket_fd = AcceptConnection(portno);
3238     if (socket_fd >= 0) {
3239       g_vsc.input.descriptor = StreamDescriptor::from_socket(socket_fd, true);
3240       g_vsc.output.descriptor = StreamDescriptor::from_socket(socket_fd, false);
3241     } else {
3242       return EXIT_FAILURE;
3243     }
3244   } else {
3245     g_vsc.input.descriptor = StreamDescriptor::from_file(fileno(stdin), false);
3246     g_vsc.output.descriptor = StreamDescriptor::from_file(new_stdout_fd, false);
3247   }
3248 
3249   uint32_t packet_idx = 0;
3250   while (!g_vsc.sent_terminated_event) {
3251     llvm::json::Object object;
3252     lldb_vscode::PacketStatus status = g_vsc.GetNextObject(object);
3253     if (status == lldb_vscode::PacketStatus::EndOfFile)
3254       break;
3255     if (status != lldb_vscode::PacketStatus::Success)
3256       return 1; // Fatal error
3257 
3258     if (!g_vsc.HandleObject(object))
3259       return 1;
3260     ++packet_idx;
3261   }
3262 
3263   return EXIT_SUCCESS;
3264 }
3265