blob: a27426c1be8d124b65763aa9965e2825428d6d08 (
plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
|
/* 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
|