//===-- DAP.cpp -------------------------------------------------*- C++ -*-===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// #include <chrono> #include <cstdarg> #include <fstream> #include <mutex> #include <sstream> #include "DAP.h" #include "LLDBUtils.h" #include "lldb/API/SBCommandInterpreter.h" #include "llvm/ADT/StringExtras.h" #include "llvm/Support/FormatVariadic.h" #if defined(_WIN32) #define NOMINMAX #include <fcntl.h> #include <io.h> #include <windows.h> #endif usingnamespacelldb_dap; namespace lldb_dap { DAP g_dap; DAP::DAP() : … { … } DAP::~DAP() = default; /// Return string with first character capitalized. static std::string capitalize(llvm::StringRef str) { … } void DAP::PopulateExceptionBreakpoints() { … } ExceptionBreakpoint *DAP::GetExceptionBreakpoint(const std::string &filter) { … } ExceptionBreakpoint *DAP::GetExceptionBreakpoint(const lldb::break_id_t bp_id) { … } // Send the JSON in "json_str" to the "out" stream. Correctly send the // "Content-Length:" field followed by the length, followed by the raw // JSON bytes. void DAP::SendJSON(const std::string &json_str) { … } // Serialize the JSON value into a string and send the JSON packet to // the "out" stream. void DAP::SendJSON(const llvm::json::Value &json) { … } // Read a JSON packet from the "in" stream. std::string DAP::ReadJSON() { … } // "OutputEvent": { // "allOf": [ { "$ref": "#/definitions/Event" }, { // "type": "object", // "description": "Event message for 'output' event type. The event // indicates that the target has produced some output.", // "properties": { // "event": { // "type": "string", // "enum": [ "output" ] // }, // "body": { // "type": "object", // "properties": { // "category": { // "type": "string", // "description": "The output category. If not specified, // 'console' is assumed.", // "_enum": [ "console", "stdout", "stderr", "telemetry" ] // }, // "output": { // "type": "string", // "description": "The output to report." // }, // "variablesReference": { // "type": "number", // "description": "If an attribute 'variablesReference' exists // and its value is > 0, the output contains // objects which can be retrieved by passing // variablesReference to the VariablesRequest." // }, // "source": { // "$ref": "#/definitions/Source", // "description": "An optional source location where the output // was produced." // }, // "line": { // "type": "integer", // "description": "An optional source location line where the // output was produced." // }, // "column": { // "type": "integer", // "description": "An optional source location column where the // output was produced." // }, // "data": { // "type":["array","boolean","integer","null","number","object", // "string"], // "description": "Optional data to report. For the 'telemetry' // category the data will be sent to telemetry, for // the other categories the data is shown in JSON // format." // } // }, // "required": ["output"] // } // }, // "required": [ "event", "body" ] // }] // } void DAP::SendOutput(OutputType o, const llvm::StringRef output) { … } // interface ProgressStartEvent extends Event { // event: 'progressStart'; // // body: { // /** // * An ID that must be used in subsequent 'progressUpdate' and // 'progressEnd' // * events to make them refer to the same progress reporting. // * IDs must be unique within a debug session. // */ // progressId: string; // // /** // * Mandatory (short) title of the progress reporting. Shown in the UI to // * describe the long running operation. // */ // title: string; // // /** // * The request ID that this progress report is related to. If specified a // * debug adapter is expected to emit // * progress events for the long running request until the request has // been // * either completed or cancelled. // * If the request ID is omitted, the progress report is assumed to be // * related to some general activity of the debug adapter. // */ // requestId?: number; // // /** // * If true, the request that reports progress may be canceled with a // * 'cancel' request. // * So this property basically controls whether the client should use UX // that // * supports cancellation. // * Clients that don't support cancellation are allowed to ignore the // * setting. // */ // cancellable?: boolean; // // /** // * Optional, more detailed progress message. // */ // message?: string; // // /** // * Optional progress percentage to display (value range: 0 to 100). If // * omitted no percentage will be shown. // */ // percentage?: number; // }; // } // // interface ProgressUpdateEvent extends Event { // event: 'progressUpdate'; // // body: { // /** // * The ID that was introduced in the initial 'progressStart' event. // */ // progressId: string; // // /** // * Optional, more detailed progress message. If omitted, the previous // * message (if any) is used. // */ // message?: string; // // /** // * Optional progress percentage to display (value range: 0 to 100). If // * omitted no percentage will be shown. // */ // percentage?: number; // }; // } // // interface ProgressEndEvent extends Event { // event: 'progressEnd'; // // body: { // /** // * The ID that was introduced in the initial 'ProgressStartEvent'. // */ // progressId: string; // // /** // * Optional, more detailed progress message. If omitted, the previous // * message (if any) is used. // */ // message?: string; // }; // } void DAP::SendProgressEvent(uint64_t progress_id, const char *message, uint64_t completed, uint64_t total) { … } void __attribute__((format(printf, 3, 4))) DAP::SendFormattedOutput(OutputType o, const char *format, ...) { … } ExceptionBreakpoint *DAP::GetExceptionBPFromStopReason(lldb::SBThread &thread) { … } lldb::SBThread DAP::GetLLDBThread(const llvm::json::Object &arguments) { … } lldb::SBFrame DAP::GetLLDBFrame(const llvm::json::Object &arguments) { … } llvm::json::Value DAP::CreateTopLevelScopes() { … } ExpressionContext DAP::DetectExpressionContext(lldb::SBFrame frame, std::string &expression) { … } bool DAP::RunLLDBCommands(llvm::StringRef prefix, llvm::ArrayRef<std::string> commands) { … } static llvm::Error createRunLLDBCommandsErrorMessage(llvm::StringRef category) { … } llvm::Error DAP::RunAttachCommands(llvm::ArrayRef<std::string> attach_commands) { … } llvm::Error DAP::RunLaunchCommands(llvm::ArrayRef<std::string> launch_commands) { … } llvm::Error DAP::RunInitCommands() { … } llvm::Error DAP::RunPreInitCommands() { … } llvm::Error DAP::RunPreRunCommands() { … } void DAP::RunPostRunCommands() { … } void DAP::RunStopCommands() { … } void DAP::RunExitCommands() { … } void DAP::RunTerminateCommands() { … } lldb::SBTarget DAP::CreateTargetFromArguments(const llvm::json::Object &arguments, lldb::SBError &error) { … } void DAP::SetTarget(const lldb::SBTarget target) { … } PacketStatus DAP::GetNextObject(llvm::json::Object &object) { … } bool DAP::HandleObject(const llvm::json::Object &object) { … } llvm::Error DAP::Loop() { … } void DAP::SendReverseRequest(llvm::StringRef command, llvm::json::Value arguments, ResponseCallback callback) { … } void DAP::RegisterRequestCallback(std::string request, RequestCallback callback) { … } lldb::SBError DAP::WaitForProcessToStop(uint32_t seconds) { … } void Variables::Clear() { … } int64_t Variables::GetNewVariableReference(bool is_permanent) { … } bool Variables::IsPermanentVariableReference(int64_t var_ref) { … } lldb::SBValue Variables::GetVariable(int64_t var_ref) const { … } int64_t Variables::InsertVariable(lldb::SBValue variable, bool is_permanent) { … } bool StartDebuggingRequestHandler::DoExecute( lldb::SBDebugger debugger, char **command, lldb::SBCommandReturnObject &result) { … } bool ReplModeRequestHandler::DoExecute(lldb::SBDebugger debugger, char **command, lldb::SBCommandReturnObject &result) { … } void DAP::SetFrameFormat(llvm::StringRef format) { … } void DAP::SetThreadFormat(llvm::StringRef format) { … } InstructionBreakpoint * DAP::GetInstructionBreakpoint(const lldb::break_id_t bp_id) { … } InstructionBreakpoint * DAP::GetInstructionBPFromStopReason(lldb::SBThread &thread) { … } } // namespace lldb_dap