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   g_vsc.stop_at_entry = GetBoolean(arguments, "stopOnEntry", false);
1186   const auto debuggerRoot = GetString(arguments, "debuggerRoot");
1187 
1188   // This is a hack for loading DWARF in .o files on Mac where the .o files
1189   // in the debug map of the main executable have relative paths which require
1190   // the lldb-vscode binary to have its working directory set to that relative
1191   // root for the .o files in order to be able to load debug info.
1192   if (!debuggerRoot.empty()) {
1193     llvm::sys::fs::set_current_path(debuggerRoot.data());
1194   }
1195 
1196   SetSourceMapFromArguments(*arguments);
1197 
1198   // Run any initialize LLDB commands the user specified in the launch.json
1199   g_vsc.RunInitCommands();
1200 
1201   // Grab the current working directory if there is one and set it in the
1202   // launch info.
1203   const auto cwd = GetString(arguments, "cwd");
1204   if (!cwd.empty())
1205     g_vsc.launch_info.SetWorkingDirectory(cwd.data());
1206 
1207   // Grab the name of the program we need to debug and set it as the first
1208   // argument that will be passed to the program we will debug.
1209   llvm::StringRef program = GetString(arguments, "program");
1210   if (!program.empty()) {
1211     lldb::SBFileSpec program_fspec(program.data(), true /*resolve_path*/);
1212     g_vsc.launch_info.SetExecutableFile(program_fspec,
1213                                         true /*add_as_first_arg*/);
1214     const char *target_triple = nullptr;
1215     const char *uuid_cstr = nullptr;
1216     // Stand alone debug info file if different from executable
1217     const char *symfile = nullptr;
1218     lldb::SBModule module = g_vsc.target.AddModule(
1219         program.data(), target_triple, uuid_cstr, symfile);
1220     if (!module.IsValid()) {
1221       response["success"] = llvm::json::Value(false);
1222 
1223       EmplaceSafeString(
1224           response, "message",
1225           llvm::formatv("Could not load program '{0}'.", program).str());
1226       g_vsc.SendJSON(llvm::json::Value(std::move(response)));
1227       return;
1228     }
1229   }
1230 
1231   // Extract any extra arguments and append them to our program arguments for
1232   // when we launch
1233   auto args = GetStrings(arguments, "args");
1234   if (!args.empty())
1235     g_vsc.launch_info.SetArguments(MakeArgv(args).data(), true);
1236 
1237   // Pass any environment variables along that the user specified.
1238   auto envs = GetStrings(arguments, "env");
1239   if (!envs.empty())
1240     g_vsc.launch_info.SetEnvironmentEntries(MakeArgv(envs).data(), true);
1241 
1242   auto flags = g_vsc.launch_info.GetLaunchFlags();
1243 
1244   if (GetBoolean(arguments, "disableASLR", true))
1245     flags |= lldb::eLaunchFlagDisableASLR;
1246   if (GetBoolean(arguments, "disableSTDIO", false))
1247     flags |= lldb::eLaunchFlagDisableSTDIO;
1248   if (GetBoolean(arguments, "shellExpandArguments", false))
1249     flags |= lldb::eLaunchFlagShellExpandArguments;
1250   const bool detatchOnError = GetBoolean(arguments, "detachOnError", false);
1251   g_vsc.launch_info.SetDetachOnError(detatchOnError);
1252   g_vsc.launch_info.SetLaunchFlags(flags | lldb::eLaunchFlagDebug |
1253                                    lldb::eLaunchFlagStopAtEntry);
1254 
1255   // Run any pre run LLDB commands the user specified in the launch.json
1256   g_vsc.RunPreRunCommands();
1257 
1258   // Disable async events so the launch will be successful when we return from
1259   // the launch call and the launch will happen synchronously
1260   g_vsc.debugger.SetAsync(false);
1261   g_vsc.target.Launch(g_vsc.launch_info, error);
1262   if (error.Fail()) {
1263     response["success"] = llvm::json::Value(false);
1264     EmplaceSafeString(response, "message", std::string(error.GetCString()));
1265   }
1266   g_vsc.SendJSON(llvm::json::Value(std::move(response)));
1267 
1268   SendProcessEvent(Launch);
1269   g_vsc.SendJSON(llvm::json::Value(CreateEventObject("initialized")));
1270   // Reenable async events and start the event thread to catch async events.
1271   g_vsc.debugger.SetAsync(true);
1272 }
1273 
1274 // "NextRequest": {
1275 //   "allOf": [ { "$ref": "#/definitions/Request" }, {
1276 //     "type": "object",
1277 //     "description": "Next request; value of command field is 'next'. The
1278 //                     request starts the debuggee to run again for one step.
1279 //                     The debug adapter first sends the NextResponse and then
1280 //                     a StoppedEvent (event type 'step') after the step has
1281 //                     completed.",
1282 //     "properties": {
1283 //       "command": {
1284 //         "type": "string",
1285 //         "enum": [ "next" ]
1286 //       },
1287 //       "arguments": {
1288 //         "$ref": "#/definitions/NextArguments"
1289 //       }
1290 //     },
1291 //     "required": [ "command", "arguments"  ]
1292 //   }]
1293 // },
1294 // "NextArguments": {
1295 //   "type": "object",
1296 //   "description": "Arguments for 'next' request.",
1297 //   "properties": {
1298 //     "threadId": {
1299 //       "type": "integer",
1300 //       "description": "Execute 'next' for this thread."
1301 //     }
1302 //   },
1303 //   "required": [ "threadId" ]
1304 // },
1305 // "NextResponse": {
1306 //   "allOf": [ { "$ref": "#/definitions/Response" }, {
1307 //     "type": "object",
1308 //     "description": "Response to 'next' request. This is just an
1309 //                     acknowledgement, so no body field is required."
1310 //   }]
1311 // }
1312 void request_next(const llvm::json::Object &request) {
1313   llvm::json::Object response;
1314   FillResponse(request, response);
1315   auto arguments = request.getObject("arguments");
1316   lldb::SBThread thread = g_vsc.GetLLDBThread(*arguments);
1317   if (thread.IsValid()) {
1318     // Remember the thread ID that caused the resume so we can set the
1319     // "threadCausedFocus" boolean value in the "stopped" events.
1320     g_vsc.focus_tid = thread.GetThreadID();
1321     thread.StepOver();
1322   } else {
1323     response["success"] = llvm::json::Value(false);
1324   }
1325   g_vsc.SendJSON(llvm::json::Value(std::move(response)));
1326 }
1327 
1328 // "PauseRequest": {
1329 //   "allOf": [ { "$ref": "#/definitions/Request" }, {
1330 //     "type": "object",
1331 //     "description": "Pause request; value of command field is 'pause'. The
1332 //     request suspenses the debuggee. The debug adapter first sends the
1333 //     PauseResponse and then a StoppedEvent (event type 'pause') after the
1334 //     thread has been paused successfully.", "properties": {
1335 //       "command": {
1336 //         "type": "string",
1337 //         "enum": [ "pause" ]
1338 //       },
1339 //       "arguments": {
1340 //         "$ref": "#/definitions/PauseArguments"
1341 //       }
1342 //     },
1343 //     "required": [ "command", "arguments"  ]
1344 //   }]
1345 // },
1346 // "PauseArguments": {
1347 //   "type": "object",
1348 //   "description": "Arguments for 'pause' request.",
1349 //   "properties": {
1350 //     "threadId": {
1351 //       "type": "integer",
1352 //       "description": "Pause execution for this thread."
1353 //     }
1354 //   },
1355 //   "required": [ "threadId" ]
1356 // },
1357 // "PauseResponse": {
1358 //   "allOf": [ { "$ref": "#/definitions/Response" }, {
1359 //     "type": "object",
1360 //     "description": "Response to 'pause' request. This is just an
1361 //     acknowledgement, so no body field is required."
1362 //   }]
1363 // }
1364 void request_pause(const llvm::json::Object &request) {
1365   llvm::json::Object response;
1366   FillResponse(request, response);
1367   lldb::SBProcess process = g_vsc.target.GetProcess();
1368   lldb::SBError error = process.Stop();
1369   g_vsc.SendJSON(llvm::json::Value(std::move(response)));
1370 }
1371 
1372 // "ScopesRequest": {
1373 //   "allOf": [ { "$ref": "#/definitions/Request" }, {
1374 //     "type": "object",
1375 //     "description": "Scopes request; value of command field is 'scopes'. The
1376 //     request returns the variable scopes for a given stackframe ID.",
1377 //     "properties": {
1378 //       "command": {
1379 //         "type": "string",
1380 //         "enum": [ "scopes" ]
1381 //       },
1382 //       "arguments": {
1383 //         "$ref": "#/definitions/ScopesArguments"
1384 //       }
1385 //     },
1386 //     "required": [ "command", "arguments"  ]
1387 //   }]
1388 // },
1389 // "ScopesArguments": {
1390 //   "type": "object",
1391 //   "description": "Arguments for 'scopes' request.",
1392 //   "properties": {
1393 //     "frameId": {
1394 //       "type": "integer",
1395 //       "description": "Retrieve the scopes for this stackframe."
1396 //     }
1397 //   },
1398 //   "required": [ "frameId" ]
1399 // },
1400 // "ScopesResponse": {
1401 //   "allOf": [ { "$ref": "#/definitions/Response" }, {
1402 //     "type": "object",
1403 //     "description": "Response to 'scopes' request.",
1404 //     "properties": {
1405 //       "body": {
1406 //         "type": "object",
1407 //         "properties": {
1408 //           "scopes": {
1409 //             "type": "array",
1410 //             "items": {
1411 //               "$ref": "#/definitions/Scope"
1412 //             },
1413 //             "description": "The scopes of the stackframe. If the array has
1414 //             length zero, there are no scopes available."
1415 //           }
1416 //         },
1417 //         "required": [ "scopes" ]
1418 //       }
1419 //     },
1420 //     "required": [ "body" ]
1421 //   }]
1422 // }
1423 void request_scopes(const llvm::json::Object &request) {
1424   llvm::json::Object response;
1425   FillResponse(request, response);
1426   llvm::json::Object body;
1427   auto arguments = request.getObject("arguments");
1428   lldb::SBFrame frame = g_vsc.GetLLDBFrame(*arguments);
1429   g_vsc.variables.Clear();
1430   g_vsc.variables.Append(frame.GetVariables(true,   // arguments
1431                                             true,   // locals
1432                                             false,  // statics
1433                                             true)); // in_scope_only
1434   g_vsc.num_locals = g_vsc.variables.GetSize();
1435   g_vsc.variables.Append(frame.GetVariables(false,  // arguments
1436                                             false,  // locals
1437                                             true,   // statics
1438                                             true)); // in_scope_only
1439   g_vsc.num_globals = g_vsc.variables.GetSize() - (g_vsc.num_locals);
1440   g_vsc.variables.Append(frame.GetRegisters());
1441   g_vsc.num_regs =
1442       g_vsc.variables.GetSize() - (g_vsc.num_locals + g_vsc.num_globals);
1443   body.try_emplace("scopes", g_vsc.CreateTopLevelScopes());
1444   response.try_emplace("body", std::move(body));
1445   g_vsc.SendJSON(llvm::json::Value(std::move(response)));
1446 }
1447 
1448 // "SetBreakpointsRequest": {
1449 //   "allOf": [ { "$ref": "#/definitions/Request" }, {
1450 //     "type": "object",
1451 //     "description": "SetBreakpoints request; value of command field is
1452 //     'setBreakpoints'. Sets multiple breakpoints for a single source and
1453 //     clears all previous breakpoints in that source. To clear all breakpoint
1454 //     for a source, specify an empty array. When a breakpoint is hit, a
1455 //     StoppedEvent (event type 'breakpoint') is generated.", "properties": {
1456 //       "command": {
1457 //         "type": "string",
1458 //         "enum": [ "setBreakpoints" ]
1459 //       },
1460 //       "arguments": {
1461 //         "$ref": "#/definitions/SetBreakpointsArguments"
1462 //       }
1463 //     },
1464 //     "required": [ "command", "arguments"  ]
1465 //   }]
1466 // },
1467 // "SetBreakpointsArguments": {
1468 //   "type": "object",
1469 //   "description": "Arguments for 'setBreakpoints' request.",
1470 //   "properties": {
1471 //     "source": {
1472 //       "$ref": "#/definitions/Source",
1473 //       "description": "The source location of the breakpoints; either
1474 //       source.path or source.reference must be specified."
1475 //     },
1476 //     "breakpoints": {
1477 //       "type": "array",
1478 //       "items": {
1479 //         "$ref": "#/definitions/SourceBreakpoint"
1480 //       },
1481 //       "description": "The code locations of the breakpoints."
1482 //     },
1483 //     "lines": {
1484 //       "type": "array",
1485 //       "items": {
1486 //         "type": "integer"
1487 //       },
1488 //       "description": "Deprecated: The code locations of the breakpoints."
1489 //     },
1490 //     "sourceModified": {
1491 //       "type": "boolean",
1492 //       "description": "A value of true indicates that the underlying source
1493 //       has been modified which results in new breakpoint locations."
1494 //     }
1495 //   },
1496 //   "required": [ "source" ]
1497 // },
1498 // "SetBreakpointsResponse": {
1499 //   "allOf": [ { "$ref": "#/definitions/Response" }, {
1500 //     "type": "object",
1501 //     "description": "Response to 'setBreakpoints' request. Returned is
1502 //     information about each breakpoint created by this request. This includes
1503 //     the actual code location and whether the breakpoint could be verified.
1504 //     The breakpoints returned are in the same order as the elements of the
1505 //     'breakpoints' (or the deprecated 'lines') in the
1506 //     SetBreakpointsArguments.", "properties": {
1507 //       "body": {
1508 //         "type": "object",
1509 //         "properties": {
1510 //           "breakpoints": {
1511 //             "type": "array",
1512 //             "items": {
1513 //               "$ref": "#/definitions/Breakpoint"
1514 //             },
1515 //             "description": "Information about the breakpoints. The array
1516 //             elements are in the same order as the elements of the
1517 //             'breakpoints' (or the deprecated 'lines') in the
1518 //             SetBreakpointsArguments."
1519 //           }
1520 //         },
1521 //         "required": [ "breakpoints" ]
1522 //       }
1523 //     },
1524 //     "required": [ "body" ]
1525 //   }]
1526 // },
1527 // "SourceBreakpoint": {
1528 //   "type": "object",
1529 //   "description": "Properties of a breakpoint or logpoint passed to the
1530 //   setBreakpoints request.", "properties": {
1531 //     "line": {
1532 //       "type": "integer",
1533 //       "description": "The source line of the breakpoint or logpoint."
1534 //     },
1535 //     "column": {
1536 //       "type": "integer",
1537 //       "description": "An optional source column of the breakpoint."
1538 //     },
1539 //     "condition": {
1540 //       "type": "string",
1541 //       "description": "An optional expression for conditional breakpoints."
1542 //     },
1543 //     "hitCondition": {
1544 //       "type": "string",
1545 //       "description": "An optional expression that controls how many hits of
1546 //       the breakpoint are ignored. The backend is expected to interpret the
1547 //       expression as needed."
1548 //     },
1549 //     "logMessage": {
1550 //       "type": "string",
1551 //       "description": "If this attribute exists and is non-empty, the backend
1552 //       must not 'break' (stop) but log the message instead. Expressions within
1553 //       {} are interpolated."
1554 //     }
1555 //   },
1556 //   "required": [ "line" ]
1557 // }
1558 void request_setBreakpoints(const llvm::json::Object &request) {
1559   llvm::json::Object response;
1560   lldb::SBError error;
1561   FillResponse(request, response);
1562   auto arguments = request.getObject("arguments");
1563   auto source = arguments->getObject("source");
1564   const auto path = GetString(source, "path");
1565   auto breakpoints = arguments->getArray("breakpoints");
1566   llvm::json::Array response_breakpoints;
1567   // Decode the source breakpoint infos for this "setBreakpoints" request
1568   SourceBreakpointMap request_bps;
1569   for (const auto &bp : *breakpoints) {
1570     auto bp_obj = bp.getAsObject();
1571     if (bp_obj) {
1572       SourceBreakpoint src_bp(*bp_obj);
1573       request_bps[src_bp.line] = std::move(src_bp);
1574     }
1575   }
1576 
1577   // See if we already have breakpoints set for this source file from a
1578   // previous "setBreakpoints" request
1579   auto old_src_bp_pos = g_vsc.source_breakpoints.find(path);
1580   if (old_src_bp_pos != g_vsc.source_breakpoints.end()) {
1581 
1582     // We have already set breakpoints in this source file and they are giving
1583     // use a new list of lines to set breakpoints on. Some breakpoints might
1584     // already be set, and some might not. We need to remove any breakpoints
1585     // whose lines are not contained in the any breakpoints lines in in the
1586     // "breakpoints" array.
1587 
1588     // Delete any breakpoints in this source file that aren't in the
1589     // request_bps set. There is no call to remove breakpoints other than
1590     // calling this function with a smaller or empty "breakpoints" list.
1591     std::vector<uint32_t> remove_lines;
1592     for (auto &pair: old_src_bp_pos->second) {
1593       auto request_pos = request_bps.find(pair.first);
1594       if (request_pos == request_bps.end()) {
1595         // This breakpoint no longer exists in this source file, delete it
1596         g_vsc.target.BreakpointDelete(pair.second.bp.GetID());
1597         remove_lines.push_back(pair.first);
1598       } else {
1599         pair.second.UpdateBreakpoint(request_pos->second);
1600         // Remove this breakpoint from the request breakpoints since we have
1601         // handled it here and we don't need to set a new breakpoint below.
1602         request_bps.erase(request_pos);
1603         // Add this breakpoint info to the response
1604         AppendBreakpoint(pair.second.bp, response_breakpoints);
1605       }
1606     }
1607     // Remove any lines from this existing source breakpoint map
1608     for (auto line: remove_lines)
1609      old_src_bp_pos->second.erase(line);
1610 
1611     // Now add any breakpoint infos left over in request_bps are the
1612     // breakpoints that weren't set in this source file yet. We need to update
1613     // thread source breakpoint info for the source file in the variable
1614     // "old_src_bp_pos->second" so the info for this source file is up to date.
1615     for (auto &pair : request_bps) {
1616       pair.second.SetBreakpoint(path.data());
1617       // Add this breakpoint info to the response
1618       AppendBreakpoint(pair.second.bp, response_breakpoints);
1619       old_src_bp_pos->second[pair.first] = std::move(pair.second);
1620     }
1621   } else {
1622     // No breakpoints were set for this source file yet. Set all breakpoints
1623     // for each line and add them to the response and create an entry in
1624     // g_vsc.source_breakpoints for this source file.
1625     for (auto &pair : request_bps) {
1626       pair.second.SetBreakpoint(path.data());
1627       // Add this breakpoint info to the response
1628       AppendBreakpoint(pair.second.bp, response_breakpoints);
1629     }
1630     g_vsc.source_breakpoints[path] = std::move(request_bps);
1631   }
1632 
1633   llvm::json::Object body;
1634   body.try_emplace("breakpoints", std::move(response_breakpoints));
1635   response.try_emplace("body", std::move(body));
1636   g_vsc.SendJSON(llvm::json::Value(std::move(response)));
1637 }
1638 
1639 // "SetExceptionBreakpointsRequest": {
1640 //   "allOf": [ { "$ref": "#/definitions/Request" }, {
1641 //     "type": "object",
1642 //     "description": "SetExceptionBreakpoints request; value of command field
1643 //     is 'setExceptionBreakpoints'. The request configures the debuggers
1644 //     response to thrown exceptions. If an exception is configured to break, a
1645 //     StoppedEvent is fired (event type 'exception').", "properties": {
1646 //       "command": {
1647 //         "type": "string",
1648 //         "enum": [ "setExceptionBreakpoints" ]
1649 //       },
1650 //       "arguments": {
1651 //         "$ref": "#/definitions/SetExceptionBreakpointsArguments"
1652 //       }
1653 //     },
1654 //     "required": [ "command", "arguments"  ]
1655 //   }]
1656 // },
1657 // "SetExceptionBreakpointsArguments": {
1658 //   "type": "object",
1659 //   "description": "Arguments for 'setExceptionBreakpoints' request.",
1660 //   "properties": {
1661 //     "filters": {
1662 //       "type": "array",
1663 //       "items": {
1664 //         "type": "string"
1665 //       },
1666 //       "description": "IDs of checked exception options. The set of IDs is
1667 //       returned via the 'exceptionBreakpointFilters' capability."
1668 //     },
1669 //     "exceptionOptions": {
1670 //       "type": "array",
1671 //       "items": {
1672 //         "$ref": "#/definitions/ExceptionOptions"
1673 //       },
1674 //       "description": "Configuration options for selected exceptions."
1675 //     }
1676 //   },
1677 //   "required": [ "filters" ]
1678 // },
1679 // "SetExceptionBreakpointsResponse": {
1680 //   "allOf": [ { "$ref": "#/definitions/Response" }, {
1681 //     "type": "object",
1682 //     "description": "Response to 'setExceptionBreakpoints' request. This is
1683 //     just an acknowledgement, so no body field is required."
1684 //   }]
1685 // }
1686 void request_setExceptionBreakpoints(const llvm::json::Object &request) {
1687   llvm::json::Object response;
1688   lldb::SBError error;
1689   FillResponse(request, response);
1690   auto arguments = request.getObject("arguments");
1691   auto filters = arguments->getArray("filters");
1692   // Keep a list of any exception breakpoint filter names that weren't set
1693   // so we can clear any exception breakpoints if needed.
1694   std::set<std::string> unset_filters;
1695   for (const auto &bp : g_vsc.exception_breakpoints)
1696     unset_filters.insert(bp.filter);
1697 
1698   for (const auto &value : *filters) {
1699     const auto filter = GetAsString(value);
1700     auto exc_bp = g_vsc.GetExceptionBreakpoint(filter);
1701     if (exc_bp) {
1702       exc_bp->SetBreakpoint();
1703       unset_filters.erase(filter);
1704     }
1705   }
1706   for (const auto &filter : unset_filters) {
1707     auto exc_bp = g_vsc.GetExceptionBreakpoint(filter);
1708     if (exc_bp)
1709       exc_bp->ClearBreakpoint();
1710   }
1711   g_vsc.SendJSON(llvm::json::Value(std::move(response)));
1712 }
1713 
1714 // "SetFunctionBreakpointsRequest": {
1715 //   "allOf": [ { "$ref": "#/definitions/Request" }, {
1716 //     "type": "object",
1717 //     "description": "SetFunctionBreakpoints request; value of command field is
1718 //     'setFunctionBreakpoints'. Sets multiple function breakpoints and clears
1719 //     all previous function breakpoints. To clear all function breakpoint,
1720 //     specify an empty array. When a function breakpoint is hit, a StoppedEvent
1721 //     (event type 'function breakpoint') is generated.", "properties": {
1722 //       "command": {
1723 //         "type": "string",
1724 //         "enum": [ "setFunctionBreakpoints" ]
1725 //       },
1726 //       "arguments": {
1727 //         "$ref": "#/definitions/SetFunctionBreakpointsArguments"
1728 //       }
1729 //     },
1730 //     "required": [ "command", "arguments"  ]
1731 //   }]
1732 // },
1733 // "SetFunctionBreakpointsArguments": {
1734 //   "type": "object",
1735 //   "description": "Arguments for 'setFunctionBreakpoints' request.",
1736 //   "properties": {
1737 //     "breakpoints": {
1738 //       "type": "array",
1739 //       "items": {
1740 //         "$ref": "#/definitions/FunctionBreakpoint"
1741 //       },
1742 //       "description": "The function names of the breakpoints."
1743 //     }
1744 //   },
1745 //   "required": [ "breakpoints" ]
1746 // },
1747 // "FunctionBreakpoint": {
1748 //   "type": "object",
1749 //   "description": "Properties of a breakpoint passed to the
1750 //   setFunctionBreakpoints request.", "properties": {
1751 //     "name": {
1752 //       "type": "string",
1753 //       "description": "The name of the function."
1754 //     },
1755 //     "condition": {
1756 //       "type": "string",
1757 //       "description": "An optional expression for conditional breakpoints."
1758 //     },
1759 //     "hitCondition": {
1760 //       "type": "string",
1761 //       "description": "An optional expression that controls how many hits of
1762 //       the breakpoint are ignored. The backend is expected to interpret the
1763 //       expression as needed."
1764 //     }
1765 //   },
1766 //   "required": [ "name" ]
1767 // },
1768 // "SetFunctionBreakpointsResponse": {
1769 //   "allOf": [ { "$ref": "#/definitions/Response" }, {
1770 //     "type": "object",
1771 //     "description": "Response to 'setFunctionBreakpoints' request. Returned is
1772 //     information about each breakpoint created by this request.",
1773 //     "properties": {
1774 //       "body": {
1775 //         "type": "object",
1776 //         "properties": {
1777 //           "breakpoints": {
1778 //             "type": "array",
1779 //             "items": {
1780 //               "$ref": "#/definitions/Breakpoint"
1781 //             },
1782 //             "description": "Information about the breakpoints. The array
1783 //             elements correspond to the elements of the 'breakpoints' array."
1784 //           }
1785 //         },
1786 //         "required": [ "breakpoints" ]
1787 //       }
1788 //     },
1789 //     "required": [ "body" ]
1790 //   }]
1791 // }
1792 void request_setFunctionBreakpoints(const llvm::json::Object &request) {
1793   llvm::json::Object response;
1794   lldb::SBError error;
1795   FillResponse(request, response);
1796   auto arguments = request.getObject("arguments");
1797   auto breakpoints = arguments->getArray("breakpoints");
1798   FunctionBreakpointMap request_bps;
1799   llvm::json::Array response_breakpoints;
1800   for (const auto &value : *breakpoints) {
1801     auto bp_obj = value.getAsObject();
1802     if (bp_obj == nullptr)
1803       continue;
1804     FunctionBreakpoint func_bp(*bp_obj);
1805     request_bps[func_bp.functionName] = std::move(func_bp);
1806   }
1807 
1808   std::vector<llvm::StringRef> remove_names;
1809   // Disable any function breakpoints that aren't in the request_bps.
1810   // There is no call to remove function breakpoints other than calling this
1811   // function with a smaller or empty "breakpoints" list.
1812   for (auto &pair: g_vsc.function_breakpoints) {
1813     auto request_pos = request_bps.find(pair.first());
1814     if (request_pos == request_bps.end()) {
1815       // This function breakpoint no longer exists delete it from LLDB
1816       g_vsc.target.BreakpointDelete(pair.second.bp.GetID());
1817       remove_names.push_back(pair.first());
1818     } else {
1819       // Update the existing breakpoint as any setting withing the function
1820       // breakpoint might have changed.
1821       pair.second.UpdateBreakpoint(request_pos->second);
1822       // Remove this breakpoint from the request breakpoints since we have
1823       // handled it here and we don't need to set a new breakpoint below.
1824       request_bps.erase(request_pos);
1825       // Add this breakpoint info to the response
1826       AppendBreakpoint(pair.second.bp, response_breakpoints);
1827     }
1828   }
1829   // Remove any breakpoints that are no longer in our list
1830   for (const auto &name: remove_names)
1831     g_vsc.function_breakpoints.erase(name);
1832 
1833   // Any breakpoints that are left in "request_bps" are breakpoints that
1834   // need to be set.
1835   for (auto &pair : request_bps) {
1836     pair.second.SetBreakpoint();
1837     // Add this breakpoint info to the response
1838     AppendBreakpoint(pair.second.bp, response_breakpoints);
1839     g_vsc.function_breakpoints[pair.first()] = std::move(pair.second);
1840   }
1841 
1842   llvm::json::Object body;
1843   body.try_emplace("breakpoints", std::move(response_breakpoints));
1844   response.try_emplace("body", std::move(body));
1845   g_vsc.SendJSON(llvm::json::Value(std::move(response)));
1846 }
1847 
1848 // "SourceRequest": {
1849 //   "allOf": [ { "$ref": "#/definitions/Request" }, {
1850 //     "type": "object",
1851 //     "description": "Source request; value of command field is 'source'. The
1852 //     request retrieves the source code for a given source reference.",
1853 //     "properties": {
1854 //       "command": {
1855 //         "type": "string",
1856 //         "enum": [ "source" ]
1857 //       },
1858 //       "arguments": {
1859 //         "$ref": "#/definitions/SourceArguments"
1860 //       }
1861 //     },
1862 //     "required": [ "command", "arguments"  ]
1863 //   }]
1864 // },
1865 // "SourceArguments": {
1866 //   "type": "object",
1867 //   "description": "Arguments for 'source' request.",
1868 //   "properties": {
1869 //     "source": {
1870 //       "$ref": "#/definitions/Source",
1871 //       "description": "Specifies the source content to load. Either
1872 //       source.path or source.sourceReference must be specified."
1873 //     },
1874 //     "sourceReference": {
1875 //       "type": "integer",
1876 //       "description": "The reference to the source. This is the same as
1877 //       source.sourceReference. This is provided for backward compatibility
1878 //       since old backends do not understand the 'source' attribute."
1879 //     }
1880 //   },
1881 //   "required": [ "sourceReference" ]
1882 // },
1883 // "SourceResponse": {
1884 //   "allOf": [ { "$ref": "#/definitions/Response" }, {
1885 //     "type": "object",
1886 //     "description": "Response to 'source' request.",
1887 //     "properties": {
1888 //       "body": {
1889 //         "type": "object",
1890 //         "properties": {
1891 //           "content": {
1892 //             "type": "string",
1893 //             "description": "Content of the source reference."
1894 //           },
1895 //           "mimeType": {
1896 //             "type": "string",
1897 //             "description": "Optional content type (mime type) of the source."
1898 //           }
1899 //         },
1900 //         "required": [ "content" ]
1901 //       }
1902 //     },
1903 //     "required": [ "body" ]
1904 //   }]
1905 // }
1906 void request_source(const llvm::json::Object &request) {
1907   llvm::json::Object response;
1908   FillResponse(request, response);
1909   llvm::json::Object body;
1910 
1911   auto arguments = request.getObject("arguments");
1912   auto source = arguments->getObject("source");
1913   auto sourceReference = GetSigned(source, "sourceReference", -1);
1914   auto pos = g_vsc.source_map.find((lldb::addr_t)sourceReference);
1915   if (pos != g_vsc.source_map.end()) {
1916     EmplaceSafeString(body, "content", pos->second.content);
1917   } else {
1918     response["success"] = llvm::json::Value(false);
1919   }
1920   response.try_emplace("body", std::move(body));
1921   g_vsc.SendJSON(llvm::json::Value(std::move(response)));
1922 }
1923 
1924 // "StackTraceRequest": {
1925 //   "allOf": [ { "$ref": "#/definitions/Request" }, {
1926 //     "type": "object",
1927 //     "description": "StackTrace request; value of command field is
1928 //     'stackTrace'. The request returns a stacktrace from the current execution
1929 //     state.", "properties": {
1930 //       "command": {
1931 //         "type": "string",
1932 //         "enum": [ "stackTrace" ]
1933 //       },
1934 //       "arguments": {
1935 //         "$ref": "#/definitions/StackTraceArguments"
1936 //       }
1937 //     },
1938 //     "required": [ "command", "arguments"  ]
1939 //   }]
1940 // },
1941 // "StackTraceArguments": {
1942 //   "type": "object",
1943 //   "description": "Arguments for 'stackTrace' request.",
1944 //   "properties": {
1945 //     "threadId": {
1946 //       "type": "integer",
1947 //       "description": "Retrieve the stacktrace for this thread."
1948 //     },
1949 //     "startFrame": {
1950 //       "type": "integer",
1951 //       "description": "The index of the first frame to return; if omitted
1952 //       frames start at 0."
1953 //     },
1954 //     "levels": {
1955 //       "type": "integer",
1956 //       "description": "The maximum number of frames to return. If levels is
1957 //       not specified or 0, all frames are returned."
1958 //     },
1959 //     "format": {
1960 //       "$ref": "#/definitions/StackFrameFormat",
1961 //       "description": "Specifies details on how to format the stack frames."
1962 //     }
1963 //  },
1964 //   "required": [ "threadId" ]
1965 // },
1966 // "StackTraceResponse": {
1967 //   "allOf": [ { "$ref": "#/definitions/Response" }, {
1968 //     "type": "object",
1969 //     "description": "Response to 'stackTrace' request.",
1970 //     "properties": {
1971 //       "body": {
1972 //         "type": "object",
1973 //         "properties": {
1974 //           "stackFrames": {
1975 //             "type": "array",
1976 //             "items": {
1977 //               "$ref": "#/definitions/StackFrame"
1978 //             },
1979 //             "description": "The frames of the stackframe. If the array has
1980 //             length zero, there are no stackframes available. This means that
1981 //             there is no location information available."
1982 //           },
1983 //           "totalFrames": {
1984 //             "type": "integer",
1985 //             "description": "The total number of frames available."
1986 //           }
1987 //         },
1988 //         "required": [ "stackFrames" ]
1989 //       }
1990 //     },
1991 //     "required": [ "body" ]
1992 //   }]
1993 // }
1994 void request_stackTrace(const llvm::json::Object &request) {
1995   llvm::json::Object response;
1996   FillResponse(request, response);
1997   lldb::SBError error;
1998   auto arguments = request.getObject("arguments");
1999   lldb::SBThread thread = g_vsc.GetLLDBThread(*arguments);
2000   llvm::json::Array stackFrames;
2001   llvm::json::Object body;
2002 
2003   if (thread.IsValid()) {
2004     const auto startFrame = GetUnsigned(arguments, "startFrame", 0);
2005     const auto levels = GetUnsigned(arguments, "levels", 0);
2006     const auto endFrame = (levels == 0) ? INT64_MAX : (startFrame + levels);
2007     for (uint32_t i = startFrame; i < endFrame; ++i) {
2008       auto frame = thread.GetFrameAtIndex(i);
2009       if (!frame.IsValid())
2010         break;
2011       stackFrames.emplace_back(CreateStackFrame(frame));
2012     }
2013   }
2014   body.try_emplace("stackFrames", std::move(stackFrames));
2015   response.try_emplace("body", std::move(body));
2016   g_vsc.SendJSON(llvm::json::Value(std::move(response)));
2017 }
2018 
2019 // "StepInRequest": {
2020 //   "allOf": [ { "$ref": "#/definitions/Request" }, {
2021 //     "type": "object",
2022 //     "description": "StepIn request; value of command field is 'stepIn'. The
2023 //     request starts the debuggee to step into a function/method if possible.
2024 //     If it cannot step into a target, 'stepIn' behaves like 'next'. The debug
2025 //     adapter first sends the StepInResponse and then a StoppedEvent (event
2026 //     type 'step') after the step has completed. If there are multiple
2027 //     function/method calls (or other targets) on the source line, the optional
2028 //     argument 'targetId' can be used to control into which target the 'stepIn'
2029 //     should occur. The list of possible targets for a given source line can be
2030 //     retrieved via the 'stepInTargets' request.", "properties": {
2031 //       "command": {
2032 //         "type": "string",
2033 //         "enum": [ "stepIn" ]
2034 //       },
2035 //       "arguments": {
2036 //         "$ref": "#/definitions/StepInArguments"
2037 //       }
2038 //     },
2039 //     "required": [ "command", "arguments"  ]
2040 //   }]
2041 // },
2042 // "StepInArguments": {
2043 //   "type": "object",
2044 //   "description": "Arguments for 'stepIn' request.",
2045 //   "properties": {
2046 //     "threadId": {
2047 //       "type": "integer",
2048 //       "description": "Execute 'stepIn' for this thread."
2049 //     },
2050 //     "targetId": {
2051 //       "type": "integer",
2052 //       "description": "Optional id of the target to step into."
2053 //     }
2054 //   },
2055 //   "required": [ "threadId" ]
2056 // },
2057 // "StepInResponse": {
2058 //   "allOf": [ { "$ref": "#/definitions/Response" }, {
2059 //     "type": "object",
2060 //     "description": "Response to 'stepIn' request. This is just an
2061 //     acknowledgement, so no body field is required."
2062 //   }]
2063 // }
2064 void request_stepIn(const llvm::json::Object &request) {
2065   llvm::json::Object response;
2066   FillResponse(request, response);
2067   auto arguments = request.getObject("arguments");
2068   lldb::SBThread thread = g_vsc.GetLLDBThread(*arguments);
2069   if (thread.IsValid()) {
2070     // Remember the thread ID that caused the resume so we can set the
2071     // "threadCausedFocus" boolean value in the "stopped" events.
2072     g_vsc.focus_tid = thread.GetThreadID();
2073     thread.StepInto();
2074   } else {
2075     response["success"] = llvm::json::Value(false);
2076   }
2077   g_vsc.SendJSON(llvm::json::Value(std::move(response)));
2078 }
2079 
2080 // "StepOutRequest": {
2081 //   "allOf": [ { "$ref": "#/definitions/Request" }, {
2082 //     "type": "object",
2083 //     "description": "StepOut request; value of command field is 'stepOut'. The
2084 //     request starts the debuggee to run again for one step. The debug adapter
2085 //     first sends the StepOutResponse and then a StoppedEvent (event type
2086 //     'step') after the step has completed.", "properties": {
2087 //       "command": {
2088 //         "type": "string",
2089 //         "enum": [ "stepOut" ]
2090 //       },
2091 //       "arguments": {
2092 //         "$ref": "#/definitions/StepOutArguments"
2093 //       }
2094 //     },
2095 //     "required": [ "command", "arguments"  ]
2096 //   }]
2097 // },
2098 // "StepOutArguments": {
2099 //   "type": "object",
2100 //   "description": "Arguments for 'stepOut' request.",
2101 //   "properties": {
2102 //     "threadId": {
2103 //       "type": "integer",
2104 //       "description": "Execute 'stepOut' for this thread."
2105 //     }
2106 //   },
2107 //   "required": [ "threadId" ]
2108 // },
2109 // "StepOutResponse": {
2110 //   "allOf": [ { "$ref": "#/definitions/Response" }, {
2111 //     "type": "object",
2112 //     "description": "Response to 'stepOut' request. This is just an
2113 //     acknowledgement, so no body field is required."
2114 //   }]
2115 // }
2116 void request_stepOut(const llvm::json::Object &request) {
2117   llvm::json::Object response;
2118   FillResponse(request, response);
2119   auto arguments = request.getObject("arguments");
2120   lldb::SBThread thread = g_vsc.GetLLDBThread(*arguments);
2121   if (thread.IsValid()) {
2122     // Remember the thread ID that caused the resume so we can set the
2123     // "threadCausedFocus" boolean value in the "stopped" events.
2124     g_vsc.focus_tid = thread.GetThreadID();
2125     thread.StepOut();
2126   } else {
2127     response["success"] = llvm::json::Value(false);
2128   }
2129   g_vsc.SendJSON(llvm::json::Value(std::move(response)));
2130 }
2131 
2132 // "ThreadsRequest": {
2133 //   "allOf": [ { "$ref": "#/definitions/Request" }, {
2134 //     "type": "object",
2135 //     "description": "Thread request; value of command field is 'threads'. The
2136 //     request retrieves a list of all threads.", "properties": {
2137 //       "command": {
2138 //         "type": "string",
2139 //         "enum": [ "threads" ]
2140 //       }
2141 //     },
2142 //     "required": [ "command" ]
2143 //   }]
2144 // },
2145 // "ThreadsResponse": {
2146 //   "allOf": [ { "$ref": "#/definitions/Response" }, {
2147 //     "type": "object",
2148 //     "description": "Response to 'threads' request.",
2149 //     "properties": {
2150 //       "body": {
2151 //         "type": "object",
2152 //         "properties": {
2153 //           "threads": {
2154 //             "type": "array",
2155 //             "items": {
2156 //               "$ref": "#/definitions/Thread"
2157 //             },
2158 //             "description": "All threads."
2159 //           }
2160 //         },
2161 //         "required": [ "threads" ]
2162 //       }
2163 //     },
2164 //     "required": [ "body" ]
2165 //   }]
2166 // }
2167 void request_threads(const llvm::json::Object &request) {
2168 
2169   lldb::SBProcess process = g_vsc.target.GetProcess();
2170   llvm::json::Object response;
2171   FillResponse(request, response);
2172 
2173   const uint32_t num_threads = process.GetNumThreads();
2174   llvm::json::Array threads;
2175   for (uint32_t thread_idx = 0; thread_idx < num_threads; ++thread_idx) {
2176     lldb::SBThread thread = process.GetThreadAtIndex(thread_idx);
2177     threads.emplace_back(CreateThread(thread));
2178   }
2179   if (threads.size() == 0) {
2180     response["success"] = llvm::json::Value(false);
2181   }
2182   llvm::json::Object body;
2183   body.try_emplace("threads", std::move(threads));
2184   response.try_emplace("body", std::move(body));
2185   g_vsc.SendJSON(llvm::json::Value(std::move(response)));
2186 }
2187 
2188 // "SetVariableRequest": {
2189 //   "allOf": [ { "$ref": "#/definitions/Request" }, {
2190 //     "type": "object",
2191 //     "description": "setVariable request; value of command field is
2192 //     'setVariable'. Set the variable with the given name in the variable
2193 //     container to a new value.", "properties": {
2194 //       "command": {
2195 //         "type": "string",
2196 //         "enum": [ "setVariable" ]
2197 //       },
2198 //       "arguments": {
2199 //         "$ref": "#/definitions/SetVariableArguments"
2200 //       }
2201 //     },
2202 //     "required": [ "command", "arguments"  ]
2203 //   }]
2204 // },
2205 // "SetVariableArguments": {
2206 //   "type": "object",
2207 //   "description": "Arguments for 'setVariable' request.",
2208 //   "properties": {
2209 //     "variablesReference": {
2210 //       "type": "integer",
2211 //       "description": "The reference of the variable container."
2212 //     },
2213 //     "name": {
2214 //       "type": "string",
2215 //       "description": "The name of the variable."
2216 //     },
2217 //     "value": {
2218 //       "type": "string",
2219 //       "description": "The value of the variable."
2220 //     },
2221 //     "format": {
2222 //       "$ref": "#/definitions/ValueFormat",
2223 //       "description": "Specifies details on how to format the response value."
2224 //     }
2225 //   },
2226 //   "required": [ "variablesReference", "name", "value" ]
2227 // },
2228 // "SetVariableResponse": {
2229 //   "allOf": [ { "$ref": "#/definitions/Response" }, {
2230 //     "type": "object",
2231 //     "description": "Response to 'setVariable' request.",
2232 //     "properties": {
2233 //       "body": {
2234 //         "type": "object",
2235 //         "properties": {
2236 //           "value": {
2237 //             "type": "string",
2238 //             "description": "The new value of the variable."
2239 //           },
2240 //           "type": {
2241 //             "type": "string",
2242 //             "description": "The type of the new value. Typically shown in the
2243 //             UI when hovering over the value."
2244 //           },
2245 //           "variablesReference": {
2246 //             "type": "number",
2247 //             "description": "If variablesReference is > 0, the new value is
2248 //             structured and its children can be retrieved by passing
2249 //             variablesReference to the VariablesRequest."
2250 //           },
2251 //           "namedVariables": {
2252 //             "type": "number",
2253 //             "description": "The number of named child variables. The client
2254 //             can use this optional information to present the variables in a
2255 //             paged UI and fetch them in chunks."
2256 //           },
2257 //           "indexedVariables": {
2258 //             "type": "number",
2259 //             "description": "The number of indexed child variables. The client
2260 //             can use this optional information to present the variables in a
2261 //             paged UI and fetch them in chunks."
2262 //           }
2263 //         },
2264 //         "required": [ "value" ]
2265 //       }
2266 //     },
2267 //     "required": [ "body" ]
2268 //   }]
2269 // }
2270 void request_setVariable(const llvm::json::Object &request) {
2271   llvm::json::Object response;
2272   FillResponse(request, response);
2273   llvm::json::Array variables;
2274   llvm::json::Object body;
2275   auto arguments = request.getObject("arguments");
2276   // This is a reference to the containing variable/scope
2277   const auto variablesReference =
2278       GetUnsigned(arguments, "variablesReference", 0);
2279   const auto name = GetString(arguments, "name");
2280   const auto value = GetString(arguments, "value");
2281   // Set success to false just in case we don't find the variable by name
2282   response.try_emplace("success", false);
2283 
2284   lldb::SBValue variable;
2285   int64_t newVariablesReference = 0;
2286 
2287   // The "id" is the unique integer ID that is unique within the enclosing
2288   // variablesReference. It is optionally added to any "interface Variable"
2289   // objects to uniquely identify a variable within an enclosing
2290   // variablesReference. It helps to disambiguate between two variables that
2291   // have the same name within the same scope since the "setVariables" request
2292   // only specifies the variable reference of the enclosing scope/variable, and
2293   // the name of the variable. We could have two shadowed variables with the
2294   // same name in "Locals" or "Globals". In our case the "id" absolute index
2295   // of the variable within the g_vsc.variables list.
2296   const auto id_value = GetUnsigned(arguments, "id", UINT64_MAX);
2297   if (id_value != UINT64_MAX) {
2298     variable = g_vsc.variables.GetValueAtIndex(id_value);
2299   } else if (VARREF_IS_SCOPE(variablesReference)) {
2300     // variablesReference is one of our scopes, not an actual variable it is
2301     // asking for a variable in locals or globals or registers
2302     int64_t start_idx = 0;
2303     int64_t end_idx = 0;
2304     switch (variablesReference) {
2305     case VARREF_LOCALS:
2306       start_idx = 0;
2307       end_idx = start_idx + g_vsc.num_locals;
2308       break;
2309     case VARREF_GLOBALS:
2310       start_idx = g_vsc.num_locals;
2311       end_idx = start_idx + g_vsc.num_globals;
2312       break;
2313     case VARREF_REGS:
2314       start_idx = g_vsc.num_locals + g_vsc.num_globals;
2315       end_idx = start_idx + g_vsc.num_regs;
2316       break;
2317     default:
2318       break;
2319     }
2320 
2321     // Find the variable by name in the correct scope and hope we don't have
2322     // multiple variables with the same name. We search backwards because
2323     // the list of variables has the top most variables first and variables
2324     // in deeper scopes are last. This means we will catch the deepest
2325     // variable whose name matches which is probably what the user wants.
2326     for (int64_t i = end_idx - 1; i >= start_idx; --i) {
2327       auto curr_variable = g_vsc.variables.GetValueAtIndex(i);
2328       llvm::StringRef variable_name(curr_variable.GetName());
2329       if (variable_name == name) {
2330         variable = curr_variable;
2331         if (curr_variable.MightHaveChildren())
2332           newVariablesReference = i;
2333         break;
2334       }
2335     }
2336   } else {
2337     // We have a named item within an actual variable so we need to find it
2338     // withing the container variable by name.
2339     const int64_t var_idx = VARREF_TO_VARIDX(variablesReference);
2340     lldb::SBValue container = g_vsc.variables.GetValueAtIndex(var_idx);
2341     variable = container.GetChildMemberWithName(name.data());
2342     if (!variable.IsValid()) {
2343       if (name.startswith("[")) {
2344         llvm::StringRef index_str(name.drop_front(1));
2345         uint64_t index = 0;
2346         if (!index_str.consumeInteger(0, index)) {
2347           if (index_str == "]")
2348             variable = container.GetChildAtIndex(index);
2349         }
2350       }
2351     }
2352 
2353     // We don't know the index of the variable in our g_vsc.variables
2354     if (variable.IsValid()) {
2355       if (variable.MightHaveChildren()) {
2356         newVariablesReference = VARIDX_TO_VARREF(g_vsc.variables.GetSize());
2357         g_vsc.variables.Append(variable);
2358       }
2359     }
2360   }
2361 
2362   if (variable.IsValid()) {
2363     lldb::SBError error;
2364     bool success = variable.SetValueFromCString(value.data(), error);
2365     if (success) {
2366       SetValueForKey(variable, body, "value");
2367       EmplaceSafeString(body, "type", variable.GetType().GetDisplayTypeName());
2368       body.try_emplace("variablesReference", newVariablesReference);
2369     } else {
2370       EmplaceSafeString(body, "message", std::string(error.GetCString()));
2371     }
2372     response["success"] = llvm::json::Value(success);
2373   }
2374 
2375   response.try_emplace("body", std::move(body));
2376   g_vsc.SendJSON(llvm::json::Value(std::move(response)));
2377 }
2378 
2379 // "VariablesRequest": {
2380 //   "allOf": [ { "$ref": "#/definitions/Request" }, {
2381 //     "type": "object",
2382 //     "description": "Variables request; value of command field is 'variables'.
2383 //     Retrieves all child variables for the given variable reference. An
2384 //     optional filter can be used to limit the fetched children to either named
2385 //     or indexed children.", "properties": {
2386 //       "command": {
2387 //         "type": "string",
2388 //         "enum": [ "variables" ]
2389 //       },
2390 //       "arguments": {
2391 //         "$ref": "#/definitions/VariablesArguments"
2392 //       }
2393 //     },
2394 //     "required": [ "command", "arguments"  ]
2395 //   }]
2396 // },
2397 // "VariablesArguments": {
2398 //   "type": "object",
2399 //   "description": "Arguments for 'variables' request.",
2400 //   "properties": {
2401 //     "variablesReference": {
2402 //       "type": "integer",
2403 //       "description": "The Variable reference."
2404 //     },
2405 //     "filter": {
2406 //       "type": "string",
2407 //       "enum": [ "indexed", "named" ],
2408 //       "description": "Optional filter to limit the child variables to either
2409 //       named or indexed. If ommited, both types are fetched."
2410 //     },
2411 //     "start": {
2412 //       "type": "integer",
2413 //       "description": "The index of the first variable to return; if omitted
2414 //       children start at 0."
2415 //     },
2416 //     "count": {
2417 //       "type": "integer",
2418 //       "description": "The number of variables to return. If count is missing
2419 //       or 0, all variables are returned."
2420 //     },
2421 //     "format": {
2422 //       "$ref": "#/definitions/ValueFormat",
2423 //       "description": "Specifies details on how to format the Variable
2424 //       values."
2425 //     }
2426 //   },
2427 //   "required": [ "variablesReference" ]
2428 // },
2429 // "VariablesResponse": {
2430 //   "allOf": [ { "$ref": "#/definitions/Response" }, {
2431 //     "type": "object",
2432 //     "description": "Response to 'variables' request.",
2433 //     "properties": {
2434 //       "body": {
2435 //         "type": "object",
2436 //         "properties": {
2437 //           "variables": {
2438 //             "type": "array",
2439 //             "items": {
2440 //               "$ref": "#/definitions/Variable"
2441 //             },
2442 //             "description": "All (or a range) of variables for the given
2443 //             variable reference."
2444 //           }
2445 //         },
2446 //         "required": [ "variables" ]
2447 //       }
2448 //     },
2449 //     "required": [ "body" ]
2450 //   }]
2451 // }
2452 void request_variables(const llvm::json::Object &request) {
2453   llvm::json::Object response;
2454   FillResponse(request, response);
2455   llvm::json::Array variables;
2456   auto arguments = request.getObject("arguments");
2457   const auto variablesReference =
2458       GetUnsigned(arguments, "variablesReference", 0);
2459   const int64_t start = GetSigned(arguments, "start", 0);
2460   const int64_t count = GetSigned(arguments, "count", 0);
2461   bool hex = false;
2462   auto format = arguments->getObject("format");
2463   if (format)
2464     hex = GetBoolean(format, "hex", false);
2465 
2466   if (VARREF_IS_SCOPE(variablesReference)) {
2467     // variablesReference is one of our scopes, not an actual variable it is
2468     // asking for the list of args, locals or globals.
2469     int64_t start_idx = 0;
2470     int64_t num_children = 0;
2471     switch (variablesReference) {
2472     case VARREF_LOCALS:
2473       start_idx = start;
2474       num_children = g_vsc.num_locals;
2475       break;
2476     case VARREF_GLOBALS:
2477       start_idx = start + g_vsc.num_locals + start;
2478       num_children = g_vsc.num_globals;
2479       break;
2480     case VARREF_REGS:
2481       start_idx = start + g_vsc.num_locals + g_vsc.num_globals;
2482       num_children = g_vsc.num_regs;
2483       break;
2484     default:
2485       break;
2486     }
2487     const int64_t end_idx = start_idx + ((count == 0) ? num_children : count);
2488     for (auto i = start_idx; i < end_idx; ++i) {
2489       lldb::SBValue variable = g_vsc.variables.GetValueAtIndex(i);
2490       if (!variable.IsValid())
2491         break;
2492       variables.emplace_back(
2493           CreateVariable(variable, VARIDX_TO_VARREF(i), i, hex));
2494     }
2495   } else {
2496     // We are expanding a variable that has children, so we will return its
2497     // children.
2498     const int64_t var_idx = VARREF_TO_VARIDX(variablesReference);
2499     lldb::SBValue variable = g_vsc.variables.GetValueAtIndex(var_idx);
2500     if (variable.IsValid()) {
2501       const auto num_children = variable.GetNumChildren();
2502       const int64_t end_idx = start + ((count == 0) ? num_children : count);
2503       for (auto i = start; i < end_idx; ++i) {
2504         lldb::SBValue child = variable.GetChildAtIndex(i);
2505         if (!child.IsValid())
2506           break;
2507         if (child.MightHaveChildren()) {
2508           const int64_t var_idx = g_vsc.variables.GetSize();
2509           auto childVariablesReferences = VARIDX_TO_VARREF(var_idx);
2510           variables.emplace_back(
2511               CreateVariable(child, childVariablesReferences, var_idx, hex));
2512           g_vsc.variables.Append(child);
2513         } else {
2514           variables.emplace_back(CreateVariable(child, 0, INT64_MAX, hex));
2515         }
2516       }
2517     }
2518   }
2519   llvm::json::Object body;
2520   body.try_emplace("variables", std::move(variables));
2521   response.try_emplace("body", std::move(body));
2522   g_vsc.SendJSON(llvm::json::Value(std::move(response)));
2523 }
2524 
2525 // A request used in testing to get the details on all breakpoints that are
2526 // currently set in the target. This helps us to test "setBreakpoints" and
2527 // "setFunctionBreakpoints" requests to verify we have the correct set of
2528 // breakpoints currently set in LLDB.
2529 void request__testGetTargetBreakpoints(const llvm::json::Object &request) {
2530   llvm::json::Object response;
2531   FillResponse(request, response);
2532   llvm::json::Array response_breakpoints;
2533   for (uint32_t i = 0; g_vsc.target.GetBreakpointAtIndex(i).IsValid(); ++i) {
2534     auto bp = g_vsc.target.GetBreakpointAtIndex(i);
2535     AppendBreakpoint(bp, response_breakpoints);
2536   }
2537   llvm::json::Object body;
2538   body.try_emplace("breakpoints", std::move(response_breakpoints));
2539   response.try_emplace("body", std::move(body));
2540   g_vsc.SendJSON(llvm::json::Value(std::move(response)));
2541 }
2542 
2543 const std::map<std::string, RequestCallback> &GetRequestHandlers() {
2544 #define REQUEST_CALLBACK(name)                                                 \
2545   { #name, request_##name }
2546   static std::map<std::string, RequestCallback> g_request_handlers = {
2547       // VSCode Debug Adaptor requests
2548       REQUEST_CALLBACK(attach),
2549       REQUEST_CALLBACK(continue),
2550       REQUEST_CALLBACK(configurationDone),
2551       REQUEST_CALLBACK(disconnect),
2552       REQUEST_CALLBACK(evaluate),
2553       REQUEST_CALLBACK(exceptionInfo),
2554       REQUEST_CALLBACK(initialize),
2555       REQUEST_CALLBACK(launch),
2556       REQUEST_CALLBACK(next),
2557       REQUEST_CALLBACK(pause),
2558       REQUEST_CALLBACK(scopes),
2559       REQUEST_CALLBACK(setBreakpoints),
2560       REQUEST_CALLBACK(setExceptionBreakpoints),
2561       REQUEST_CALLBACK(setFunctionBreakpoints),
2562       REQUEST_CALLBACK(setVariable),
2563       REQUEST_CALLBACK(source),
2564       REQUEST_CALLBACK(stackTrace),
2565       REQUEST_CALLBACK(stepIn),
2566       REQUEST_CALLBACK(stepOut),
2567       REQUEST_CALLBACK(threads),
2568       REQUEST_CALLBACK(variables),
2569       // Testing requests
2570       REQUEST_CALLBACK(_testGetTargetBreakpoints),
2571   };
2572 #undef REQUEST_CALLBACK
2573   return g_request_handlers;
2574 }
2575 
2576 } // anonymous namespace
2577 
2578 int main(int argc, char *argv[]) {
2579 
2580   // Initialize LLDB first before we do anything.
2581   lldb::SBDebugger::Initialize();
2582 
2583   if (argc == 2) {
2584     const char *arg = argv[1];
2585 #if !defined(_WIN32)
2586     if (strcmp(arg, "-g") == 0) {
2587       printf("Paused waiting for debugger to attach (pid = %i)...\n", getpid());
2588       pause();
2589     } else {
2590 #else
2591     {
2592 #endif
2593       int portno = atoi(arg);
2594       printf("Listening on port %i...\n", portno);
2595       SOCKET socket_fd = AcceptConnection(portno);
2596       if (socket_fd >= 0) {
2597         g_vsc.input.descriptor = StreamDescriptor::from_socket(socket_fd, true);
2598         g_vsc.output.descriptor =
2599             StreamDescriptor::from_socket(socket_fd, false);
2600       } else {
2601         exit(1);
2602       }
2603     }
2604   } else {
2605     g_vsc.input.descriptor = StreamDescriptor::from_file(fileno(stdin), false);
2606     g_vsc.output.descriptor =
2607         StreamDescriptor::from_file(fileno(stdout), false);
2608   }
2609   auto request_handlers = GetRequestHandlers();
2610   uint32_t packet_idx = 0;
2611   while (true) {
2612     std::string json = g_vsc.ReadJSON();
2613     if (json.empty())
2614       break;
2615 
2616     llvm::StringRef json_sref(json);
2617     llvm::Expected<llvm::json::Value> json_value = llvm::json::parse(json_sref);
2618     if (!json_value) {
2619       auto error = json_value.takeError();
2620       if (g_vsc.log) {
2621         std::string error_str;
2622         llvm::raw_string_ostream strm(error_str);
2623         strm << error;
2624         strm.flush();
2625 
2626         *g_vsc.log << "error: failed to parse JSON: " << error_str << std::endl
2627                    << json << std::endl;
2628       }
2629       return 1;
2630     }
2631 
2632     auto object = json_value->getAsObject();
2633     if (!object) {
2634       if (g_vsc.log)
2635         *g_vsc.log << "error: json packet isn't a object" << std::endl;
2636       return 1;
2637     }
2638 
2639     const auto packet_type = GetString(object, "type");
2640     if (packet_type == "request") {
2641       const auto command = GetString(object, "command");
2642       auto handler_pos = request_handlers.find(command);
2643       if (handler_pos != request_handlers.end()) {
2644         handler_pos->second(*object);
2645       } else {
2646         if (g_vsc.log)
2647           *g_vsc.log << "error: unhandled command \"" << command.data() << std::endl;
2648         return 1;
2649       }
2650     }
2651     ++packet_idx;
2652   }
2653 
2654   // We must terminate the debugger in a thread before the C++ destructor
2655   // chain messes everything up.
2656   lldb::SBDebugger::Terminate();
2657   return 0;
2658 }
2659