82 lines · cpp
1//===-- ExceptionInfoRequestHandler.cpp -----------------------------------===//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-exception6//7//===----------------------------------------------------------------------===//8 9#include "DAP.h"10#include "DAPError.h"11#include "Protocol/ProtocolRequests.h"12#include "Protocol/ProtocolTypes.h"13#include "RequestHandler.h"14#include "lldb/API/SBStream.h"15 16using namespace lldb_dap::protocol;17 18namespace lldb_dap {19 20/// Retrieves the details of the exception that caused this event to be raised.21///22/// Clients should only call this request if the corresponding capability23/// `supportsExceptionInfoRequest` is true.24llvm::Expected<ExceptionInfoResponseBody>25ExceptionInfoRequestHandler::Run(const ExceptionInfoArguments &args) const {26 27 lldb::SBThread thread = dap.GetLLDBThread(args.threadId);28 if (!thread.IsValid())29 return llvm::make_error<DAPError>(30 llvm::formatv("Invalid thread id: {}", args.threadId).str());31 32 ExceptionInfoResponseBody response;33 response.breakMode = eExceptionBreakModeAlways;34 const lldb::StopReason stop_reason = thread.GetStopReason();35 switch (stop_reason) {36 case lldb::eStopReasonSignal:37 response.exceptionId = "signal";38 break;39 case lldb::eStopReasonBreakpoint: {40 const ExceptionBreakpoint *exc_bp =41 dap.GetExceptionBPFromStopReason(thread);42 if (exc_bp) {43 response.exceptionId = exc_bp->GetFilter();44 response.description = exc_bp->GetLabel();45 } else {46 response.exceptionId = "exception";47 }48 } break;49 default:50 response.exceptionId = "exception";51 }52 53 lldb::SBStream stream;54 if (response.description.empty()) {55 if (thread.GetStopDescription(stream)) {56 response.description = {stream.GetData(), stream.GetSize()};57 }58 }59 60 if (lldb::SBValue exception = thread.GetCurrentException()) {61 stream.Clear();62 response.details = ExceptionDetails{};63 if (exception.GetDescription(stream)) {64 response.details->message = {stream.GetData(), stream.GetSize()};65 }66 67 if (lldb::SBThread exception_backtrace =68 thread.GetCurrentExceptionBacktrace()) {69 stream.Clear();70 exception_backtrace.GetDescription(stream);71 72 for (uint32_t idx = 0; idx < exception_backtrace.GetNumFrames(); idx++) {73 lldb::SBFrame frame = exception_backtrace.GetFrameAtIndex(idx);74 frame.GetDescription(stream);75 }76 response.details->stackTrace = {stream.GetData(), stream.GetSize()};77 }78 }79 return response;80}81} // namespace lldb_dap82