101263c6cSJonas Devlieghere //===-- DAP.h ---------------------------------------------------*- C++ -*-===// 201263c6cSJonas Devlieghere // 301263c6cSJonas Devlieghere // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 401263c6cSJonas Devlieghere // See https://llvm.org/LICENSE.txt for license information. 501263c6cSJonas Devlieghere // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 601263c6cSJonas Devlieghere // 701263c6cSJonas Devlieghere //===----------------------------------------------------------------------===// 801263c6cSJonas Devlieghere 901263c6cSJonas Devlieghere #ifndef LLDB_TOOLS_LLDB_DAP_DAP_H 1001263c6cSJonas Devlieghere #define LLDB_TOOLS_LLDB_DAP_DAP_H 1101263c6cSJonas Devlieghere 12*873426beSJohn Harrison #include "DAPForward.h" 1381898ac0SBenjamin Kramer #include "ExceptionBreakpoint.h" 1481898ac0SBenjamin Kramer #include "FunctionBreakpoint.h" 1581898ac0SBenjamin Kramer #include "IOStream.h" 1681898ac0SBenjamin Kramer #include "InstructionBreakpoint.h" 17*873426beSJohn Harrison #include "OutputRedirector.h" 1881898ac0SBenjamin Kramer #include "ProgressEvent.h" 1981898ac0SBenjamin Kramer #include "SourceBreakpoint.h" 20*873426beSJohn Harrison #include "lldb/API/SBBroadcaster.h" 21*873426beSJohn Harrison #include "lldb/API/SBCommandInterpreter.h" 22*873426beSJohn Harrison #include "lldb/API/SBDebugger.h" 23*873426beSJohn Harrison #include "lldb/API/SBError.h" 24*873426beSJohn Harrison #include "lldb/API/SBFile.h" 25*873426beSJohn Harrison #include "lldb/API/SBFormat.h" 26*873426beSJohn Harrison #include "lldb/API/SBFrame.h" 27*873426beSJohn Harrison #include "lldb/API/SBTarget.h" 28*873426beSJohn Harrison #include "lldb/API/SBThread.h" 29*873426beSJohn Harrison #include "lldb/API/SBValue.h" 30*873426beSJohn Harrison #include "lldb/API/SBValueList.h" 31*873426beSJohn Harrison #include "lldb/lldb-types.h" 32*873426beSJohn Harrison #include "llvm/ADT/DenseMap.h" 33*873426beSJohn Harrison #include "llvm/ADT/DenseSet.h" 34*873426beSJohn Harrison #include "llvm/ADT/StringMap.h" 35*873426beSJohn Harrison #include "llvm/ADT/StringRef.h" 36*873426beSJohn Harrison #include "llvm/Support/Error.h" 37*873426beSJohn Harrison #include "llvm/Support/JSON.h" 38*873426beSJohn Harrison #include "llvm/Support/Threading.h" 39*873426beSJohn Harrison #include <map> 40*873426beSJohn Harrison #include <mutex> 41*873426beSJohn Harrison #include <optional> 42*873426beSJohn Harrison #include <thread> 43*873426beSJohn Harrison #include <vector> 4401263c6cSJonas Devlieghere 4501263c6cSJonas Devlieghere #define VARREF_LOCALS (int64_t)1 4601263c6cSJonas Devlieghere #define VARREF_GLOBALS (int64_t)2 4701263c6cSJonas Devlieghere #define VARREF_REGS (int64_t)3 4801263c6cSJonas Devlieghere #define VARREF_FIRST_VAR_IDX (int64_t)4 4901263c6cSJonas Devlieghere #define NO_TYPENAME "<no-type>" 5001263c6cSJonas Devlieghere 5101263c6cSJonas Devlieghere namespace lldb_dap { 5201263c6cSJonas Devlieghere 53ceeb08b9SMichael Buch typedef llvm::DenseMap<uint32_t, SourceBreakpoint> SourceBreakpointMap; 5401263c6cSJonas Devlieghere typedef llvm::StringMap<FunctionBreakpoint> FunctionBreakpointMap; 5589c27d6bSSanthosh Kumar Ellendula typedef llvm::DenseMap<lldb::addr_t, InstructionBreakpoint> 5689c27d6bSSanthosh Kumar Ellendula InstructionBreakpointMap; 5730ca06c4SJohn Harrison 5801263c6cSJonas Devlieghere enum class OutputType { Console, Stdout, Stderr, Telemetry }; 5901263c6cSJonas Devlieghere 6030ca06c4SJohn Harrison /// Buffer size for handling output events. 6130ca06c4SJohn Harrison constexpr uint64_t OutputBufferSize = (1u << 12); 6230ca06c4SJohn Harrison 6301263c6cSJonas Devlieghere enum DAPBroadcasterBits { 6401263c6cSJonas Devlieghere eBroadcastBitStopEventThread = 1u << 0, 6501263c6cSJonas Devlieghere eBroadcastBitStopProgressThread = 1u << 1 6601263c6cSJonas Devlieghere }; 6701263c6cSJonas Devlieghere 683121f752SJohn Harrison typedef void (*RequestCallback)(DAP &dap, const llvm::json::Object &command); 6901263c6cSJonas Devlieghere typedef void (*ResponseCallback)(llvm::Expected<llvm::json::Value> value); 7001263c6cSJonas Devlieghere 7101263c6cSJonas Devlieghere enum class PacketStatus { 7201263c6cSJonas Devlieghere Success = 0, 7301263c6cSJonas Devlieghere EndOfFile, 7401263c6cSJonas Devlieghere JSONMalformed, 7501263c6cSJonas Devlieghere JSONNotObject 7601263c6cSJonas Devlieghere }; 7701263c6cSJonas Devlieghere 7801263c6cSJonas Devlieghere enum class ReplMode { Variable = 0, Command, Auto }; 7901263c6cSJonas Devlieghere 8001263c6cSJonas Devlieghere struct Variables { 8101263c6cSJonas Devlieghere /// Variable_reference start index of permanent expandable variable. 8201263c6cSJonas Devlieghere static constexpr int64_t PermanentVariableStartIndex = (1ll << 32); 8301263c6cSJonas Devlieghere 8401263c6cSJonas Devlieghere lldb::SBValueList locals; 8501263c6cSJonas Devlieghere lldb::SBValueList globals; 8601263c6cSJonas Devlieghere lldb::SBValueList registers; 8701263c6cSJonas Devlieghere 8801263c6cSJonas Devlieghere int64_t next_temporary_var_ref{VARREF_FIRST_VAR_IDX}; 8901263c6cSJonas Devlieghere int64_t next_permanent_var_ref{PermanentVariableStartIndex}; 9001263c6cSJonas Devlieghere 910cc2cd78SAdrian Vogelsgesang /// Variables that are alive in this stop state. 9201263c6cSJonas Devlieghere /// Will be cleared when debuggee resumes. 930cc2cd78SAdrian Vogelsgesang llvm::DenseMap<int64_t, lldb::SBValue> referenced_variables; 940cc2cd78SAdrian Vogelsgesang /// Variables that persist across entire debug session. 9501263c6cSJonas Devlieghere /// These are the variables evaluated from debug console REPL. 960cc2cd78SAdrian Vogelsgesang llvm::DenseMap<int64_t, lldb::SBValue> referenced_permanent_variables; 9701263c6cSJonas Devlieghere 9801263c6cSJonas Devlieghere /// Check if \p var_ref points to a variable that should persist for the 9901263c6cSJonas Devlieghere /// entire duration of the debug session, e.g. repl expandable variables 10001263c6cSJonas Devlieghere static bool IsPermanentVariableReference(int64_t var_ref); 10101263c6cSJonas Devlieghere 10201263c6cSJonas Devlieghere /// \return a new variableReference. 10301263c6cSJonas Devlieghere /// Specify is_permanent as true for variable that should persist entire 10401263c6cSJonas Devlieghere /// debug session. 10501263c6cSJonas Devlieghere int64_t GetNewVariableReference(bool is_permanent); 10601263c6cSJonas Devlieghere 10701263c6cSJonas Devlieghere /// \return the expandable variable corresponding with variableReference 10801263c6cSJonas Devlieghere /// value of \p value. 10901263c6cSJonas Devlieghere /// If \p var_ref is invalid an empty SBValue is returned. 11001263c6cSJonas Devlieghere lldb::SBValue GetVariable(int64_t var_ref) const; 11101263c6cSJonas Devlieghere 11201263c6cSJonas Devlieghere /// Insert a new \p variable. 11301263c6cSJonas Devlieghere /// \return variableReference assigned to this expandable variable. 1140cc2cd78SAdrian Vogelsgesang int64_t InsertVariable(lldb::SBValue variable, bool is_permanent); 11501263c6cSJonas Devlieghere 11601263c6cSJonas Devlieghere /// Clear all scope variables and non-permanent expandable variables. 11701263c6cSJonas Devlieghere void Clear(); 11801263c6cSJonas Devlieghere }; 11901263c6cSJonas Devlieghere 12001263c6cSJonas Devlieghere struct StartDebuggingRequestHandler : public lldb::SBCommandPluginInterface { 121a6d299ddSJohn Harrison DAP &dap; 122a6d299ddSJohn Harrison explicit StartDebuggingRequestHandler(DAP &d) : dap(d) {}; 12301263c6cSJonas Devlieghere bool DoExecute(lldb::SBDebugger debugger, char **command, 12401263c6cSJonas Devlieghere lldb::SBCommandReturnObject &result) override; 12501263c6cSJonas Devlieghere }; 12601263c6cSJonas Devlieghere 12701263c6cSJonas Devlieghere struct ReplModeRequestHandler : public lldb::SBCommandPluginInterface { 128a6d299ddSJohn Harrison DAP &dap; 129a6d299ddSJohn Harrison explicit ReplModeRequestHandler(DAP &d) : dap(d) {}; 13001263c6cSJonas Devlieghere bool DoExecute(lldb::SBDebugger debugger, char **command, 13101263c6cSJonas Devlieghere lldb::SBCommandReturnObject &result) override; 13201263c6cSJonas Devlieghere }; 13301263c6cSJonas Devlieghere 134c5c11f34SJohn Harrison struct SendEventRequestHandler : public lldb::SBCommandPluginInterface { 135a6d299ddSJohn Harrison DAP &dap; 136a6d299ddSJohn Harrison explicit SendEventRequestHandler(DAP &d) : dap(d) {}; 137c5c11f34SJohn Harrison bool DoExecute(lldb::SBDebugger debugger, char **command, 138c5c11f34SJohn Harrison lldb::SBCommandReturnObject &result) override; 139c5c11f34SJohn Harrison }; 140c5c11f34SJohn Harrison 14101263c6cSJonas Devlieghere struct DAP { 1423121f752SJohn Harrison llvm::StringRef debug_adaptor_path; 143*873426beSJohn Harrison std::ofstream *log; 14401263c6cSJonas Devlieghere InputStream input; 14501263c6cSJonas Devlieghere OutputStream output; 146*873426beSJohn Harrison lldb::SBFile in; 147*873426beSJohn Harrison OutputRedirector out; 148*873426beSJohn Harrison OutputRedirector err; 14901263c6cSJonas Devlieghere lldb::SBDebugger debugger; 15001263c6cSJonas Devlieghere lldb::SBTarget target; 15101263c6cSJonas Devlieghere Variables variables; 15201263c6cSJonas Devlieghere lldb::SBBroadcaster broadcaster; 15301263c6cSJonas Devlieghere std::thread event_thread; 15401263c6cSJonas Devlieghere std::thread progress_event_thread; 15501263c6cSJonas Devlieghere llvm::StringMap<SourceBreakpointMap> source_breakpoints; 15601263c6cSJonas Devlieghere FunctionBreakpointMap function_breakpoints; 15789c27d6bSSanthosh Kumar Ellendula InstructionBreakpointMap instruction_breakpoints; 158e951bd0fSVy Nguyen std::optional<std::vector<ExceptionBreakpoint>> exception_breakpoints; 159e951bd0fSVy Nguyen llvm::once_flag init_exception_breakpoints_flag; 160541f22eeSWalter Erquinigo std::vector<std::string> pre_init_commands; 16101263c6cSJonas Devlieghere std::vector<std::string> init_commands; 16201263c6cSJonas Devlieghere std::vector<std::string> pre_run_commands; 163aa207674SWalter Erquinigo std::vector<std::string> post_run_commands; 16401263c6cSJonas Devlieghere std::vector<std::string> exit_commands; 16501263c6cSJonas Devlieghere std::vector<std::string> stop_commands; 16601263c6cSJonas Devlieghere std::vector<std::string> terminate_commands; 1672f2e31c3Sjeffreytan81 // Map step in target id to list of function targets that user can choose. 1682f2e31c3Sjeffreytan81 llvm::DenseMap<lldb::addr_t, std::string> step_in_targets; 16901263c6cSJonas Devlieghere // A copy of the last LaunchRequest or AttachRequest so we can reuse its 17001263c6cSJonas Devlieghere // arguments if we get a RestartRequest. 17101263c6cSJonas Devlieghere std::optional<llvm::json::Object> last_launch_or_attach_request; 17201263c6cSJonas Devlieghere lldb::tid_t focus_tid; 173871f4839SPavel Labath bool disconnecting = false; 17477ae18b0SPavel Labath llvm::once_flag terminated_event_flag; 17501263c6cSJonas Devlieghere bool stop_at_entry; 17601263c6cSJonas Devlieghere bool is_attach; 17701263c6cSJonas Devlieghere bool enable_auto_variable_summaries; 17801263c6cSJonas Devlieghere bool enable_synthetic_child_debugging; 17919ecdedcSAdrian Vogelsgesang bool display_extended_backtrace; 18001263c6cSJonas Devlieghere // The process event thread normally responds to process exited events by 18101263c6cSJonas Devlieghere // shutting down the entire adapter. When we're restarting, we keep the id of 18201263c6cSJonas Devlieghere // the old process here so we can detect this case and keep running. 18301263c6cSJonas Devlieghere lldb::pid_t restarting_process_id; 18401263c6cSJonas Devlieghere bool configuration_done_sent; 185c3c424d2SKazu Hirata std::map<std::string, RequestCallback, std::less<>> request_handlers; 18601263c6cSJonas Devlieghere bool waiting_for_run_in_terminal; 18701263c6cSJonas Devlieghere ProgressEventReporter progress_event_reporter; 18801263c6cSJonas Devlieghere // Keep track of the last stop thread index IDs as threads won't go away 18901263c6cSJonas Devlieghere // unless we send a "thread" event to indicate the thread exited. 19001263c6cSJonas Devlieghere llvm::DenseSet<lldb::tid_t> thread_ids; 19101263c6cSJonas Devlieghere uint32_t reverse_request_seq; 19201263c6cSJonas Devlieghere std::mutex call_mutex; 19301263c6cSJonas Devlieghere std::map<int /* request_seq */, ResponseCallback /* reply handler */> 19401263c6cSJonas Devlieghere inflight_reverse_requests; 19501263c6cSJonas Devlieghere ReplMode repl_mode; 19610664813SWalter Erquinigo std::string command_escape_prefix = "`"; 197d9ec4b24SWalter Erquinigo lldb::SBFormat frame_format; 1981654d7dcSWalter Erquinigo lldb::SBFormat thread_format; 1992011cbcdScmtice // This is used to allow request_evaluate to handle empty expressions 2002011cbcdScmtice // (ie the user pressed 'return' and expects the previous expression to 2012011cbcdScmtice // repeat). If the previous expression was a command, this string will be 2022011cbcdScmtice // empty; if the previous expression was a variable expression, this string 2032011cbcdScmtice // will contain that expression. 2042011cbcdScmtice std::string last_nonempty_var_expression; 20501263c6cSJonas Devlieghere 206*873426beSJohn Harrison DAP(llvm::StringRef path, std::ofstream *log, ReplMode repl_mode, 207*873426beSJohn Harrison StreamDescriptor input, StreamDescriptor output); 20801263c6cSJonas Devlieghere ~DAP(); 20901263c6cSJonas Devlieghere DAP(const DAP &rhs) = delete; 21001263c6cSJonas Devlieghere void operator=(const DAP &rhs) = delete; 21101263c6cSJonas Devlieghere ExceptionBreakpoint *GetExceptionBreakpoint(const std::string &filter); 21201263c6cSJonas Devlieghere ExceptionBreakpoint *GetExceptionBreakpoint(const lldb::break_id_t bp_id); 21301263c6cSJonas Devlieghere 214*873426beSJohn Harrison /// Redirect stdout and stderr fo the IDE's console output. 215*873426beSJohn Harrison /// 216*873426beSJohn Harrison /// Errors in this operation will be printed to the log file and the IDE's 217*873426beSJohn Harrison /// console output as well. 218*873426beSJohn Harrison llvm::Error ConfigureIO(std::FILE *overrideOut, std::FILE *overrideErr); 219*873426beSJohn Harrison 220*873426beSJohn Harrison /// Stop the redirected IO threads and associated pipes. 221*873426beSJohn Harrison void StopIO(); 222*873426beSJohn Harrison 22301263c6cSJonas Devlieghere // Serialize the JSON value into a string and send the JSON packet to 22401263c6cSJonas Devlieghere // the "out" stream. 22501263c6cSJonas Devlieghere void SendJSON(const llvm::json::Value &json); 22601263c6cSJonas Devlieghere 22701263c6cSJonas Devlieghere std::string ReadJSON(); 22801263c6cSJonas Devlieghere 22901263c6cSJonas Devlieghere void SendOutput(OutputType o, const llvm::StringRef output); 23001263c6cSJonas Devlieghere 23101263c6cSJonas Devlieghere void SendProgressEvent(uint64_t progress_id, const char *message, 23201263c6cSJonas Devlieghere uint64_t completed, uint64_t total); 23301263c6cSJonas Devlieghere 23401263c6cSJonas Devlieghere void __attribute__((format(printf, 3, 4))) 23501263c6cSJonas Devlieghere SendFormattedOutput(OutputType o, const char *format, ...); 23601263c6cSJonas Devlieghere 23701263c6cSJonas Devlieghere static int64_t GetNextSourceReference(); 23801263c6cSJonas Devlieghere 23901263c6cSJonas Devlieghere ExceptionBreakpoint *GetExceptionBPFromStopReason(lldb::SBThread &thread); 24001263c6cSJonas Devlieghere 24101263c6cSJonas Devlieghere lldb::SBThread GetLLDBThread(const llvm::json::Object &arguments); 24201263c6cSJonas Devlieghere 24301263c6cSJonas Devlieghere lldb::SBFrame GetLLDBFrame(const llvm::json::Object &arguments); 24401263c6cSJonas Devlieghere 24501263c6cSJonas Devlieghere llvm::json::Value CreateTopLevelScopes(); 24601263c6cSJonas Devlieghere 247e951bd0fSVy Nguyen void PopulateExceptionBreakpoints(); 248e951bd0fSVy Nguyen 2494ea1994aSJohn Harrison /// Attempt to determine if an expression is a variable expression or 250a5876befSAdrian Vogelsgesang /// lldb command using a heuristic based on the first term of the 2514ea1994aSJohn Harrison /// expression. 252a5876befSAdrian Vogelsgesang /// 253a5876befSAdrian Vogelsgesang /// \param[in] frame 254a5876befSAdrian Vogelsgesang /// The frame, used as context to detect local variable names 255a5876befSAdrian Vogelsgesang /// \param[inout] expression 256a5876befSAdrian Vogelsgesang /// The expression string. Might be modified by this function to 257a5876befSAdrian Vogelsgesang /// remove the leading escape character. 258a5876befSAdrian Vogelsgesang /// \param[in] partial_expression 259a5876befSAdrian Vogelsgesang /// Whether the provided `expression` is only a prefix of the 260a5876befSAdrian Vogelsgesang /// final expression. If `true`, this function might return 261a5876befSAdrian Vogelsgesang /// `ReplMode::Auto` to indicate that the expression could be 262a5876befSAdrian Vogelsgesang /// either an expression or a statement, depending on the rest of 263a5876befSAdrian Vogelsgesang /// the expression. 264a5876befSAdrian Vogelsgesang /// \return the expression mode 265a5876befSAdrian Vogelsgesang ReplMode DetectReplMode(lldb::SBFrame frame, std::string &expression, 266a5876befSAdrian Vogelsgesang bool partial_expression); 26701263c6cSJonas Devlieghere 268aa207674SWalter Erquinigo /// \return 269aa207674SWalter Erquinigo /// \b false if a fatal error was found while executing these commands, 270aa207674SWalter Erquinigo /// according to the rules of \a LLDBUtils::RunLLDBCommands. 271aa207674SWalter Erquinigo bool RunLLDBCommands(llvm::StringRef prefix, 272aa207674SWalter Erquinigo llvm::ArrayRef<std::string> commands); 27301263c6cSJonas Devlieghere 274aa207674SWalter Erquinigo llvm::Error RunAttachCommands(llvm::ArrayRef<std::string> attach_commands); 275aa207674SWalter Erquinigo llvm::Error RunLaunchCommands(llvm::ArrayRef<std::string> launch_commands); 276541f22eeSWalter Erquinigo llvm::Error RunPreInitCommands(); 277aa207674SWalter Erquinigo llvm::Error RunInitCommands(); 278aa207674SWalter Erquinigo llvm::Error RunPreRunCommands(); 279aa207674SWalter Erquinigo void RunPostRunCommands(); 28001263c6cSJonas Devlieghere void RunStopCommands(); 28101263c6cSJonas Devlieghere void RunExitCommands(); 28201263c6cSJonas Devlieghere void RunTerminateCommands(); 28301263c6cSJonas Devlieghere 28401263c6cSJonas Devlieghere /// Create a new SBTarget object from the given request arguments. 28501263c6cSJonas Devlieghere /// \param[in] arguments 28601263c6cSJonas Devlieghere /// Launch configuration arguments. 28701263c6cSJonas Devlieghere /// 28801263c6cSJonas Devlieghere /// \param[out] error 28901263c6cSJonas Devlieghere /// An SBError object that will contain an error description if 29001263c6cSJonas Devlieghere /// function failed to create the target. 29101263c6cSJonas Devlieghere /// 29201263c6cSJonas Devlieghere /// \return 29301263c6cSJonas Devlieghere /// An SBTarget object. 29401263c6cSJonas Devlieghere lldb::SBTarget CreateTargetFromArguments(const llvm::json::Object &arguments, 29501263c6cSJonas Devlieghere lldb::SBError &error); 29601263c6cSJonas Devlieghere 29701263c6cSJonas Devlieghere /// Set given target object as a current target for lldb-dap and start 29801263c6cSJonas Devlieghere /// listeing for its breakpoint events. 29901263c6cSJonas Devlieghere void SetTarget(const lldb::SBTarget target); 30001263c6cSJonas Devlieghere 30101263c6cSJonas Devlieghere const std::map<std::string, RequestCallback> &GetRequestHandlers(); 30201263c6cSJonas Devlieghere 30301263c6cSJonas Devlieghere PacketStatus GetNextObject(llvm::json::Object &object); 30401263c6cSJonas Devlieghere bool HandleObject(const llvm::json::Object &object); 30501263c6cSJonas Devlieghere 30601263c6cSJonas Devlieghere llvm::Error Loop(); 30701263c6cSJonas Devlieghere 30801263c6cSJonas Devlieghere /// Send a Debug Adapter Protocol reverse request to the IDE. 30901263c6cSJonas Devlieghere /// 31001263c6cSJonas Devlieghere /// \param[in] command 31101263c6cSJonas Devlieghere /// The reverse request command. 31201263c6cSJonas Devlieghere /// 31301263c6cSJonas Devlieghere /// \param[in] arguments 31401263c6cSJonas Devlieghere /// The reverse request arguements. 31501263c6cSJonas Devlieghere /// 31601263c6cSJonas Devlieghere /// \param[in] callback 31701263c6cSJonas Devlieghere /// A callback to execute when the response arrives. 31801263c6cSJonas Devlieghere void SendReverseRequest(llvm::StringRef command, llvm::json::Value arguments, 31901263c6cSJonas Devlieghere ResponseCallback callback); 32001263c6cSJonas Devlieghere 32101263c6cSJonas Devlieghere /// Registers a callback handler for a Debug Adapter Protocol request 32201263c6cSJonas Devlieghere /// 32301263c6cSJonas Devlieghere /// \param[in] request 32401263c6cSJonas Devlieghere /// The name of the request following the Debug Adapter Protocol 32501263c6cSJonas Devlieghere /// specification. 32601263c6cSJonas Devlieghere /// 32701263c6cSJonas Devlieghere /// \param[in] callback 32801263c6cSJonas Devlieghere /// The callback to execute when the given request is triggered by the 32901263c6cSJonas Devlieghere /// IDE. 33001263c6cSJonas Devlieghere void RegisterRequestCallback(std::string request, RequestCallback callback); 33101263c6cSJonas Devlieghere 33201263c6cSJonas Devlieghere /// Debuggee will continue from stopped state. 33301263c6cSJonas Devlieghere void WillContinue() { variables.Clear(); } 33401263c6cSJonas Devlieghere 33501263c6cSJonas Devlieghere /// Poll the process to wait for it to reach the eStateStopped state. 33601263c6cSJonas Devlieghere /// 33701263c6cSJonas Devlieghere /// Wait for the process hit a stopped state. When running a launch with 33801263c6cSJonas Devlieghere /// "launchCommands", or attach with "attachCommands", the calls might take 33901263c6cSJonas Devlieghere /// some time to stop at the entry point since the command is asynchronous. We 34001263c6cSJonas Devlieghere /// need to sync up with the process and make sure it is stopped before we 34101263c6cSJonas Devlieghere /// proceed to do anything else as we will soon be asked to set breakpoints 34201263c6cSJonas Devlieghere /// and other things that require the process to be stopped. We must use 34301263c6cSJonas Devlieghere /// polling because "attachCommands" or "launchCommands" may or may not send 34401263c6cSJonas Devlieghere /// process state change events depending on if the user modifies the async 34501263c6cSJonas Devlieghere /// setting in the debugger. Since both "attachCommands" and "launchCommands" 34601263c6cSJonas Devlieghere /// could end up using any combination of LLDB commands, we must ensure we can 34701263c6cSJonas Devlieghere /// also catch when the process stops, so we must poll the process to make 34801263c6cSJonas Devlieghere /// sure we handle all cases. 34901263c6cSJonas Devlieghere /// 35001263c6cSJonas Devlieghere /// \param[in] seconds 35101263c6cSJonas Devlieghere /// The number of seconds to poll the process to wait until it is stopped. 35201263c6cSJonas Devlieghere /// 35301263c6cSJonas Devlieghere /// \return Error if waiting for the process fails, no error if succeeds. 35401263c6cSJonas Devlieghere lldb::SBError WaitForProcessToStop(uint32_t seconds); 35501263c6cSJonas Devlieghere 356d9ec4b24SWalter Erquinigo void SetFrameFormat(llvm::StringRef format); 357d9ec4b24SWalter Erquinigo 3581654d7dcSWalter Erquinigo void SetThreadFormat(llvm::StringRef format); 3591654d7dcSWalter Erquinigo 36089c27d6bSSanthosh Kumar Ellendula InstructionBreakpoint *GetInstructionBreakpoint(const lldb::break_id_t bp_id); 36189c27d6bSSanthosh Kumar Ellendula 36289c27d6bSSanthosh Kumar Ellendula InstructionBreakpoint *GetInstructionBPFromStopReason(lldb::SBThread &thread); 36389c27d6bSSanthosh Kumar Ellendula 36401263c6cSJonas Devlieghere private: 36501263c6cSJonas Devlieghere // Send the JSON in "json_str" to the "out" stream. Correctly send the 36601263c6cSJonas Devlieghere // "Content-Length:" field followed by the length, followed by the raw 36701263c6cSJonas Devlieghere // JSON bytes. 36801263c6cSJonas Devlieghere void SendJSON(const std::string &json_str); 36901263c6cSJonas Devlieghere }; 37001263c6cSJonas Devlieghere 37101263c6cSJonas Devlieghere } // namespace lldb_dap 37201263c6cSJonas Devlieghere 37301263c6cSJonas Devlieghere #endif 374