Skip to content

Commit 9f84066

Browse files
JDevlieghereIanWood1
authored andcommitted
[lldb] Emit diagnostics as "important" output (llvm#137280)
Handle diagnostics events from the debugger (i.e. asynchronous errors and warnings) in the lldb-dap event handler and emit them as "important" output.
1 parent af627c4 commit 9f84066

File tree

8 files changed

+85
-3
lines changed

8 files changed

+85
-3
lines changed

lldb/packages/Python/lldbsuite/test/tools/lldb-dap/lldbdap_testcase.py

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -217,14 +217,22 @@ def get_stdout(self, timeout=0.0):
217217
def get_console(self, timeout=0.0):
218218
return self.dap_server.get_output("console", timeout=timeout)
219219

220+
def get_important(self, timeout=0.0):
221+
return self.dap_server.get_output("important", timeout=timeout)
222+
223+
def collect_stdout(self, timeout_secs, pattern=None):
224+
return self.dap_server.collect_output(
225+
"stdout", timeout_secs=timeout_secs, pattern=pattern
226+
)
227+
220228
def collect_console(self, timeout_secs, pattern=None):
221229
return self.dap_server.collect_output(
222230
"console", timeout_secs=timeout_secs, pattern=pattern
223231
)
224232

225-
def collect_stdout(self, timeout_secs, pattern=None):
233+
def collect_important(self, timeout_secs, pattern=None):
226234
return self.dap_server.collect_output(
227-
"stdout", timeout_secs=timeout_secs, pattern=pattern
235+
"important", timeout_secs=timeout_secs, pattern=pattern
228236
)
229237

230238
def get_local_as_int(self, name, threadId=None):

lldb/test/API/tools/lldb-dap/console/TestDAP_console.py

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -164,3 +164,20 @@ def test_exit_status_message_ok(self):
164164
console_output,
165165
"Exit status does not contain message 'exited with status'",
166166
)
167+
168+
def test_diagnositcs(self):
169+
program = self.getBuildArtifact("a.out")
170+
self.build_and_launch(program)
171+
172+
core = self.getBuildArtifact("minidump.core")
173+
self.yaml2obj("minidump.yaml", core)
174+
self.dap_server.request_evaluate(
175+
f"target create --core {core}", context="repl"
176+
)
177+
178+
output = self.get_important()
179+
self.assertIn(
180+
"warning: unable to retrieve process ID from minidump file",
181+
output,
182+
"diagnostic found in important output",
183+
)
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
--- !minidump
2+
Streams:
3+
- Type: ThreadList
4+
Threads:
5+
- Thread Id: 0x00003E81
6+
Context: 0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000B0010000000000033000000000000000000000006020100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000010A234EBFC7F000010A234EBFC7F00000000000000000000F09C34EBFC7F0000C0A91ABCE97F00000000000000000000A0163FBCE97F00004602000000000000921C40000000000030A434EBFC7F000000000000000000000000000000000000C61D4000000000007F0300000000000000000000000000000000000000000000801F0000FFFF0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000FFFF00FFFFFFFFFFFFFF00FFFFFFFF25252525252525252525252525252525000000000000000000000000000000000000000000000000000000000000000000FFFF00FFFFFFFFFFFFFF00FFFFFFFF0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000FF00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
7+
Stack:
8+
Start of Memory Range: 0x00007FFCEB34A000
9+
Content: ''
10+
- Type: ModuleList
11+
Modules:
12+
- Base of Image: 0x0000000000400000
13+
Size of Image: 0x00017000
14+
Module Name: 'a.out'
15+
CodeView Record: ''
16+
- Type: SystemInfo
17+
Processor Arch: AMD64
18+
Platform ID: Linux
19+
CSD Version: 'Linux 3.13'
20+
CPU:
21+
Vendor ID: GenuineIntel
22+
Version Info: 0x00000000
23+
Feature Info: 0x00000000
24+
...

lldb/tools/lldb-dap/DAP.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -342,6 +342,9 @@ void DAP::SendOutput(OutputType o, const llvm::StringRef output) {
342342
case OutputType::Console:
343343
category = "console";
344344
break;
345+
case OutputType::Important:
346+
category = "important";
347+
break;
345348
case OutputType::Stdout:
346349
category = "stdout";
347350
break;

lldb/tools/lldb-dap/DAP.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,7 @@ typedef llvm::DenseMap<lldb::addr_t, InstructionBreakpoint>
6868
using AdapterFeature = protocol::AdapterFeature;
6969
using ClientFeature = protocol::ClientFeature;
7070

71-
enum class OutputType { Console, Stdout, Stderr, Telemetry };
71+
enum class OutputType { Console, Important, Stdout, Stderr, Telemetry };
7272

7373
/// Buffer size for handling output events.
7474
constexpr uint64_t OutputBufferSize = (1u << 12);

lldb/tools/lldb-dap/Handler/InitializeRequestHandler.cpp

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
#include "DAP.h"
1010
#include "EventHelper.h"
1111
#include "JSONUtils.h"
12+
#include "LLDBUtils.h"
1213
#include "Protocol/ProtocolRequests.h"
1314
#include "RequestHandler.h"
1415
#include "lldb/API/SBEvent.h"
@@ -117,6 +118,8 @@ static void EventThreadFunction(DAP &dap) {
117118
lldb::SBEvent event;
118119
lldb::SBListener listener = dap.debugger.GetListener();
119120
dap.broadcaster.AddListener(listener, eBroadcastBitStopEventThread);
121+
dap.debugger.GetBroadcaster().AddListener(listener, eBroadcastBitError |
122+
eBroadcastBitWarning);
120123
bool done = false;
121124
while (!done) {
122125
if (listener.WaitForEvent(1, event)) {
@@ -222,6 +225,15 @@ static void EventThreadFunction(DAP &dap) {
222225
dap.SendJSON(llvm::json::Value(std::move(bp_event)));
223226
}
224227
}
228+
} else if (event_mask & eBroadcastBitError ||
229+
event_mask & eBroadcastBitWarning) {
230+
SBStructuredData data = SBDebugger::GetDiagnosticFromEvent(event);
231+
if (!data.IsValid())
232+
continue;
233+
std::string type = GetStringValue(data.GetValueForKey("type"));
234+
std::string message = GetStringValue(data.GetValueForKey("message"));
235+
dap.SendOutput(OutputType::Important,
236+
llvm::formatv("{0}: {1}", type, message).str());
225237
} else if (event.BroadcasterMatchesRef(dap.broadcaster)) {
226238
if (event_mask & eBroadcastBitStopEventThread) {
227239
done = true;

lldb/tools/lldb-dap/LLDBUtils.cpp

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,11 +13,13 @@
1313
#include "lldb/API/SBDebugger.h"
1414
#include "lldb/API/SBFrame.h"
1515
#include "lldb/API/SBStringList.h"
16+
#include "lldb/API/SBStructuredData.h"
1617
#include "lldb/API/SBThread.h"
1718
#include "lldb/lldb-enumerations.h"
1819
#include "llvm/ADT/ArrayRef.h"
1920
#include "llvm/Support/JSON.h"
2021
#include "llvm/Support/raw_ostream.h"
22+
2123
#include <mutex>
2224
#include <system_error>
2325

@@ -193,4 +195,17 @@ llvm::Error ToError(const lldb::SBError &error) {
193195
error.GetCString());
194196
}
195197

198+
std::string GetStringValue(const lldb::SBStructuredData &data) {
199+
if (!data.IsValid())
200+
return "";
201+
202+
const size_t str_length = data.GetStringValue(nullptr, 0);
203+
if (!str_length)
204+
return "";
205+
206+
std::string str(str_length, 0);
207+
data.GetStringValue(str.data(), str_length + 1);
208+
return str;
209+
}
210+
196211
} // namespace lldb_dap

lldb/tools/lldb-dap/LLDBUtils.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -162,6 +162,9 @@ GetEnvironmentFromArguments(const llvm::json::Object &arguments);
162162
/// Take ownership of the stored error.
163163
llvm::Error ToError(const lldb::SBError &error);
164164

165+
/// Provides the string value if this data structure is a string type.
166+
std::string GetStringValue(const lldb::SBStructuredData &data);
167+
165168
} // namespace lldb_dap
166169

167170
#endif

0 commit comments

Comments
 (0)