[Lldb-commits] [lldb] [lldb] Log errors to the system log if they would otherwise get dropped (PR #111911)
https://github.com/JDevlieghere updated https://github.com/llvm/llvm-project/pull/111911 >From 55eab57c695d4be99305d2b6cee0c4f44261a473 Mon Sep 17 00:00:00 2001 From: Jonas Devlieghere Date: Thu, 10 Oct 2024 14:39:44 -0700 Subject: [PATCH 1/2] [lldb] Log errors to the system log if they would otherwise get dropped Log errors to the (always-on) system log if they would otherwise get dropped by LLDB_LOG_ERROR and LLDB_LOG_ERRORV. --- lldb/include/lldb/Utility/Log.h | 15 +++ lldb/source/API/SystemInitializerFull.cpp | 3 +++ lldb/source/Utility/Log.cpp | 8 3 files changed, 26 insertions(+) diff --git a/lldb/include/lldb/Utility/Log.h b/lldb/include/lldb/Utility/Log.h index ac6347153a1014..f8545cd59a18ba 100644 --- a/lldb/include/lldb/Utility/Log.h +++ b/lldb/include/lldb/Utility/Log.h @@ -335,6 +335,15 @@ template Log *GetLog(Cat mask) { return LogChannelFor().GetLog(Log::MaskType(mask)); } +/// Getter and setter for the error log (see g_error_log). +/// The error log is set to the system log in SystemInitializerFull. We can't +/// use the system log directly because that would violate the layering between +/// Utility and Host. +/// @{ +void SetLLDBErrorLog(Log *log); +Log *GetLLDBErrorLog(); +/// @} + } // namespace lldb_private /// The LLDB_LOG* macros defined below are the way to emit log messages. @@ -387,6 +396,9 @@ template Log *GetLog(Cat mask) { if (log_private && error_private) { \ log_private->FormatError(::std::move(error_private), __FILE__, __func__, \ __VA_ARGS__); \ +} else if (::lldb_private::Log *log_error = GetLLDBErrorLog()) { \ + log_error->FormatError(::std::move(error_private), __FILE__, __func__, \ + __VA_ARGS__); \ } else \ ::llvm::consumeError(::std::move(error_private)); \ } while (0) @@ -401,6 +413,9 @@ template Log *GetLog(Cat mask) { if (log_private && log_private->GetVerbose() && error_private) { \ log_private->FormatError(::std::move(error_private), __FILE__, __func__, \ __VA_ARGS__); \ +} else if (::lldb_private::Log *log_error = GetLLDBErrorLog()) { \ + log_error->FormatError(::std::move(error_private), __FILE__, __func__, \ + __VA_ARGS__); \ } else \ ::llvm::consumeError(::std::move(error_private)); \ } while (0) diff --git a/lldb/source/API/SystemInitializerFull.cpp b/lldb/source/API/SystemInitializerFull.cpp index 8a992a6889a91b..31f3a9f30b81f0 100644 --- a/lldb/source/API/SystemInitializerFull.cpp +++ b/lldb/source/API/SystemInitializerFull.cpp @@ -84,6 +84,9 @@ llvm::Error SystemInitializerFull::Initialize() { // Use the Debugger's LLDBAssert callback. SetLLDBAssertCallback(Debugger::AssertCallback); + // Use the system log to report errors that would otherwise get dropped. + SetLLDBErrorLog(GetLog(SystemLog::System)); + LLDB_LOG(GetLog(SystemLog::System), "{0}", GetVersion()); return llvm::Error::success(); diff --git a/lldb/source/Utility/Log.cpp b/lldb/source/Utility/Log.cpp index 3798f406476370..a57d415be033ba 100644 --- a/lldb/source/Utility/Log.cpp +++ b/lldb/source/Utility/Log.cpp @@ -43,6 +43,10 @@ char TeeLogHandler::ID; llvm::ManagedStatic Log::g_channel_map; +// The error log is used by LLDB_LOG_ERROR and LLDB_LOG_ERRORV. If the given +// log channel is not enabled, error messages are logged to the error log. +static std::atomic g_error_log = nullptr; + void Log::ForEachCategory( const Log::ChannelMap::value_type &entry, llvm::function_ref lambda) { @@ -460,3 +464,7 @@ void TeeLogHandler::Emit(llvm::StringRef message) { m_first_log_handler->Emit(message); m_second_log_handler->Emit(message); } + +void lldb_private::SetLLDBErrorLog(Log *log) { g_error_log.exchange(log); } + +Log *lldb_private::GetLLDBErrorLog() { return g_error_log; } >From 99b70b38050344115c8a6b17929cfd8c93b55571 Mon Sep 17 00:00:00 2001 From: Jonas Devlieghere Date: Sun, 13 Oct 2024 09:01:08 -0700 Subject: [PATCH 2/2] Address Pavel's feedback --- lldb/include/lldb/Utility/Log.h | 8 ++-- 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/lldb/include/lldb/Utility/Log.h b/lldb/include/lldb/Utility/Log.h index f8545cd59a18ba..1529178cb83b4b 100644 --- a/lldb/include/lldb/Utility/Log.h +++ b/lldb/include/lldb/Utility/Log.h @@ -393,12 +393,11 @@ Log *GetLLDBErrorLog(); do { \ ::lldb_private::Log *l
[Lldb-commits] [lldb] [lldb] Log errors to the system log if they would otherwise get dropped (PR #111911)
https://github.com/JDevlieghere updated https://github.com/llvm/llvm-project/pull/111911 >From 55eab57c695d4be99305d2b6cee0c4f44261a473 Mon Sep 17 00:00:00 2001 From: Jonas Devlieghere Date: Thu, 10 Oct 2024 14:39:44 -0700 Subject: [PATCH 1/3] [lldb] Log errors to the system log if they would otherwise get dropped Log errors to the (always-on) system log if they would otherwise get dropped by LLDB_LOG_ERROR and LLDB_LOG_ERRORV. --- lldb/include/lldb/Utility/Log.h | 15 +++ lldb/source/API/SystemInitializerFull.cpp | 3 +++ lldb/source/Utility/Log.cpp | 8 3 files changed, 26 insertions(+) diff --git a/lldb/include/lldb/Utility/Log.h b/lldb/include/lldb/Utility/Log.h index ac6347153a1014..f8545cd59a18ba 100644 --- a/lldb/include/lldb/Utility/Log.h +++ b/lldb/include/lldb/Utility/Log.h @@ -335,6 +335,15 @@ template Log *GetLog(Cat mask) { return LogChannelFor().GetLog(Log::MaskType(mask)); } +/// Getter and setter for the error log (see g_error_log). +/// The error log is set to the system log in SystemInitializerFull. We can't +/// use the system log directly because that would violate the layering between +/// Utility and Host. +/// @{ +void SetLLDBErrorLog(Log *log); +Log *GetLLDBErrorLog(); +/// @} + } // namespace lldb_private /// The LLDB_LOG* macros defined below are the way to emit log messages. @@ -387,6 +396,9 @@ template Log *GetLog(Cat mask) { if (log_private && error_private) { \ log_private->FormatError(::std::move(error_private), __FILE__, __func__, \ __VA_ARGS__); \ +} else if (::lldb_private::Log *log_error = GetLLDBErrorLog()) { \ + log_error->FormatError(::std::move(error_private), __FILE__, __func__, \ + __VA_ARGS__); \ } else \ ::llvm::consumeError(::std::move(error_private)); \ } while (0) @@ -401,6 +413,9 @@ template Log *GetLog(Cat mask) { if (log_private && log_private->GetVerbose() && error_private) { \ log_private->FormatError(::std::move(error_private), __FILE__, __func__, \ __VA_ARGS__); \ +} else if (::lldb_private::Log *log_error = GetLLDBErrorLog()) { \ + log_error->FormatError(::std::move(error_private), __FILE__, __func__, \ + __VA_ARGS__); \ } else \ ::llvm::consumeError(::std::move(error_private)); \ } while (0) diff --git a/lldb/source/API/SystemInitializerFull.cpp b/lldb/source/API/SystemInitializerFull.cpp index 8a992a6889a91b..31f3a9f30b81f0 100644 --- a/lldb/source/API/SystemInitializerFull.cpp +++ b/lldb/source/API/SystemInitializerFull.cpp @@ -84,6 +84,9 @@ llvm::Error SystemInitializerFull::Initialize() { // Use the Debugger's LLDBAssert callback. SetLLDBAssertCallback(Debugger::AssertCallback); + // Use the system log to report errors that would otherwise get dropped. + SetLLDBErrorLog(GetLog(SystemLog::System)); + LLDB_LOG(GetLog(SystemLog::System), "{0}", GetVersion()); return llvm::Error::success(); diff --git a/lldb/source/Utility/Log.cpp b/lldb/source/Utility/Log.cpp index 3798f406476370..a57d415be033ba 100644 --- a/lldb/source/Utility/Log.cpp +++ b/lldb/source/Utility/Log.cpp @@ -43,6 +43,10 @@ char TeeLogHandler::ID; llvm::ManagedStatic Log::g_channel_map; +// The error log is used by LLDB_LOG_ERROR and LLDB_LOG_ERRORV. If the given +// log channel is not enabled, error messages are logged to the error log. +static std::atomic g_error_log = nullptr; + void Log::ForEachCategory( const Log::ChannelMap::value_type &entry, llvm::function_ref lambda) { @@ -460,3 +464,7 @@ void TeeLogHandler::Emit(llvm::StringRef message) { m_first_log_handler->Emit(message); m_second_log_handler->Emit(message); } + +void lldb_private::SetLLDBErrorLog(Log *log) { g_error_log.exchange(log); } + +Log *lldb_private::GetLLDBErrorLog() { return g_error_log; } >From 99b70b38050344115c8a6b17929cfd8c93b55571 Mon Sep 17 00:00:00 2001 From: Jonas Devlieghere Date: Sun, 13 Oct 2024 09:01:08 -0700 Subject: [PATCH 2/3] Address Pavel's feedback --- lldb/include/lldb/Utility/Log.h | 8 ++-- 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/lldb/include/lldb/Utility/Log.h b/lldb/include/lldb/Utility/Log.h index f8545cd59a18ba..1529178cb83b4b 100644 --- a/lldb/include/lldb/Utility/Log.h +++ b/lldb/include/lldb/Utility/Log.h @@ -393,12 +393,11 @@ Log *GetLLDBErrorLog(); do { \ ::lldb_private::Log *l
[Lldb-commits] [lldb] DynamicLoaderDarwin load images in parallel (PR #110439)
jasonmolenda wrote: Thanks for all the work you've done on this, and updating the setting. I looked over the implementations, and they all look like reasonable changes to me - I did laugh a little when I realized that 2/3rds of all the changes were related to adding the setting :) that's always a bit of boilerplate for the first setting in a plugin. In a process launch scenario, or attaching to a process when it was launched in a stopped state, there will only be two binaries, dyld and the main app binary, and I don't think there would be any much perf benefit to the "preload" approach where we can parallelize special binaries (dyld, main executable) -- dyld is just a little guy. But when we attach to a launched app, where we have the two special binaries and a thousand others, if we load those two special binaries sequentially, all the other binaries are blocked until a possibly-expensive main binary has been parsed, and I think that's where the real perf difference you were measuring kicked in (you showed a 10.5 second versus 13.4 second time difference for preload versus parallel in the beginning), do I have that right? Or were you attaching to a stopped process with just dyld+main binary, I can't imagine doing those two in parallel would lead to the savings you measured. I think the preload approach where we can parallelize the two special binaries along with all the others on a "fully launched process" attach scenario is the right choice, thanks for investigating both of them and presenting both options. Do you prefer the non-preload approach? I know it is a simpler patch, but I can see how the perf benefit of preload could be significant with attaching to a fully launched process. https://github.com/llvm/llvm-project/pull/110439 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb] Make the system log a NOOP on Windows (PR #112052)
grandinj wrote: Windows system log : https://learn.microsoft.com/en-us/windows/win32/Events/windows-events https://github.com/llvm/llvm-project/pull/112052 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] Improve namespace lookup using .debug_names parent chain (PR #110062)
@@ -151,3 +151,19 @@ bool DWARFIndex::ProcessTypeDIEMatchQuery( return true; return callback(die); } + +void DWARFIndex::GetNamespacesWithParents( +ConstString name, const CompilerDeclContext &parent_decl_ctx, +llvm::function_ref callback) { + GetNamespaces(name, [&](DWARFDIE die) { +return ProcessNamespaceDieMatchParents(parent_decl_ctx, die, callback); jeffreytan81 wrote: Yes https://github.com/llvm/llvm-project/pull/110062 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] Improve namespace lookup using .debug_names parent chain (PR #110062)
@@ -565,6 +565,48 @@ void DebugNamesDWARFIndex::GetTypesWithQuery( m_fallback.GetTypesWithQuery(query, callback); } +void DebugNamesDWARFIndex::GetNamespacesWithParents( +ConstString name, const CompilerDeclContext &parent_decl_ctx, +llvm::function_ref callback) { + std::vector parent_contexts = + parent_decl_ctx.GetCompilerContext(); + if (parent_contexts.empty()) +return GetNamespaces(name, callback); + + llvm::SmallVector parent_named_contexts; + std::copy_if(parent_contexts.rbegin(), parent_contexts.rend(), + std::back_inserter(parent_named_contexts), + [](const CompilerContext &ctx) { return !ctx.name.IsEmpty(); }); jeffreytan81 wrote: Thanks for sharing, good to know. Did not find any lldb code using this API, so will keep existing code. https://github.com/llvm/llvm-project/pull/110062 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] Improve namespace lookup using .debug_names parent chain (PR #110062)
@@ -71,6 +71,14 @@ class DWARFIndex { virtual void GetTypesWithQuery(TypeQuery &query, llvm::function_ref callback); + /// Get namespace DIEs whose base name match \param name with \param jeffreytan81 wrote: There is no `query` in `GetNamespacesWithParents` API. Are you reading `GetTypesWithQuery()` API whose comment has mentioned `query` above. https://github.com/llvm/llvm-project/pull/110062 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] Improve namespace lookup using .debug_names parent chain (PR #110062)
https://github.com/jeffreytan81 updated https://github.com/llvm/llvm-project/pull/110062 >From c5bbc5f17dd5039fb9d5a01ade2397afd5d4c967 Mon Sep 17 00:00:00 2001 From: jeffreytan81 Date: Tue, 24 Sep 2024 14:43:44 -0700 Subject: [PATCH 1/2] Improve namespace lookup --- .../Plugins/SymbolFile/DWARF/DWARFIndex.cpp | 16 +++ .../Plugins/SymbolFile/DWARF/DWARFIndex.h | 11 + .../SymbolFile/DWARF/DebugNamesDWARFIndex.cpp | 42 +++ .../SymbolFile/DWARF/DebugNamesDWARFIndex.h | 4 +- .../SymbolFile/DWARF/SymbolFileDWARF.cpp | 2 +- 5 files changed, 73 insertions(+), 2 deletions(-) diff --git a/lldb/source/Plugins/SymbolFile/DWARF/DWARFIndex.cpp b/lldb/source/Plugins/SymbolFile/DWARF/DWARFIndex.cpp index dee90804c52584..c18edd10b96819 100644 --- a/lldb/source/Plugins/SymbolFile/DWARF/DWARFIndex.cpp +++ b/lldb/source/Plugins/SymbolFile/DWARF/DWARFIndex.cpp @@ -151,3 +151,19 @@ bool DWARFIndex::ProcessTypeDIEMatchQuery( return true; return callback(die); } + +void DWARFIndex::GetNamespacesWithParents( +ConstString name, const CompilerDeclContext &parent_decl_ctx, +llvm::function_ref callback) { + GetNamespaces(name, [&](DWARFDIE die) { +return ProcessNamespaceDieMatchParents(parent_decl_ctx, die, callback); + }); +} + +bool DWARFIndex::ProcessNamespaceDieMatchParents( +const CompilerDeclContext &parent_decl_ctx, DWARFDIE die, +llvm::function_ref callback) { + if (!SymbolFileDWARF::DIEInDeclContext(parent_decl_ctx, die)) +return true; + return callback(die); +} diff --git a/lldb/source/Plugins/SymbolFile/DWARF/DWARFIndex.h b/lldb/source/Plugins/SymbolFile/DWARF/DWARFIndex.h index fea3a4fd697389..ac1f75e91c2195 100644 --- a/lldb/source/Plugins/SymbolFile/DWARF/DWARFIndex.h +++ b/lldb/source/Plugins/SymbolFile/DWARF/DWARFIndex.h @@ -71,6 +71,14 @@ class DWARFIndex { virtual void GetTypesWithQuery(TypeQuery &query, llvm::function_ref callback); + /// Get namespace DIEs whose base name match \param name with \param + /// parent_decl_ctx in its decl parent chain. A base implementation + /// is provided. Specializations should override this if they are able to + /// provide a faster implementation. + virtual void + GetNamespacesWithParents(ConstString name, + const CompilerDeclContext &parent_decl_ctx, + llvm::function_ref callback); virtual void GetFunctions(const Module::LookupInfo &lookup_info, SymbolFileDWARF &dwarf, const CompilerDeclContext &parent_decl_ctx, @@ -127,6 +135,9 @@ class DWARFIndex { bool ProcessTypeDIEMatchQuery(TypeQuery &query, DWARFDIE die, llvm::function_ref callback); + bool ProcessNamespaceDieMatchParents( + const CompilerDeclContext &parent_decl_ctx, DWARFDIE die, + llvm::function_ref callback); }; } // namespace dwarf } // namespace lldb_private::plugin diff --git a/lldb/source/Plugins/SymbolFile/DWARF/DebugNamesDWARFIndex.cpp b/lldb/source/Plugins/SymbolFile/DWARF/DebugNamesDWARFIndex.cpp index c809e5ff7f8535..aeeb6b91c80fa3 100644 --- a/lldb/source/Plugins/SymbolFile/DWARF/DebugNamesDWARFIndex.cpp +++ b/lldb/source/Plugins/SymbolFile/DWARF/DebugNamesDWARFIndex.cpp @@ -565,6 +565,48 @@ void DebugNamesDWARFIndex::GetTypesWithQuery( m_fallback.GetTypesWithQuery(query, callback); } +void DebugNamesDWARFIndex::GetNamespacesWithParents( +ConstString name, const CompilerDeclContext &parent_decl_ctx, +llvm::function_ref callback) { + std::vector parent_contexts = + parent_decl_ctx.GetCompilerContext(); + if (parent_contexts.empty()) +return GetNamespaces(name, callback); + + llvm::SmallVector parent_named_contexts; + std::copy_if(parent_contexts.rbegin(), parent_contexts.rend(), + std::back_inserter(parent_named_contexts), + [](const CompilerContext &ctx) { return !ctx.name.IsEmpty(); }); + for (const DebugNames::Entry &entry : + m_debug_names_up->equal_range(name.GetStringRef())) { +lldb_private::dwarf::Tag entry_tag = entry.tag(); +if (entry_tag == DW_TAG_namespace || +entry_tag == DW_TAG_imported_declaration) { + std::optional> parent_chain = + getParentChain(entry); + if (!parent_chain) { +// Fallback: use the base class implementation. +if (!ProcessEntry(entry, [&](DWARFDIE die) { + return ProcessNamespaceDieMatchParents(parent_decl_ctx, die, + callback); +})) + return; +continue; + } + + if (WithinParentChain(parent_named_contexts, *parent_chain) && + !ProcessEntry(entry, [&](DWARFDIE die) { +// After .debug_names filtering still sending to base class for +// further filtering before calling the callback. +return ProcessNamespaceDieMatchParents(parent_decl_ctx, die, +
[Lldb-commits] [lldb] [lldb][AIX] Added XCOFF Object File Header for AIX (PR #111814)
DhruvSrivastavaX wrote: Okay sure. Thats not a problem Pavel, better to have it in smaller understandable pieces, so that it can be organised and reviewed properly. There are a couple of incoming code with such huge changes, it will be good to adhere to this systematic approach. So, I will go ahead and modify this PR to drop a smaller piece of ObjectFileXCOFF.h and ObjectFileXCOFF.cpp instead, which can be reviewed easily (some base skeleton and declaration of parent virtual functions etc). Once that gets pulled in, I will build my next few PRs on that in order to complete these new additions. Will also try to add relevant test cases. Thanks! https://github.com/llvm/llvm-project/pull/111814 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb] Expose structured command diagnostics via the SBAPI. (PR #112109)
https://github.com/adrian-prantl updated https://github.com/llvm/llvm-project/pull/112109 >From e60c7d3313748bc3147be188e2243f271d71d19a Mon Sep 17 00:00:00 2001 From: Adrian Prantl Date: Fri, 11 Oct 2024 19:27:37 -0700 Subject: [PATCH] [lldb] Expose structured command diagnostics via the SBAPI. This allows IDEs to render LLDB expression diagnostics to their liking without relying on characterprecise ASCII art from LLDB. It is exposed as a versioned SBStructuredData object, since it is expected that this may need to be tweaked based on actual usage. --- lldb/include/lldb/API/SBCommandReturnObject.h | 1 + lldb/include/lldb/API/SBStructuredData.h | 2 + .../lldb/Interpreter/CommandReturnObject.h| 13 ++- lldb/source/API/SBCommandReturnObject.cpp | 11 +++ .../Commands/CommandObjectDWIMPrint.cpp | 2 +- .../Commands/CommandObjectExpression.cpp | 42 +++--- .../source/Interpreter/CommandInterpreter.cpp | 23 +++-- .../Interpreter/CommandReturnObject.cpp | 84 +++ .../diagnostics/TestExprDiagnostics.py| 61 -- .../Shell/Commands/Inputs/multiline-expr.txt | 6 ++ .../Commands/command-expr-diagnostics.test| 28 +++ 11 files changed, 167 insertions(+), 106 deletions(-) create mode 100644 lldb/test/Shell/Commands/Inputs/multiline-expr.txt create mode 100644 lldb/test/Shell/Commands/command-expr-diagnostics.test diff --git a/lldb/include/lldb/API/SBCommandReturnObject.h b/lldb/include/lldb/API/SBCommandReturnObject.h index f96384a4710b16..e8e20a3f3016b8 100644 --- a/lldb/include/lldb/API/SBCommandReturnObject.h +++ b/lldb/include/lldb/API/SBCommandReturnObject.h @@ -45,6 +45,7 @@ class LLDB_API SBCommandReturnObject { const char *GetOutput(); const char *GetError(); + SBStructuredData GetErrorData(); #ifndef SWIG LLDB_DEPRECATED_FIXME("Use PutOutput(SBFile) or PutOutput(FileSP)", diff --git a/lldb/include/lldb/API/SBStructuredData.h b/lldb/include/lldb/API/SBStructuredData.h index fc6e1ec95c7b86..ccdd12cab94b2f 100644 --- a/lldb/include/lldb/API/SBStructuredData.h +++ b/lldb/include/lldb/API/SBStructuredData.h @@ -9,6 +9,7 @@ #ifndef LLDB_API_SBSTRUCTUREDDATA_H #define LLDB_API_SBSTRUCTUREDDATA_H +#include "lldb/API/SBCommandReturnObject.h" #include "lldb/API/SBDefines.h" #include "lldb/API/SBModule.h" #include "lldb/API/SBScriptObject.h" @@ -110,6 +111,7 @@ class SBStructuredData { protected: friend class SBAttachInfo; + friend class SBCommandReturnObject; friend class SBLaunchInfo; friend class SBDebugger; friend class SBTarget; diff --git a/lldb/include/lldb/Interpreter/CommandReturnObject.h b/lldb/include/lldb/Interpreter/CommandReturnObject.h index eda841869ba432..a491a6c1535b11 100644 --- a/lldb/include/lldb/Interpreter/CommandReturnObject.h +++ b/lldb/include/lldb/Interpreter/CommandReturnObject.h @@ -13,6 +13,7 @@ #include "lldb/Utility/DiagnosticsRendering.h" #include "lldb/Utility/StreamString.h" #include "lldb/Utility/StreamTee.h" +#include "lldb/Utility/StructuredData.h" #include "lldb/lldb-private.h" #include "llvm/ADT/StringRef.h" @@ -31,7 +32,7 @@ class CommandReturnObject { ~CommandReturnObject() = default; /// Format any inline diagnostics with an indentation of \c indent. - llvm::StringRef GetInlineDiagnosticString(unsigned indent); + std::string GetInlineDiagnosticString(unsigned indent); llvm::StringRef GetOutputString() { lldb::StreamSP stream_sp(m_out_stream.GetStreamAtIndex(eStreamStringIndex)); @@ -40,7 +41,13 @@ class CommandReturnObject { return llvm::StringRef(); } - llvm::StringRef GetErrorString(); + /// Return the errors as a string. + /// + /// If \c with_diagnostics is true, all diagnostics are also + /// rendered into the string. Otherwise the expectation is that they + /// are fetched with \ref GetInlineDiagnosticString(). + std::string GetErrorString(bool with_diagnostics = true); + StructuredData::ObjectSP GetErrorData(); Stream &GetOutputStream() { // Make sure we at least have our normal string stream output stream @@ -168,7 +175,6 @@ class CommandReturnObject { StreamTee m_out_stream; StreamTee m_err_stream; std::vector m_diagnostics; - StreamString m_diag_stream; std::optional m_diagnostic_indent; lldb::ReturnStatus m_status = lldb::eReturnStatusStarted; @@ -178,6 +184,7 @@ class CommandReturnObject { /// If true, then the input handle from the debugger will be hooked up. bool m_interactive = true; + bool m_colors; }; } // namespace lldb_private diff --git a/lldb/source/API/SBCommandReturnObject.cpp b/lldb/source/API/SBCommandReturnObject.cpp index a94eff75ffcb9e..9df8aa48b99366 100644 --- a/lldb/source/API/SBCommandReturnObject.cpp +++ b/lldb/source/API/SBCommandReturnObject.cpp @@ -11,6 +11,8 @@ #include "lldb/API/SBError.h" #include "lldb/API/SBFile.h" #include "lldb/API/SBStream.h" +#include "lldb/API/SBStructuredData.h" +#include "lldb/Core/Structured