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"
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
);
27 // https://microsoft.github.io/debug-adapter-protocol/specification#Requests_ExceptionInfo
28 DapSession
->registerHandler([&](const dap::ExceptionInfoRequest
& request
) {
30 return HandleExceptionInfoRequest();
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;
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
;
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