Coverage Report

Created: 2022-01-18 06:27

/Users/buildslave/jenkins/workspace/coverage/llvm-project/lldb/tools/lldb-vscode/VSCode.h
Line
Count
Source (jump to first uncovered line)
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 "llvm/Config/llvm-config.h" // for LLVM_ON_UNIX
13
14
#include <condition_variable>
15
#include <cstdio>
16
#include <iosfwd>
17
#include <map>
18
#include <set>
19
#include <thread>
20
21
#include "llvm/ADT/DenseMap.h"
22
#include "llvm/ADT/DenseSet.h"
23
#include "llvm/ADT/StringMap.h"
24
#include "llvm/ADT/StringRef.h"
25
#include "llvm/Support/JSON.h"
26
#include "llvm/Support/raw_ostream.h"
27
28
#include "lldb/API/SBAttachInfo.h"
29
#include "lldb/API/SBBreakpoint.h"
30
#include "lldb/API/SBBreakpointLocation.h"
31
#include "lldb/API/SBCommandInterpreter.h"
32
#include "lldb/API/SBCommandReturnObject.h"
33
#include "lldb/API/SBCommunication.h"
34
#include "lldb/API/SBDebugger.h"
35
#include "lldb/API/SBEvent.h"
36
#include "lldb/API/SBHostOS.h"
37
#include "lldb/API/SBInstruction.h"
38
#include "lldb/API/SBInstructionList.h"
39
#include "lldb/API/SBLanguageRuntime.h"
40
#include "lldb/API/SBLaunchInfo.h"
41
#include "lldb/API/SBLineEntry.h"
42
#include "lldb/API/SBListener.h"
43
#include "lldb/API/SBProcess.h"
44
#include "lldb/API/SBStream.h"
45
#include "lldb/API/SBStringList.h"
46
#include "lldb/API/SBTarget.h"
47
#include "lldb/API/SBThread.h"
48
49
#include "ExceptionBreakpoint.h"
50
#include "FunctionBreakpoint.h"
51
#include "IOStream.h"
52
#include "ProgressEvent.h"
53
#include "RunInTerminal.h"
54
#include "SourceBreakpoint.h"
55
#include "SourceReference.h"
56
57
0
#define VARREF_LOCALS (int64_t)1
58
0
#define VARREF_GLOBALS (int64_t)2
59
0
#define VARREF_REGS (int64_t)3
60
#define VARREF_FIRST_VAR_IDX (int64_t)4
61
0
#define NO_TYPENAME "<no-type>"
62
63
namespace lldb_vscode {
64
65
typedef llvm::DenseMap<uint32_t, SourceBreakpoint> SourceBreakpointMap;
66
typedef llvm::StringMap<FunctionBreakpoint> FunctionBreakpointMap;
67
enum class OutputType { Console, Stdout, Stderr, Telemetry };
68
69
enum VSCodeBroadcasterBits {
70
  eBroadcastBitStopEventThread = 1u << 0,
71
  eBroadcastBitStopProgressThread = 1u << 1
72
};
73
74
typedef void (*RequestCallback)(const llvm::json::Object &command);
75
76
enum class PacketStatus {
77
  Success = 0,
78
  EndOfFile,
79
  JSONMalformed,
80
  JSONNotObject
81
};
82
83
struct Variables {
84
  /// Variable_reference start index of permanent expandable variable.
85
  static constexpr int64_t PermanentVariableStartIndex = (1ll << 32);
86
87
  lldb::SBValueList locals;
88
  lldb::SBValueList globals;
89
  lldb::SBValueList registers;
90
91
  int64_t next_temporary_var_ref{VARREF_FIRST_VAR_IDX};
92
  int64_t next_permanent_var_ref{PermanentVariableStartIndex};
93
94
  /// Expandable variables that are alive in this stop state.
95
  /// Will be cleared when debuggee resumes.
96
  llvm::DenseMap<int64_t, lldb::SBValue> expandable_variables;
97
  /// Expandable variables that persist across entire debug session.
98
  /// These are the variables evaluated from debug console REPL.
99
  llvm::DenseMap<int64_t, lldb::SBValue> expandable_permanent_variables;
100
101
  /// Check if \p var_ref points to a variable that should persist for the
102
  /// entire duration of the debug session, e.g. repl expandable variables
103
  static bool IsPermanentVariableReference(int64_t var_ref);
104
105
  /// \return a new variableReference.
106
  /// Specify is_permanent as true for variable that should persist entire
107
  /// debug session.
108
  int64_t GetNewVariableRefence(bool is_permanent);
109
110
  /// \return the expandable variable corresponding with variableReference
111
  /// value of \p value.
112
  /// If \p var_ref is invalid an empty SBValue is returned.
113
  lldb::SBValue GetVariable(int64_t var_ref) const;
114
115
  /// Insert a new \p variable.
116
  /// \return variableReference assigned to this expandable variable.
117
  int64_t InsertExpandableVariable(lldb::SBValue variable, bool is_permanent);
118
119
  /// Clear all scope variables and non-permanent expandable variables.
120
  void Clear();
121
};
122
123
struct VSCode {
124
  std::string debug_adaptor_path;
125
  InputStream input;
126
  OutputStream output;
127
  lldb::SBDebugger debugger;
128
  lldb::SBTarget target;
129
  Variables variables;
130
  lldb::SBBroadcaster broadcaster;
131
  std::thread event_thread;
132
  std::thread progress_event_thread;
133
  std::unique_ptr<std::ofstream> log;
134
  llvm::DenseMap<lldb::addr_t, int64_t> addr_to_source_ref;
135
  llvm::DenseMap<int64_t, SourceReference> source_map;
136
  llvm::StringMap<SourceBreakpointMap> source_breakpoints;
137
  FunctionBreakpointMap function_breakpoints;
138
  std::vector<ExceptionBreakpoint> exception_breakpoints;
139
  std::vector<std::string> init_commands;
140
  std::vector<std::string> pre_run_commands;
141
  std::vector<std::string> exit_commands;
142
  std::vector<std::string> stop_commands;
143
  std::vector<std::string> terminate_commands;
144
  lldb::tid_t focus_tid;
145
  bool sent_terminated_event;
146
  bool stop_at_entry;
147
  bool is_attach;
148
  uint32_t reverse_request_seq;
149
  std::map<std::string, RequestCallback> request_handlers;
150
  bool waiting_for_run_in_terminal;
151
  ProgressEventReporter progress_event_reporter;
152
  // Keep track of the last stop thread index IDs as threads won't go away
153
  // unless we send a "thread" event to indicate the thread exited.
154
  llvm::DenseSet<lldb::tid_t> thread_ids;
155
  VSCode();
156
  ~VSCode();
157
  VSCode(const VSCode &rhs) = delete;
158
  void operator=(const VSCode &rhs) = delete;
159
  int64_t GetLineForPC(int64_t sourceReference, lldb::addr_t pc) const;
160
  ExceptionBreakpoint *GetExceptionBreakpoint(const std::string &filter);
161
  ExceptionBreakpoint *GetExceptionBreakpoint(const lldb::break_id_t bp_id);
162
163
  // Serialize the JSON value into a string and send the JSON packet to
164
  // the "out" stream.
165
  void SendJSON(const llvm::json::Value &json);
166
167
  std::string ReadJSON();
168
169
  void SendOutput(OutputType o, const llvm::StringRef output);
170
171
  void SendProgressEvent(uint64_t progress_id, const char *message,
172
                         uint64_t completed, uint64_t total);
173
174
  void __attribute__((format(printf, 3, 4)))
175
  SendFormattedOutput(OutputType o, const char *format, ...);
176
177
  static int64_t GetNextSourceReference();
178
179
  ExceptionBreakpoint *GetExceptionBPFromStopReason(lldb::SBThread &thread);
180
181
  lldb::SBThread GetLLDBThread(const llvm::json::Object &arguments);
182
183
  lldb::SBFrame GetLLDBFrame(const llvm::json::Object &arguments);
184
185
  llvm::json::Value CreateTopLevelScopes();
186
187
  void RunLLDBCommands(llvm::StringRef prefix,
188
                       const std::vector<std::string> &commands);
189
190
  void RunInitCommands();
191
  void RunPreRunCommands();
192
  void RunStopCommands();
193
  void RunExitCommands();
194
  void RunTerminateCommands();
195
196
  /// Create a new SBTarget object from the given request arguments.
197
  /// \param[in] arguments
198
  ///     Launch configuration arguments.
199
  ///
200
  /// \param[out] error
201
  ///     An SBError object that will contain an error description if
202
  ///     function failed to create the target.
203
  ///
204
  /// \return
205
  ///     An SBTarget object.
206
  lldb::SBTarget CreateTargetFromArguments(const llvm::json::Object &arguments,
207
                                           lldb::SBError &error);
208
209
  /// Set given target object as a current target for lldb-vscode and start
210
  /// listeing for its breakpoint events.
211
  void SetTarget(const lldb::SBTarget target);
212
213
  const std::map<std::string, RequestCallback> &GetRequestHandlers();
214
215
  PacketStatus GetNextObject(llvm::json::Object &object);
216
  bool HandleObject(const llvm::json::Object &object);
217
218
  /// Send a Debug Adapter Protocol reverse request to the IDE
219
  ///
220
  /// \param[in] request
221
  ///   The payload of the request to send.
222
  ///
223
  /// \param[out] response
224
  ///   The response of the IDE. It might be undefined if there was an error.
225
  ///
226
  /// \return
227
  ///   A \a PacketStatus object indicating the sucess or failure of the
228
  ///   request.
229
  PacketStatus SendReverseRequest(llvm::json::Object request,
230
                                  llvm::json::Object &response);
231
232
  /// Registers a callback handler for a Debug Adapter Protocol request
233
  ///
234
  /// \param[in] request
235
  ///     The name of the request following the Debug Adapter Protocol
236
  ///     specification.
237
  ///
238
  /// \param[in] callback
239
  ///     The callback to execute when the given request is triggered by the
240
  ///     IDE.
241
  void RegisterRequestCallback(std::string request, RequestCallback callback);
242
243
  /// Debuggee will continue from stopped state.
244
0
  void WillContinue() { variables.Clear(); }
245
246
private:
247
  // Send the JSON in "json_str" to the "out" stream. Correctly send the
248
  // "Content-Length:" field followed by the length, followed by the raw
249
  // JSON bytes.
250
  void SendJSON(const std::string &json_str);
251
};
252
253
extern VSCode g_vsc;
254
255
} // namespace lldb_vscode
256
257
#endif