1 | //===-- InitializeRequestHandler.cpp --------------------------------------===// |
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 "CommandPlugins.h" |
10 | #include "DAP.h" |
11 | #include "EventHelper.h" |
12 | #include "JSONUtils.h" |
13 | #include "LLDBUtils.h" |
14 | #include "Protocol/ProtocolRequests.h" |
15 | #include "RequestHandler.h" |
16 | #include "lldb/API/SBTarget.h" |
17 | |
18 | using namespace lldb_dap; |
19 | using namespace lldb_dap::protocol; |
20 | |
21 | /// Initialize request; value of command field is 'initialize'. |
22 | llvm::Expected<InitializeResponse> InitializeRequestHandler::Run( |
23 | const InitializeRequestArguments &arguments) const { |
24 | dap.clientFeatures = arguments.supportedFeatures; |
25 | |
26 | // Do not source init files until in/out/err are configured. |
27 | dap.debugger = lldb::SBDebugger::Create(source_init_files: false); |
28 | dap.debugger.SetInputFile(dap.in); |
29 | dap.target = dap.debugger.GetDummyTarget(); |
30 | |
31 | llvm::Expected<int> out_fd = dap.out.GetWriteFileDescriptor(); |
32 | if (!out_fd) |
33 | return out_fd.takeError(); |
34 | dap.debugger.SetOutputFile(lldb::SBFile(*out_fd, "w" , false)); |
35 | |
36 | llvm::Expected<int> err_fd = dap.err.GetWriteFileDescriptor(); |
37 | if (!err_fd) |
38 | return err_fd.takeError(); |
39 | dap.debugger.SetErrorFile(lldb::SBFile(*err_fd, "w" , false)); |
40 | |
41 | auto interp = dap.debugger.GetCommandInterpreter(); |
42 | |
43 | // The sourceInitFile option is not part of the DAP specification. It is an |
44 | // extension used by the test suite to prevent sourcing `.lldbinit` and |
45 | // changing its behavior. |
46 | if (arguments.lldbExtSourceInitFile.value_or(u: true)) { |
47 | dap.debugger.SkipLLDBInitFiles(b: false); |
48 | dap.debugger.SkipAppInitFiles(b: false); |
49 | lldb::SBCommandReturnObject init; |
50 | interp.SourceInitFileInGlobalDirectory(result&: init); |
51 | interp.SourceInitFileInHomeDirectory(result&: init); |
52 | } |
53 | |
54 | if (llvm::Error err = dap.RunPreInitCommands()) |
55 | return err; |
56 | |
57 | dap.PopulateExceptionBreakpoints(); |
58 | auto cmd = dap.debugger.GetCommandInterpreter().AddMultiwordCommand( |
59 | name: "lldb-dap" , help: "Commands for managing lldb-dap." ); |
60 | if (arguments.supportedFeatures.contains( |
61 | V: eClientFeatureStartDebuggingRequest)) { |
62 | cmd.AddCommand( |
63 | name: "start-debugging" , impl: new StartDebuggingCommand(dap), |
64 | help: "Sends a startDebugging request from the debug adapter to the client " |
65 | "to start a child debug session of the same type as the caller." ); |
66 | } |
67 | cmd.AddCommand( |
68 | name: "repl-mode" , impl: new ReplModeCommand(dap), |
69 | help: "Get or set the repl behavior of lldb-dap evaluation requests." ); |
70 | cmd.AddCommand(name: "send-event" , impl: new SendEventCommand(dap), |
71 | help: "Sends an DAP event to the client." ); |
72 | |
73 | if (arguments.supportedFeatures.contains(V: eClientFeatureProgressReporting)) |
74 | dap.StartProgressEventThread(); |
75 | |
76 | // Start our event thread so we can receive events from the debugger, target, |
77 | // process and more. |
78 | dap.StartEventThread(); |
79 | |
80 | return dap.GetCapabilities(); |
81 | } |
82 | |