[lldb] Expose diagnostic events through the SB API

Expose diagnostic events through the SB API. Unlike the progress events,
I opted to use a SBStructuredData so that we can add fields in the
future.

Differential revision: https://reviews.llvm.org/D121818
This commit is contained in:
Jonas Devlieghere 2022-03-16 10:17:44 -07:00
parent 74cf8575f7
commit ff9e596b10
No known key found for this signature in database
GPG Key ID: 49CC0BD90FDEED4D
6 changed files with 129 additions and 2 deletions

View File

@ -119,7 +119,9 @@ class SBDebugger
public:
enum
{
eBroadcastBitProgress = (1 << 0)
eBroadcastBitProgress = (1 << 0),
eBroadcastBitWarning = (1 << 1),
eBroadcastBitError = (1 << 2),
};
@ -129,6 +131,8 @@ public:
uint64_t &OUTPUT,
bool &OUTPUT);
static lldb::SBStructuredData GetDiagnosticFromEvent(const lldb::SBEvent &event);
SBBroadcaster GetBroadcaster();
static void

View File

@ -33,7 +33,11 @@ public:
class LLDB_API SBDebugger {
public:
FLAGS_ANONYMOUS_ENUM(){eBroadcastBitProgress = (1 << 0)};
FLAGS_ANONYMOUS_ENUM(){
eBroadcastBitProgress = (1 << 0),
eBroadcastBitWarning = (1 << 1),
eBroadcastBitError = (1 << 2),
};
SBDebugger();
@ -79,6 +83,9 @@ public:
uint64_t &completed, uint64_t &total,
bool &is_debugger_specific);
static lldb::SBStructuredData
GetDiagnosticFromEvent(const lldb::SBEvent &event);
lldb::SBDebugger &operator=(const lldb::SBDebugger &rhs);
static void Initialize();

View File

@ -59,6 +59,7 @@ public:
~DiagnosticEventData() {}
const std::string &GetMessage() const { return m_message; }
bool IsDebuggerSpecific() const { return m_debugger_specific; }
Type GetType() const { return m_type; }
llvm::StringRef GetPrefix() const;

View File

@ -164,6 +164,26 @@ const char *SBDebugger::GetProgressFromEvent(const lldb::SBEvent &event,
return progress_data->GetMessage().c_str();
}
lldb::SBStructuredData
SBDebugger::GetDiagnosticFromEvent(const lldb::SBEvent &event) {
LLDB_INSTRUMENT_VA(event);
const DiagnosticEventData *diagnostic_data =
DiagnosticEventData::GetEventDataFromEvent(event.get());
if (!diagnostic_data)
return {};
auto dictionary = std::make_unique<StructuredData::Dictionary>();
dictionary->AddStringItem("message", diagnostic_data->GetMessage());
dictionary->AddStringItem("type", diagnostic_data->GetPrefix());
dictionary->AddBooleanItem("debugger_specific",
diagnostic_data->IsDebuggerSpecific());
SBStructuredData data;
data.m_impl_up->SetObjectSP(std::move(dictionary));
return data;
}
SBBroadcaster SBDebugger::GetBroadcaster() {
LLDB_INSTRUMENT_VA(this);
SBBroadcaster broadcaster(&m_opaque_sp->GetBroadcaster(), false);

View File

@ -0,0 +1,71 @@
"""
Test that we are able to broadcast and receive diagnostic events from lldb
"""
import lldb
from lldbsuite.test.lldbtest import *
from lldbsuite.test.decorators import *
import lldbsuite.test.lldbutil as lldbutil
import threading
class TestDiagnosticReporting(TestBase):
mydir = TestBase.compute_mydir(__file__)
eBroadcastBitStopDiagnosticThread = (1 << 0)
def setUp(self):
TestBase.setUp(self)
self.diagnostic_events = []
def fetch_events(self):
event = lldb.SBEvent()
done = False
while not done:
if self.listener.WaitForEvent(1, event):
event_mask = event.GetType()
if event.BroadcasterMatchesRef(self.test_broadcaster):
if event_mask & self.eBroadcastBitStopDiagnosticThread:
done = True
elif event.BroadcasterMatchesRef(self.diagnostic_broadcaster):
self.diagnostic_events.append(
lldb.SBDebugger.GetDiagnosticFromEvent(event))
def test_dwarf_symbol_loading_diagnostic_report(self):
"""Test that we are able to fetch diagnostic events"""
self.listener = lldb.SBListener("lldb.diagnostic.listener")
self.test_broadcaster = lldb.SBBroadcaster('lldb.broadcaster.test')
self.listener.StartListeningForEvents(
self.test_broadcaster, self.eBroadcastBitStopDiagnosticThread)
self.diagnostic_broadcaster = self.dbg.GetBroadcaster()
self.diagnostic_broadcaster.AddListener(
self.listener, lldb.SBDebugger.eBroadcastBitWarning)
self.diagnostic_broadcaster.AddListener(
self.listener, lldb.SBDebugger.eBroadcastBitError)
listener_thread = threading.Thread(target=self.fetch_events)
listener_thread.start()
self.yaml2obj("minidump.yaml", self.getBuildArtifact("minidump.core"))
self.dbg.CreateTarget(None)
self.target = self.dbg.GetSelectedTarget()
self.process = self.target.LoadCore(
self.getBuildArtifact("minidump.core"))
self.test_broadcaster.BroadcastEventByType(
self.eBroadcastBitStopDiagnosticThread)
listener_thread.join()
self.assertEquals(len(self.diagnostic_events), 1)
diagnostic_event = self.diagnostic_events[0]
self.assertEquals(
diagnostic_event.GetValueForKey("type").GetStringValue(100),
"warning")
self.assertEquals(
diagnostic_event.GetValueForKey("message").GetStringValue(100),
"unable to retrieve process ID from minidump file, setting process ID to 1"
)

View File

@ -0,0 +1,24 @@
--- !minidump
Streams:
- Type: ThreadList
Threads:
- Thread Id: 0x00003E81
Context: 0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000B0010000000000033000000000000000000000006020100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000010A234EBFC7F000010A234EBFC7F00000000000000000000F09C34EBFC7F0000C0A91ABCE97F00000000000000000000A0163FBCE97F00004602000000000000921C40000000000030A434EBFC7F000000000000000000000000000000000000C61D4000000000007F0300000000000000000000000000000000000000000000801F0000FFFF0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000FFFF00FFFFFFFFFFFFFF00FFFFFFFF25252525252525252525252525252525000000000000000000000000000000000000000000000000000000000000000000FFFF00FFFFFFFFFFFFFF00FFFFFFFF0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000FF00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
Stack:
Start of Memory Range: 0x00007FFCEB34A000
Content: ''
- Type: ModuleList
Modules:
- Base of Image: 0x0000000000400000
Size of Image: 0x00017000
Module Name: 'a.out'
CodeView Record: ''
- Type: SystemInfo
Processor Arch: AMD64
Platform ID: Linux
CSD Version: 'Linux 3.13'
CPU:
Vendor ID: GenuineIntel
Version Info: 0x00000000
Feature Info: 0x00000000
...