123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129 |
- /* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
- file Copyright.txt or https://cmake.org/licensing for details. */
- #include "cmDebuggerExceptionManager.h"
- #include <utility>
- #include <vector>
- #include <cm3p/cppdap/optional.h>
- #include <cm3p/cppdap/session.h>
- #include <cm3p/cppdap/types.h>
- #include "cmDebuggerProtocol.h"
- #include "cmMessageType.h"
- namespace cmDebugger {
- cmDebuggerExceptionManager::cmDebuggerExceptionManager(
- dap::Session* dapSession)
- : DapSession(dapSession)
- {
- // https://microsoft.github.io/debug-adapter-protocol/specification#Requests_SetExceptionBreakpoints
- DapSession->registerHandler(
- [&](const dap::SetExceptionBreakpointsRequest& request) {
- return HandleSetExceptionBreakpointsRequest(request);
- });
- // https://microsoft.github.io/debug-adapter-protocol/specification#Requests_ExceptionInfo
- DapSession->registerHandler([&](const dap::ExceptionInfoRequest& request) {
- (void)request;
- return HandleExceptionInfoRequest();
- });
- ExceptionMap[MessageType::AUTHOR_WARNING] =
- cmDebuggerExceptionFilter{ "AUTHOR_WARNING", "Warning (dev)" };
- ExceptionMap[MessageType::AUTHOR_ERROR] =
- cmDebuggerExceptionFilter{ "AUTHOR_ERROR", "Error (dev)" };
- ExceptionMap[MessageType::FATAL_ERROR] =
- cmDebuggerExceptionFilter{ "FATAL_ERROR", "Fatal error" };
- ExceptionMap[MessageType::INTERNAL_ERROR] =
- cmDebuggerExceptionFilter{ "INTERNAL_ERROR", "Internal error" };
- ExceptionMap[MessageType::MESSAGE] =
- cmDebuggerExceptionFilter{ "MESSAGE", "Other messages" };
- ExceptionMap[MessageType::WARNING] =
- cmDebuggerExceptionFilter{ "WARNING", "Warning" };
- ExceptionMap[MessageType::LOG] =
- cmDebuggerExceptionFilter{ "LOG", "Debug log" };
- ExceptionMap[MessageType::DEPRECATION_ERROR] =
- cmDebuggerExceptionFilter{ "DEPRECATION_ERROR", "Deprecation error" };
- ExceptionMap[MessageType::DEPRECATION_WARNING] =
- cmDebuggerExceptionFilter{ "DEPRECATION_WARNING", "Deprecation warning" };
- RaiseExceptions["AUTHOR_ERROR"] = true;
- RaiseExceptions["FATAL_ERROR"] = true;
- RaiseExceptions["INTERNAL_ERROR"] = true;
- RaiseExceptions["DEPRECATION_ERROR"] = true;
- }
- dap::SetExceptionBreakpointsResponse
- cmDebuggerExceptionManager::HandleSetExceptionBreakpointsRequest(
- dap::SetExceptionBreakpointsRequest const& request)
- {
- std::unique_lock<std::mutex> lock(Mutex);
- dap::SetExceptionBreakpointsResponse response;
- RaiseExceptions.clear();
- for (const auto& filter : request.filters) {
- RaiseExceptions[filter] = true;
- }
- return response;
- }
- dap::ExceptionInfoResponse
- cmDebuggerExceptionManager::HandleExceptionInfoRequest()
- {
- std::unique_lock<std::mutex> lock(Mutex);
- dap::ExceptionInfoResponse response;
- if (TheException.has_value()) {
- response.exceptionId = TheException->Id;
- response.breakMode = "always";
- response.description = TheException->Description;
- TheException = {};
- }
- return response;
- }
- void cmDebuggerExceptionManager::HandleInitializeRequest(
- dap::CMakeInitializeResponse& response)
- {
- std::unique_lock<std::mutex> lock(Mutex);
- response.supportsExceptionInfoRequest = true;
- dap::array<dap::ExceptionBreakpointsFilter> exceptionBreakpointFilters;
- for (auto& pair : ExceptionMap) {
- dap::ExceptionBreakpointsFilter filter;
- filter.filter = pair.second.Filter;
- filter.label = pair.second.Label;
- filter.def = RaiseExceptions[filter.filter];
- exceptionBreakpointFilters.emplace_back(filter);
- }
- response.exceptionBreakpointFilters = exceptionBreakpointFilters;
- }
- cm::optional<dap::StoppedEvent>
- cmDebuggerExceptionManager::RaiseExceptionIfAny(MessageType t,
- std::string const& text)
- {
- cm::optional<dap::StoppedEvent> maybeStoppedEvent;
- std::unique_lock<std::mutex> lock(Mutex);
- if (RaiseExceptions[ExceptionMap[t].Filter]) {
- dap::StoppedEvent stoppedEvent;
- stoppedEvent.allThreadsStopped = true;
- stoppedEvent.reason = "exception";
- stoppedEvent.description = "Pause on exception";
- stoppedEvent.text = text;
- TheException = cmDebuggerException{ ExceptionMap[t].Filter, text };
- maybeStoppedEvent = std::move(stoppedEvent);
- }
- return maybeStoppedEvent;
- }
- void cmDebuggerExceptionManager::ClearAll()
- {
- std::unique_lock<std::mutex> lock(Mutex);
- RaiseExceptions.clear();
- }
- } // namespace cmDebugger
|