diff options
Diffstat (limited to 'lldb/tools/lldb-dap/Handler/ExceptionInfoRequestHandler.cpp')
| -rw-r--r-- | lldb/tools/lldb-dap/Handler/ExceptionInfoRequestHandler.cpp | 209 |
1 files changed, 58 insertions, 151 deletions
diff --git a/lldb/tools/lldb-dap/Handler/ExceptionInfoRequestHandler.cpp b/lldb/tools/lldb-dap/Handler/ExceptionInfoRequestHandler.cpp index c1c2adb32a51..ddf55e6fb382 100644 --- a/lldb/tools/lldb-dap/Handler/ExceptionInfoRequestHandler.cpp +++ b/lldb/tools/lldb-dap/Handler/ExceptionInfoRequestHandler.cpp @@ -7,168 +7,75 @@ //===----------------------------------------------------------------------===// #include "DAP.h" -#include "EventHelper.h" -#include "JSONUtils.h" +#include "DAPError.h" +#include "Protocol/ProtocolRequests.h" +#include "Protocol/ProtocolTypes.h" #include "RequestHandler.h" #include "lldb/API/SBStream.h" +using namespace lldb_dap::protocol; + namespace lldb_dap { -// "ExceptionInfoRequest": { -// "allOf": [ { "$ref": "#/definitions/Request" }, { -// "type": "object", -// "description": "Retrieves the details of the exception that -// caused this event to be raised. Clients should only call this request if -// the corresponding capability `supportsExceptionInfoRequest` is true.", -// "properties": { -// "command": { -// "type": "string", -// "enum": [ "exceptionInfo" ] -// }, -// "arguments": { -// "$ref": "#/definitions/ExceptionInfoArguments" -// } -// }, -// "required": [ "command", "arguments" ] -// }] -// }, -// "ExceptionInfoArguments": { -// "type": "object", -// "description": "Arguments for `exceptionInfo` request.", -// "properties": { -// "threadId": { -// "type": "integer", -// "description": "Thread for which exception information should be -// retrieved." -// } -// }, -// "required": [ "threadId" ] -// }, -// "ExceptionInfoResponse": { -// "allOf": [ { "$ref": "#/definitions/Response" }, { -// "type": "object", -// "description": "Response to `exceptionInfo` request.", -// "properties": { -// "body": { -// "type": "object", -// "properties": { -// "exceptionId": { -// "type": "string", -// "description": "ID of the exception that was thrown." -// }, -// "description": { -// "type": "string", -// "description": "Descriptive text for the exception." -// }, -// "breakMode": { -// "$ref": "#/definitions/ExceptionBreakMode", -// "description": "Mode that caused the exception notification to -// be raised." -// }, -// "details": { -// "$ref": "#/definitions/ExceptionDetails", -// "description": "Detailed information about the exception." -// } -// }, -// "required": [ "exceptionId", "breakMode" ] -// } -// }, -// "required": [ "body" ] -// }] -// } -// "ExceptionDetails": { -// "type": "object", -// "description": "Detailed information about an exception that has -// occurred.", "properties": { -// "message": { -// "type": "string", -// "description": "Message contained in the exception." -// }, -// "typeName": { -// "type": "string", -// "description": "Short type name of the exception object." -// }, -// "fullTypeName": { -// "type": "string", -// "description": "Fully-qualified type name of the exception object." -// }, -// "evaluateName": { -// "type": "string", -// "description": "An expression that can be evaluated in the current -// scope to obtain the exception object." -// }, -// "stackTrace": { -// "type": "string", -// "description": "Stack trace at the time the exception was thrown." -// }, -// "innerException": { -// "type": "array", -// "items": { -// "$ref": "#/definitions/ExceptionDetails" -// }, -// "description": "Details of the exception contained by this exception, -// if any." -// } -// } -// }, -void ExceptionInfoRequestHandler::operator()( - const llvm::json::Object &request) const { - llvm::json::Object response; - FillResponse(request, response); - const auto *arguments = request.getObject("arguments"); - llvm::json::Object body; - lldb::SBThread thread = dap.GetLLDBThread(*arguments); - if (thread.IsValid()) { - auto stopReason = thread.GetStopReason(); - if (stopReason == lldb::eStopReasonSignal) - body.try_emplace("exceptionId", "signal"); - else if (stopReason == lldb::eStopReasonBreakpoint) { - ExceptionBreakpoint *exc_bp = dap.GetExceptionBPFromStopReason(thread); - if (exc_bp) { - EmplaceSafeString(body, "exceptionId", exc_bp->GetFilter()); - EmplaceSafeString(body, "description", exc_bp->GetLabel()); - } else { - body.try_emplace("exceptionId", "exception"); - } +/// Retrieves the details of the exception that caused this event to be raised. +/// +/// Clients should only call this request if the corresponding capability +/// `supportsExceptionInfoRequest` is true. +llvm::Expected<ExceptionInfoResponseBody> +ExceptionInfoRequestHandler::Run(const ExceptionInfoArguments &args) const { + + lldb::SBThread thread = dap.GetLLDBThread(args.threadId); + if (!thread.IsValid()) + return llvm::make_error<DAPError>( + llvm::formatv("Invalid thread id: {}", args.threadId).str()); + + ExceptionInfoResponseBody response; + response.breakMode = eExceptionBreakModeAlways; + const lldb::StopReason stop_reason = thread.GetStopReason(); + switch (stop_reason) { + case lldb::eStopReasonSignal: + response.exceptionId = "signal"; + break; + case lldb::eStopReasonBreakpoint: { + const ExceptionBreakpoint *exc_bp = + dap.GetExceptionBPFromStopReason(thread); + if (exc_bp) { + response.exceptionId = exc_bp->GetFilter(); + response.description = exc_bp->GetLabel(); } else { - body.try_emplace("exceptionId", "exception"); + response.exceptionId = "exception"; } - if (!ObjectContainsKey(body, "description")) { - char description[1024]; - if (thread.GetStopDescription(description, sizeof(description))) { - EmplaceSafeString(body, "description", description); - } + } break; + default: + response.exceptionId = "exception"; + } + + lldb::SBStream stream; + if (response.description.empty()) { + if (thread.GetStopDescription(stream)) { + response.description = {stream.GetData(), stream.GetSize()}; } - body.try_emplace("breakMode", "always"); - auto exception = thread.GetCurrentException(); - if (exception.IsValid()) { - llvm::json::Object details; - lldb::SBStream stream; - if (exception.GetDescription(stream)) { - EmplaceSafeString(details, "message", stream.GetData()); - } + } - auto exceptionBacktrace = thread.GetCurrentExceptionBacktrace(); - if (exceptionBacktrace.IsValid()) { - lldb::SBStream stream; - exceptionBacktrace.GetDescription(stream); - for (uint32_t i = 0; i < exceptionBacktrace.GetNumFrames(); i++) { - lldb::SBFrame frame = exceptionBacktrace.GetFrameAtIndex(i); - frame.GetDescription(stream); - } - EmplaceSafeString(details, "stackTrace", stream.GetData()); - } + if (lldb::SBValue exception = thread.GetCurrentException()) { + stream.Clear(); + response.details = ExceptionDetails{}; + if (exception.GetDescription(stream)) { + response.details->message = {stream.GetData(), stream.GetSize()}; + } + + if (lldb::SBThread exception_backtrace = + thread.GetCurrentExceptionBacktrace()) { + stream.Clear(); + exception_backtrace.GetDescription(stream); - body.try_emplace("details", std::move(details)); + for (uint32_t idx = 0; idx < exception_backtrace.GetNumFrames(); idx++) { + lldb::SBFrame frame = exception_backtrace.GetFrameAtIndex(idx); + frame.GetDescription(stream); + } + response.details->stackTrace = {stream.GetData(), stream.GetSize()}; } - // auto excInfoCount = thread.GetStopReasonDataCount(); - // for (auto i=0; i<excInfoCount; ++i) { - // uint64_t exc_data = thread.GetStopReasonDataAtIndex(i); - // } - } else { - response["success"] = llvm::json::Value(false); } - response.try_emplace("body", std::move(body)); - dap.SendJSON(llvm::json::Value(std::move(response))); + return response; } } // namespace lldb_dap |
