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 <assert.h>
10 #include <limits.h>
11 #include <stdarg.h>
12 #include <stdio.h>
13 #include <stdlib.h>
14 #include <string.h>
15 #include <sys/stat.h>
16 #include <sys/types.h>
17 #if defined(_WIN32)
18 // We need to #define NOMINMAX in order to skip `min()` and `max()` macro
19 // definitions that conflict with other system headers.
20 // We also need to #undef GetObject (which is defined to GetObjectW) because
21 // the JSON code we use also has methods named `GetObject()` and we conflict
22 // against these.
23 #define NOMINMAX
24 #include <windows.h>
25 #undef GetObject
26 #include <io.h>
27 #else
28 #include <netinet/in.h>
29 #include <sys/socket.h>
30 #include <unistd.h>
31 #endif
32 
33 #include <algorithm>
34 #include <chrono>
35 #include <fstream>
36 #include <map>
37 #include <memory>
38 #include <mutex>
39 #include <set>
40 #include <sstream>
41 #include <thread>
42 
43 #include "llvm/ADT/ArrayRef.h"
44 #include "llvm/Support/Errno.h"
45 #include "llvm/Support/FileSystem.h"
46 #include "llvm/Support/raw_ostream.h"
47 
48 #include "JSONUtils.h"
49 #include "LLDBUtils.h"
50 #include "VSCode.h"
51 
52 #if defined(_WIN32)
53 #ifndef PATH_MAX
54 #define PATH_MAX MAX_PATH
55 #endif
56 typedef int socklen_t;
57 constexpr const char *dev_null_path = "nul";
58 
59 #else
60 constexpr const char *dev_null_path = "/dev/null";
61 
62 #endif
63 
64 using namespace lldb_vscode;
65 
66 namespace {
67 
68 typedef void (*RequestCallback)(const llvm::json::Object &command);
69 
70 enum LaunchMethod { Launch, Attach, AttachForSuspendedLaunch };
71 
72 enum VSCodeBroadcasterBits { eBroadcastBitStopEventThread = 1u << 0 };
73 
74 SOCKET AcceptConnection(int portno) {
75   // Accept a socket connection from any host on "portno".
76   SOCKET newsockfd = -1;
77   struct sockaddr_in serv_addr, cli_addr;
78   SOCKET sockfd = socket(AF_INET, SOCK_STREAM, 0);
79   if (sockfd < 0) {
80     if (g_vsc.log)
81       *g_vsc.log << "error: opening socket (" << strerror(errno) << ")"
82                  << std::endl;
83   } else {
84     memset((char *)&serv_addr, 0, sizeof(serv_addr));
85     serv_addr.sin_family = AF_INET;
86     // serv_addr.sin_addr.s_addr = htonl(INADDR_ANY);
87     serv_addr.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
88     serv_addr.sin_port = htons(portno);
89     if (bind(sockfd, (struct sockaddr *)&serv_addr, sizeof(serv_addr)) < 0) {
90       if (g_vsc.log)
91         *g_vsc.log << "error: binding socket (" << strerror(errno) << ")"
92                    << std::endl;
93     } else {
94       listen(sockfd, 5);
95       socklen_t clilen = sizeof(cli_addr);
96       newsockfd = llvm::sys::RetryAfterSignal(-1, accept,
97           sockfd, (struct sockaddr *)&cli_addr, &clilen);
98       if (newsockfd < 0)
99         if (g_vsc.log)
100           *g_vsc.log << "error: accept (" << strerror(errno) << ")"
101                      << std::endl;
102     }
103 #if defined(_WIN32)
104     closesocket(sockfd);
105 #else
106     close(sockfd);
107 #endif
108   }
109   return newsockfd;
110 }
111 
112 std::vector<const char *> MakeArgv(const llvm::ArrayRef<std::string> &strs) {
113   // Create and return an array of "const char *", one for each C string in
114   // "strs" and terminate the list with a NULL. This can be used for argument
115   // vectors (argv) or environment vectors (envp) like those passed to the
116   // "main" function in C programs.
117   std::vector<const char *> argv;
118   for (const auto &s : strs)
119     argv.push_back(s.c_str());
120   argv.push_back(nullptr);
121   return argv;
122 }
123 
124 // Send a "exited" event to indicate the process has exited.
125 void SendProcessExitedEvent(lldb::SBProcess &process) {
126   llvm::json::Object event(CreateEventObject("exited"));
127   llvm::json::Object body;
128   body.try_emplace("exitCode", (int64_t)process.GetExitStatus());
129   event.try_emplace("body", std::move(body));
130   g_vsc.SendJSON(llvm::json::Value(std::move(event)));
131 }
132 
133 void SendThreadExitedEvent(lldb::tid_t tid) {
134   llvm::json::Object event(CreateEventObject("thread"));
135   llvm::json::Object body;
136   body.try_emplace("reason", "exited");
137   body.try_emplace("threadId", (int64_t)tid);
138   event.try_emplace("body", std::move(body));
139   g_vsc.SendJSON(llvm::json::Value(std::move(event)));
140 }
141 
142 // Send a "terminated" event to indicate the process is done being
143 // debugged.
144 void SendTerminatedEvent() {
145   if (!g_vsc.sent_terminated_event) {
146     g_vsc.sent_terminated_event = true;
147     // Send a "terminated" event
148     llvm::json::Object event(CreateEventObject("terminated"));
149     g_vsc.SendJSON(llvm::json::Value(std::move(event)));
150   }
151 }
152 
153 // Send a thread stopped event for all threads as long as the process
154 // is stopped.
155 void SendThreadStoppedEvent() {
156   lldb::SBProcess process = g_vsc.target.GetProcess();
157   if (process.IsValid()) {
158     auto state = process.GetState();
159     if (state == lldb::eStateStopped) {
160       llvm::DenseSet<lldb::tid_t> old_thread_ids;
161       old_thread_ids.swap(g_vsc.thread_ids);
162       uint32_t stop_id = process.GetStopID();
163       const uint32_t num_threads = process.GetNumThreads();
164 
165       // First make a pass through the threads to see if the focused thread
166       // has a stop reason. In case the focus thread doesn't have a stop
167       // reason, remember the first thread that has a stop reason so we can
168       // set it as the focus thread if below if needed.
169       lldb::tid_t first_tid_with_reason = LLDB_INVALID_THREAD_ID;
170       uint32_t num_threads_with_reason = 0;
171       for (uint32_t thread_idx = 0; thread_idx < num_threads; ++thread_idx) {
172         lldb::SBThread thread = process.GetThreadAtIndex(thread_idx);
173         const lldb::tid_t tid = thread.GetThreadID();
174         const bool has_reason = ThreadHasStopReason(thread);
175         // If the focus thread doesn't have a stop reason, clear the thread ID
176         if (tid == g_vsc.focus_tid && !has_reason)
177           g_vsc.focus_tid = LLDB_INVALID_THREAD_ID;
178         if (has_reason) {
179           ++num_threads_with_reason;
180           if (first_tid_with_reason == LLDB_INVALID_THREAD_ID)
181             first_tid_with_reason = tid;
182         }
183       }
184 
185       // We will have cleared g_vsc.focus_tid if he focus thread doesn't
186       // have a stop reason, so if it was cleared, or wasn't set, then set the
187       // focus thread to the first thread with a stop reason.
188       if (g_vsc.focus_tid == LLDB_INVALID_THREAD_ID)
189         g_vsc.focus_tid = first_tid_with_reason;
190 
191       // If no threads stopped with a reason, then report the first one so
192       // we at least let the UI know we stopped.
193       if (num_threads_with_reason == 0) {
194         lldb::SBThread thread = process.GetThreadAtIndex(0);
195         g_vsc.SendJSON(CreateThreadStopped(thread, stop_id));
196       } else {
197         for (uint32_t thread_idx = 0; thread_idx < num_threads; ++thread_idx) {
198           lldb::SBThread thread = process.GetThreadAtIndex(thread_idx);
199           g_vsc.thread_ids.insert(thread.GetThreadID());
200           if (ThreadHasStopReason(thread)) {
201             g_vsc.SendJSON(CreateThreadStopped(thread, stop_id));
202           }
203         }
204       }
205 
206       for (auto tid : old_thread_ids) {
207         auto end = g_vsc.thread_ids.end();
208         auto pos = g_vsc.thread_ids.find(tid);
209         if (pos == end)
210           SendThreadExitedEvent(tid);
211       }
212     } else {
213       if (g_vsc.log)
214         *g_vsc.log << "error: SendThreadStoppedEvent() when process"
215                       " isn't stopped ("
216                    << lldb::SBDebugger::StateAsCString(state) << ')'
217                    << std::endl;
218     }
219   } else {
220     if (g_vsc.log)
221       *g_vsc.log << "error: SendThreadStoppedEvent() invalid process"
222                  << std::endl;
223   }
224   g_vsc.RunStopCommands();
225 }
226 
227 // "ProcessEvent": {
228 //   "allOf": [
229 //     { "$ref": "#/definitions/Event" },
230 //     {
231 //       "type": "object",
232 //       "description": "Event message for 'process' event type. The event
233 //                       indicates that the debugger has begun debugging a
234 //                       new process. Either one that it has launched, or one
235 //                       that it has attached to.",
236 //       "properties": {
237 //         "event": {
238 //           "type": "string",
239 //           "enum": [ "process" ]
240 //         },
241 //         "body": {
242 //           "type": "object",
243 //           "properties": {
244 //             "name": {
245 //               "type": "string",
246 //               "description": "The logical name of the process. This is
247 //                               usually the full path to process's executable
248 //                               file. Example: /home/myproj/program.js."
249 //             },
250 //             "systemProcessId": {
251 //               "type": "integer",
252 //               "description": "The system process id of the debugged process.
253 //                               This property will be missing for non-system
254 //                               processes."
255 //             },
256 //             "isLocalProcess": {
257 //               "type": "boolean",
258 //               "description": "If true, the process is running on the same
259 //                               computer as the debug adapter."
260 //             },
261 //             "startMethod": {
262 //               "type": "string",
263 //               "enum": [ "launch", "attach", "attachForSuspendedLaunch" ],
264 //               "description": "Describes how the debug engine started
265 //                               debugging this process.",
266 //               "enumDescriptions": [
267 //                 "Process was launched under the debugger.",
268 //                 "Debugger attached to an existing process.",
269 //                 "A project launcher component has launched a new process in
270 //                  a suspended state and then asked the debugger to attach."
271 //               ]
272 //             }
273 //           },
274 //           "required": [ "name" ]
275 //         }
276 //       },
277 //       "required": [ "event", "body" ]
278 //     }
279 //   ]
280 // }
281 void SendProcessEvent(LaunchMethod launch_method) {
282   lldb::SBFileSpec exe_fspec = g_vsc.target.GetExecutable();
283   char exe_path[PATH_MAX];
284   exe_fspec.GetPath(exe_path, sizeof(exe_path));
285   llvm::json::Object event(CreateEventObject("process"));
286   llvm::json::Object body;
287   EmplaceSafeString(body, "name", std::string(exe_path));
288   const auto pid = g_vsc.target.GetProcess().GetProcessID();
289   body.try_emplace("systemProcessId", (int64_t)pid);
290   body.try_emplace("isLocalProcess", true);
291   const char *startMethod = nullptr;
292   switch (launch_method) {
293   case Launch:
294     startMethod = "launch";
295     break;
296   case Attach:
297     startMethod = "attach";
298     break;
299   case AttachForSuspendedLaunch:
300     startMethod = "attachForSuspendedLaunch";
301     break;
302   }
303   body.try_emplace("startMethod", startMethod);
304   event.try_emplace("body", std::move(body));
305   g_vsc.SendJSON(llvm::json::Value(std::move(event)));
306 }
307 
308 // Grab any STDOUT and STDERR from the process and send it up to VS Code
309 // via an "output" event to the "stdout" and "stderr" categories.
310 void SendStdOutStdErr(lldb::SBProcess &process) {
311   char buffer[1024];
312   size_t count;
313   while ((count = process.GetSTDOUT(buffer, sizeof(buffer))) > 0)
314   g_vsc.SendOutput(OutputType::Stdout, llvm::StringRef(buffer, count));
315   while ((count = process.GetSTDERR(buffer, sizeof(buffer))) > 0)
316     g_vsc.SendOutput(OutputType::Stderr, llvm::StringRef(buffer, count));
317 }
318 
319 // All events from the debugger, target, process, thread and frames are
320 // received in this function that runs in its own thread. We are using a
321 // "FILE *" to output packets back to VS Code and they have mutexes in them
322 // them prevent multiple threads from writing simultaneously so no locking
323 // is required.
324 void EventThreadFunction() {
325   lldb::SBEvent event;
326   lldb::SBListener listener = g_vsc.debugger.GetListener();
327   bool done = false;
328   while (!done) {
329     if (listener.WaitForEvent(1, event)) {
330       const auto event_mask = event.GetType();
331       if (lldb::SBProcess::EventIsProcessEvent(event)) {
332         lldb::SBProcess process = lldb::SBProcess::GetProcessFromEvent(event);
333         if (event_mask & lldb::SBProcess::eBroadcastBitStateChanged) {
334           auto state = lldb::SBProcess::GetStateFromEvent(event);
335           switch (state) {
336           case lldb::eStateInvalid:
337             // Not a state event
338             break;
339           case lldb::eStateUnloaded:
340             break;
341           case lldb::eStateConnected:
342             break;
343           case lldb::eStateAttaching:
344             break;
345           case lldb::eStateLaunching:
346             break;
347           case lldb::eStateStepping:
348             break;
349           case lldb::eStateCrashed:
350             break;
351           case lldb::eStateDetached:
352             break;
353           case lldb::eStateSuspended:
354             break;
355           case lldb::eStateStopped:
356             // Only report a stopped event if the process was not restarted.
357             if (!lldb::SBProcess::GetRestartedFromEvent(event)) {
358               SendStdOutStdErr(process);
359               SendThreadStoppedEvent();
360             }
361             break;
362           case lldb::eStateRunning:
363             break;
364           case lldb::eStateExited: {
365             // Run any exit LLDB commands the user specified in the
366             // launch.json
367             g_vsc.RunExitCommands();
368             SendProcessExitedEvent(process);
369             SendTerminatedEvent();
370             done = true;
371           } break;
372           }
373         } else if ((event_mask & lldb::SBProcess::eBroadcastBitSTDOUT) ||
374                    (event_mask & lldb::SBProcess::eBroadcastBitSTDERR)) {
375           SendStdOutStdErr(process);
376         }
377       } else if (lldb::SBBreakpoint::EventIsBreakpointEvent(event)) {
378         if (event_mask & lldb::SBTarget::eBroadcastBitBreakpointChanged) {
379           auto event_type =
380               lldb::SBBreakpoint::GetBreakpointEventTypeFromEvent(event);
381           const auto num_locs =
382               lldb::SBBreakpoint::GetNumBreakpointLocationsFromEvent(event);
383           auto bp = lldb::SBBreakpoint::GetBreakpointFromEvent(event);
384           bool added = event_type & lldb::eBreakpointEventTypeLocationsAdded;
385           bool removed =
386               event_type & lldb::eBreakpointEventTypeLocationsRemoved;
387           if (added || removed) {
388             for (size_t i = 0; i < num_locs; ++i) {
389               auto bp_loc =
390                   lldb::SBBreakpoint::GetBreakpointLocationAtIndexFromEvent(
391                       event, i);
392               auto bp_event = CreateEventObject("breakpoint");
393               llvm::json::Object body;
394               body.try_emplace("breakpoint", CreateBreakpoint(bp_loc));
395               if (added)
396                 body.try_emplace("reason", "new");
397               else
398                 body.try_emplace("reason", "removed");
399               bp_event.try_emplace("body", std::move(body));
400               g_vsc.SendJSON(llvm::json::Value(std::move(bp_event)));
401             }
402           }
403         }
404       } else if (event.BroadcasterMatchesRef(g_vsc.broadcaster)) {
405         if (event_mask & eBroadcastBitStopEventThread) {
406           done = true;
407         }
408       }
409     }
410   }
411 }
412 
413 // Both attach and launch take a either a sourcePath or sourceMap
414 // argument (or neither), from which we need to set the target.source-map.
415 void SetSourceMapFromArguments(const llvm::json::Object &arguments) {
416   const char *sourceMapHelp =
417       "source must be be an array of two-element arrays, "
418       "each containing a source and replacement path string.\n";
419 
420   std::string sourceMapCommand;
421   llvm::raw_string_ostream strm(sourceMapCommand);
422   strm << "settings set target.source-map ";
423   auto sourcePath = GetString(arguments, "sourcePath");
424 
425   // sourceMap is the new, more general form of sourcePath and overrides it.
426   auto sourceMap = arguments.getArray("sourceMap");
427   if (sourceMap) {
428     for (const auto &value : *sourceMap) {
429       auto mapping = value.getAsArray();
430       if (mapping == nullptr || mapping->size() != 2 ||
431           (*mapping)[0].kind() != llvm::json::Value::String ||
432           (*mapping)[1].kind() != llvm::json::Value::String) {
433         g_vsc.SendOutput(OutputType::Console, llvm::StringRef(sourceMapHelp));
434         return;
435       }
436       auto mapFrom = GetAsString((*mapping)[0]);
437       auto mapTo = GetAsString((*mapping)[1]);
438       strm << "\"" << mapFrom << "\" \"" << mapTo << "\"";
439     }
440   } else {
441     if (ObjectContainsKey(arguments, "sourceMap")) {
442       g_vsc.SendOutput(OutputType::Console, llvm::StringRef(sourceMapHelp));
443       return;
444     }
445     if (sourcePath.empty())
446       return;
447     // Do any source remapping needed before we create our targets
448     strm << "\".\" \"" << sourcePath << "\"";
449   }
450   strm.flush();
451   if (!sourceMapCommand.empty()) {
452     g_vsc.RunLLDBCommands("Setting source map:", {sourceMapCommand});
453   }
454 }
455 
456 // "AttachRequest": {
457 //   "allOf": [ { "$ref": "#/definitions/Request" }, {
458 //     "type": "object",
459 //     "description": "Attach request; value of command field is 'attach'.",
460 //     "properties": {
461 //       "command": {
462 //         "type": "string",
463 //         "enum": [ "attach" ]
464 //       },
465 //       "arguments": {
466 //         "$ref": "#/definitions/AttachRequestArguments"
467 //       }
468 //     },
469 //     "required": [ "command", "arguments" ]
470 //   }]
471 // },
472 // "AttachRequestArguments": {
473 //   "type": "object",
474 //   "description": "Arguments for 'attach' request.\nThe attach request has no
475 //   standardized attributes."
476 // },
477 // "AttachResponse": {
478 //   "allOf": [ { "$ref": "#/definitions/Response" }, {
479 //     "type": "object",
480 //     "description": "Response to 'attach' request. This is just an
481 //     acknowledgement, so no body field is required."
482 //   }]
483 // }
484 void request_attach(const llvm::json::Object &request) {
485   llvm::json::Object response;
486   lldb::SBError error;
487   FillResponse(request, response);
488   auto arguments = request.getObject("arguments");
489   const lldb::pid_t pid =
490       GetUnsigned(arguments, "pid", LLDB_INVALID_PROCESS_ID);
491   if (pid != LLDB_INVALID_PROCESS_ID)
492     g_vsc.attach_info.SetProcessID(pid);
493   const auto wait_for = GetBoolean(arguments, "waitFor", false);
494   g_vsc.attach_info.SetWaitForLaunch(wait_for, false /*async*/);
495   g_vsc.init_commands = GetStrings(arguments, "initCommands");
496   g_vsc.pre_run_commands = GetStrings(arguments, "preRunCommands");
497   g_vsc.stop_commands = GetStrings(arguments, "stopCommands");
498   g_vsc.exit_commands = GetStrings(arguments, "exitCommands");
499   auto attachCommands = GetStrings(arguments, "attachCommands");
500   g_vsc.stop_at_entry = GetBoolean(arguments, "stopOnEntry", false);
501   const auto debuggerRoot = GetString(arguments, "debuggerRoot");
502 
503   // This is a hack for loading DWARF in .o files on Mac where the .o files
504   // in the debug map of the main executable have relative paths which require
505   // the lldb-vscode binary to have its working directory set to that relative
506   // root for the .o files in order to be able to load debug info.
507   if (!debuggerRoot.empty()) {
508     llvm::sys::fs::set_current_path(debuggerRoot.data());
509   }
510 
511   // Run any initialize LLDB commands the user specified in the launch.json
512   g_vsc.RunInitCommands();
513 
514   // Grab the name of the program we need to debug and set it as the first
515   // argument that will be passed to the program we will debug.
516   const auto program = GetString(arguments, "program");
517   if (!program.empty()) {
518     lldb::SBFileSpec program_fspec(program.data(), true /*resolve_path*/);
519 
520     g_vsc.launch_info.SetExecutableFile(program_fspec,
521                                         false /*add_as_first_arg*/);
522     const char *target_triple = nullptr;
523     const char *uuid_cstr = nullptr;
524     // Stand alone debug info file if different from executable
525     const char *symfile = nullptr;
526     g_vsc.target.AddModule(program.data(), target_triple, uuid_cstr, symfile);
527     if (error.Fail()) {
528       response["success"] = llvm::json::Value(false);
529       EmplaceSafeString(response, "message", std::string(error.GetCString()));
530       g_vsc.SendJSON(llvm::json::Value(std::move(response)));
531       return;
532     }
533   }
534 
535   const bool detatchOnError = GetBoolean(arguments, "detachOnError", false);
536   g_vsc.launch_info.SetDetachOnError(detatchOnError);
537 
538   // Run any pre run LLDB commands the user specified in the launch.json
539   g_vsc.RunPreRunCommands();
540 
541   if (pid == LLDB_INVALID_PROCESS_ID && wait_for) {
542     char attach_info[256];
543     auto attach_info_len =
544         snprintf(attach_info, sizeof(attach_info),
545                  "Waiting to attach to \"%s\"...", program.data());
546     g_vsc.SendOutput(OutputType::Console, llvm::StringRef(attach_info,
547                                                           attach_info_len));
548   }
549   if (attachCommands.empty()) {
550     // No "attachCommands", just attach normally.
551     // Disable async events so the attach will be successful when we return from
552     // the launch call and the launch will happen synchronously
553     g_vsc.debugger.SetAsync(false);
554     g_vsc.target.Attach(g_vsc.attach_info, error);
555     // Reenable async events
556     g_vsc.debugger.SetAsync(true);
557   } else {
558     // We have "attachCommands" that are a set of commands that are expected
559     // to execute the commands after which a process should be created. If there
560     // is no valid process after running these commands, we have failed.
561     g_vsc.RunLLDBCommands("Running attachCommands:", attachCommands);
562     // The custom commands might have created a new target so we should use the
563     // selected target after these commands are run.
564     g_vsc.target = g_vsc.debugger.GetSelectedTarget();
565   }
566 
567   SetSourceMapFromArguments(*arguments);
568 
569   if (error.Success()) {
570     auto attached_pid = g_vsc.target.GetProcess().GetProcessID();
571     if (attached_pid == LLDB_INVALID_PROCESS_ID) {
572       if (attachCommands.empty())
573         error.SetErrorString("failed to attach to a process");
574       else
575         error.SetErrorString("attachCommands failed to attach to a process");
576     }
577   }
578 
579   if (error.Fail()) {
580     response["success"] = llvm::json::Value(false);
581     EmplaceSafeString(response, "message", std::string(error.GetCString()));
582   }
583   g_vsc.SendJSON(llvm::json::Value(std::move(response)));
584   if (error.Success()) {
585     SendProcessEvent(Attach);
586     g_vsc.SendJSON(CreateEventObject("initialized"));
587     // SendThreadStoppedEvent();
588   }
589 }
590 
591 // "ContinueRequest": {
592 //   "allOf": [ { "$ref": "#/definitions/Request" }, {
593 //     "type": "object",
594 //     "description": "Continue request; value of command field is 'continue'.
595 //                     The request starts the debuggee to run again.",
596 //     "properties": {
597 //       "command": {
598 //         "type": "string",
599 //         "enum": [ "continue" ]
600 //       },
601 //       "arguments": {
602 //         "$ref": "#/definitions/ContinueArguments"
603 //       }
604 //     },
605 //     "required": [ "command", "arguments"  ]
606 //   }]
607 // },
608 // "ContinueArguments": {
609 //   "type": "object",
610 //   "description": "Arguments for 'continue' request.",
611 //   "properties": {
612 //     "threadId": {
613 //       "type": "integer",
614 //       "description": "Continue execution for the specified thread (if
615 //                       possible). If the backend cannot continue on a single
616 //                       thread but will continue on all threads, it should
617 //                       set the allThreadsContinued attribute in the response
618 //                       to true."
619 //     }
620 //   },
621 //   "required": [ "threadId" ]
622 // },
623 // "ContinueResponse": {
624 //   "allOf": [ { "$ref": "#/definitions/Response" }, {
625 //     "type": "object",
626 //     "description": "Response to 'continue' request.",
627 //     "properties": {
628 //       "body": {
629 //         "type": "object",
630 //         "properties": {
631 //           "allThreadsContinued": {
632 //             "type": "boolean",
633 //             "description": "If true, the continue request has ignored the
634 //                             specified thread and continued all threads
635 //                             instead. If this attribute is missing a value
636 //                             of 'true' is assumed for backward
637 //                             compatibility."
638 //           }
639 //         }
640 //       }
641 //     },
642 //     "required": [ "body" ]
643 //   }]
644 // }
645 void request_continue(const llvm::json::Object &request) {
646   llvm::json::Object response;
647   FillResponse(request, response);
648   lldb::SBProcess process = g_vsc.target.GetProcess();
649   auto arguments = request.getObject("arguments");
650   // Remember the thread ID that caused the resume so we can set the
651   // "threadCausedFocus" boolean value in the "stopped" events.
652   g_vsc.focus_tid = GetUnsigned(arguments, "threadId", LLDB_INVALID_THREAD_ID);
653   lldb::SBError error = process.Continue();
654   llvm::json::Object body;
655   body.try_emplace("allThreadsContinued", true);
656   response.try_emplace("body", std::move(body));
657   g_vsc.SendJSON(llvm::json::Value(std::move(response)));
658 }
659 
660 // "ConfigurationDoneRequest": {
661 //   "allOf": [ { "$ref": "#/definitions/Request" }, {
662 //             "type": "object",
663 //             "description": "ConfigurationDone request; value of command field
664 //             is 'configurationDone'.\nThe client of the debug protocol must
665 //             send this request at the end of the sequence of configuration
666 //             requests (which was started by the InitializedEvent).",
667 //             "properties": {
668 //             "command": {
669 //             "type": "string",
670 //             "enum": [ "configurationDone" ]
671 //             },
672 //             "arguments": {
673 //             "$ref": "#/definitions/ConfigurationDoneArguments"
674 //             }
675 //             },
676 //             "required": [ "command" ]
677 //             }]
678 // },
679 // "ConfigurationDoneArguments": {
680 //   "type": "object",
681 //   "description": "Arguments for 'configurationDone' request.\nThe
682 //   configurationDone request has no standardized attributes."
683 // },
684 // "ConfigurationDoneResponse": {
685 //   "allOf": [ { "$ref": "#/definitions/Response" }, {
686 //             "type": "object",
687 //             "description": "Response to 'configurationDone' request. This is
688 //             just an acknowledgement, so no body field is required."
689 //             }]
690 // },
691 void request_configurationDone(const llvm::json::Object &request) {
692   llvm::json::Object response;
693   FillResponse(request, response);
694   g_vsc.SendJSON(llvm::json::Value(std::move(response)));
695   if (g_vsc.stop_at_entry)
696     SendThreadStoppedEvent();
697   else
698     g_vsc.target.GetProcess().Continue();
699 }
700 
701 // "DisconnectRequest": {
702 //   "allOf": [ { "$ref": "#/definitions/Request" }, {
703 //     "type": "object",
704 //     "description": "Disconnect request; value of command field is
705 //                     'disconnect'.",
706 //     "properties": {
707 //       "command": {
708 //         "type": "string",
709 //         "enum": [ "disconnect" ]
710 //       },
711 //       "arguments": {
712 //         "$ref": "#/definitions/DisconnectArguments"
713 //       }
714 //     },
715 //     "required": [ "command" ]
716 //   }]
717 // },
718 // "DisconnectArguments": {
719 //   "type": "object",
720 //   "description": "Arguments for 'disconnect' request.",
721 //   "properties": {
722 //     "terminateDebuggee": {
723 //       "type": "boolean",
724 //       "description": "Indicates whether the debuggee should be terminated
725 //                       when the debugger is disconnected. If unspecified,
726 //                       the debug adapter is free to do whatever it thinks
727 //                       is best. A client can only rely on this attribute
728 //                       being properly honored if a debug adapter returns
729 //                       true for the 'supportTerminateDebuggee' capability."
730 //     },
731 //     "restart": {
732 //       "type": "boolean",
733 //       "description": "Indicates whether the debuggee should be restart
734 //                       the process."
735 //     }
736 //   }
737 // },
738 // "DisconnectResponse": {
739 //   "allOf": [ { "$ref": "#/definitions/Response" }, {
740 //     "type": "object",
741 //     "description": "Response to 'disconnect' request. This is just an
742 //                     acknowledgement, so no body field is required."
743 //   }]
744 // }
745 void request_disconnect(const llvm::json::Object &request) {
746   llvm::json::Object response;
747   FillResponse(request, response);
748   auto arguments = request.getObject("arguments");
749 
750   bool terminateDebuggee = GetBoolean(arguments, "terminateDebuggee", false);
751   lldb::SBProcess process = g_vsc.target.GetProcess();
752   auto state = process.GetState();
753 
754   switch (state) {
755   case lldb::eStateInvalid:
756   case lldb::eStateUnloaded:
757   case lldb::eStateDetached:
758   case lldb::eStateExited:
759     break;
760   case lldb::eStateConnected:
761   case lldb::eStateAttaching:
762   case lldb::eStateLaunching:
763   case lldb::eStateStepping:
764   case lldb::eStateCrashed:
765   case lldb::eStateSuspended:
766   case lldb::eStateStopped:
767   case lldb::eStateRunning:
768     g_vsc.debugger.SetAsync(false);
769     if (terminateDebuggee)
770       process.Kill();
771     else
772       process.Detach();
773     g_vsc.debugger.SetAsync(true);
774     break;
775   }
776   g_vsc.SendJSON(llvm::json::Value(std::move(response)));
777   SendTerminatedEvent();
778   if (g_vsc.event_thread.joinable()) {
779     g_vsc.broadcaster.BroadcastEventByType(eBroadcastBitStopEventThread);
780     g_vsc.event_thread.join();
781   }
782 }
783 
784 void request_exceptionInfo(const llvm::json::Object &request) {
785   llvm::json::Object response;
786   FillResponse(request, response);
787   auto arguments = request.getObject("arguments");
788   llvm::json::Object body;
789   lldb::SBThread thread = g_vsc.GetLLDBThread(*arguments);
790   if (thread.IsValid()) {
791     auto stopReason = thread.GetStopReason();
792     if (stopReason == lldb::eStopReasonSignal)
793       body.try_emplace("exceptionId", "signal");
794     else if (stopReason == lldb::eStopReasonBreakpoint) {
795       ExceptionBreakpoint *exc_bp = g_vsc.GetExceptionBPFromStopReason(thread);
796       if (exc_bp) {
797         EmplaceSafeString(body, "exceptionId", exc_bp->filter);
798         EmplaceSafeString(body, "description", exc_bp->label);
799       } else {
800         body.try_emplace("exceptionId", "exception");
801       }
802     } else {
803       body.try_emplace("exceptionId", "exception");
804     }
805     if (!ObjectContainsKey(body, "description")) {
806       char description[1024];
807       if (thread.GetStopDescription(description, sizeof(description))) {
808         EmplaceSafeString(body, "description", std::string(description));
809       }
810     }
811     body.try_emplace("breakMode", "always");
812     // auto excInfoCount = thread.GetStopReasonDataCount();
813     // for (auto i=0; i<excInfoCount; ++i) {
814     //   uint64_t exc_data = thread.GetStopReasonDataAtIndex(i);
815     // }
816   } else {
817     response["success"] = llvm::json::Value(false);
818   }
819   response.try_emplace("body", std::move(body));
820   g_vsc.SendJSON(llvm::json::Value(std::move(response)));
821 }
822 
823 //  "EvaluateRequest": {
824 //    "allOf": [ { "$ref": "#/definitions/Request" }, {
825 //      "type": "object",
826 //      "description": "Evaluate request; value of command field is 'evaluate'.
827 //                      Evaluates the given expression in the context of the
828 //                      top most stack frame. The expression has access to any
829 //                      variables and arguments that are in scope.",
830 //      "properties": {
831 //        "command": {
832 //          "type": "string",
833 //          "enum": [ "evaluate" ]
834 //        },
835 //        "arguments": {
836 //          "$ref": "#/definitions/EvaluateArguments"
837 //        }
838 //      },
839 //      "required": [ "command", "arguments"  ]
840 //    }]
841 //  },
842 //  "EvaluateArguments": {
843 //    "type": "object",
844 //    "description": "Arguments for 'evaluate' request.",
845 //    "properties": {
846 //      "expression": {
847 //        "type": "string",
848 //        "description": "The expression to evaluate."
849 //      },
850 //      "frameId": {
851 //        "type": "integer",
852 //        "description": "Evaluate the expression in the scope of this stack
853 //                        frame. If not specified, the expression is evaluated
854 //                        in the global scope."
855 //      },
856 //      "context": {
857 //        "type": "string",
858 //        "_enum": [ "watch", "repl", "hover" ],
859 //        "enumDescriptions": [
860 //          "evaluate is run in a watch.",
861 //          "evaluate is run from REPL console.",
862 //          "evaluate is run from a data hover."
863 //        ],
864 //        "description": "The context in which the evaluate request is run."
865 //      },
866 //      "format": {
867 //        "$ref": "#/definitions/ValueFormat",
868 //        "description": "Specifies details on how to format the Evaluate
869 //                        result."
870 //      }
871 //    },
872 //    "required": [ "expression" ]
873 //  },
874 //  "EvaluateResponse": {
875 //    "allOf": [ { "$ref": "#/definitions/Response" }, {
876 //      "type": "object",
877 //      "description": "Response to 'evaluate' request.",
878 //      "properties": {
879 //        "body": {
880 //          "type": "object",
881 //          "properties": {
882 //            "result": {
883 //              "type": "string",
884 //              "description": "The result of the evaluate request."
885 //            },
886 //            "type": {
887 //              "type": "string",
888 //              "description": "The optional type of the evaluate result."
889 //            },
890 //            "presentationHint": {
891 //              "$ref": "#/definitions/VariablePresentationHint",
892 //              "description": "Properties of a evaluate result that can be
893 //                              used to determine how to render the result in
894 //                              the UI."
895 //            },
896 //            "variablesReference": {
897 //              "type": "number",
898 //              "description": "If variablesReference is > 0, the evaluate
899 //                              result is structured and its children can be
900 //                              retrieved by passing variablesReference to the
901 //                              VariablesRequest."
902 //            },
903 //            "namedVariables": {
904 //              "type": "number",
905 //              "description": "The number of named child variables. The
906 //                              client can use this optional information to
907 //                              present the variables in a paged UI and fetch
908 //                              them in chunks."
909 //            },
910 //            "indexedVariables": {
911 //              "type": "number",
912 //              "description": "The number of indexed child variables. The
913 //                              client can use this optional information to
914 //                              present the variables in a paged UI and fetch
915 //                              them in chunks."
916 //            }
917 //          },
918 //          "required": [ "result", "variablesReference" ]
919 //        }
920 //      },
921 //      "required": [ "body" ]
922 //    }]
923 //  }
924 void request_evaluate(const llvm::json::Object &request) {
925   llvm::json::Object response;
926   FillResponse(request, response);
927   llvm::json::Object body;
928   auto arguments = request.getObject("arguments");
929   lldb::SBFrame frame = g_vsc.GetLLDBFrame(*arguments);
930   const auto expression = GetString(arguments, "expression");
931 
932   if (!expression.empty() && expression[0] == '`') {
933     auto result = RunLLDBCommands(llvm::StringRef(),
934                                      {expression.substr(1)});
935     EmplaceSafeString(body, "result", result);
936     body.try_emplace("variablesReference", (int64_t)0);
937   } else {
938     // Always try to get the answer from the local variables if possible. If
939     // this fails, then actually evaluate an expression using the expression
940     // parser. "frame variable" is more reliable than the expression parser in
941     // many cases and it is faster.
942     lldb::SBValue value = frame.GetValueForVariablePath(
943         expression.data(), lldb::eDynamicDontRunTarget);
944     if (value.GetError().Fail())
945       value = frame.EvaluateExpression(expression.data());
946     if (value.GetError().Fail()) {
947       response["success"] = llvm::json::Value(false);
948       // This error object must live until we're done with the pointer returned
949       // by GetCString().
950       lldb::SBError error = value.GetError();
951       const char *error_cstr = error.GetCString();
952       if (error_cstr && error_cstr[0])
953         EmplaceSafeString(response, "message", std::string(error_cstr));
954       else
955         EmplaceSafeString(response, "message", "evaluate failed");
956     } else {
957       SetValueForKey(value, body, "result");
958       auto value_typename = value.GetType().GetDisplayTypeName();
959       EmplaceSafeString(body, "type", value_typename ? value_typename : NO_TYPENAME);
960       if (value.MightHaveChildren()) {
961         auto variablesReference = VARIDX_TO_VARREF(g_vsc.variables.GetSize());
962         g_vsc.variables.Append(value);
963         body.try_emplace("variablesReference", variablesReference);
964       } else {
965         body.try_emplace("variablesReference", (int64_t)0);
966       }
967     }
968   }
969   response.try_emplace("body", std::move(body));
970   g_vsc.SendJSON(llvm::json::Value(std::move(response)));
971 }
972 
973 // "InitializeRequest": {
974 //   "allOf": [ { "$ref": "#/definitions/Request" }, {
975 //     "type": "object",
976 //     "description": "Initialize request; value of command field is
977 //                     'initialize'.",
978 //     "properties": {
979 //       "command": {
980 //         "type": "string",
981 //         "enum": [ "initialize" ]
982 //       },
983 //       "arguments": {
984 //         "$ref": "#/definitions/InitializeRequestArguments"
985 //       }
986 //     },
987 //     "required": [ "command", "arguments" ]
988 //   }]
989 // },
990 // "InitializeRequestArguments": {
991 //   "type": "object",
992 //   "description": "Arguments for 'initialize' request.",
993 //   "properties": {
994 //     "clientID": {
995 //       "type": "string",
996 //       "description": "The ID of the (frontend) client using this adapter."
997 //     },
998 //     "adapterID": {
999 //       "type": "string",
1000 //       "description": "The ID of the debug adapter."
1001 //     },
1002 //     "locale": {
1003 //       "type": "string",
1004 //       "description": "The ISO-639 locale of the (frontend) client using
1005 //                       this adapter, e.g. en-US or de-CH."
1006 //     },
1007 //     "linesStartAt1": {
1008 //       "type": "boolean",
1009 //       "description": "If true all line numbers are 1-based (default)."
1010 //     },
1011 //     "columnsStartAt1": {
1012 //       "type": "boolean",
1013 //       "description": "If true all column numbers are 1-based (default)."
1014 //     },
1015 //     "pathFormat": {
1016 //       "type": "string",
1017 //       "_enum": [ "path", "uri" ],
1018 //       "description": "Determines in what format paths are specified. The
1019 //                       default is 'path', which is the native format."
1020 //     },
1021 //     "supportsVariableType": {
1022 //       "type": "boolean",
1023 //       "description": "Client supports the optional type attribute for
1024 //                       variables."
1025 //     },
1026 //     "supportsVariablePaging": {
1027 //       "type": "boolean",
1028 //       "description": "Client supports the paging of variables."
1029 //     },
1030 //     "supportsRunInTerminalRequest": {
1031 //       "type": "boolean",
1032 //       "description": "Client supports the runInTerminal request."
1033 //     }
1034 //   },
1035 //   "required": [ "adapterID" ]
1036 // },
1037 // "InitializeResponse": {
1038 //   "allOf": [ { "$ref": "#/definitions/Response" }, {
1039 //     "type": "object",
1040 //     "description": "Response to 'initialize' request.",
1041 //     "properties": {
1042 //       "body": {
1043 //         "$ref": "#/definitions/Capabilities",
1044 //         "description": "The capabilities of this debug adapter."
1045 //       }
1046 //     }
1047 //   }]
1048 // }
1049 void request_initialize(const llvm::json::Object &request) {
1050   g_vsc.debugger = lldb::SBDebugger::Create(true /*source_init_files*/);
1051   // Create an empty target right away since we might get breakpoint requests
1052   // before we are given an executable to launch in a "launch" request, or a
1053   // executable when attaching to a process by process ID in a "attach"
1054   // request.
1055   FILE *out = llvm::sys::RetryAfterSignal(nullptr, fopen, dev_null_path, "w");
1056   if (out) {
1057     // Set the output and error file handles to redirect into nothing otherwise
1058     // if any code in LLDB prints to the debugger file handles, the output and
1059     // error file handles are initialized to STDOUT and STDERR and any output
1060     // will kill our debug session.
1061     g_vsc.debugger.SetOutputFileHandle(out, true);
1062     g_vsc.debugger.SetErrorFileHandle(out, false);
1063   }
1064 
1065   g_vsc.target = g_vsc.debugger.CreateTarget(nullptr);
1066   lldb::SBListener listener = g_vsc.debugger.GetListener();
1067   listener.StartListeningForEvents(
1068       g_vsc.target.GetBroadcaster(),
1069       lldb::SBTarget::eBroadcastBitBreakpointChanged);
1070   listener.StartListeningForEvents(g_vsc.broadcaster,
1071                                    eBroadcastBitStopEventThread);
1072   // Start our event thread so we can receive events from the debugger, target,
1073   // process and more.
1074   g_vsc.event_thread = std::thread(EventThreadFunction);
1075 
1076   llvm::json::Object response;
1077   FillResponse(request, response);
1078   llvm::json::Object body;
1079   // The debug adapter supports the configurationDoneRequest.
1080   body.try_emplace("supportsConfigurationDoneRequest", true);
1081   // The debug adapter supports function breakpoints.
1082   body.try_emplace("supportsFunctionBreakpoints", true);
1083   // The debug adapter supports conditional breakpoints.
1084   body.try_emplace("supportsConditionalBreakpoints", true);
1085   // The debug adapter supports breakpoints that break execution after a
1086   // specified number of hits.
1087   body.try_emplace("supportsHitConditionalBreakpoints", true);
1088   // The debug adapter supports a (side effect free) evaluate request for
1089   // data hovers.
1090   body.try_emplace("supportsEvaluateForHovers", true);
1091   // Available filters or options for the setExceptionBreakpoints request.
1092   llvm::json::Array filters;
1093   for (const auto &exc_bp : g_vsc.exception_breakpoints) {
1094     filters.emplace_back(CreateExceptionBreakpointFilter(exc_bp));
1095   }
1096   body.try_emplace("exceptionBreakpointFilters", std::move(filters));
1097   // The debug adapter supports stepping back via the stepBack and
1098   // reverseContinue requests.
1099   body.try_emplace("supportsStepBack", false);
1100   // The debug adapter supports setting a variable to a value.
1101   body.try_emplace("supportsSetVariable", true);
1102   // The debug adapter supports restarting a frame.
1103   body.try_emplace("supportsRestartFrame", false);
1104   // The debug adapter supports the gotoTargetsRequest.
1105   body.try_emplace("supportsGotoTargetsRequest", false);
1106   // The debug adapter supports the stepInTargetsRequest.
1107   body.try_emplace("supportsStepInTargetsRequest", false);
1108   // The debug adapter supports the completionsRequest.
1109   body.try_emplace("supportsCompletionsRequest", false);
1110   // The debug adapter supports the modules request.
1111   body.try_emplace("supportsModulesRequest", false);
1112   // The set of additional module information exposed by the debug adapter.
1113   //   body.try_emplace("additionalModuleColumns"] = ColumnDescriptor
1114   // Checksum algorithms supported by the debug adapter.
1115   //   body.try_emplace("supportedChecksumAlgorithms"] = ChecksumAlgorithm
1116   // The debug adapter supports the RestartRequest. In this case a client
1117   // should not implement 'restart' by terminating and relaunching the adapter
1118   // but by calling the RestartRequest.
1119   body.try_emplace("supportsRestartRequest", false);
1120   // The debug adapter supports 'exceptionOptions' on the
1121   // setExceptionBreakpoints request.
1122   body.try_emplace("supportsExceptionOptions", true);
1123   // The debug adapter supports a 'format' attribute on the stackTraceRequest,
1124   // variablesRequest, and evaluateRequest.
1125   body.try_emplace("supportsValueFormattingOptions", true);
1126   // The debug adapter supports the exceptionInfo request.
1127   body.try_emplace("supportsExceptionInfoRequest", true);
1128   // The debug adapter supports the 'terminateDebuggee' attribute on the
1129   // 'disconnect' request.
1130   body.try_emplace("supportTerminateDebuggee", true);
1131   // The debug adapter supports the delayed loading of parts of the stack,
1132   // which requires that both the 'startFrame' and 'levels' arguments and the
1133   // 'totalFrames' result of the 'StackTrace' request are supported.
1134   body.try_emplace("supportsDelayedStackTraceLoading", true);
1135   // The debug adapter supports the 'loadedSources' request.
1136   body.try_emplace("supportsLoadedSourcesRequest", false);
1137 
1138   response.try_emplace("body", std::move(body));
1139   g_vsc.SendJSON(llvm::json::Value(std::move(response)));
1140 }
1141 
1142 // "LaunchRequest": {
1143 //   "allOf": [ { "$ref": "#/definitions/Request" }, {
1144 //     "type": "object",
1145 //     "description": "Launch request; value of command field is 'launch'.",
1146 //     "properties": {
1147 //       "command": {
1148 //         "type": "string",
1149 //         "enum": [ "launch" ]
1150 //       },
1151 //       "arguments": {
1152 //         "$ref": "#/definitions/LaunchRequestArguments"
1153 //       }
1154 //     },
1155 //     "required": [ "command", "arguments"  ]
1156 //   }]
1157 // },
1158 // "LaunchRequestArguments": {
1159 //   "type": "object",
1160 //   "description": "Arguments for 'launch' request.",
1161 //   "properties": {
1162 //     "noDebug": {
1163 //       "type": "boolean",
1164 //       "description": "If noDebug is true the launch request should launch
1165 //                       the program without enabling debugging."
1166 //     }
1167 //   }
1168 // },
1169 // "LaunchResponse": {
1170 //   "allOf": [ { "$ref": "#/definitions/Response" }, {
1171 //     "type": "object",
1172 //     "description": "Response to 'launch' request. This is just an
1173 //                     acknowledgement, so no body field is required."
1174 //   }]
1175 // }
1176 void request_launch(const llvm::json::Object &request) {
1177   llvm::json::Object response;
1178   lldb::SBError error;
1179   FillResponse(request, response);
1180   auto arguments = request.getObject("arguments");
1181   g_vsc.init_commands = GetStrings(arguments, "initCommands");
1182   g_vsc.pre_run_commands = GetStrings(arguments, "preRunCommands");
1183   g_vsc.stop_commands = GetStrings(arguments, "stopCommands");
1184   g_vsc.exit_commands = GetStrings(arguments, "exitCommands");
1185   auto launchCommands = GetStrings(arguments, "launchCommands");
1186   g_vsc.stop_at_entry = GetBoolean(arguments, "stopOnEntry", false);
1187   const auto debuggerRoot = GetString(arguments, "debuggerRoot");
1188 
1189   // This is a hack for loading DWARF in .o files on Mac where the .o files
1190   // in the debug map of the main executable have relative paths which require
1191   // the lldb-vscode binary to have its working directory set to that relative
1192   // root for the .o files in order to be able to load debug info.
1193   if (!debuggerRoot.empty()) {
1194     llvm::sys::fs::set_current_path(debuggerRoot.data());
1195   }
1196 
1197   SetSourceMapFromArguments(*arguments);
1198 
1199   // Run any initialize LLDB commands the user specified in the launch.json
1200   g_vsc.RunInitCommands();
1201 
1202   // Grab the current working directory if there is one and set it in the
1203   // launch info.
1204   const auto cwd = GetString(arguments, "cwd");
1205   if (!cwd.empty())
1206     g_vsc.launch_info.SetWorkingDirectory(cwd.data());
1207 
1208   // Grab the name of the program we need to debug and set it as the first
1209   // argument that will be passed to the program we will debug.
1210   llvm::StringRef program = GetString(arguments, "program");
1211   if (!program.empty()) {
1212     lldb::SBFileSpec program_fspec(program.data(), true /*resolve_path*/);
1213     g_vsc.launch_info.SetExecutableFile(program_fspec,
1214                                         true /*add_as_first_arg*/);
1215     const char *target_triple = nullptr;
1216     const char *uuid_cstr = nullptr;
1217     // Stand alone debug info file if different from executable
1218     const char *symfile = nullptr;
1219     lldb::SBModule module = g_vsc.target.AddModule(
1220         program.data(), target_triple, uuid_cstr, symfile);
1221     if (!module.IsValid()) {
1222       response["success"] = llvm::json::Value(false);
1223 
1224       EmplaceSafeString(
1225           response, "message",
1226           llvm::formatv("Could not load program '{0}'.", program).str());
1227       g_vsc.SendJSON(llvm::json::Value(std::move(response)));
1228       return;
1229     }
1230   }
1231 
1232   // Extract any extra arguments and append them to our program arguments for
1233   // when we launch
1234   auto args = GetStrings(arguments, "args");
1235   if (!args.empty())
1236     g_vsc.launch_info.SetArguments(MakeArgv(args).data(), true);
1237 
1238   // Pass any environment variables along that the user specified.
1239   auto envs = GetStrings(arguments, "env");
1240   if (!envs.empty())
1241     g_vsc.launch_info.SetEnvironmentEntries(MakeArgv(envs).data(), true);
1242 
1243   auto flags = g_vsc.launch_info.GetLaunchFlags();
1244 
1245   if (GetBoolean(arguments, "disableASLR", true))
1246     flags |= lldb::eLaunchFlagDisableASLR;
1247   if (GetBoolean(arguments, "disableSTDIO", false))
1248     flags |= lldb::eLaunchFlagDisableSTDIO;
1249   if (GetBoolean(arguments, "shellExpandArguments", false))
1250     flags |= lldb::eLaunchFlagShellExpandArguments;
1251   const bool detatchOnError = GetBoolean(arguments, "detachOnError", false);
1252   g_vsc.launch_info.SetDetachOnError(detatchOnError);
1253   g_vsc.launch_info.SetLaunchFlags(flags | lldb::eLaunchFlagDebug |
1254                                    lldb::eLaunchFlagStopAtEntry);
1255 
1256   // Run any pre run LLDB commands the user specified in the launch.json
1257   g_vsc.RunPreRunCommands();
1258   if (launchCommands.empty()) {
1259     // Disable async events so the launch will be successful when we return from
1260     // the launch call and the launch will happen synchronously
1261     g_vsc.debugger.SetAsync(false);
1262     g_vsc.target.Launch(g_vsc.launch_info, error);
1263     g_vsc.debugger.SetAsync(true);
1264   } else {
1265     g_vsc.RunLLDBCommands("Running launchCommands:", launchCommands);
1266     // The custom commands might have created a new target so we should use the
1267     // selected target after these commands are run.
1268     g_vsc.target = g_vsc.debugger.GetSelectedTarget();
1269   }
1270 
1271   if (error.Fail()) {
1272     response["success"] = llvm::json::Value(false);
1273     EmplaceSafeString(response, "message", std::string(error.GetCString()));
1274   }
1275   g_vsc.SendJSON(llvm::json::Value(std::move(response)));
1276 
1277   SendProcessEvent(Launch);
1278   g_vsc.SendJSON(llvm::json::Value(CreateEventObject("initialized")));
1279   // Reenable async events and start the event thread to catch async events.
1280   // g_vsc.debugger.SetAsync(true);
1281 }
1282 
1283 // "NextRequest": {
1284 //   "allOf": [ { "$ref": "#/definitions/Request" }, {
1285 //     "type": "object",
1286 //     "description": "Next request; value of command field is 'next'. The
1287 //                     request starts the debuggee to run again for one step.
1288 //                     The debug adapter first sends the NextResponse and then
1289 //                     a StoppedEvent (event type 'step') after the step has
1290 //                     completed.",
1291 //     "properties": {
1292 //       "command": {
1293 //         "type": "string",
1294 //         "enum": [ "next" ]
1295 //       },
1296 //       "arguments": {
1297 //         "$ref": "#/definitions/NextArguments"
1298 //       }
1299 //     },
1300 //     "required": [ "command", "arguments"  ]
1301 //   }]
1302 // },
1303 // "NextArguments": {
1304 //   "type": "object",
1305 //   "description": "Arguments for 'next' request.",
1306 //   "properties": {
1307 //     "threadId": {
1308 //       "type": "integer",
1309 //       "description": "Execute 'next' for this thread."
1310 //     }
1311 //   },
1312 //   "required": [ "threadId" ]
1313 // },
1314 // "NextResponse": {
1315 //   "allOf": [ { "$ref": "#/definitions/Response" }, {
1316 //     "type": "object",
1317 //     "description": "Response to 'next' request. This is just an
1318 //                     acknowledgement, so no body field is required."
1319 //   }]
1320 // }
1321 void request_next(const llvm::json::Object &request) {
1322   llvm::json::Object response;
1323   FillResponse(request, response);
1324   auto arguments = request.getObject("arguments");
1325   lldb::SBThread thread = g_vsc.GetLLDBThread(*arguments);
1326   if (thread.IsValid()) {
1327     // Remember the thread ID that caused the resume so we can set the
1328     // "threadCausedFocus" boolean value in the "stopped" events.
1329     g_vsc.focus_tid = thread.GetThreadID();
1330     thread.StepOver();
1331   } else {
1332     response["success"] = llvm::json::Value(false);
1333   }
1334   g_vsc.SendJSON(llvm::json::Value(std::move(response)));
1335 }
1336 
1337 // "PauseRequest": {
1338 //   "allOf": [ { "$ref": "#/definitions/Request" }, {
1339 //     "type": "object",
1340 //     "description": "Pause request; value of command field is 'pause'. The
1341 //     request suspenses the debuggee. The debug adapter first sends the
1342 //     PauseResponse and then a StoppedEvent (event type 'pause') after the
1343 //     thread has been paused successfully.", "properties": {
1344 //       "command": {
1345 //         "type": "string",
1346 //         "enum": [ "pause" ]
1347 //       },
1348 //       "arguments": {
1349 //         "$ref": "#/definitions/PauseArguments"
1350 //       }
1351 //     },
1352 //     "required": [ "command", "arguments"  ]
1353 //   }]
1354 // },
1355 // "PauseArguments": {
1356 //   "type": "object",
1357 //   "description": "Arguments for 'pause' request.",
1358 //   "properties": {
1359 //     "threadId": {
1360 //       "type": "integer",
1361 //       "description": "Pause execution for this thread."
1362 //     }
1363 //   },
1364 //   "required": [ "threadId" ]
1365 // },
1366 // "PauseResponse": {
1367 //   "allOf": [ { "$ref": "#/definitions/Response" }, {
1368 //     "type": "object",
1369 //     "description": "Response to 'pause' request. This is just an
1370 //     acknowledgement, so no body field is required."
1371 //   }]
1372 // }
1373 void request_pause(const llvm::json::Object &request) {
1374   llvm::json::Object response;
1375   FillResponse(request, response);
1376   lldb::SBProcess process = g_vsc.target.GetProcess();
1377   lldb::SBError error = process.Stop();
1378   g_vsc.SendJSON(llvm::json::Value(std::move(response)));
1379 }
1380 
1381 // "ScopesRequest": {
1382 //   "allOf": [ { "$ref": "#/definitions/Request" }, {
1383 //     "type": "object",
1384 //     "description": "Scopes request; value of command field is 'scopes'. The
1385 //     request returns the variable scopes for a given stackframe ID.",
1386 //     "properties": {
1387 //       "command": {
1388 //         "type": "string",
1389 //         "enum": [ "scopes" ]
1390 //       },
1391 //       "arguments": {
1392 //         "$ref": "#/definitions/ScopesArguments"
1393 //       }
1394 //     },
1395 //     "required": [ "command", "arguments"  ]
1396 //   }]
1397 // },
1398 // "ScopesArguments": {
1399 //   "type": "object",
1400 //   "description": "Arguments for 'scopes' request.",
1401 //   "properties": {
1402 //     "frameId": {
1403 //       "type": "integer",
1404 //       "description": "Retrieve the scopes for this stackframe."
1405 //     }
1406 //   },
1407 //   "required": [ "frameId" ]
1408 // },
1409 // "ScopesResponse": {
1410 //   "allOf": [ { "$ref": "#/definitions/Response" }, {
1411 //     "type": "object",
1412 //     "description": "Response to 'scopes' request.",
1413 //     "properties": {
1414 //       "body": {
1415 //         "type": "object",
1416 //         "properties": {
1417 //           "scopes": {
1418 //             "type": "array",
1419 //             "items": {
1420 //               "$ref": "#/definitions/Scope"
1421 //             },
1422 //             "description": "The scopes of the stackframe. If the array has
1423 //             length zero, there are no scopes available."
1424 //           }
1425 //         },
1426 //         "required": [ "scopes" ]
1427 //       }
1428 //     },
1429 //     "required": [ "body" ]
1430 //   }]
1431 // }
1432 void request_scopes(const llvm::json::Object &request) {
1433   llvm::json::Object response;
1434   FillResponse(request, response);
1435   llvm::json::Object body;
1436   auto arguments = request.getObject("arguments");
1437   lldb::SBFrame frame = g_vsc.GetLLDBFrame(*arguments);
1438   g_vsc.variables.Clear();
1439   g_vsc.variables.Append(frame.GetVariables(true,   // arguments
1440                                             true,   // locals
1441                                             false,  // statics
1442                                             true)); // in_scope_only
1443   g_vsc.num_locals = g_vsc.variables.GetSize();
1444   g_vsc.variables.Append(frame.GetVariables(false,  // arguments
1445                                             false,  // locals
1446                                             true,   // statics
1447                                             true)); // in_scope_only
1448   g_vsc.num_globals = g_vsc.variables.GetSize() - (g_vsc.num_locals);
1449   g_vsc.variables.Append(frame.GetRegisters());
1450   g_vsc.num_regs =
1451       g_vsc.variables.GetSize() - (g_vsc.num_locals + g_vsc.num_globals);
1452   body.try_emplace("scopes", g_vsc.CreateTopLevelScopes());
1453   response.try_emplace("body", std::move(body));
1454   g_vsc.SendJSON(llvm::json::Value(std::move(response)));
1455 }
1456 
1457 // "SetBreakpointsRequest": {
1458 //   "allOf": [ { "$ref": "#/definitions/Request" }, {
1459 //     "type": "object",
1460 //     "description": "SetBreakpoints request; value of command field is
1461 //     'setBreakpoints'. Sets multiple breakpoints for a single source and
1462 //     clears all previous breakpoints in that source. To clear all breakpoint
1463 //     for a source, specify an empty array. When a breakpoint is hit, a
1464 //     StoppedEvent (event type 'breakpoint') is generated.", "properties": {
1465 //       "command": {
1466 //         "type": "string",
1467 //         "enum": [ "setBreakpoints" ]
1468 //       },
1469 //       "arguments": {
1470 //         "$ref": "#/definitions/SetBreakpointsArguments"
1471 //       }
1472 //     },
1473 //     "required": [ "command", "arguments"  ]
1474 //   }]
1475 // },
1476 // "SetBreakpointsArguments": {
1477 //   "type": "object",
1478 //   "description": "Arguments for 'setBreakpoints' request.",
1479 //   "properties": {
1480 //     "source": {
1481 //       "$ref": "#/definitions/Source",
1482 //       "description": "The source location of the breakpoints; either
1483 //       source.path or source.reference must be specified."
1484 //     },
1485 //     "breakpoints": {
1486 //       "type": "array",
1487 //       "items": {
1488 //         "$ref": "#/definitions/SourceBreakpoint"
1489 //       },
1490 //       "description": "The code locations of the breakpoints."
1491 //     },
1492 //     "lines": {
1493 //       "type": "array",
1494 //       "items": {
1495 //         "type": "integer"
1496 //       },
1497 //       "description": "Deprecated: The code locations of the breakpoints."
1498 //     },
1499 //     "sourceModified": {
1500 //       "type": "boolean",
1501 //       "description": "A value of true indicates that the underlying source
1502 //       has been modified which results in new breakpoint locations."
1503 //     }
1504 //   },
1505 //   "required": [ "source" ]
1506 // },
1507 // "SetBreakpointsResponse": {
1508 //   "allOf": [ { "$ref": "#/definitions/Response" }, {
1509 //     "type": "object",
1510 //     "description": "Response to 'setBreakpoints' request. Returned is
1511 //     information about each breakpoint created by this request. This includes
1512 //     the actual code location and whether the breakpoint could be verified.
1513 //     The breakpoints returned are in the same order as the elements of the
1514 //     'breakpoints' (or the deprecated 'lines') in the
1515 //     SetBreakpointsArguments.", "properties": {
1516 //       "body": {
1517 //         "type": "object",
1518 //         "properties": {
1519 //           "breakpoints": {
1520 //             "type": "array",
1521 //             "items": {
1522 //               "$ref": "#/definitions/Breakpoint"
1523 //             },
1524 //             "description": "Information about the breakpoints. The array
1525 //             elements are in the same order as the elements of the
1526 //             'breakpoints' (or the deprecated 'lines') in the
1527 //             SetBreakpointsArguments."
1528 //           }
1529 //         },
1530 //         "required": [ "breakpoints" ]
1531 //       }
1532 //     },
1533 //     "required": [ "body" ]
1534 //   }]
1535 // },
1536 // "SourceBreakpoint": {
1537 //   "type": "object",
1538 //   "description": "Properties of a breakpoint or logpoint passed to the
1539 //   setBreakpoints request.", "properties": {
1540 //     "line": {
1541 //       "type": "integer",
1542 //       "description": "The source line of the breakpoint or logpoint."
1543 //     },
1544 //     "column": {
1545 //       "type": "integer",
1546 //       "description": "An optional source column of the breakpoint."
1547 //     },
1548 //     "condition": {
1549 //       "type": "string",
1550 //       "description": "An optional expression for conditional breakpoints."
1551 //     },
1552 //     "hitCondition": {
1553 //       "type": "string",
1554 //       "description": "An optional expression that controls how many hits of
1555 //       the breakpoint are ignored. The backend is expected to interpret the
1556 //       expression as needed."
1557 //     },
1558 //     "logMessage": {
1559 //       "type": "string",
1560 //       "description": "If this attribute exists and is non-empty, the backend
1561 //       must not 'break' (stop) but log the message instead. Expressions within
1562 //       {} are interpolated."
1563 //     }
1564 //   },
1565 //   "required": [ "line" ]
1566 // }
1567 void request_setBreakpoints(const llvm::json::Object &request) {
1568   llvm::json::Object response;
1569   lldb::SBError error;
1570   FillResponse(request, response);
1571   auto arguments = request.getObject("arguments");
1572   auto source = arguments->getObject("source");
1573   const auto path = GetString(source, "path");
1574   auto breakpoints = arguments->getArray("breakpoints");
1575   llvm::json::Array response_breakpoints;
1576   // Decode the source breakpoint infos for this "setBreakpoints" request
1577   SourceBreakpointMap request_bps;
1578   for (const auto &bp : *breakpoints) {
1579     auto bp_obj = bp.getAsObject();
1580     if (bp_obj) {
1581       SourceBreakpoint src_bp(*bp_obj);
1582       request_bps[src_bp.line] = std::move(src_bp);
1583     }
1584   }
1585 
1586   // See if we already have breakpoints set for this source file from a
1587   // previous "setBreakpoints" request
1588   auto old_src_bp_pos = g_vsc.source_breakpoints.find(path);
1589   if (old_src_bp_pos != g_vsc.source_breakpoints.end()) {
1590 
1591     // We have already set breakpoints in this source file and they are giving
1592     // use a new list of lines to set breakpoints on. Some breakpoints might
1593     // already be set, and some might not. We need to remove any breakpoints
1594     // whose lines are not contained in the any breakpoints lines in in the
1595     // "breakpoints" array.
1596 
1597     // Delete any breakpoints in this source file that aren't in the
1598     // request_bps set. There is no call to remove breakpoints other than
1599     // calling this function with a smaller or empty "breakpoints" list.
1600     std::vector<uint32_t> remove_lines;
1601     for (auto &pair: old_src_bp_pos->second) {
1602       auto request_pos = request_bps.find(pair.first);
1603       if (request_pos == request_bps.end()) {
1604         // This breakpoint no longer exists in this source file, delete it
1605         g_vsc.target.BreakpointDelete(pair.second.bp.GetID());
1606         remove_lines.push_back(pair.first);
1607       } else {
1608         pair.second.UpdateBreakpoint(request_pos->second);
1609         // Remove this breakpoint from the request breakpoints since we have
1610         // handled it here and we don't need to set a new breakpoint below.
1611         request_bps.erase(request_pos);
1612         // Add this breakpoint info to the response
1613         AppendBreakpoint(pair.second.bp, response_breakpoints);
1614       }
1615     }
1616     // Remove any lines from this existing source breakpoint map
1617     for (auto line: remove_lines)
1618      old_src_bp_pos->second.erase(line);
1619 
1620     // Now add any breakpoint infos left over in request_bps are the
1621     // breakpoints that weren't set in this source file yet. We need to update
1622     // thread source breakpoint info for the source file in the variable
1623     // "old_src_bp_pos->second" so the info for this source file is up to date.
1624     for (auto &pair : request_bps) {
1625       pair.second.SetBreakpoint(path.data());
1626       // Add this breakpoint info to the response
1627       AppendBreakpoint(pair.second.bp, response_breakpoints);
1628       old_src_bp_pos->second[pair.first] = std::move(pair.second);
1629     }
1630   } else {
1631     // No breakpoints were set for this source file yet. Set all breakpoints
1632     // for each line and add them to the response and create an entry in
1633     // g_vsc.source_breakpoints for this source file.
1634     for (auto &pair : request_bps) {
1635       pair.second.SetBreakpoint(path.data());
1636       // Add this breakpoint info to the response
1637       AppendBreakpoint(pair.second.bp, response_breakpoints);
1638     }
1639     g_vsc.source_breakpoints[path] = std::move(request_bps);
1640   }
1641 
1642   llvm::json::Object body;
1643   body.try_emplace("breakpoints", std::move(response_breakpoints));
1644   response.try_emplace("body", std::move(body));
1645   g_vsc.SendJSON(llvm::json::Value(std::move(response)));
1646 }
1647 
1648 // "SetExceptionBreakpointsRequest": {
1649 //   "allOf": [ { "$ref": "#/definitions/Request" }, {
1650 //     "type": "object",
1651 //     "description": "SetExceptionBreakpoints request; value of command field
1652 //     is 'setExceptionBreakpoints'. The request configures the debuggers
1653 //     response to thrown exceptions. If an exception is configured to break, a
1654 //     StoppedEvent is fired (event type 'exception').", "properties": {
1655 //       "command": {
1656 //         "type": "string",
1657 //         "enum": [ "setExceptionBreakpoints" ]
1658 //       },
1659 //       "arguments": {
1660 //         "$ref": "#/definitions/SetExceptionBreakpointsArguments"
1661 //       }
1662 //     },
1663 //     "required": [ "command", "arguments"  ]
1664 //   }]
1665 // },
1666 // "SetExceptionBreakpointsArguments": {
1667 //   "type": "object",
1668 //   "description": "Arguments for 'setExceptionBreakpoints' request.",
1669 //   "properties": {
1670 //     "filters": {
1671 //       "type": "array",
1672 //       "items": {
1673 //         "type": "string"
1674 //       },
1675 //       "description": "IDs of checked exception options. The set of IDs is
1676 //       returned via the 'exceptionBreakpointFilters' capability."
1677 //     },
1678 //     "exceptionOptions": {
1679 //       "type": "array",
1680 //       "items": {
1681 //         "$ref": "#/definitions/ExceptionOptions"
1682 //       },
1683 //       "description": "Configuration options for selected exceptions."
1684 //     }
1685 //   },
1686 //   "required": [ "filters" ]
1687 // },
1688 // "SetExceptionBreakpointsResponse": {
1689 //   "allOf": [ { "$ref": "#/definitions/Response" }, {
1690 //     "type": "object",
1691 //     "description": "Response to 'setExceptionBreakpoints' request. This is
1692 //     just an acknowledgement, so no body field is required."
1693 //   }]
1694 // }
1695 void request_setExceptionBreakpoints(const llvm::json::Object &request) {
1696   llvm::json::Object response;
1697   lldb::SBError error;
1698   FillResponse(request, response);
1699   auto arguments = request.getObject("arguments");
1700   auto filters = arguments->getArray("filters");
1701   // Keep a list of any exception breakpoint filter names that weren't set
1702   // so we can clear any exception breakpoints if needed.
1703   std::set<std::string> unset_filters;
1704   for (const auto &bp : g_vsc.exception_breakpoints)
1705     unset_filters.insert(bp.filter);
1706 
1707   for (const auto &value : *filters) {
1708     const auto filter = GetAsString(value);
1709     auto exc_bp = g_vsc.GetExceptionBreakpoint(filter);
1710     if (exc_bp) {
1711       exc_bp->SetBreakpoint();
1712       unset_filters.erase(filter);
1713     }
1714   }
1715   for (const auto &filter : unset_filters) {
1716     auto exc_bp = g_vsc.GetExceptionBreakpoint(filter);
1717     if (exc_bp)
1718       exc_bp->ClearBreakpoint();
1719   }
1720   g_vsc.SendJSON(llvm::json::Value(std::move(response)));
1721 }
1722 
1723 // "SetFunctionBreakpointsRequest": {
1724 //   "allOf": [ { "$ref": "#/definitions/Request" }, {
1725 //     "type": "object",
1726 //     "description": "SetFunctionBreakpoints request; value of command field is
1727 //     'setFunctionBreakpoints'. Sets multiple function breakpoints and clears
1728 //     all previous function breakpoints. To clear all function breakpoint,
1729 //     specify an empty array. When a function breakpoint is hit, a StoppedEvent
1730 //     (event type 'function breakpoint') is generated.", "properties": {
1731 //       "command": {
1732 //         "type": "string",
1733 //         "enum": [ "setFunctionBreakpoints" ]
1734 //       },
1735 //       "arguments": {
1736 //         "$ref": "#/definitions/SetFunctionBreakpointsArguments"
1737 //       }
1738 //     },
1739 //     "required": [ "command", "arguments"  ]
1740 //   }]
1741 // },
1742 // "SetFunctionBreakpointsArguments": {
1743 //   "type": "object",
1744 //   "description": "Arguments for 'setFunctionBreakpoints' request.",
1745 //   "properties": {
1746 //     "breakpoints": {
1747 //       "type": "array",
1748 //       "items": {
1749 //         "$ref": "#/definitions/FunctionBreakpoint"
1750 //       },
1751 //       "description": "The function names of the breakpoints."
1752 //     }
1753 //   },
1754 //   "required": [ "breakpoints" ]
1755 // },
1756 // "FunctionBreakpoint": {
1757 //   "type": "object",
1758 //   "description": "Properties of a breakpoint passed to the
1759 //   setFunctionBreakpoints request.", "properties": {
1760 //     "name": {
1761 //       "type": "string",
1762 //       "description": "The name of the function."
1763 //     },
1764 //     "condition": {
1765 //       "type": "string",
1766 //       "description": "An optional expression for conditional breakpoints."
1767 //     },
1768 //     "hitCondition": {
1769 //       "type": "string",
1770 //       "description": "An optional expression that controls how many hits of
1771 //       the breakpoint are ignored. The backend is expected to interpret the
1772 //       expression as needed."
1773 //     }
1774 //   },
1775 //   "required": [ "name" ]
1776 // },
1777 // "SetFunctionBreakpointsResponse": {
1778 //   "allOf": [ { "$ref": "#/definitions/Response" }, {
1779 //     "type": "object",
1780 //     "description": "Response to 'setFunctionBreakpoints' request. Returned is
1781 //     information about each breakpoint created by this request.",
1782 //     "properties": {
1783 //       "body": {
1784 //         "type": "object",
1785 //         "properties": {
1786 //           "breakpoints": {
1787 //             "type": "array",
1788 //             "items": {
1789 //               "$ref": "#/definitions/Breakpoint"
1790 //             },
1791 //             "description": "Information about the breakpoints. The array
1792 //             elements correspond to the elements of the 'breakpoints' array."
1793 //           }
1794 //         },
1795 //         "required": [ "breakpoints" ]
1796 //       }
1797 //     },
1798 //     "required": [ "body" ]
1799 //   }]
1800 // }
1801 void request_setFunctionBreakpoints(const llvm::json::Object &request) {
1802   llvm::json::Object response;
1803   lldb::SBError error;
1804   FillResponse(request, response);
1805   auto arguments = request.getObject("arguments");
1806   auto breakpoints = arguments->getArray("breakpoints");
1807   FunctionBreakpointMap request_bps;
1808   llvm::json::Array response_breakpoints;
1809   for (const auto &value : *breakpoints) {
1810     auto bp_obj = value.getAsObject();
1811     if (bp_obj == nullptr)
1812       continue;
1813     FunctionBreakpoint func_bp(*bp_obj);
1814     request_bps[func_bp.functionName] = std::move(func_bp);
1815   }
1816 
1817   std::vector<llvm::StringRef> remove_names;
1818   // Disable any function breakpoints that aren't in the request_bps.
1819   // There is no call to remove function breakpoints other than calling this
1820   // function with a smaller or empty "breakpoints" list.
1821   for (auto &pair: g_vsc.function_breakpoints) {
1822     auto request_pos = request_bps.find(pair.first());
1823     if (request_pos == request_bps.end()) {
1824       // This function breakpoint no longer exists delete it from LLDB
1825       g_vsc.target.BreakpointDelete(pair.second.bp.GetID());
1826       remove_names.push_back(pair.first());
1827     } else {
1828       // Update the existing breakpoint as any setting withing the function
1829       // breakpoint might have changed.
1830       pair.second.UpdateBreakpoint(request_pos->second);
1831       // Remove this breakpoint from the request breakpoints since we have
1832       // handled it here and we don't need to set a new breakpoint below.
1833       request_bps.erase(request_pos);
1834       // Add this breakpoint info to the response
1835       AppendBreakpoint(pair.second.bp, response_breakpoints);
1836     }
1837   }
1838   // Remove any breakpoints that are no longer in our list
1839   for (const auto &name: remove_names)
1840     g_vsc.function_breakpoints.erase(name);
1841 
1842   // Any breakpoints that are left in "request_bps" are breakpoints that
1843   // need to be set.
1844   for (auto &pair : request_bps) {
1845     pair.second.SetBreakpoint();
1846     // Add this breakpoint info to the response
1847     AppendBreakpoint(pair.second.bp, response_breakpoints);
1848     g_vsc.function_breakpoints[pair.first()] = std::move(pair.second);
1849   }
1850 
1851   llvm::json::Object body;
1852   body.try_emplace("breakpoints", std::move(response_breakpoints));
1853   response.try_emplace("body", std::move(body));
1854   g_vsc.SendJSON(llvm::json::Value(std::move(response)));
1855 }
1856 
1857 // "SourceRequest": {
1858 //   "allOf": [ { "$ref": "#/definitions/Request" }, {
1859 //     "type": "object",
1860 //     "description": "Source request; value of command field is 'source'. The
1861 //     request retrieves the source code for a given source reference.",
1862 //     "properties": {
1863 //       "command": {
1864 //         "type": "string",
1865 //         "enum": [ "source" ]
1866 //       },
1867 //       "arguments": {
1868 //         "$ref": "#/definitions/SourceArguments"
1869 //       }
1870 //     },
1871 //     "required": [ "command", "arguments"  ]
1872 //   }]
1873 // },
1874 // "SourceArguments": {
1875 //   "type": "object",
1876 //   "description": "Arguments for 'source' request.",
1877 //   "properties": {
1878 //     "source": {
1879 //       "$ref": "#/definitions/Source",
1880 //       "description": "Specifies the source content to load. Either
1881 //       source.path or source.sourceReference must be specified."
1882 //     },
1883 //     "sourceReference": {
1884 //       "type": "integer",
1885 //       "description": "The reference to the source. This is the same as
1886 //       source.sourceReference. This is provided for backward compatibility
1887 //       since old backends do not understand the 'source' attribute."
1888 //     }
1889 //   },
1890 //   "required": [ "sourceReference" ]
1891 // },
1892 // "SourceResponse": {
1893 //   "allOf": [ { "$ref": "#/definitions/Response" }, {
1894 //     "type": "object",
1895 //     "description": "Response to 'source' request.",
1896 //     "properties": {
1897 //       "body": {
1898 //         "type": "object",
1899 //         "properties": {
1900 //           "content": {
1901 //             "type": "string",
1902 //             "description": "Content of the source reference."
1903 //           },
1904 //           "mimeType": {
1905 //             "type": "string",
1906 //             "description": "Optional content type (mime type) of the source."
1907 //           }
1908 //         },
1909 //         "required": [ "content" ]
1910 //       }
1911 //     },
1912 //     "required": [ "body" ]
1913 //   }]
1914 // }
1915 void request_source(const llvm::json::Object &request) {
1916   llvm::json::Object response;
1917   FillResponse(request, response);
1918   llvm::json::Object body;
1919 
1920   auto arguments = request.getObject("arguments");
1921   auto source = arguments->getObject("source");
1922   auto sourceReference = GetSigned(source, "sourceReference", -1);
1923   auto pos = g_vsc.source_map.find((lldb::addr_t)sourceReference);
1924   if (pos != g_vsc.source_map.end()) {
1925     EmplaceSafeString(body, "content", pos->second.content);
1926   } else {
1927     response["success"] = llvm::json::Value(false);
1928   }
1929   response.try_emplace("body", std::move(body));
1930   g_vsc.SendJSON(llvm::json::Value(std::move(response)));
1931 }
1932 
1933 // "StackTraceRequest": {
1934 //   "allOf": [ { "$ref": "#/definitions/Request" }, {
1935 //     "type": "object",
1936 //     "description": "StackTrace request; value of command field is
1937 //     'stackTrace'. The request returns a stacktrace from the current execution
1938 //     state.", "properties": {
1939 //       "command": {
1940 //         "type": "string",
1941 //         "enum": [ "stackTrace" ]
1942 //       },
1943 //       "arguments": {
1944 //         "$ref": "#/definitions/StackTraceArguments"
1945 //       }
1946 //     },
1947 //     "required": [ "command", "arguments"  ]
1948 //   }]
1949 // },
1950 // "StackTraceArguments": {
1951 //   "type": "object",
1952 //   "description": "Arguments for 'stackTrace' request.",
1953 //   "properties": {
1954 //     "threadId": {
1955 //       "type": "integer",
1956 //       "description": "Retrieve the stacktrace for this thread."
1957 //     },
1958 //     "startFrame": {
1959 //       "type": "integer",
1960 //       "description": "The index of the first frame to return; if omitted
1961 //       frames start at 0."
1962 //     },
1963 //     "levels": {
1964 //       "type": "integer",
1965 //       "description": "The maximum number of frames to return. If levels is
1966 //       not specified or 0, all frames are returned."
1967 //     },
1968 //     "format": {
1969 //       "$ref": "#/definitions/StackFrameFormat",
1970 //       "description": "Specifies details on how to format the stack frames."
1971 //     }
1972 //  },
1973 //   "required": [ "threadId" ]
1974 // },
1975 // "StackTraceResponse": {
1976 //   "allOf": [ { "$ref": "#/definitions/Response" }, {
1977 //     "type": "object",
1978 //     "description": "Response to 'stackTrace' request.",
1979 //     "properties": {
1980 //       "body": {
1981 //         "type": "object",
1982 //         "properties": {
1983 //           "stackFrames": {
1984 //             "type": "array",
1985 //             "items": {
1986 //               "$ref": "#/definitions/StackFrame"
1987 //             },
1988 //             "description": "The frames of the stackframe. If the array has
1989 //             length zero, there are no stackframes available. This means that
1990 //             there is no location information available."
1991 //           },
1992 //           "totalFrames": {
1993 //             "type": "integer",
1994 //             "description": "The total number of frames available."
1995 //           }
1996 //         },
1997 //         "required": [ "stackFrames" ]
1998 //       }
1999 //     },
2000 //     "required": [ "body" ]
2001 //   }]
2002 // }
2003 void request_stackTrace(const llvm::json::Object &request) {
2004   llvm::json::Object response;
2005   FillResponse(request, response);
2006   lldb::SBError error;
2007   auto arguments = request.getObject("arguments");
2008   lldb::SBThread thread = g_vsc.GetLLDBThread(*arguments);
2009   llvm::json::Array stackFrames;
2010   llvm::json::Object body;
2011 
2012   if (thread.IsValid()) {
2013     const auto startFrame = GetUnsigned(arguments, "startFrame", 0);
2014     const auto levels = GetUnsigned(arguments, "levels", 0);
2015     const auto endFrame = (levels == 0) ? INT64_MAX : (startFrame + levels);
2016     for (uint32_t i = startFrame; i < endFrame; ++i) {
2017       auto frame = thread.GetFrameAtIndex(i);
2018       if (!frame.IsValid())
2019         break;
2020       stackFrames.emplace_back(CreateStackFrame(frame));
2021     }
2022   }
2023   body.try_emplace("stackFrames", std::move(stackFrames));
2024   response.try_emplace("body", std::move(body));
2025   g_vsc.SendJSON(llvm::json::Value(std::move(response)));
2026 }
2027 
2028 // "StepInRequest": {
2029 //   "allOf": [ { "$ref": "#/definitions/Request" }, {
2030 //     "type": "object",
2031 //     "description": "StepIn request; value of command field is 'stepIn'. The
2032 //     request starts the debuggee to step into a function/method if possible.
2033 //     If it cannot step into a target, 'stepIn' behaves like 'next'. The debug
2034 //     adapter first sends the StepInResponse and then a StoppedEvent (event
2035 //     type 'step') after the step has completed. If there are multiple
2036 //     function/method calls (or other targets) on the source line, the optional
2037 //     argument 'targetId' can be used to control into which target the 'stepIn'
2038 //     should occur. The list of possible targets for a given source line can be
2039 //     retrieved via the 'stepInTargets' request.", "properties": {
2040 //       "command": {
2041 //         "type": "string",
2042 //         "enum": [ "stepIn" ]
2043 //       },
2044 //       "arguments": {
2045 //         "$ref": "#/definitions/StepInArguments"
2046 //       }
2047 //     },
2048 //     "required": [ "command", "arguments"  ]
2049 //   }]
2050 // },
2051 // "StepInArguments": {
2052 //   "type": "object",
2053 //   "description": "Arguments for 'stepIn' request.",
2054 //   "properties": {
2055 //     "threadId": {
2056 //       "type": "integer",
2057 //       "description": "Execute 'stepIn' for this thread."
2058 //     },
2059 //     "targetId": {
2060 //       "type": "integer",
2061 //       "description": "Optional id of the target to step into."
2062 //     }
2063 //   },
2064 //   "required": [ "threadId" ]
2065 // },
2066 // "StepInResponse": {
2067 //   "allOf": [ { "$ref": "#/definitions/Response" }, {
2068 //     "type": "object",
2069 //     "description": "Response to 'stepIn' request. This is just an
2070 //     acknowledgement, so no body field is required."
2071 //   }]
2072 // }
2073 void request_stepIn(const llvm::json::Object &request) {
2074   llvm::json::Object response;
2075   FillResponse(request, response);
2076   auto arguments = request.getObject("arguments");
2077   lldb::SBThread thread = g_vsc.GetLLDBThread(*arguments);
2078   if (thread.IsValid()) {
2079     // Remember the thread ID that caused the resume so we can set the
2080     // "threadCausedFocus" boolean value in the "stopped" events.
2081     g_vsc.focus_tid = thread.GetThreadID();
2082     thread.StepInto();
2083   } else {
2084     response["success"] = llvm::json::Value(false);
2085   }
2086   g_vsc.SendJSON(llvm::json::Value(std::move(response)));
2087 }
2088 
2089 // "StepOutRequest": {
2090 //   "allOf": [ { "$ref": "#/definitions/Request" }, {
2091 //     "type": "object",
2092 //     "description": "StepOut request; value of command field is 'stepOut'. The
2093 //     request starts the debuggee to run again for one step. The debug adapter
2094 //     first sends the StepOutResponse and then a StoppedEvent (event type
2095 //     'step') after the step has completed.", "properties": {
2096 //       "command": {
2097 //         "type": "string",
2098 //         "enum": [ "stepOut" ]
2099 //       },
2100 //       "arguments": {
2101 //         "$ref": "#/definitions/StepOutArguments"
2102 //       }
2103 //     },
2104 //     "required": [ "command", "arguments"  ]
2105 //   }]
2106 // },
2107 // "StepOutArguments": {
2108 //   "type": "object",
2109 //   "description": "Arguments for 'stepOut' request.",
2110 //   "properties": {
2111 //     "threadId": {
2112 //       "type": "integer",
2113 //       "description": "Execute 'stepOut' for this thread."
2114 //     }
2115 //   },
2116 //   "required": [ "threadId" ]
2117 // },
2118 // "StepOutResponse": {
2119 //   "allOf": [ { "$ref": "#/definitions/Response" }, {
2120 //     "type": "object",
2121 //     "description": "Response to 'stepOut' request. This is just an
2122 //     acknowledgement, so no body field is required."
2123 //   }]
2124 // }
2125 void request_stepOut(const llvm::json::Object &request) {
2126   llvm::json::Object response;
2127   FillResponse(request, response);
2128   auto arguments = request.getObject("arguments");
2129   lldb::SBThread thread = g_vsc.GetLLDBThread(*arguments);
2130   if (thread.IsValid()) {
2131     // Remember the thread ID that caused the resume so we can set the
2132     // "threadCausedFocus" boolean value in the "stopped" events.
2133     g_vsc.focus_tid = thread.GetThreadID();
2134     thread.StepOut();
2135   } else {
2136     response["success"] = llvm::json::Value(false);
2137   }
2138   g_vsc.SendJSON(llvm::json::Value(std::move(response)));
2139 }
2140 
2141 // "ThreadsRequest": {
2142 //   "allOf": [ { "$ref": "#/definitions/Request" }, {
2143 //     "type": "object",
2144 //     "description": "Thread request; value of command field is 'threads'. The
2145 //     request retrieves a list of all threads.", "properties": {
2146 //       "command": {
2147 //         "type": "string",
2148 //         "enum": [ "threads" ]
2149 //       }
2150 //     },
2151 //     "required": [ "command" ]
2152 //   }]
2153 // },
2154 // "ThreadsResponse": {
2155 //   "allOf": [ { "$ref": "#/definitions/Response" }, {
2156 //     "type": "object",
2157 //     "description": "Response to 'threads' request.",
2158 //     "properties": {
2159 //       "body": {
2160 //         "type": "object",
2161 //         "properties": {
2162 //           "threads": {
2163 //             "type": "array",
2164 //             "items": {
2165 //               "$ref": "#/definitions/Thread"
2166 //             },
2167 //             "description": "All threads."
2168 //           }
2169 //         },
2170 //         "required": [ "threads" ]
2171 //       }
2172 //     },
2173 //     "required": [ "body" ]
2174 //   }]
2175 // }
2176 void request_threads(const llvm::json::Object &request) {
2177 
2178   lldb::SBProcess process = g_vsc.target.GetProcess();
2179   llvm::json::Object response;
2180   FillResponse(request, response);
2181 
2182   const uint32_t num_threads = process.GetNumThreads();
2183   llvm::json::Array threads;
2184   for (uint32_t thread_idx = 0; thread_idx < num_threads; ++thread_idx) {
2185     lldb::SBThread thread = process.GetThreadAtIndex(thread_idx);
2186     threads.emplace_back(CreateThread(thread));
2187   }
2188   if (threads.size() == 0) {
2189     response["success"] = llvm::json::Value(false);
2190   }
2191   llvm::json::Object body;
2192   body.try_emplace("threads", std::move(threads));
2193   response.try_emplace("body", std::move(body));
2194   g_vsc.SendJSON(llvm::json::Value(std::move(response)));
2195 }
2196 
2197 // "SetVariableRequest": {
2198 //   "allOf": [ { "$ref": "#/definitions/Request" }, {
2199 //     "type": "object",
2200 //     "description": "setVariable request; value of command field is
2201 //     'setVariable'. Set the variable with the given name in the variable
2202 //     container to a new value.", "properties": {
2203 //       "command": {
2204 //         "type": "string",
2205 //         "enum": [ "setVariable" ]
2206 //       },
2207 //       "arguments": {
2208 //         "$ref": "#/definitions/SetVariableArguments"
2209 //       }
2210 //     },
2211 //     "required": [ "command", "arguments"  ]
2212 //   }]
2213 // },
2214 // "SetVariableArguments": {
2215 //   "type": "object",
2216 //   "description": "Arguments for 'setVariable' request.",
2217 //   "properties": {
2218 //     "variablesReference": {
2219 //       "type": "integer",
2220 //       "description": "The reference of the variable container."
2221 //     },
2222 //     "name": {
2223 //       "type": "string",
2224 //       "description": "The name of the variable."
2225 //     },
2226 //     "value": {
2227 //       "type": "string",
2228 //       "description": "The value of the variable."
2229 //     },
2230 //     "format": {
2231 //       "$ref": "#/definitions/ValueFormat",
2232 //       "description": "Specifies details on how to format the response value."
2233 //     }
2234 //   },
2235 //   "required": [ "variablesReference", "name", "value" ]
2236 // },
2237 // "SetVariableResponse": {
2238 //   "allOf": [ { "$ref": "#/definitions/Response" }, {
2239 //     "type": "object",
2240 //     "description": "Response to 'setVariable' request.",
2241 //     "properties": {
2242 //       "body": {
2243 //         "type": "object",
2244 //         "properties": {
2245 //           "value": {
2246 //             "type": "string",
2247 //             "description": "The new value of the variable."
2248 //           },
2249 //           "type": {
2250 //             "type": "string",
2251 //             "description": "The type of the new value. Typically shown in the
2252 //             UI when hovering over the value."
2253 //           },
2254 //           "variablesReference": {
2255 //             "type": "number",
2256 //             "description": "If variablesReference is > 0, the new value is
2257 //             structured and its children can be retrieved by passing
2258 //             variablesReference to the VariablesRequest."
2259 //           },
2260 //           "namedVariables": {
2261 //             "type": "number",
2262 //             "description": "The number of named child variables. The client
2263 //             can use this optional information to present the variables in a
2264 //             paged UI and fetch them in chunks."
2265 //           },
2266 //           "indexedVariables": {
2267 //             "type": "number",
2268 //             "description": "The number of indexed child variables. The client
2269 //             can use this optional information to present the variables in a
2270 //             paged UI and fetch them in chunks."
2271 //           }
2272 //         },
2273 //         "required": [ "value" ]
2274 //       }
2275 //     },
2276 //     "required": [ "body" ]
2277 //   }]
2278 // }
2279 void request_setVariable(const llvm::json::Object &request) {
2280   llvm::json::Object response;
2281   FillResponse(request, response);
2282   llvm::json::Array variables;
2283   llvm::json::Object body;
2284   auto arguments = request.getObject("arguments");
2285   // This is a reference to the containing variable/scope
2286   const auto variablesReference =
2287       GetUnsigned(arguments, "variablesReference", 0);
2288   const auto name = GetString(arguments, "name");
2289   const auto value = GetString(arguments, "value");
2290   // Set success to false just in case we don't find the variable by name
2291   response.try_emplace("success", false);
2292 
2293   lldb::SBValue variable;
2294   int64_t newVariablesReference = 0;
2295 
2296   // The "id" is the unique integer ID that is unique within the enclosing
2297   // variablesReference. It is optionally added to any "interface Variable"
2298   // objects to uniquely identify a variable within an enclosing
2299   // variablesReference. It helps to disambiguate between two variables that
2300   // have the same name within the same scope since the "setVariables" request
2301   // only specifies the variable reference of the enclosing scope/variable, and
2302   // the name of the variable. We could have two shadowed variables with the
2303   // same name in "Locals" or "Globals". In our case the "id" absolute index
2304   // of the variable within the g_vsc.variables list.
2305   const auto id_value = GetUnsigned(arguments, "id", UINT64_MAX);
2306   if (id_value != UINT64_MAX) {
2307     variable = g_vsc.variables.GetValueAtIndex(id_value);
2308   } else if (VARREF_IS_SCOPE(variablesReference)) {
2309     // variablesReference is one of our scopes, not an actual variable it is
2310     // asking for a variable in locals or globals or registers
2311     int64_t start_idx = 0;
2312     int64_t end_idx = 0;
2313     switch (variablesReference) {
2314     case VARREF_LOCALS:
2315       start_idx = 0;
2316       end_idx = start_idx + g_vsc.num_locals;
2317       break;
2318     case VARREF_GLOBALS:
2319       start_idx = g_vsc.num_locals;
2320       end_idx = start_idx + g_vsc.num_globals;
2321       break;
2322     case VARREF_REGS:
2323       start_idx = g_vsc.num_locals + g_vsc.num_globals;
2324       end_idx = start_idx + g_vsc.num_regs;
2325       break;
2326     default:
2327       break;
2328     }
2329 
2330     // Find the variable by name in the correct scope and hope we don't have
2331     // multiple variables with the same name. We search backwards because
2332     // the list of variables has the top most variables first and variables
2333     // in deeper scopes are last. This means we will catch the deepest
2334     // variable whose name matches which is probably what the user wants.
2335     for (int64_t i = end_idx - 1; i >= start_idx; --i) {
2336       auto curr_variable = g_vsc.variables.GetValueAtIndex(i);
2337       llvm::StringRef variable_name(curr_variable.GetName());
2338       if (variable_name == name) {
2339         variable = curr_variable;
2340         if (curr_variable.MightHaveChildren())
2341           newVariablesReference = i;
2342         break;
2343       }
2344     }
2345   } else {
2346     // We have a named item within an actual variable so we need to find it
2347     // withing the container variable by name.
2348     const int64_t var_idx = VARREF_TO_VARIDX(variablesReference);
2349     lldb::SBValue container = g_vsc.variables.GetValueAtIndex(var_idx);
2350     variable = container.GetChildMemberWithName(name.data());
2351     if (!variable.IsValid()) {
2352       if (name.startswith("[")) {
2353         llvm::StringRef index_str(name.drop_front(1));
2354         uint64_t index = 0;
2355         if (!index_str.consumeInteger(0, index)) {
2356           if (index_str == "]")
2357             variable = container.GetChildAtIndex(index);
2358         }
2359       }
2360     }
2361 
2362     // We don't know the index of the variable in our g_vsc.variables
2363     if (variable.IsValid()) {
2364       if (variable.MightHaveChildren()) {
2365         newVariablesReference = VARIDX_TO_VARREF(g_vsc.variables.GetSize());
2366         g_vsc.variables.Append(variable);
2367       }
2368     }
2369   }
2370 
2371   if (variable.IsValid()) {
2372     lldb::SBError error;
2373     bool success = variable.SetValueFromCString(value.data(), error);
2374     if (success) {
2375       SetValueForKey(variable, body, "value");
2376       EmplaceSafeString(body, "type", variable.GetType().GetDisplayTypeName());
2377       body.try_emplace("variablesReference", newVariablesReference);
2378     } else {
2379       EmplaceSafeString(body, "message", std::string(error.GetCString()));
2380     }
2381     response["success"] = llvm::json::Value(success);
2382   }
2383 
2384   response.try_emplace("body", std::move(body));
2385   g_vsc.SendJSON(llvm::json::Value(std::move(response)));
2386 }
2387 
2388 // "VariablesRequest": {
2389 //   "allOf": [ { "$ref": "#/definitions/Request" }, {
2390 //     "type": "object",
2391 //     "description": "Variables request; value of command field is 'variables'.
2392 //     Retrieves all child variables for the given variable reference. An
2393 //     optional filter can be used to limit the fetched children to either named
2394 //     or indexed children.", "properties": {
2395 //       "command": {
2396 //         "type": "string",
2397 //         "enum": [ "variables" ]
2398 //       },
2399 //       "arguments": {
2400 //         "$ref": "#/definitions/VariablesArguments"
2401 //       }
2402 //     },
2403 //     "required": [ "command", "arguments"  ]
2404 //   }]
2405 // },
2406 // "VariablesArguments": {
2407 //   "type": "object",
2408 //   "description": "Arguments for 'variables' request.",
2409 //   "properties": {
2410 //     "variablesReference": {
2411 //       "type": "integer",
2412 //       "description": "The Variable reference."
2413 //     },
2414 //     "filter": {
2415 //       "type": "string",
2416 //       "enum": [ "indexed", "named" ],
2417 //       "description": "Optional filter to limit the child variables to either
2418 //       named or indexed. If ommited, both types are fetched."
2419 //     },
2420 //     "start": {
2421 //       "type": "integer",
2422 //       "description": "The index of the first variable to return; if omitted
2423 //       children start at 0."
2424 //     },
2425 //     "count": {
2426 //       "type": "integer",
2427 //       "description": "The number of variables to return. If count is missing
2428 //       or 0, all variables are returned."
2429 //     },
2430 //     "format": {
2431 //       "$ref": "#/definitions/ValueFormat",
2432 //       "description": "Specifies details on how to format the Variable
2433 //       values."
2434 //     }
2435 //   },
2436 //   "required": [ "variablesReference" ]
2437 // },
2438 // "VariablesResponse": {
2439 //   "allOf": [ { "$ref": "#/definitions/Response" }, {
2440 //     "type": "object",
2441 //     "description": "Response to 'variables' request.",
2442 //     "properties": {
2443 //       "body": {
2444 //         "type": "object",
2445 //         "properties": {
2446 //           "variables": {
2447 //             "type": "array",
2448 //             "items": {
2449 //               "$ref": "#/definitions/Variable"
2450 //             },
2451 //             "description": "All (or a range) of variables for the given
2452 //             variable reference."
2453 //           }
2454 //         },
2455 //         "required": [ "variables" ]
2456 //       }
2457 //     },
2458 //     "required": [ "body" ]
2459 //   }]
2460 // }
2461 void request_variables(const llvm::json::Object &request) {
2462   llvm::json::Object response;
2463   FillResponse(request, response);
2464   llvm::json::Array variables;
2465   auto arguments = request.getObject("arguments");
2466   const auto variablesReference =
2467       GetUnsigned(arguments, "variablesReference", 0);
2468   const int64_t start = GetSigned(arguments, "start", 0);
2469   const int64_t count = GetSigned(arguments, "count", 0);
2470   bool hex = false;
2471   auto format = arguments->getObject("format");
2472   if (format)
2473     hex = GetBoolean(format, "hex", false);
2474 
2475   if (VARREF_IS_SCOPE(variablesReference)) {
2476     // variablesReference is one of our scopes, not an actual variable it is
2477     // asking for the list of args, locals or globals.
2478     int64_t start_idx = 0;
2479     int64_t num_children = 0;
2480     switch (variablesReference) {
2481     case VARREF_LOCALS:
2482       start_idx = start;
2483       num_children = g_vsc.num_locals;
2484       break;
2485     case VARREF_GLOBALS:
2486       start_idx = start + g_vsc.num_locals + start;
2487       num_children = g_vsc.num_globals;
2488       break;
2489     case VARREF_REGS:
2490       start_idx = start + g_vsc.num_locals + g_vsc.num_globals;
2491       num_children = g_vsc.num_regs;
2492       break;
2493     default:
2494       break;
2495     }
2496     const int64_t end_idx = start_idx + ((count == 0) ? num_children : count);
2497     for (auto i = start_idx; i < end_idx; ++i) {
2498       lldb::SBValue variable = g_vsc.variables.GetValueAtIndex(i);
2499       if (!variable.IsValid())
2500         break;
2501       variables.emplace_back(
2502           CreateVariable(variable, VARIDX_TO_VARREF(i), i, hex));
2503     }
2504   } else {
2505     // We are expanding a variable that has children, so we will return its
2506     // children.
2507     const int64_t var_idx = VARREF_TO_VARIDX(variablesReference);
2508     lldb::SBValue variable = g_vsc.variables.GetValueAtIndex(var_idx);
2509     if (variable.IsValid()) {
2510       const auto num_children = variable.GetNumChildren();
2511       const int64_t end_idx = start + ((count == 0) ? num_children : count);
2512       for (auto i = start; i < end_idx; ++i) {
2513         lldb::SBValue child = variable.GetChildAtIndex(i);
2514         if (!child.IsValid())
2515           break;
2516         if (child.MightHaveChildren()) {
2517           const int64_t var_idx = g_vsc.variables.GetSize();
2518           auto childVariablesReferences = VARIDX_TO_VARREF(var_idx);
2519           variables.emplace_back(
2520               CreateVariable(child, childVariablesReferences, var_idx, hex));
2521           g_vsc.variables.Append(child);
2522         } else {
2523           variables.emplace_back(CreateVariable(child, 0, INT64_MAX, hex));
2524         }
2525       }
2526     }
2527   }
2528   llvm::json::Object body;
2529   body.try_emplace("variables", std::move(variables));
2530   response.try_emplace("body", std::move(body));
2531   g_vsc.SendJSON(llvm::json::Value(std::move(response)));
2532 }
2533 
2534 // A request used in testing to get the details on all breakpoints that are
2535 // currently set in the target. This helps us to test "setBreakpoints" and
2536 // "setFunctionBreakpoints" requests to verify we have the correct set of
2537 // breakpoints currently set in LLDB.
2538 void request__testGetTargetBreakpoints(const llvm::json::Object &request) {
2539   llvm::json::Object response;
2540   FillResponse(request, response);
2541   llvm::json::Array response_breakpoints;
2542   for (uint32_t i = 0; g_vsc.target.GetBreakpointAtIndex(i).IsValid(); ++i) {
2543     auto bp = g_vsc.target.GetBreakpointAtIndex(i);
2544     AppendBreakpoint(bp, response_breakpoints);
2545   }
2546   llvm::json::Object body;
2547   body.try_emplace("breakpoints", std::move(response_breakpoints));
2548   response.try_emplace("body", std::move(body));
2549   g_vsc.SendJSON(llvm::json::Value(std::move(response)));
2550 }
2551 
2552 const std::map<std::string, RequestCallback> &GetRequestHandlers() {
2553 #define REQUEST_CALLBACK(name)                                                 \
2554   { #name, request_##name }
2555   static std::map<std::string, RequestCallback> g_request_handlers = {
2556       // VSCode Debug Adaptor requests
2557       REQUEST_CALLBACK(attach),
2558       REQUEST_CALLBACK(continue),
2559       REQUEST_CALLBACK(configurationDone),
2560       REQUEST_CALLBACK(disconnect),
2561       REQUEST_CALLBACK(evaluate),
2562       REQUEST_CALLBACK(exceptionInfo),
2563       REQUEST_CALLBACK(initialize),
2564       REQUEST_CALLBACK(launch),
2565       REQUEST_CALLBACK(next),
2566       REQUEST_CALLBACK(pause),
2567       REQUEST_CALLBACK(scopes),
2568       REQUEST_CALLBACK(setBreakpoints),
2569       REQUEST_CALLBACK(setExceptionBreakpoints),
2570       REQUEST_CALLBACK(setFunctionBreakpoints),
2571       REQUEST_CALLBACK(setVariable),
2572       REQUEST_CALLBACK(source),
2573       REQUEST_CALLBACK(stackTrace),
2574       REQUEST_CALLBACK(stepIn),
2575       REQUEST_CALLBACK(stepOut),
2576       REQUEST_CALLBACK(threads),
2577       REQUEST_CALLBACK(variables),
2578       // Testing requests
2579       REQUEST_CALLBACK(_testGetTargetBreakpoints),
2580   };
2581 #undef REQUEST_CALLBACK
2582   return g_request_handlers;
2583 }
2584 
2585 } // anonymous namespace
2586 
2587 int main(int argc, char *argv[]) {
2588 
2589   // Initialize LLDB first before we do anything.
2590   lldb::SBDebugger::Initialize();
2591 
2592   if (argc == 2) {
2593     const char *arg = argv[1];
2594 #if !defined(_WIN32)
2595     if (strcmp(arg, "-g") == 0) {
2596       printf("Paused waiting for debugger to attach (pid = %i)...\n", getpid());
2597       pause();
2598     } else {
2599 #else
2600     {
2601 #endif
2602       int portno = atoi(arg);
2603       printf("Listening on port %i...\n", portno);
2604       SOCKET socket_fd = AcceptConnection(portno);
2605       if (socket_fd >= 0) {
2606         g_vsc.input.descriptor = StreamDescriptor::from_socket(socket_fd, true);
2607         g_vsc.output.descriptor =
2608             StreamDescriptor::from_socket(socket_fd, false);
2609       } else {
2610         exit(1);
2611       }
2612     }
2613   } else {
2614     g_vsc.input.descriptor = StreamDescriptor::from_file(fileno(stdin), false);
2615     g_vsc.output.descriptor =
2616         StreamDescriptor::from_file(fileno(stdout), false);
2617   }
2618   auto request_handlers = GetRequestHandlers();
2619   uint32_t packet_idx = 0;
2620   while (true) {
2621     std::string json = g_vsc.ReadJSON();
2622     if (json.empty())
2623       break;
2624 
2625     llvm::StringRef json_sref(json);
2626     llvm::Expected<llvm::json::Value> json_value = llvm::json::parse(json_sref);
2627     if (!json_value) {
2628       auto error = json_value.takeError();
2629       if (g_vsc.log) {
2630         std::string error_str;
2631         llvm::raw_string_ostream strm(error_str);
2632         strm << error;
2633         strm.flush();
2634 
2635         *g_vsc.log << "error: failed to parse JSON: " << error_str << std::endl
2636                    << json << std::endl;
2637       }
2638       return 1;
2639     }
2640 
2641     auto object = json_value->getAsObject();
2642     if (!object) {
2643       if (g_vsc.log)
2644         *g_vsc.log << "error: json packet isn't a object" << std::endl;
2645       return 1;
2646     }
2647 
2648     const auto packet_type = GetString(object, "type");
2649     if (packet_type == "request") {
2650       const auto command = GetString(object, "command");
2651       auto handler_pos = request_handlers.find(command);
2652       if (handler_pos != request_handlers.end()) {
2653         handler_pos->second(*object);
2654       } else {
2655         if (g_vsc.log)
2656           *g_vsc.log << "error: unhandled command \"" << command.data() << std::endl;
2657         return 1;
2658       }
2659     }
2660     ++packet_idx;
2661   }
2662 
2663   // We must terminate the debugger in a thread before the C++ destructor
2664   // chain messes everything up.
2665   lldb::SBDebugger::Terminate();
2666   return 0;
2667 }
2668