xref: /openbsd/gnu/llvm/lldb/tools/lldb-vscode/VSCode.h (revision 771fbea0)
1 //===-- VSCode.h ------------------------------------------------*- C++ -*-===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 
9 #ifndef LLDB_TOOLS_LLDB_VSCODE_VSCODE_H
10 #define LLDB_TOOLS_LLDB_VSCODE_VSCODE_H
11 
12 #include <iosfwd>
13 #include <map>
14 #include <set>
15 #include <stdio.h>
16 #include <thread>
17 
18 #include "llvm/ADT/DenseMap.h"
19 #include "llvm/ADT/DenseSet.h"
20 #include "llvm/ADT/StringMap.h"
21 #include "llvm/ADT/StringRef.h"
22 #include "llvm/Support/raw_ostream.h"
23 
24 #include "lldb/API/SBAttachInfo.h"
25 #include "lldb/API/SBBreakpoint.h"
26 #include "lldb/API/SBBreakpointLocation.h"
27 #include "lldb/API/SBCommandInterpreter.h"
28 #include "lldb/API/SBCommandReturnObject.h"
29 #include "lldb/API/SBCommunication.h"
30 #include "lldb/API/SBDebugger.h"
31 #include "lldb/API/SBEvent.h"
32 #include "lldb/API/SBHostOS.h"
33 #include "lldb/API/SBInstruction.h"
34 #include "lldb/API/SBInstructionList.h"
35 #include "lldb/API/SBLanguageRuntime.h"
36 #include "lldb/API/SBLaunchInfo.h"
37 #include "lldb/API/SBLineEntry.h"
38 #include "lldb/API/SBListener.h"
39 #include "lldb/API/SBProcess.h"
40 #include "lldb/API/SBStream.h"
41 #include "lldb/API/SBStringList.h"
42 #include "lldb/API/SBTarget.h"
43 #include "lldb/API/SBThread.h"
44 
45 #include "ExceptionBreakpoint.h"
46 #include "FunctionBreakpoint.h"
47 #include "IOStream.h"
48 #include "SourceBreakpoint.h"
49 #include "SourceReference.h"
50 
51 #define VARREF_LOCALS (int64_t)1
52 #define VARREF_GLOBALS (int64_t)2
53 #define VARREF_REGS (int64_t)3
54 #define VARREF_FIRST_VAR_IDX (int64_t)4
55 #define VARREF_IS_SCOPE(v) (VARREF_LOCALS <= 1 && v < VARREF_FIRST_VAR_IDX)
56 #define VARIDX_TO_VARREF(i) ((i) + VARREF_FIRST_VAR_IDX)
57 #define VARREF_TO_VARIDX(v) ((v)-VARREF_FIRST_VAR_IDX)
58 #define NO_TYPENAME "<no-type>"
59 
60 namespace lldb_vscode {
61 
62 typedef llvm::DenseMap<uint32_t, SourceBreakpoint> SourceBreakpointMap;
63 typedef llvm::StringMap<FunctionBreakpoint> FunctionBreakpointMap;
64 enum class OutputType { Console, Stdout, Stderr, Telemetry };
65 
66 enum VSCodeBroadcasterBits { eBroadcastBitStopEventThread = 1u << 0 };
67 
68 struct VSCode {
69   InputStream input;
70   OutputStream output;
71   lldb::SBDebugger debugger;
72   lldb::SBTarget target;
73   lldb::SBValueList variables;
74   lldb::SBBroadcaster broadcaster;
75   int64_t num_regs;
76   int64_t num_locals;
77   int64_t num_globals;
78   std::thread event_thread;
79   std::unique_ptr<std::ofstream> log;
80   llvm::DenseMap<lldb::addr_t, int64_t> addr_to_source_ref;
81   llvm::DenseMap<int64_t, SourceReference> source_map;
82   llvm::StringMap<SourceBreakpointMap> source_breakpoints;
83   FunctionBreakpointMap function_breakpoints;
84   std::vector<ExceptionBreakpoint> exception_breakpoints;
85   std::vector<std::string> init_commands;
86   std::vector<std::string> pre_run_commands;
87   std::vector<std::string> exit_commands;
88   std::vector<std::string> stop_commands;
89   std::vector<std::string> terminate_commands;
90   lldb::tid_t focus_tid;
91   bool sent_terminated_event;
92   bool stop_at_entry;
93   bool is_attach;
94   // Keep track of the last stop thread index IDs as threads won't go away
95   // unless we send a "thread" event to indicate the thread exited.
96   llvm::DenseSet<lldb::tid_t> thread_ids;
97   VSCode();
98   ~VSCode();
99   VSCode(const VSCode &rhs) = delete;
100   void operator=(const VSCode &rhs) = delete;
101   int64_t GetLineForPC(int64_t sourceReference, lldb::addr_t pc) const;
102   ExceptionBreakpoint *GetExceptionBreakpoint(const std::string &filter);
103   ExceptionBreakpoint *GetExceptionBreakpoint(const lldb::break_id_t bp_id);
104   // Send the JSON in "json_str" to the "out" stream. Correctly send the
105   // "Content-Length:" field followed by the length, followed by the raw
106   // JSON bytes.
107   void SendJSON(const std::string &json_str);
108 
109   // Serialize the JSON value into a string and send the JSON packet to
110   // the "out" stream.
111   void SendJSON(const llvm::json::Value &json);
112 
113   std::string ReadJSON();
114 
115   void SendOutput(OutputType o, const llvm::StringRef output);
116 
117   void __attribute__((format(printf, 3, 4)))
118   SendFormattedOutput(OutputType o, const char *format, ...);
119 
120   static int64_t GetNextSourceReference();
121 
122   ExceptionBreakpoint *GetExceptionBPFromStopReason(lldb::SBThread &thread);
123 
124   lldb::SBThread GetLLDBThread(const llvm::json::Object &arguments);
125 
126   lldb::SBFrame GetLLDBFrame(const llvm::json::Object &arguments);
127 
128   llvm::json::Value CreateTopLevelScopes();
129 
130   void RunLLDBCommands(llvm::StringRef prefix,
131                        const std::vector<std::string> &commands);
132 
133   void RunInitCommands();
134   void RunPreRunCommands();
135   void RunStopCommands();
136   void RunExitCommands();
137   void RunTerminateCommands();
138 
139   /// Create a new SBTarget object from the given request arguments.
140   /// \param[in] arguments
141   ///     Launch configuration arguments.
142   ///
143   /// \param[out] error
144   ///     An SBError object that will contain an error description if
145   ///     function failed to create the target.
146   ///
147   /// \return
148   ///     An SBTarget object.
149   lldb::SBTarget CreateTargetFromArguments(
150       const llvm::json::Object &arguments,
151       lldb::SBError &error);
152 
153   /// Set given target object as a current target for lldb-vscode and start
154   /// listeing for its breakpoint events.
155   void SetTarget(const lldb::SBTarget target);
156 };
157 
158 extern VSCode g_vsc;
159 
160 } // namespace lldb_vscode
161 
162 #endif
163