diff --git a/lldb/bindings/interface/SBDebugger.i b/lldb/bindings/interface/SBDebugger.i index 0ef1766a50c6b..e9a6168d0c093 100644 --- a/lldb/bindings/interface/SBDebugger.i +++ b/lldb/bindings/interface/SBDebugger.i @@ -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 diff --git a/lldb/include/lldb/API/SBDebugger.h b/lldb/include/lldb/API/SBDebugger.h index a82c147053eb9..0893bc60315e6 100644 --- a/lldb/include/lldb/API/SBDebugger.h +++ b/lldb/include/lldb/API/SBDebugger.h @@ -33,7 +33,11 @@ class LLDB_API SBInputReader { 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 @@ class LLDB_API SBDebugger { 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(); diff --git a/lldb/include/lldb/Core/DebuggerEvents.h b/lldb/include/lldb/Core/DebuggerEvents.h index e4394da2ffdac..8388d5ce66f1c 100644 --- a/lldb/include/lldb/Core/DebuggerEvents.h +++ b/lldb/include/lldb/Core/DebuggerEvents.h @@ -59,6 +59,7 @@ class DiagnosticEventData : public EventData { ~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; diff --git a/lldb/source/API/SBDebugger.cpp b/lldb/source/API/SBDebugger.cpp index 72b5f5742fa04..3391665786d56 100644 --- a/lldb/source/API/SBDebugger.cpp +++ b/lldb/source/API/SBDebugger.cpp @@ -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(); + 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); diff --git a/lldb/test/API/functionalities/diagnostic_reporting/TestDiagnosticReporting.py b/lldb/test/API/functionalities/diagnostic_reporting/TestDiagnosticReporting.py new file mode 100644 index 0000000000000..1bfc313e8381f --- /dev/null +++ b/lldb/test/API/functionalities/diagnostic_reporting/TestDiagnosticReporting.py @@ -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" + ) diff --git a/lldb/test/API/functionalities/diagnostic_reporting/minidump.yaml b/lldb/test/API/functionalities/diagnostic_reporting/minidump.yaml new file mode 100644 index 0000000000000..42f0a23702950 --- /dev/null +++ b/lldb/test/API/functionalities/diagnostic_reporting/minidump.yaml @@ -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 +...