CMake Nightly Date Stamp
[kiteware-cmake.git] / Source / cmDebuggerExceptionManager.cxx
blob470e44c9dc3335cefd138f453de8a76cbffa4a46
1 /* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
2 file Copyright.txt or https://cmake.org/licensing for details. */
3 #include "cmDebuggerExceptionManager.h"
5 #include <utility>
6 #include <vector>
8 #include <cm3p/cppdap/optional.h>
9 #include <cm3p/cppdap/session.h>
10 #include <cm3p/cppdap/types.h>
12 #include "cmDebuggerProtocol.h"
13 #include "cmMessageType.h"
15 namespace cmDebugger {
17 cmDebuggerExceptionManager::cmDebuggerExceptionManager(
18 dap::Session* dapSession)
19 : DapSession(dapSession)
21 // https://microsoft.github.io/debug-adapter-protocol/specification#Requests_SetExceptionBreakpoints
22 DapSession->registerHandler(
23 [&](const dap::SetExceptionBreakpointsRequest& request) {
24 return HandleSetExceptionBreakpointsRequest(request);
25 });
27 // https://microsoft.github.io/debug-adapter-protocol/specification#Requests_ExceptionInfo
28 DapSession->registerHandler([&](const dap::ExceptionInfoRequest& request) {
29 (void)request;
30 return HandleExceptionInfoRequest();
31 });
33 ExceptionMap[MessageType::AUTHOR_WARNING] =
34 cmDebuggerExceptionFilter{ "AUTHOR_WARNING", "Warning (dev)" };
35 ExceptionMap[MessageType::AUTHOR_ERROR] =
36 cmDebuggerExceptionFilter{ "AUTHOR_ERROR", "Error (dev)" };
37 ExceptionMap[MessageType::FATAL_ERROR] =
38 cmDebuggerExceptionFilter{ "FATAL_ERROR", "Fatal error" };
39 ExceptionMap[MessageType::INTERNAL_ERROR] =
40 cmDebuggerExceptionFilter{ "INTERNAL_ERROR", "Internal error" };
41 ExceptionMap[MessageType::MESSAGE] =
42 cmDebuggerExceptionFilter{ "MESSAGE", "Other messages" };
43 ExceptionMap[MessageType::WARNING] =
44 cmDebuggerExceptionFilter{ "WARNING", "Warning" };
45 ExceptionMap[MessageType::LOG] =
46 cmDebuggerExceptionFilter{ "LOG", "Debug log" };
47 ExceptionMap[MessageType::DEPRECATION_ERROR] =
48 cmDebuggerExceptionFilter{ "DEPRECATION_ERROR", "Deprecation error" };
49 ExceptionMap[MessageType::DEPRECATION_WARNING] =
50 cmDebuggerExceptionFilter{ "DEPRECATION_WARNING", "Deprecation warning" };
51 RaiseExceptions["AUTHOR_ERROR"] = true;
52 RaiseExceptions["FATAL_ERROR"] = true;
53 RaiseExceptions["INTERNAL_ERROR"] = true;
54 RaiseExceptions["DEPRECATION_ERROR"] = true;
57 dap::SetExceptionBreakpointsResponse
58 cmDebuggerExceptionManager::HandleSetExceptionBreakpointsRequest(
59 dap::SetExceptionBreakpointsRequest const& request)
61 std::unique_lock<std::mutex> lock(Mutex);
62 dap::SetExceptionBreakpointsResponse response;
63 RaiseExceptions.clear();
64 for (const auto& filter : request.filters) {
65 RaiseExceptions[filter] = true;
68 return response;
71 dap::ExceptionInfoResponse
72 cmDebuggerExceptionManager::HandleExceptionInfoRequest()
74 std::unique_lock<std::mutex> lock(Mutex);
76 dap::ExceptionInfoResponse response;
77 if (TheException.has_value()) {
78 response.exceptionId = TheException->Id;
79 response.breakMode = "always";
80 response.description = TheException->Description;
81 TheException = cm::nullopt;
83 return response;
86 void cmDebuggerExceptionManager::HandleInitializeRequest(
87 dap::CMakeInitializeResponse& response)
89 std::unique_lock<std::mutex> lock(Mutex);
90 response.supportsExceptionInfoRequest = true;
92 dap::array<dap::ExceptionBreakpointsFilter> exceptionBreakpointFilters;
93 for (auto& pair : ExceptionMap) {
94 dap::ExceptionBreakpointsFilter filter;
95 filter.filter = pair.second.Filter;
96 filter.label = pair.second.Label;
97 filter.def = RaiseExceptions[filter.filter];
98 exceptionBreakpointFilters.emplace_back(filter);
101 response.exceptionBreakpointFilters = exceptionBreakpointFilters;
104 cm::optional<dap::StoppedEvent>
105 cmDebuggerExceptionManager::RaiseExceptionIfAny(MessageType t,
106 std::string const& text)
108 cm::optional<dap::StoppedEvent> maybeStoppedEvent;
109 std::unique_lock<std::mutex> lock(Mutex);
110 if (RaiseExceptions[ExceptionMap[t].Filter]) {
111 dap::StoppedEvent stoppedEvent;
112 stoppedEvent.allThreadsStopped = true;
113 stoppedEvent.reason = "exception";
114 stoppedEvent.description = "Pause on exception";
115 stoppedEvent.text = text;
116 TheException = cmDebuggerException{ ExceptionMap[t].Filter, text };
117 maybeStoppedEvent = std::move(stoppedEvent);
120 return maybeStoppedEvent;
123 void cmDebuggerExceptionManager::ClearAll()
125 std::unique_lock<std::mutex> lock(Mutex);
126 RaiseExceptions.clear();
129 } // namespace cmDebugger