[Lldb-commits] [lldb] [LLDB] Add an assert to verify sign_bit_pos is within the valid range (NFC) (PR #95678)
https://github.com/xgupta updated https://github.com/llvm/llvm-project/pull/95678 >From c02fa111c62f98a20055745d5d8b75aea8fd748a Mon Sep 17 00:00:00 2001 From: Shivam Gupta Date: Sun, 16 Jun 2024 00:21:51 +0530 Subject: [PATCH 1/2] [LLDB] Add an assert to verify sign_bit_pos is within the valid range --- lldb/source/Utility/Scalar.cpp | 31 +++ 1 file changed, 15 insertions(+), 16 deletions(-) diff --git a/lldb/source/Utility/Scalar.cpp b/lldb/source/Utility/Scalar.cpp index c680101aa9efa..6e2f1ca4c1613 100644 --- a/lldb/source/Utility/Scalar.cpp +++ b/lldb/source/Utility/Scalar.cpp @@ -745,26 +745,25 @@ Status Scalar::SetValueFromData(const DataExtractor &data, bool Scalar::SignExtend(uint32_t sign_bit_pos) { const uint32_t max_bit_pos = GetByteSize() * 8; + assert(sign_bit_pos < max_bit_pos); - if (sign_bit_pos < max_bit_pos) { -switch (m_type) { -case Scalar::e_void: -case Scalar::e_float: - return false; + switch (m_type) { + case Scalar::e_void: + case Scalar::e_float: +return false; -case Scalar::e_int: - if (sign_bit_pos < (max_bit_pos - 1)) { -llvm::APInt sign_bit = llvm::APInt::getSignMask(sign_bit_pos + 1); -llvm::APInt bitwize_and = m_integer & sign_bit; -if (bitwize_and.getBoolValue()) { - llvm::APInt mask = - ~(sign_bit) + llvm::APInt(m_integer.getBitWidth(), 1); - m_integer |= APSInt(std::move(mask), m_integer.isUnsigned()); -} -return true; + case Scalar::e_int: +if (sign_bit_pos < (max_bit_pos - 1)) { + llvm::APInt sign_bit = llvm::APInt::getSignMask(sign_bit_pos + 1); + llvm::APInt bitwize_and = m_integer & sign_bit; + if (bitwize_and.getBoolValue()) { +llvm::APInt mask = +~(sign_bit) + llvm::APInt(m_integer.getBitWidth(), 1); +m_integer |= APSInt(std::move(mask), m_integer.isUnsigned()); } - break; + return true; } +break; } return false; } >From fc09409c733a4f5c92fdbb30cb6e23858bf1e49a Mon Sep 17 00:00:00 2001 From: Shivam Gupta Date: Wed, 19 Jun 2024 13:57:55 +0530 Subject: [PATCH 2/2] address review suggestion --- lldb/source/Utility/Scalar.cpp | 24 1 file changed, 8 insertions(+), 16 deletions(-) diff --git a/lldb/source/Utility/Scalar.cpp b/lldb/source/Utility/Scalar.cpp index 6e2f1ca4c1613..496f402a74114 100644 --- a/lldb/source/Utility/Scalar.cpp +++ b/lldb/source/Utility/Scalar.cpp @@ -747,25 +747,17 @@ bool Scalar::SignExtend(uint32_t sign_bit_pos) { const uint32_t max_bit_pos = GetByteSize() * 8; assert(sign_bit_pos < max_bit_pos); - switch (m_type) { - case Scalar::e_void: - case Scalar::e_float: + if (m_type != Scalar::e_int || sign_bit_pos >= (max_bit_pos - 1)) { return false; + } - case Scalar::e_int: -if (sign_bit_pos < (max_bit_pos - 1)) { - llvm::APInt sign_bit = llvm::APInt::getSignMask(sign_bit_pos + 1); - llvm::APInt bitwize_and = m_integer & sign_bit; - if (bitwize_and.getBoolValue()) { -llvm::APInt mask = -~(sign_bit) + llvm::APInt(m_integer.getBitWidth(), 1); -m_integer |= APSInt(std::move(mask), m_integer.isUnsigned()); - } - return true; -} -break; + llvm::APInt sign_bit = llvm::APInt::getSignMask(sign_bit_pos + 1); + llvm::APInt bitwize_and = m_integer & sign_bit; + if (bitwize_and.getBoolValue()) { +llvm::APInt mask = ~(sign_bit) + llvm::APInt(m_integer.getBitWidth(), 1); +m_integer |= APSInt(std::move(mask), m_integer.isUnsigned()); } - return false; + return true; } size_t Scalar::GetAsMemoryData(void *dst, size_t dst_len, ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [API] add GetSyntheticValue (PR #95959)
https://github.com/labath edited https://github.com/llvm/llvm-project/pull/95959 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [API] add GetSyntheticValue (PR #95959)
https://github.com/labath approved this pull request. Thanks. https://github.com/llvm/llvm-project/pull/95959 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [API] add GetSyntheticValue (PR #95959)
@@ -155,6 +155,18 @@ def cleanup(): ], ) labath wrote: ```suggestion ) self.dbg.GetCategory("CCCSynth").SetEnabled(False) ``` I'm not sure how lldb chooses the summary providers in case of conflicts, but since that's not what we're testing here, we might as well remove the ambiguity. https://github.com/llvm/llvm-project/pull/95959 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb] Unify Platform::ResolveExecutable (PR #96256)
https://github.com/labath edited https://github.com/llvm/llvm-project/pull/96256 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb] Unify Platform::ResolveExecutable (PR #96256)
https://github.com/labath approved this pull request. Good stuff. https://github.com/llvm/llvm-project/pull/96256 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb] Unify Platform::ResolveExecutable (PR #96256)
@@ -1004,10 +1004,7 @@ class Platform : public PluginInterface { virtual const char *GetCacheHostname(); - virtual Status - ResolveRemoteExecutable(const ModuleSpec &module_spec, - lldb::ModuleSP &exe_module_sp, - const FileSpecList *module_search_paths_ptr); + /// The method is virtual for mocking in the unit tests. labath wrote: Which function is this comment referring to (if I'm reading the diff right, it's just floating there)? https://github.com/llvm/llvm-project/pull/96256 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb] Parse and display register field enums (PR #95768)
https://github.com/DavidSpickett updated https://github.com/llvm/llvm-project/pull/95768 >From a9b542a1686be0afd73ad89a504d2c66ba6c4a4f Mon Sep 17 00:00:00 2001 From: David Spickett Date: Mon, 11 Mar 2024 10:56:29 + Subject: [PATCH 1/3] [lldb] Parse and display register field enums This teaches lldb to parse the enum XML elements sent by lldb-server, and make use of the information in `register read` and `register info`. The format is described in https://sourceware.org/gdb/current/onlinedocs/gdb.html/Enum-Target-Types.html. The target XML parser will drop any invalid enum or evalue. If we find multiple evalue for the same value, we will use the last one we find. The order of evalues from the XML is preserved as there may be good reason they are not in numerical order. --- lldb/include/lldb/Target/RegisterFlags.h | 7 + lldb/source/Core/DumpRegisterInfo.cpp | 7 +- .../Process/gdb-remote/ProcessGDBRemote.cpp | 188 +- .../Process/gdb-remote/ProcessGDBRemote.h | 5 + .../RegisterTypeBuilderClang.cpp | 30 +- lldb/source/Target/RegisterFlags.cpp | 10 + .../gdb_remote_client/TestXMLRegisterFlags.py | 322 ++ lldb/unittests/Core/DumpRegisterInfoTest.cpp | 26 ++ 8 files changed, 573 insertions(+), 22 deletions(-) diff --git a/lldb/include/lldb/Target/RegisterFlags.h b/lldb/include/lldb/Target/RegisterFlags.h index 1c6bf5dcf4a7f..628c841c10d95 100644 --- a/lldb/include/lldb/Target/RegisterFlags.h +++ b/lldb/include/lldb/Target/RegisterFlags.h @@ -32,10 +32,15 @@ class FieldEnum { : m_value(value), m_name(std::move(name)) {} void ToXML(Stream &strm) const; + +void log(Log *log) const; }; typedef std::vector Enumerators; + // GDB also includes a "size" that is the size of the underlying register. + // We will not store that here but instead use the size of the register + // this gets attached to when emitting XML. FieldEnum(std::string id, const Enumerators &enumerators); const Enumerators &GetEnumerators() const { return m_enumerators; } @@ -44,6 +49,8 @@ class FieldEnum { void ToXML(Stream &strm, unsigned size) const; + void log(Log *log) const; + private: std::string m_id; Enumerators m_enumerators; diff --git a/lldb/source/Core/DumpRegisterInfo.cpp b/lldb/source/Core/DumpRegisterInfo.cpp index 8334795416902..eccc6784cd497 100644 --- a/lldb/source/Core/DumpRegisterInfo.cpp +++ b/lldb/source/Core/DumpRegisterInfo.cpp @@ -111,6 +111,11 @@ void lldb_private::DoDumpRegisterInfo( }; DumpList(strm, "In sets: ", in_sets, emit_set); - if (flags_type) + if (flags_type) { strm.Printf("\n\n%s", flags_type->AsTable(terminal_width).c_str()); + +std::string enumerators = flags_type->DumpEnums(terminal_width); +if (enumerators.size()) + strm << "\n\n" << enumerators; + } } diff --git a/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp b/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp index a5a731981299f..4754698e6e88f 100644 --- a/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp +++ b/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp @@ -4179,21 +4179,124 @@ struct GdbServerTargetInfo { RegisterSetMap reg_set_map; }; -static std::vector ParseFlagsFields(XMLNode flags_node, - unsigned size) { +static FieldEnum::Enumerators ParseEnumEvalues(const XMLNode &enum_node) { + Log *log(GetLog(GDBRLog::Process)); + // We will use the last instance of each value. Also we preserve the order + // of declaration in the XML, as it may not be numerical. + std::map enumerators; + + enum_node.ForEachChildElementWithName( + "evalue", [&enumerators, &log](const XMLNode &enumerator_node) { +std::optional name; +std::optional value; + +enumerator_node.ForEachAttribute( +[&name, &value, &log](const llvm::StringRef &attr_name, + const llvm::StringRef &attr_value) { + if (attr_name == "name") { +if (attr_value.size()) + name = attr_value; +else + LLDB_LOG(log, "ProcessGDBRemote::ParseEnumEvalues " +"Ignoring empty name in evalue"); + } else if (attr_name == "value") { +uint64_t parsed_value = 0; +if (llvm::to_integer(attr_value, parsed_value)) + value = parsed_value; +else + LLDB_LOG(log, + "ProcessGDBRemote::ParseEnumEvalues " + "Invalid value \"{0}\" in " + "evalue", + attr_value.data()); + } else +LLDB_LOG(log, + "ProcessGDBRemote::ParseEnumEvalues Ignoring " + "unknown attribute " +
[Lldb-commits] [lldb] [lldb][ExpressionParser][NFCI] Add new DoPrepareForExecution interface to be implemented by language plugins (PR #96290)
https://github.com/Michael137 created https://github.com/llvm/llvm-project/pull/96290 This patch adds a new `DoPrepareForExecution` API, which can be implemented by the Clang and Swift language plugins. This also moves `RunStaticInitializers` into `ExpressionParser::PrepareForExecution`, so we call it consistently between language plugins. This *should* be mostly NFC (the static initializers will still only run after we finished parsing). We've been living on this patch downstream for sometime now. >From 67d8bab2d2d42ca3ec5d07efd3be94e614dde2e9 Mon Sep 17 00:00:00 2001 From: Michael Buch Date: Thu, 20 Jun 2024 18:29:15 +0100 Subject: [PATCH] [lldb][ExpressionParser] Add DoPrepareForExecution API --- .../lldb/Expression/ExpressionParser.h| 25 ++- lldb/source/Expression/CMakeLists.txt | 1 + lldb/source/Expression/ExpressionParser.cpp | 73 +++ .../Clang/ClangExpressionParser.cpp | 46 +--- .../Clang/ClangExpressionParser.h | 23 ++ .../Clang/ClangUserExpression.cpp | 15 6 files changed, 103 insertions(+), 80 deletions(-) create mode 100644 lldb/source/Expression/ExpressionParser.cpp diff --git a/lldb/include/lldb/Expression/ExpressionParser.h b/lldb/include/lldb/Expression/ExpressionParser.h index ab5223c915530..2ef7e036909c7 100644 --- a/lldb/include/lldb/Expression/ExpressionParser.h +++ b/lldb/include/lldb/Expression/ExpressionParser.h @@ -119,14 +119,35 @@ class ExpressionParser { /// \return /// An error code indicating the success or failure of the operation. /// Test with Success(). - virtual Status + Status PrepareForExecution(lldb::addr_t &func_addr, lldb::addr_t &func_end, std::shared_ptr &execution_unit_sp, ExecutionContext &exe_ctx, bool &can_interpret, - lldb_private::ExecutionPolicy execution_policy) = 0; + lldb_private::ExecutionPolicy execution_policy); bool GetGenerateDebugInfo() const { return m_generate_debug_info; } +protected: + virtual Status + DoPrepareForExecution(lldb::addr_t &func_addr, lldb::addr_t &func_end, +std::shared_ptr &execution_unit_sp, +ExecutionContext &exe_ctx, bool &can_interpret, +lldb_private::ExecutionPolicy execution_policy) = 0; + +private: + /// Run all static initializers for an execution unit. + /// + /// \param[in] execution_unit_sp + /// The execution unit. + /// + /// \param[in] exe_ctx + /// The execution context to use when running them. Thread can't be null. + /// + /// \return + /// The error code indicating the + Status RunStaticInitializers(lldb::IRExecutionUnitSP &execution_unit_sp, + ExecutionContext &exe_ctx); + protected: Expression &m_expr; ///< The expression to be parsed bool m_generate_debug_info; diff --git a/lldb/source/Expression/CMakeLists.txt b/lldb/source/Expression/CMakeLists.txt index 9ba5fefc09b6a..be1e132f7aaad 100644 --- a/lldb/source/Expression/CMakeLists.txt +++ b/lldb/source/Expression/CMakeLists.txt @@ -3,6 +3,7 @@ add_lldb_library(lldbExpression NO_PLUGIN_DEPENDENCIES DWARFExpression.cpp DWARFExpressionList.cpp Expression.cpp + ExpressionParser.cpp ExpressionTypeSystemHelper.cpp ExpressionVariable.cpp FunctionCaller.cpp diff --git a/lldb/source/Expression/ExpressionParser.cpp b/lldb/source/Expression/ExpressionParser.cpp new file mode 100644 index 0..ac727be78e8d3 --- /dev/null +++ b/lldb/source/Expression/ExpressionParser.cpp @@ -0,0 +1,73 @@ +//===-- ExpressionParser.cpp --===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===--===// + +#include "lldb/Expression/ExpressionParser.h" +#include "lldb/Expression/DiagnosticManager.h" +#include "lldb/Expression/IRExecutionUnit.h" +#include "lldb/Target/ExecutionContext.h" +#include "lldb/Target/ThreadPlanCallFunction.h" + +using namespace lldb_private; + +Status ExpressionParser::PrepareForExecution( +lldb::addr_t &func_addr, lldb::addr_t &func_end, +std::shared_ptr &execution_unit_sp, +ExecutionContext &exe_ctx, bool &can_interpret, +lldb_private::ExecutionPolicy execution_policy) { + Status status = + DoPrepareForExecution(func_addr, func_end, execution_unit_sp, exe_ctx, +can_interpret, execution_policy); + if (status.Success() && exe_ctx.GetProcessPtr() && exe_ctx.HasThreadScope()) { +status = RunStaticInitializers(execution_unit_sp, exe_ctx); + } + return status; +} + +Status ExpressionParser::RunStaticInitializers( +lldb::IRExecutionUnitSP &execution_
[Lldb-commits] [lldb] [lldb][ExpressionParser][NFCI] Add new DoPrepareForExecution interface to be implemented by language plugins (PR #96290)
llvmbot wrote: @llvm/pr-subscribers-lldb Author: Michael Buch (Michael137) Changes This patch adds a new `DoPrepareForExecution` API, which can be implemented by the Clang and Swift language plugins. This also moves `RunStaticInitializers` into `ExpressionParser::PrepareForExecution`, so we call it consistently between language plugins. This *should* be mostly NFC (the static initializers will still only run after we finished parsing). We've been living on this patch downstream for sometime now. --- Full diff: https://github.com/llvm/llvm-project/pull/96290.diff 6 Files Affected: - (modified) lldb/include/lldb/Expression/ExpressionParser.h (+23-2) - (modified) lldb/source/Expression/CMakeLists.txt (+1) - (added) lldb/source/Expression/ExpressionParser.cpp (+73) - (modified) lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionParser.cpp (+1-45) - (modified) lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionParser.h (+5-18) - (modified) lldb/source/Plugins/ExpressionParser/Clang/ClangUserExpression.cpp (-15) ``diff diff --git a/lldb/include/lldb/Expression/ExpressionParser.h b/lldb/include/lldb/Expression/ExpressionParser.h index ab5223c915530..2ef7e036909c7 100644 --- a/lldb/include/lldb/Expression/ExpressionParser.h +++ b/lldb/include/lldb/Expression/ExpressionParser.h @@ -119,14 +119,35 @@ class ExpressionParser { /// \return /// An error code indicating the success or failure of the operation. /// Test with Success(). - virtual Status + Status PrepareForExecution(lldb::addr_t &func_addr, lldb::addr_t &func_end, std::shared_ptr &execution_unit_sp, ExecutionContext &exe_ctx, bool &can_interpret, - lldb_private::ExecutionPolicy execution_policy) = 0; + lldb_private::ExecutionPolicy execution_policy); bool GetGenerateDebugInfo() const { return m_generate_debug_info; } +protected: + virtual Status + DoPrepareForExecution(lldb::addr_t &func_addr, lldb::addr_t &func_end, +std::shared_ptr &execution_unit_sp, +ExecutionContext &exe_ctx, bool &can_interpret, +lldb_private::ExecutionPolicy execution_policy) = 0; + +private: + /// Run all static initializers for an execution unit. + /// + /// \param[in] execution_unit_sp + /// The execution unit. + /// + /// \param[in] exe_ctx + /// The execution context to use when running them. Thread can't be null. + /// + /// \return + /// The error code indicating the + Status RunStaticInitializers(lldb::IRExecutionUnitSP &execution_unit_sp, + ExecutionContext &exe_ctx); + protected: Expression &m_expr; ///< The expression to be parsed bool m_generate_debug_info; diff --git a/lldb/source/Expression/CMakeLists.txt b/lldb/source/Expression/CMakeLists.txt index 9ba5fefc09b6a..be1e132f7aaad 100644 --- a/lldb/source/Expression/CMakeLists.txt +++ b/lldb/source/Expression/CMakeLists.txt @@ -3,6 +3,7 @@ add_lldb_library(lldbExpression NO_PLUGIN_DEPENDENCIES DWARFExpression.cpp DWARFExpressionList.cpp Expression.cpp + ExpressionParser.cpp ExpressionTypeSystemHelper.cpp ExpressionVariable.cpp FunctionCaller.cpp diff --git a/lldb/source/Expression/ExpressionParser.cpp b/lldb/source/Expression/ExpressionParser.cpp new file mode 100644 index 0..ac727be78e8d3 --- /dev/null +++ b/lldb/source/Expression/ExpressionParser.cpp @@ -0,0 +1,73 @@ +//===-- ExpressionParser.cpp --===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===--===// + +#include "lldb/Expression/ExpressionParser.h" +#include "lldb/Expression/DiagnosticManager.h" +#include "lldb/Expression/IRExecutionUnit.h" +#include "lldb/Target/ExecutionContext.h" +#include "lldb/Target/ThreadPlanCallFunction.h" + +using namespace lldb_private; + +Status ExpressionParser::PrepareForExecution( +lldb::addr_t &func_addr, lldb::addr_t &func_end, +std::shared_ptr &execution_unit_sp, +ExecutionContext &exe_ctx, bool &can_interpret, +lldb_private::ExecutionPolicy execution_policy) { + Status status = + DoPrepareForExecution(func_addr, func_end, execution_unit_sp, exe_ctx, +can_interpret, execution_policy); + if (status.Success() && exe_ctx.GetProcessPtr() && exe_ctx.HasThreadScope()) { +status = RunStaticInitializers(execution_unit_sp, exe_ctx); + } + return status; +} + +Status ExpressionParser::RunStaticInitializers( +lldb::IRExecutionUnitSP &execution_unit_sp, ExecutionContext &exe_ctx) { + lldb_private::Status err; + + lldbassert(execution_unit_sp.get()); + lldbassert(ex
[Lldb-commits] [lldb] [lldb][ExpressionParser][NFCI] Add new DoPrepareForExecution interface to be implemented by language plugins (PR #96290)
https://github.com/Michael137 edited https://github.com/llvm/llvm-project/pull/96290 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb] Change lldb's breakpoint handling behavior (PR #96260)
https://github.com/labath edited https://github.com/llvm/llvm-project/pull/96260 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb] Change lldb's breakpoint handling behavior (PR #96260)
@@ -377,6 +382,19 @@ class Thread : public std::enable_shared_from_this, virtual void SetQueueLibdispatchQueueAddress(lldb::addr_t dispatch_queue_t) {} + /// When a thread has executed/trapped a breakpoint, set the address of that + /// breakpoint so we know it has been hit already, and should be silently + /// stepped past on resume. labath wrote: I'm a little unclear as to why do we need to store this separately. Shouldn't this already be stored in the stop reason of the thread (i.e., StopInfoBreakpoint implies we've hit a breakpoint, and the breakpoint site within it should give us the PC value)? https://github.com/llvm/llvm-project/pull/96260 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb] Change lldb's breakpoint handling behavior (PR #96260)
https://github.com/labath commented: I like this change a lot, but I'm wondering if there's a clearer way to store the intermediate state. It seems like this info could go into the StopInfo class, which would have the benefit of automatically being backed up when doing expression evaluation. Is there a reason to not do that? If the reason is that the StopInfo of the thread has been cleared by the time we call SetupForResume (and there's no good way to change that), maybe we could pass the old stop info to the function as an argument, since that's effectively what the function is doing -- deciding how to resume the thread based on how it was previously stopped. Regarding the scenarios you mention in the description (moving the PC to a breakpoint site, setting a breakpoint site at the current pc), are these tested by any of the existing tests? > Caroline Tice mentioned it is also a problem they've had with putting a > breakpoint on _dl_debug_state I believe this was fixed by 60b90b523323f8196a9e4a68b1f33358624c09eb. https://github.com/llvm/llvm-project/pull/96260 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb] Change lldb's breakpoint handling behavior (PR #96260)
@@ -377,6 +382,19 @@ class Thread : public std::enable_shared_from_this, virtual void SetQueueLibdispatchQueueAddress(lldb::addr_t dispatch_queue_t) {} + /// When a thread has executed/trapped a breakpoint, set the address of that + /// breakpoint so we know it has been hit already, and should be silently + /// stepped past on resume. + void SetThreadHitBreakpointAtAddr(lldb::addr_t pc) { m_hit_bp_at_addr = pc; } + + /// When a thread stops at a breakpoint instruction/address, but has not yet + /// executed/triggered it, record that so we can detect when a user adds a + /// breakpoint (or changes a thread to a breakpoint site) and we need to + /// silently step past that when resuming. + void SetThreadStoppedAtBreakpointSite(lldb::addr_t pc) { +m_bpsite_at_stop_pc = pc; + } labath wrote: I'm also finding it hard to wrap my head around the meaning of this variable. If I understand correctly it tells us: the pc that we've stopped at; that there was a breakpoint site there at the time of the stop; and we did not hit that site. I'm wondering if it would be clearer if we unpacked that. What if we: - unconditionally stored the PC of the last stop. Maybe this could be even a part of the StopInfo class, as I think it could be useful to see the PC value at the time of the stop, even if the user changed the PC afterwards. - a flag indicating whether we stopped at a breakpoint site, regardless of whether we've hit it or not (per the previous comment, that could be indicated by the stop reason). This doesn't really look like it belongs to StopInfo class, but I think I'd be fine with putting it there for collocation purposes. https://github.com/llvm/llvm-project/pull/96260 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] 906316e - [lldb] More descriptive name for register flags logging functions
Author: David Spickett Date: 2024-06-21T10:05:48Z New Revision: 906316eababcbcfd71e357aa3b66bdfc9237b3b9 URL: https://github.com/llvm/llvm-project/commit/906316eababcbcfd71e357aa3b66bdfc9237b3b9 DIFF: https://github.com/llvm/llvm-project/commit/906316eababcbcfd71e357aa3b66bdfc9237b3b9.diff LOG: [lldb] More descriptive name for register flags logging functions This was requested on a review for enum code that added new log functions. Added: Modified: lldb/include/lldb/Target/RegisterFlags.h lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp lldb/source/Target/RegisterFlags.cpp Removed: diff --git a/lldb/include/lldb/Target/RegisterFlags.h b/lldb/include/lldb/Target/RegisterFlags.h index 1c6bf5dcf4a7f..1112972cf72e1 100644 --- a/lldb/include/lldb/Target/RegisterFlags.h +++ b/lldb/include/lldb/Target/RegisterFlags.h @@ -89,7 +89,7 @@ class RegisterFlags { unsigned GetEnd() const { return m_end; } const FieldEnum *GetEnum() const { return m_enum_type; } bool Overlaps(const Field &other) const; -void log(Log *log) const; +void DumpToLog(Log *log) const; /// Return the number of bits between this field and the other, that are not /// covered by either field. @@ -158,7 +158,7 @@ class RegisterFlags { const std::vector &GetFields() const { return m_fields; } const std::string &GetID() const { return m_id; } unsigned GetSize() const { return m_size; } - void log(Log *log) const; + void DumpToLog(Log *log) const; /// Produce a text table showing the layout of all the fields. Unnamed/padding /// fields will be included, with only their positions shown. diff --git a/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp b/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp index a5a731981299f..43c61fc9df6e4 100644 --- a/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp +++ b/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp @@ -4383,7 +4383,7 @@ bool ParseRegisters( ParseFlags(feature_node, registers_flags_types); for (const auto &flags : registers_flags_types) -flags.second->log(log); +flags.second->DumpToLog(log); feature_node.ForEachChildElementWithName( "reg", diff --git a/lldb/source/Target/RegisterFlags.cpp b/lldb/source/Target/RegisterFlags.cpp index d8a87090a7a41..d2fc5392f1a76 100644 --- a/lldb/source/Target/RegisterFlags.cpp +++ b/lldb/source/Target/RegisterFlags.cpp @@ -47,7 +47,7 @@ RegisterFlags::Field::Field(std::string name, unsigned start, unsigned end, } } -void RegisterFlags::Field::log(Log *log) const { +void RegisterFlags::Field::DumpToLog(Log *log) const { LLDB_LOG(log, " Name: \"{0}\" Start: {1} End: {2}", m_name.c_str(), m_start, m_end); } @@ -156,10 +156,10 @@ RegisterFlags::RegisterFlags(std::string id, unsigned size, SetFields(fields); } -void RegisterFlags::log(Log *log) const { +void RegisterFlags::DumpToLog(Log *log) const { LLDB_LOG(log, "ID: \"{0}\" Size: {1}", m_id.c_str(), m_size); for (const Field &field : m_fields) -field.log(log); +field.DumpToLog(log); } static StreamString FormatCell(const StreamString &content, ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb/DWARF] Fix type definition search with simple template names (PR #95905)
@@ -3073,14 +3073,43 @@ SymbolFileDWARF::FindDefinitionTypeForDWARFDeclContext(const DWARFDIE &die) { // See comments below about -gsimple-template-names for why we attempt to // compute missing template parameter names. -ConstString template_params; -if (type_system) { - DWARFASTParser *dwarf_ast = type_system->GetDWARFParser(); - if (dwarf_ast) -template_params = dwarf_ast->GetDIEClassTemplateParams(die); +std::vector template_params; +DWARFDeclContext die_dwarf_decl_ctx; +DWARFASTParser *dwarf_ast = type_system ? type_system->GetDWARFParser() : nullptr; +for (DWARFDIE ctx_die = die; ctx_die && !isUnitType(ctx_die.Tag()); + ctx_die = ctx_die.GetParentDeclContextDIE()) { + die_dwarf_decl_ctx.AppendDeclContext(ctx_die.Tag(), ctx_die.GetName()); + template_params.push_back( + (ctx_die.IsStructUnionOrClass() && dwarf_ast) + ? dwarf_ast->GetDIEClassTemplateParams(ctx_die) + : ""); } +const bool any_template_params = llvm::any_of( +template_params, [](llvm::StringRef p) { return !p.empty(); }); -const DWARFDeclContext die_dwarf_decl_ctx = die.GetDWARFDeclContext(); +auto die_matches = [&](DWARFDIE type_die) { + // Resolve the type if both have the same tag or {class, struct} tags. + const bool tag_matches = + type_die.Tag() == tag || + (IsStructOrClassTag(type_die.Tag()) && IsStructOrClassTag(tag)); labath wrote: > I guess printing types in lldb would be technically wrong, since it'd print > as "struct MyType {" instead of "class MyType {"? Yes, that's why I said "it matters for ast construction". I think it would nice to still print the type in the original way, which mostly comes up when someone (technically incorrectly) forward-declares something as `struct Foo`, but defines it as a class. If we wanted to, we could make all members public regardless of the tag type. I don't know why we don't do that. Is it just because it's nice to see the original access specifiers in the type readouts ? (a rhetorical question) I know that the access specifier can in theory affect the type layout, but I don't think that's true for any real world ABI (and dwarf already encodes the layout anyway).. Some users may declare types inside expressions and their members would be private without the hack, but maybe they should just get what they asked for... https://github.com/llvm/llvm-project/pull/95905 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb] Parse and display register field enums (PR #95768)
https://github.com/DavidSpickett updated https://github.com/llvm/llvm-project/pull/95768 >From a9b542a1686be0afd73ad89a504d2c66ba6c4a4f Mon Sep 17 00:00:00 2001 From: David Spickett Date: Mon, 11 Mar 2024 10:56:29 + Subject: [PATCH 1/4] [lldb] Parse and display register field enums This teaches lldb to parse the enum XML elements sent by lldb-server, and make use of the information in `register read` and `register info`. The format is described in https://sourceware.org/gdb/current/onlinedocs/gdb.html/Enum-Target-Types.html. The target XML parser will drop any invalid enum or evalue. If we find multiple evalue for the same value, we will use the last one we find. The order of evalues from the XML is preserved as there may be good reason they are not in numerical order. --- lldb/include/lldb/Target/RegisterFlags.h | 7 + lldb/source/Core/DumpRegisterInfo.cpp | 7 +- .../Process/gdb-remote/ProcessGDBRemote.cpp | 188 +- .../Process/gdb-remote/ProcessGDBRemote.h | 5 + .../RegisterTypeBuilderClang.cpp | 30 +- lldb/source/Target/RegisterFlags.cpp | 10 + .../gdb_remote_client/TestXMLRegisterFlags.py | 322 ++ lldb/unittests/Core/DumpRegisterInfoTest.cpp | 26 ++ 8 files changed, 573 insertions(+), 22 deletions(-) diff --git a/lldb/include/lldb/Target/RegisterFlags.h b/lldb/include/lldb/Target/RegisterFlags.h index 1c6bf5dcf4a7f..628c841c10d95 100644 --- a/lldb/include/lldb/Target/RegisterFlags.h +++ b/lldb/include/lldb/Target/RegisterFlags.h @@ -32,10 +32,15 @@ class FieldEnum { : m_value(value), m_name(std::move(name)) {} void ToXML(Stream &strm) const; + +void log(Log *log) const; }; typedef std::vector Enumerators; + // GDB also includes a "size" that is the size of the underlying register. + // We will not store that here but instead use the size of the register + // this gets attached to when emitting XML. FieldEnum(std::string id, const Enumerators &enumerators); const Enumerators &GetEnumerators() const { return m_enumerators; } @@ -44,6 +49,8 @@ class FieldEnum { void ToXML(Stream &strm, unsigned size) const; + void log(Log *log) const; + private: std::string m_id; Enumerators m_enumerators; diff --git a/lldb/source/Core/DumpRegisterInfo.cpp b/lldb/source/Core/DumpRegisterInfo.cpp index 8334795416902..eccc6784cd497 100644 --- a/lldb/source/Core/DumpRegisterInfo.cpp +++ b/lldb/source/Core/DumpRegisterInfo.cpp @@ -111,6 +111,11 @@ void lldb_private::DoDumpRegisterInfo( }; DumpList(strm, "In sets: ", in_sets, emit_set); - if (flags_type) + if (flags_type) { strm.Printf("\n\n%s", flags_type->AsTable(terminal_width).c_str()); + +std::string enumerators = flags_type->DumpEnums(terminal_width); +if (enumerators.size()) + strm << "\n\n" << enumerators; + } } diff --git a/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp b/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp index a5a731981299f..4754698e6e88f 100644 --- a/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp +++ b/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp @@ -4179,21 +4179,124 @@ struct GdbServerTargetInfo { RegisterSetMap reg_set_map; }; -static std::vector ParseFlagsFields(XMLNode flags_node, - unsigned size) { +static FieldEnum::Enumerators ParseEnumEvalues(const XMLNode &enum_node) { + Log *log(GetLog(GDBRLog::Process)); + // We will use the last instance of each value. Also we preserve the order + // of declaration in the XML, as it may not be numerical. + std::map enumerators; + + enum_node.ForEachChildElementWithName( + "evalue", [&enumerators, &log](const XMLNode &enumerator_node) { +std::optional name; +std::optional value; + +enumerator_node.ForEachAttribute( +[&name, &value, &log](const llvm::StringRef &attr_name, + const llvm::StringRef &attr_value) { + if (attr_name == "name") { +if (attr_value.size()) + name = attr_value; +else + LLDB_LOG(log, "ProcessGDBRemote::ParseEnumEvalues " +"Ignoring empty name in evalue"); + } else if (attr_name == "value") { +uint64_t parsed_value = 0; +if (llvm::to_integer(attr_value, parsed_value)) + value = parsed_value; +else + LLDB_LOG(log, + "ProcessGDBRemote::ParseEnumEvalues " + "Invalid value \"{0}\" in " + "evalue", + attr_value.data()); + } else +LLDB_LOG(log, + "ProcessGDBRemote::ParseEnumEvalues Ignoring " + "unknown attribute " +
[Lldb-commits] [lldb] [lldb/DWARF] Fix type definition search with simple template names (PR #95905)
@@ -3073,14 +3073,43 @@ SymbolFileDWARF::FindDefinitionTypeForDWARFDeclContext(const DWARFDIE &die) { // See comments below about -gsimple-template-names for why we attempt to // compute missing template parameter names. -ConstString template_params; -if (type_system) { - DWARFASTParser *dwarf_ast = type_system->GetDWARFParser(); - if (dwarf_ast) -template_params = dwarf_ast->GetDIEClassTemplateParams(die); +std::vector template_params; +DWARFDeclContext die_dwarf_decl_ctx; +DWARFASTParser *dwarf_ast = type_system ? type_system->GetDWARFParser() : nullptr; +for (DWARFDIE ctx_die = die; ctx_die && !isUnitType(ctx_die.Tag()); + ctx_die = ctx_die.GetParentDeclContextDIE()) { + die_dwarf_decl_ctx.AppendDeclContext(ctx_die.Tag(), ctx_die.GetName()); + template_params.push_back( + (ctx_die.IsStructUnionOrClass() && dwarf_ast) + ? dwarf_ast->GetDIEClassTemplateParams(ctx_die) + : ""); } +const bool any_template_params = llvm::any_of( +template_params, [](llvm::StringRef p) { return !p.empty(); }); -const DWARFDeclContext die_dwarf_decl_ctx = die.GetDWARFDeclContext(); +auto die_matches = [&](DWARFDIE type_die) { + // Resolve the type if both have the same tag or {class, struct} tags. + const bool tag_matches = + type_die.Tag() == tag || + (IsStructOrClassTag(type_die.Tag()) && IsStructOrClassTag(tag)); labath wrote: > Yes, that's why I said "it matters for ast construction". I think it would > nice to still print the type in the original way, which mostly comes up when > someone (technically incorrectly) forward-declares something as `struct Foo`, > but defines it as a class. > I lost a sentence here. It would be nice to print the types in the original way. We need the canonicalization to handle the cases where the forward declarations and definitions don't have matching tags. https://github.com/llvm/llvm-project/pull/95905 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb] Parse and display register field enums (PR #95768)
DavidSpickett wrote: > The only thing I could suggest is that we check the specified fields/size are > less than 64 bits when reading the enum field definitions, but that means I > can specify fields above 32 bits and then associate that with a 32-bit cpsr > register and it won't be detected. I have updated the test `test_evalue_value_limits` to check that we are able to parse an `evalue` that is the maximum 64 bit unsigned value, and that anything above that is rejected. The other part is covered by the test `test_enum_value_range`. So you could define an enum with a > 32 bit evalue, then assign that to a 32 bit register that had a single 32 bit field. lldb would check that all the evalues of that enum fit into that field. They do not, so it will ignore the enum. Any other 64 bit registers with fields large enough to be compatible can still use the enum. ``` ``` There are log messages for both these scenarios. https://github.com/llvm/llvm-project/pull/95768 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb][test] Support remote run of Shell tests (PR #95986)
labath wrote: > > Can't say I'm excited to see this feature (although I admit it is looking > > less daunting than I originally feared). Can you explain why you need this > > feature? Is there some particular aspect of lldb's remote operation that > > you think isn't well covered by the existing tests? Is there a particular > > category of tests that you'd like to have more than others? How many of the > > existing tests would exercise the remote platform capability in a > > meaningful way (a lot of these tests don't even build runnable binaries)? > > I'm sorry, it took a bit longer time to answer than I expected, my apologies. > > In general, our goal is to maximize the functionality of the testing toolkit > in case of cross-compilation+remote launch setup. > > I agree that not every Shell test launches binaries. According to my > grep-based statistics, it's roughly one-fifth of the tests currently (117/533 > test files that contain "r", "run", or "process launch" commands). Though > it's still a number. Thank you for finding that number. > > Also, launching the "platform select" and "platform connect ..." commands > before executing the rest of a Shell test script may be useful. Here is an > example case of a potentially unexpected behavior #94165. So it's not always > necessary to have a Shell test build and run a binary to reveal some nuances. That's true, but this still seems like a pretty big hammer for that. > And it seems to me, that it won't cause excessive maintenance overhead since > we essentially add just two extra commands to %lldb invocation. Maybe. Like I said, it's cleaner than I though, but I'm still somewhat worried about where this will lead. If you can support running these tests on a different machine, then I think the next question becomes "why not run them with a different compiler as well". And then you need to XFAIL the tests for a particular compiler, so you end up replicating all of the `@skipIfClang71ExceptOnTuesdays` logic. I don't know if this is a slippery slope fallacy or an actual slippery slope, but this extra bit of test coverage does not seem worth it to me, and I sort of liked the separation how API tests can run in a multitude of configurations while a Shell test runs in one. I know that isn't really a good separation since "the way I write the tests" is in principle independent of "where I want to run it", but since the two tests use completely separate infrastructures, I think it would make sense to keep this functionality in just one of them. That said I don't want to be only person blocking this, so I'd like to hear what others think as well. @JDevlieghere ? > I haven't opened an RFC since I thought it would be clearer to discuss that > idea with the showcase of implementation. I'm open to moving a discussion > there if it's considered as a better approach in this case (please let me > know😅). Maybe the best would be an RFC with a link to a POC, but now that we're here, I think we can stick with it and see how it goes. https://github.com/llvm/llvm-project/pull/95986 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb] Change lldb's breakpoint handling behavior (PR #96260)
AlexK0 wrote: > @AlexK0 if you have a setup to build and run the testsuite on windows, could > you try it with this patch some time when you're able? I can't see this being > merged for at least another 5-6 days, there's no rush. You can download the > unidiff style diff of the patch from > https://patch-diff.githubusercontent.com/raw/llvm/llvm-project/pull/96260.diff @jasonmolenda I checked the tests with VS2022/x86-64/win11 in a debug build with assertions enabled. Unfortunately, the main branch is a bit unstable, and some tests constantly fail :( . Nonetheless, I noticed one new failure with the applied patch: `functionalities/breakpoint/consecutive_breakpoints/TestConsecutiveBreakpoints.py` backtrace: ``` FAIL: test_single_step_thread_specific (TestConsecutiveBreakpoints.ConsecutiveBreakpointsTestCase) Test that single step stops, even though the second breakpoint is not valid. -- Traceback (most recent call last): File "D:\Projects\github\llvm-project-jasonmolenda\lldb\packages\Python\lldbsuite\test\decorators.py", line 451, in wrapper return func(self, *args, **kwargs) File "D:\Projects\github\llvm-project-jasonmolenda\lldb\test\API\functionalities\breakpoint\consecutive_breakpoints\TestConsecutiveBreakpoints.py", line 121, in test_single_step_thread_specific self.finish_test() File "D:\Projects\github\llvm-project-jasonmolenda\lldb\test\API\functionalities\breakpoint\consecutive_breakpoints\TestConsecutiveBreakpoints.py", line 42, in finish_test self.assertState(self.process.GetState(), lldb.eStateExited) File "D:\Projects\github\llvm-project-jasonmolenda\lldb\packages\Python\lldbsuite\test\lldbtest.py", line 2578, in assertState self.fail(self._formatMessage(msg, error)) AssertionError: stopped (5) != exited (10) Config=x86_64-D:\Projects\github\llvm-project-jasonmolenda\build\bin\clang.exe -- ``` https://github.com/llvm/llvm-project/pull/96260 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [llvm] Add support for using foreign type units in .debug_names. (PR #87740)
https://github.com/labath commented: The llvm stuff looks good (thank you), but there are still (small) some unresolved comments in the lldb code. I've pinged them in this review. https://github.com/llvm/llvm-project/pull/87740 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [llvm] Add support for using foreign type units in .debug_names. (PR #87740)
@@ -0,0 +1,127 @@ +// REQUIRES: lld + +// This test will make a type that will be compiled differently into two +// different .dwo files in a type unit with the same type hash, but with +// differing contents. Clang's type unit signature is based only on the mangled +// name of the type, regardless of the contents of the type, so that will help +// us test foreign type units in the .debug_names section of the main +// executable. When a DWP file is made, only one type unit will be kept and the +// type unit that is kept has the .dwo file name that it came from. When LLDB +// loads the foreign type units, it needs to verify that any entries from +// foreign type units come from the right .dwo file. We test this since the +// contents of type units are not always the same even though they have the same +// type hash. We don't want invalid accelerator table entries to come from one +// .dwo file and be used on a type unit from another since this could cause +// invalid lookups to happen. LLDB knows how to track down which .dwo file a +// type unit comes from by looking at the DW_AT_dwo_name attribute in the +// DW_TAG_type_unit. + +// Now test with DWARF5 labath wrote: This too. https://github.com/llvm/llvm-project/pull/87740 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [llvm] Add support for using foreign type units in .debug_names. (PR #87740)
https://github.com/labath edited https://github.com/llvm/llvm-project/pull/87740 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [llvm] Add support for using foreign type units in .debug_names. (PR #87740)
@@ -1741,45 +1741,61 @@ lldb::ModuleSP SymbolFileDWARF::GetExternalModule(ConstString name) { return pos->second; } -DWARFDIE -SymbolFileDWARF::GetDIE(const DIERef &die_ref) { - // This method can be called without going through the symbol vendor so we - // need to lock the module. - std::lock_guard guard(GetModuleMutex()); - - SymbolFileDWARF *symbol_file = nullptr; - +SymbolFileDWARF *SymbolFileDWARF::GetDIERefSymbolFile(const DIERef &die_ref) { // Anytime we get a "lldb::user_id_t" from an lldb_private::SymbolFile API we // must make sure we use the correct DWARF file when resolving things. On // MacOSX, when using SymbolFileDWARFDebugMap, we will use multiple // SymbolFileDWARF classes, one for each .o file. We can often end up with // references to other DWARF objects and we must be ready to receive a // "lldb::user_id_t" that specifies a DIE from another SymbolFileDWARF // instance. + std::optional file_index = die_ref.file_index(); + + // If the file index matches, then we have the right SymbolFileDWARF already. + // This will work for both .dwo file and DWARF in .o files for mac. Also if + // both the file indexes are invalid, then we have a match. + if (GetFileIndex() == file_index) +return this; + + // If we are currently in a .dwo file and our file index doesn't match we need + // to let the base symbol file handle this. + SymbolFileDWARFDwo *dwo = llvm::dyn_cast_or_null(this); + if (dwo) +return dwo->GetDIERefSymbolFile(die_ref); labath wrote: This comment still holds (please remove the dyn_cast and the associated code) https://github.com/llvm/llvm-project/pull/87740 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [llvm] Add support for using foreign type units in .debug_names. (PR #87740)
@@ -0,0 +1,127 @@ +// REQUIRES: lld + +// This test will make a type that will be compiled differently into two +// different .dwo files in a type unit with the same type hash, but with +// differing contents. Clang's type unit signature is based only on the mangled +// name of the type, regardless of the contents of the type, so that will help +// us test foreign type units in the .debug_names section of the main +// executable. When a DWP file is made, only one type unit will be kept and the +// type unit that is kept has the .dwo file name that it came from. When LLDB +// loads the foreign type units, it needs to verify that any entries from +// foreign type units come from the right .dwo file. We test this since the +// contents of type units are not always the same even though they have the same +// type hash. We don't want invalid accelerator table entries to come from one +// .dwo file and be used on a type unit from another since this could cause +// invalid lookups to happen. LLDB knows how to track down which .dwo file a +// type unit comes from by looking at the DW_AT_dwo_name attribute in the +// DW_TAG_type_unit. + +// Now test with DWARF5 +// RUN: %clang -target x86_64-pc-linux -gdwarf-5 -gsplit-dwarf \ +// RUN: -fdebug-types-section -gpubnames -c %s -o %t.main.o +// RUN: %clang -target x86_64-pc-linux -gdwarf-5 -gsplit-dwarf -DVARIANT \ +// RUN: -fdebug-types-section -gpubnames -c %s -o %t.foo.o +// RUN: ld.lld %t.main.o %t.foo.o -o %t + +// Check when have no .dwp file that we can find the types in both .dwo files. +// RUN: rm -f %t.dwp +// RUN: %lldb \ +// RUN: -o "type lookup IntegerType" \ +// RUN: -o "type lookup FloatType" \ +// RUN: -o "type lookup CustomType" \ +// RUN: -b %t | FileCheck %s --check-prefix=NODWP +// NODWP: (lldb) type lookup IntegerType +// NODWP-NEXT: int +// NODWP-NEXT: unsigned int +// NODWP: (lldb) type lookup FloatType +// NODWP-NEXT: double +// NODWP-NEXT: float +// NODWP: (lldb) type lookup CustomType +// NODWP-NEXT: struct CustomType { +// NODWP-NEXT: typedef int IntegerType; +// NODWP-NEXT: typedef double FloatType; +// NODWP-NEXT: CustomType::IntegerType x; +// NODWP-NEXT: CustomType::FloatType y; +// NODWP-NEXT: } +// NODWP-NEXT: struct CustomType { +// NODWP-NEXT: typedef unsigned int IntegerType; +// NODWP-NEXT: typedef float FloatType; +// NODWP-NEXT: CustomType::IntegerType x; +// NODWP-NEXT: CustomType::FloatType y; +// NODWP-NEXT: } + +// Check when we make the .dwp file with %t.main.dwo first so it will +// pick the type unit from %t.main.dwo. Verify we find only the types from +// %t.main.dwo's type unit. +// RUN: llvm-dwp %t.main.dwo %t.foo.dwo -o %t.dwp +// RUN: %lldb \ +// RUN: -o "type lookup IntegerType" \ +// RUN: -o "type lookup FloatType" \ +// RUN: -o "type lookup CustomType" \ +// RUN: -b %t | FileCheck %s --check-prefix=DWPMAIN +// DWPMAIN: (lldb) type lookup IntegerType +// DWPMAIN-NEXT: int +// DWPMAIN: (lldb) type lookup FloatType +// DWPMAIN-NEXT: double +// DWPMAIN: (lldb) type lookup CustomType +// DWPMAIN-NEXT: struct CustomType { +// DWPMAIN-NEXT: typedef int IntegerType; +// DWPMAIN-NEXT: typedef double FloatType; +// DWPMAIN-NEXT: CustomType::IntegerType x; +// DWPMAIN-NEXT: CustomType::FloatType y; +// DWPMAIN-NEXT: } + +// Next we check when we make the .dwp file with %t.foo.dwo first so it will +// pick the type unit from %t.main.dwo. Verify we find only the types from +// %t.main.dwo's type unit. +// RUN: llvm-dwp %t.foo.dwo %t.main.dwo -o %t.dwp +// RUN: %lldb \ +// RUN: -o "type lookup IntegerType" \ +// RUN: -o "type lookup FloatType" \ +// RUN: -o "type lookup CustomType" \ +// RUN: -b %t | FileCheck %s --check-prefix=DWPFOO + +// DWPFOO: (lldb) type lookup IntegerType +// DWPFOO-NEXT: unsigned int +// DWPFOO: (lldb) type lookup FloatType +// DWPFOO-NEXT: float +// DWPFOO: (lldb) type lookup CustomType +// DWPFOO-NEXT: struct CustomType { +// DWPFOO-NEXT: typedef unsigned int IntegerType; +// DWPFOO-NEXT: typedef float FloatType; +// DWPFOO-NEXT: CustomType::IntegerType x; +// DWPFOO-NEXT: CustomType::FloatType y; +// DWPFOO-NEXT: } + +// We need to do this so we end with a type unit in each .dwo file and that has +// the same signature but different contents. When we make the .dwp file, then +// one of the type units will end up in the .dwp file and we will have +// .debug_names accelerator tables for both type units and we need to ignore +// the type units .debug_names entries that don't match the .dwo file whose +// copy of the type unit ends up in the final .dwp file. To do this, LLDB will +// look at the type unit and take the DWO name attribute and make sure it +// matches, and if it doesn't, it will ignore the accelerator table entry. labath wrote: And this. https://github.com/llvm/llvm-project/pull/87740 ___ lldb-commits mailing list lldb-com
[Lldb-commits] [lldb] [llvm] Add support for using foreign type units in .debug_names. (PR #87740)
@@ -1727,45 +1727,61 @@ lldb::ModuleSP SymbolFileDWARF::GetExternalModule(ConstString name) { return pos->second; } -DWARFDIE -SymbolFileDWARF::GetDIE(const DIERef &die_ref) { - // This method can be called without going through the symbol vendor so we - // need to lock the module. - std::lock_guard guard(GetModuleMutex()); - - SymbolFileDWARF *symbol_file = nullptr; - +SymbolFileDWARF *SymbolFileDWARF::GetDIERefSymbolFile(const DIERef &die_ref) { // Anytime we get a "lldb::user_id_t" from an lldb_private::SymbolFile API we // must make sure we use the correct DWARF file when resolving things. On // MacOSX, when using SymbolFileDWARFDebugMap, we will use multiple // SymbolFileDWARF classes, one for each .o file. We can often end up with // references to other DWARF objects and we must be ready to receive a // "lldb::user_id_t" that specifies a DIE from another SymbolFileDWARF // instance. + std::optional file_index = die_ref.file_index(); + + // If the file index matches, then we have the right SymbolFileDWARF already. + // This will work for both .dwo file and DWARF in .o files for mac. Also if + // both the file indexes are invalid, then we have a match. + if (GetFileIndex() == file_index) +return this; + + // If we are currently in a .dwo file and our file index doesn't match we need + // to let the base symbol file handle this. + SymbolFileDWARFDwo *dwo = llvm::dyn_cast_or_null(this); + if (dwo) +return dwo->GetDIERefSymbolFile(die_ref); + if (file_index) { -if (SymbolFileDWARFDebugMap *debug_map = GetDebugMapSymfile()) { - symbol_file = debug_map->GetSymbolFileByOSOIndex(*file_index); // OSO case - if (symbol_file) -return symbol_file->DebugInfo().GetDIE(die_ref.section(), - die_ref.die_offset()); - return DWARFDIE(); +SymbolFileDWARFDebugMap *debug_map = GetDebugMapSymfile(); +if (debug_map) { + // We have a SymbolFileDWARFDebugMap, so let it find the right file + return debug_map->GetSymbolFileByOSOIndex(*file_index); +} else { + // Handle the .dwp file case correctly + if (*file_index == DIERef::k_file_index_mask) +return GetDwpSymbolFile().get(); // DWP case + + // Handle the .dwo file case correctly + return DebugInfo() + .GetUnitAtIndex(*die_ref.file_index()) + ->GetDwoSymbolFile(); // DWO case } + } + return this; +} -if (*file_index == DIERef::k_file_index_mask) - symbol_file = GetDwpSymbolFile().get(); // DWP case -else - symbol_file = this->DebugInfo() -.GetUnitAtIndex(*die_ref.file_index()) -->GetDwoSymbolFile(); // DWO case - } else if (die_ref.die_offset() == DW_INVALID_OFFSET) { +DWARFDIE +SymbolFileDWARF::GetDIE(const DIERef &die_ref) { + if (die_ref.die_offset() == DW_INVALID_OFFSET) return DWARFDIE(); - } + // This method can be called without going through the symbol vendor so we + // need to lock the module. + std::lock_guard guard(GetModuleMutex()); + SymbolFileDWARF *symbol_file = GetDIERefSymbolFile(die_ref); labath wrote: This only uses the file_index component of the DIERef, how about we just pass that (and call the function something like `GetSymbolFileByIndex`)? https://github.com/llvm/llvm-project/pull/87740 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] 9c49440 - [lldb] Add missing includes (NFC)
Author: Nikita Popov Date: 2024-06-21T14:05:36+02:00 New Revision: 9c4944095db919580bdc698273065d1c91a98ed8 URL: https://github.com/llvm/llvm-project/commit/9c4944095db919580bdc698273065d1c91a98ed8 DIFF: https://github.com/llvm/llvm-project/commit/9c4944095db919580bdc698273065d1c91a98ed8.diff LOG: [lldb] Add missing includes (NFC) Added: Modified: lldb/include/lldb/Target/TraceDumper.h lldb/source/Commands/CommandObjectThreadUtil.h Removed: diff --git a/lldb/include/lldb/Target/TraceDumper.h b/lldb/include/lldb/Target/TraceDumper.h index ca08dc254182a..d3cea4b28449e 100644 --- a/lldb/include/lldb/Target/TraceDumper.h +++ b/lldb/include/lldb/Target/TraceDumper.h @@ -9,6 +9,7 @@ #include "lldb/Symbol/SymbolContext.h" #include "lldb/Target/TraceCursor.h" #include +#include #ifndef LLDB_TARGET_TRACE_INSTRUCTION_DUMPER_H #define LLDB_TARGET_TRACE_INSTRUCTION_DUMPER_H diff --git a/lldb/source/Commands/CommandObjectThreadUtil.h b/lldb/source/Commands/CommandObjectThreadUtil.h index 74d1136bab7f1..3fc28efe8cf71 100644 --- a/lldb/source/Commands/CommandObjectThreadUtil.h +++ b/lldb/source/Commands/CommandObjectThreadUtil.h @@ -10,6 +10,7 @@ #define LLDB_SOURCE_COMMANDS_COMMANDOBJECTTHREADUTIL_H #include "lldb/Interpreter/CommandObjectMultiword.h" +#include namespace lldb_private { ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] c399aea - [lldb] Remove YAMLTraits.h include (NFC)
Author: Nikita Popov Date: 2024-06-21T14:56:26+02:00 New Revision: c399aeacf67e517bcfa9c4d7e5cc709a3fbe5d09 URL: https://github.com/llvm/llvm-project/commit/c399aeacf67e517bcfa9c4d7e5cc709a3fbe5d09 DIFF: https://github.com/llvm/llvm-project/commit/c399aeacf67e517bcfa9c4d7e5cc709a3fbe5d09.diff LOG: [lldb] Remove YAMLTraits.h include (NFC) The YAML functionality was dropped in 70599d70273b671b1b2e6a0e0b9c11e413209647, but this include was left behind. Added: Modified: lldb/include/lldb/Target/Thread.h lldb/include/lldb/Utility/Args.h Removed: diff --git a/lldb/include/lldb/Target/Thread.h b/lldb/include/lldb/Target/Thread.h index c17bddf4d98b8..2ff1f50d497e2 100644 --- a/lldb/include/lldb/Target/Thread.h +++ b/lldb/include/lldb/Target/Thread.h @@ -26,6 +26,7 @@ #include "lldb/Utility/UnimplementedError.h" #include "lldb/Utility/UserID.h" #include "lldb/lldb-private.h" +#include "llvm/Support/MemoryBuffer.h" #define LLDB_THREAD_MAX_STOP_EXC_DATA 8 diff --git a/lldb/include/lldb/Utility/Args.h b/lldb/include/lldb/Utility/Args.h index 40b9358484b69..757f7e2ba5ec6 100644 --- a/lldb/include/lldb/Utility/Args.h +++ b/lldb/include/lldb/Utility/Args.h @@ -13,8 +13,8 @@ #include "lldb/lldb-private-types.h" #include "lldb/lldb-types.h" #include "llvm/ADT/ArrayRef.h" +#include "llvm/ADT/StringExtras.h" #include "llvm/ADT/StringRef.h" -#include "llvm/Support/YAMLTraits.h" #include #include #include ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] Reapply PR/87550 (again) (PR #95571)
https://github.com/oontvoo updated https://github.com/llvm/llvm-project/pull/95571 >From 018c7a6052add708e0b0d09b911a904b52199da5 Mon Sep 17 00:00:00 2001 From: Vy Nguyen Date: Tue, 11 Jun 2024 14:15:43 -0400 Subject: [PATCH 1/3] Reapply "Reapply PR/87550 (#94625)" This reverts commit adcf33f8fbcc0f068bd4b8254994b16dda525009. --- lldb/include/lldb/API/SBDebugger.h| 2 + lldb/include/lldb/Symbol/TypeSystem.h | 1 + lldb/source/API/SBDebugger.cpp| 4 ++ lldb/source/Symbol/TypeSystem.cpp | 11 + lldb/tools/lldb-dap/DAP.cpp | 61 ++- lldb/tools/lldb-dap/DAP.h | 5 ++- lldb/tools/lldb-dap/lldb-dap.cpp | 6 ++- 7 files changed, 77 insertions(+), 13 deletions(-) diff --git a/lldb/include/lldb/API/SBDebugger.h b/lldb/include/lldb/API/SBDebugger.h index af19b1faf3bf5..84ea9c0f772e1 100644 --- a/lldb/include/lldb/API/SBDebugger.h +++ b/lldb/include/lldb/API/SBDebugger.h @@ -57,6 +57,8 @@ class LLDB_API SBDebugger { static const char *GetBroadcasterClass(); + static bool SupportsLanguage(lldb::LanguageType language); + lldb::SBBroadcaster GetBroadcaster(); /// Get progress data from a SBEvent whose type is eBroadcastBitProgress. diff --git a/lldb/include/lldb/Symbol/TypeSystem.h b/lldb/include/lldb/Symbol/TypeSystem.h index b4025c173a186..7d48f9b316138 100644 --- a/lldb/include/lldb/Symbol/TypeSystem.h +++ b/lldb/include/lldb/Symbol/TypeSystem.h @@ -209,6 +209,7 @@ class TypeSystem : public PluginInterface, // TypeSystems can support more than one language virtual bool SupportsLanguage(lldb::LanguageType language) = 0; + static bool SupportsLanguageStatic(lldb::LanguageType language); // Type Completion virtual bool GetCompleteType(lldb::opaque_compiler_type_t type) = 0; diff --git a/lldb/source/API/SBDebugger.cpp b/lldb/source/API/SBDebugger.cpp index 7ef0d6efd4aaa..29da7d33dd80b 100644 --- a/lldb/source/API/SBDebugger.cpp +++ b/lldb/source/API/SBDebugger.cpp @@ -1742,3 +1742,7 @@ bool SBDebugger::InterruptRequested() { return m_opaque_sp->InterruptRequested(); return false; } + +bool SBDebugger::SupportsLanguage(lldb::LanguageType language) { + return TypeSystem::SupportsLanguageStatic(language); +} diff --git a/lldb/source/Symbol/TypeSystem.cpp b/lldb/source/Symbol/TypeSystem.cpp index 4956f10a0b0a7..5d56d9b1829da 100644 --- a/lldb/source/Symbol/TypeSystem.cpp +++ b/lldb/source/Symbol/TypeSystem.cpp @@ -335,3 +335,14 @@ TypeSystemMap::GetTypeSystemForLanguage(lldb::LanguageType language, } return GetTypeSystemForLanguage(language); } + +bool TypeSystem::SupportsLanguageStatic(lldb::LanguageType language) { + if (language == eLanguageTypeUnknown) +return false; + + LanguageSet languages = + PluginManager::GetAllTypeSystemSupportedLanguagesForTypes(); + if (languages.Empty()) +return false; + return languages[language]; +} diff --git a/lldb/tools/lldb-dap/DAP.cpp b/lldb/tools/lldb-dap/DAP.cpp index d419f821999e6..263e841b7254d 100644 --- a/lldb/tools/lldb-dap/DAP.cpp +++ b/lldb/tools/lldb-dap/DAP.cpp @@ -32,14 +32,7 @@ namespace lldb_dap { DAP g_dap; DAP::DAP() -: broadcaster("lldb-dap"), - exception_breakpoints( - {{"cpp_catch", "C++ Catch", lldb::eLanguageTypeC_plus_plus}, - {"cpp_throw", "C++ Throw", lldb::eLanguageTypeC_plus_plus}, - {"objc_catch", "Objective-C Catch", lldb::eLanguageTypeObjC}, - {"objc_throw", "Objective-C Throw", lldb::eLanguageTypeObjC}, - {"swift_catch", "Swift Catch", lldb::eLanguageTypeSwift}, - {"swift_throw", "Swift Throw", lldb::eLanguageTypeSwift}}), +: broadcaster("lldb-dap"), exception_breakpoints(), focus_tid(LLDB_INVALID_THREAD_ID), stop_at_entry(false), is_attach(false), enable_auto_variable_summaries(false), enable_synthetic_child_debugging(false), @@ -65,8 +58,51 @@ DAP::DAP() DAP::~DAP() = default; +void DAP::PopulateExceptionBreakpoints() { + llvm::call_once(initExceptionBreakpoints, [this]() { +exception_breakpoints = {}; +if (lldb::SBDebugger::SupportsLanguage(lldb::eLanguageTypeC_plus_plus)) { + exception_breakpoints->emplace_back("cpp_catch", "C++ Catch", + lldb::eLanguageTypeC_plus_plus); + exception_breakpoints->emplace_back("cpp_throw", "C++ Throw", + lldb::eLanguageTypeC_plus_plus); +} +if (lldb::SBDebugger::SupportsLanguage(lldb::eLanguageTypeObjC)) { + exception_breakpoints->emplace_back("objc_catch", "Objective-C Catch", + lldb::eLanguageTypeObjC); + exception_breakpoints->emplace_back("objc_throw", "Objective-C Throw", + lldb::eLanguageTypeObjC); +} +if (lldb::SBDebugger::SupportsLanguage(lldb::eLanguageTypeSwift)) { + exception_breakpoints->emplace_back("swift_catch", "Swift Catch", +
[Lldb-commits] [lldb] Reapply PR/87550 (again) (PR #95571)
@@ -65,16 +58,67 @@ DAP::DAP() DAP::~DAP() = default; +void DAP::PopulateExceptionBreakpoints() { + llvm::call_once(initExceptionBreakpoints, [this]() { +exception_breakpoints = std::vector {}; + +if (lldb::SBDebugger::SupportsLanguage(lldb::eLanguageTypeC_plus_plus)) { + exception_breakpoints->emplace_back("cpp_catch", "C++ Catch", + lldb::eLanguageTypeC_plus_plus); + exception_breakpoints->emplace_back("cpp_throw", "C++ Throw", + lldb::eLanguageTypeC_plus_plus); +} +if (lldb::SBDebugger::SupportsLanguage(lldb::eLanguageTypeObjC)) { + exception_breakpoints->emplace_back("objc_catch", "Objective-C Catch", + lldb::eLanguageTypeObjC); + exception_breakpoints->emplace_back("objc_throw", "Objective-C Throw", + lldb::eLanguageTypeObjC); +} +if (lldb::SBDebugger::SupportsLanguage(lldb::eLanguageTypeSwift)) { + exception_breakpoints->emplace_back("swift_catch", "Swift Catch", + lldb::eLanguageTypeSwift); + exception_breakpoints->emplace_back("swift_throw", "Swift Throw", + lldb::eLanguageTypeSwift); +} +assert(exception_breakpoints.has_value() && "should have been initted"); +assert(!exception_breakpoints->empty() && "should not be empty"); oontvoo wrote: The `exceptions_breakpoints` *could* be empty if for some reason all of the if-condition above returns false. That would be unexpected and I think it's easier to catch the bug right here rather than later https://github.com/llvm/llvm-project/pull/95571 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] Reapply PR/87550 (again) (PR #95571)
https://github.com/oontvoo edited https://github.com/llvm/llvm-project/pull/95571 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] Reapply PR/87550 (again) (PR #95571)
@@ -65,16 +58,67 @@ DAP::DAP() DAP::~DAP() = default; +void DAP::PopulateExceptionBreakpoints() { + llvm::call_once(initExceptionBreakpoints, [this]() { +exception_breakpoints = std::vector {}; + +if (lldb::SBDebugger::SupportsLanguage(lldb::eLanguageTypeC_plus_plus)) { + exception_breakpoints->emplace_back("cpp_catch", "C++ Catch", + lldb::eLanguageTypeC_plus_plus); + exception_breakpoints->emplace_back("cpp_throw", "C++ Throw", + lldb::eLanguageTypeC_plus_plus); +} +if (lldb::SBDebugger::SupportsLanguage(lldb::eLanguageTypeObjC)) { + exception_breakpoints->emplace_back("objc_catch", "Objective-C Catch", + lldb::eLanguageTypeObjC); + exception_breakpoints->emplace_back("objc_throw", "Objective-C Throw", + lldb::eLanguageTypeObjC); +} +if (lldb::SBDebugger::SupportsLanguage(lldb::eLanguageTypeSwift)) { + exception_breakpoints->emplace_back("swift_catch", "Swift Catch", + lldb::eLanguageTypeSwift); + exception_breakpoints->emplace_back("swift_throw", "Swift Throw", + lldb::eLanguageTypeSwift); +} +assert(exception_breakpoints.has_value() && "should have been initted"); +assert(!exception_breakpoints->empty() && "should not be empty"); labath wrote: That's the second assertion, not the first one. The first one is really just a test for the implementation of `optional::operator=`. I don't have such strong feelings about the second one, although one could easily argue that the fact that lldb says it does not support any of the mentioned languages is not a bug (at least, not a bug in lldb-dap). Correctness of the code following the assertion does not depend on the vector being non-empty (only on its existence), so this feels like it would be better off as a test. https://github.com/llvm/llvm-project/pull/95571 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] 30299b8 - [CommandLine] Avoid ManagedStatic.h include (NFC)
Author: Nikita Popov Date: 2024-06-21T15:45:17+02:00 New Revision: 30299b87171cbad2dacb8b1ec0e75801785f16d9 URL: https://github.com/llvm/llvm-project/commit/30299b87171cbad2dacb8b1ec0e75801785f16d9 DIFF: https://github.com/llvm/llvm-project/commit/30299b87171cbad2dacb8b1ec0e75801785f16d9.diff LOG: [CommandLine] Avoid ManagedStatic.h include (NFC) The two variables using ManagedStatic that are exported by this header are not actually used anywhere -- they are used through SubCommand::getTopLevel() and SubCommand::getAll() instead. Drop the extern declarations and the include. Added: Modified: clang/lib/Frontend/PrecompiledPreamble.cpp lldb/utils/TableGen/LLDBTableGen.cpp llvm/include/llvm/Support/CommandLine.h llvm/lib/Support/CommandLine.cpp llvm/lib/Support/RandomNumberGenerator.cpp llvm/lib/Support/TypeSize.cpp Removed: diff --git a/clang/lib/Frontend/PrecompiledPreamble.cpp b/clang/lib/Frontend/PrecompiledPreamble.cpp index fdf05c3613c95..cab5838fceb24 100644 --- a/clang/lib/Frontend/PrecompiledPreamble.cpp +++ b/clang/lib/Frontend/PrecompiledPreamble.cpp @@ -28,6 +28,7 @@ #include "llvm/Config/llvm-config.h" #include "llvm/Support/CrashRecoveryContext.h" #include "llvm/Support/FileSystem.h" +#include "llvm/Support/ManagedStatic.h" #include "llvm/Support/Path.h" #include "llvm/Support/Process.h" #include "llvm/Support/VirtualFileSystem.h" diff --git a/lldb/utils/TableGen/LLDBTableGen.cpp b/lldb/utils/TableGen/LLDBTableGen.cpp index c63ca76c0d48f..bbd3f3d6c66c4 100644 --- a/lldb/utils/TableGen/LLDBTableGen.cpp +++ b/lldb/utils/TableGen/LLDBTableGen.cpp @@ -12,6 +12,7 @@ #include "LLDBTableGenBackends.h" // Declares all backends. #include "llvm/Support/CommandLine.h" +#include "llvm/Support/ManagedStatic.h" #include "llvm/Support/PrettyStackTrace.h" #include "llvm/Support/Signals.h" #include "llvm/TableGen/Error.h" diff --git a/llvm/include/llvm/Support/CommandLine.h b/llvm/include/llvm/Support/CommandLine.h index b035209406b68..5d60bb64bbb20 100644 --- a/llvm/include/llvm/Support/CommandLine.h +++ b/llvm/include/llvm/Support/CommandLine.h @@ -28,7 +28,6 @@ #include "llvm/ADT/Twine.h" #include "llvm/ADT/iterator_range.h" #include "llvm/Support/ErrorHandling.h" -#include "llvm/Support/ManagedStatic.h" #include "llvm/Support/StringSaver.h" #include "llvm/Support/raw_ostream.h" #include @@ -237,12 +236,6 @@ class SubCommand { Option *ConsumeAfterOpt = nullptr; // The ConsumeAfter option if it exists. }; -// A special subcommand representing no subcommand -extern ManagedStatic TopLevelSubCommand; - -// A special subcommand that can be used to put an option into all subcommands. -extern ManagedStatic AllSubCommands; - class SubCommandGroup { SmallVector Subs; diff --git a/llvm/lib/Support/CommandLine.cpp b/llvm/lib/Support/CommandLine.cpp index 8a00d4798f33d..6dc0c86cea894 100644 --- a/llvm/lib/Support/CommandLine.cpp +++ b/llvm/lib/Support/CommandLine.cpp @@ -455,10 +455,10 @@ void OptionCategory::registerCategory() { // initialization because it is referenced from cl::opt constructors, which run // dynamically in an arbitrary order. LLVM_REQUIRE_CONSTANT_INITIALIZATION -ManagedStatic llvm::cl::TopLevelSubCommand; +static ManagedStatic TopLevelSubCommand; // A special subcommand that can be used to put an option into all subcommands. -ManagedStatic llvm::cl::AllSubCommands; +static ManagedStatic AllSubCommands; SubCommand &SubCommand::getTopLevel() { return *TopLevelSubCommand; } diff --git a/llvm/lib/Support/RandomNumberGenerator.cpp b/llvm/lib/Support/RandomNumberGenerator.cpp index 12fe109dbc2b5..2959fc2bfed17 100644 --- a/llvm/lib/Support/RandomNumberGenerator.cpp +++ b/llvm/lib/Support/RandomNumberGenerator.cpp @@ -19,6 +19,7 @@ #include "llvm/Support/CommandLine.h" #include "llvm/Support/Debug.h" #include "llvm/Support/Error.h" +#include "llvm/Support/ManagedStatic.h" #include "llvm/Support/raw_ostream.h" #ifdef _WIN32 #include "llvm/Support/Windows/WindowsSupport.h" diff --git a/llvm/lib/Support/TypeSize.cpp b/llvm/lib/Support/TypeSize.cpp index 8bed9b29cba55..43346b81cd676 100644 --- a/llvm/lib/Support/TypeSize.cpp +++ b/llvm/lib/Support/TypeSize.cpp @@ -8,6 +8,7 @@ #include "llvm/Support/TypeSize.h" #include "llvm/Support/CommandLine.h" +#include "llvm/Support/ManagedStatic.h" #include "llvm/Support/WithColor.h" #include "DebugOptions.h" ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb/DWARF] Optimize DIEToType handling (PR #96308)
https://github.com/labath created https://github.com/llvm/llvm-project/pull/96308 - move type insertion from individual parse methods into ParseTypeFromDWARF - optimize sentinel (TYPE_IS_BEING_PARSED) insertion to avoid double map lookup - as this requires the map to not have nullptr values, I've replaced all `operator[]` queries with calls to `lookup`. >From 3a23841439d09cffef5b1e4eb127d328c1dfa76b Mon Sep 17 00:00:00 2001 From: Pavel Labath Date: Fri, 21 Jun 2024 15:04:40 +0200 Subject: [PATCH] [lldb/DWARF] Optimize DIEToType handling - move type insertion from individual parse methods into ParseTypeFromDWARF - optimize sentinel (TYPE_IS_BEING_PARSED) insertion to avoid double map lookup - as this requires the map to not have nullptr values, I've replaced all `operator[]` queries with calls to `lookup`. --- .../SymbolFile/DWARF/DWARFASTParserClang.cpp | 178 -- 1 file changed, 74 insertions(+), 104 deletions(-) diff --git a/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp b/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp index ae3eaf88ff4a8..52f4d765cbbd4 100644 --- a/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp +++ b/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp @@ -223,7 +223,6 @@ TypeSP DWARFASTParserClang::ParseTypeFromClangModule(const SymbolContext &sc, nullptr, LLDB_INVALID_UID, Type::eEncodingInvalid, &pcm_type_sp->GetDeclaration(), type, Type::ResolveState::Forward, TypePayloadClang(GetOwningClangModule(die))); - dwarf->GetDIEToType()[die.GetDIE()] = type_sp.get(); clang::TagDecl *tag_decl = TypeSystemClang::GetAsTagDecl(type); if (tag_decl) { LinkDeclContextToDIE(tag_decl, die); @@ -458,90 +457,78 @@ TypeSP DWARFASTParserClang::ParseTypeFromDWARF(const SymbolContext &sc, DW_TAG_value_to_name(die.Tag()), die.Tag(), die.GetName()); } - Type *type_ptr = dwarf->GetDIEToType().lookup(die.GetDIE()); - if (type_ptr == DIE_IS_BEING_PARSED) -return nullptr; - if (type_ptr) -return type_ptr->shared_from_this(); // Set a bit that lets us know that we are currently parsing this - dwarf->GetDIEToType()[die.GetDIE()] = DIE_IS_BEING_PARSED; + if (auto [it, inserted] = + dwarf->GetDIEToType().try_emplace(die.GetDIE(), DIE_IS_BEING_PARSED); + !inserted) { +if (it->getSecond() == nullptr || it->getSecond() == DIE_IS_BEING_PARSED) + return nullptr; +return it->getSecond()->shared_from_this(); + } ParsedDWARFTypeAttributes attrs(die); + TypeSP type_sp; if (DWARFDIE signature_die = attrs.signature.Reference()) { -if (TypeSP type_sp = -ParseTypeFromDWARF(sc, signature_die, type_is_new_ptr)) { - dwarf->GetDIEToType()[die.GetDIE()] = type_sp.get(); +type_sp = ParseTypeFromDWARF(sc, signature_die, type_is_new_ptr); +if (type_sp) { if (clang::DeclContext *decl_ctx = GetCachedClangDeclContextForDIE(signature_die)) LinkDeclContextToDIE(decl_ctx, die); - return type_sp; } -return nullptr; - } - - if (type_is_new_ptr) -*type_is_new_ptr = true; - - const dw_tag_t tag = die.Tag(); - - TypeSP type_sp; - - switch (tag) { - case DW_TAG_typedef: - case DW_TAG_base_type: - case DW_TAG_pointer_type: - case DW_TAG_reference_type: - case DW_TAG_rvalue_reference_type: - case DW_TAG_const_type: - case DW_TAG_restrict_type: - case DW_TAG_volatile_type: - case DW_TAG_LLVM_ptrauth_type: - case DW_TAG_atomic_type: - case DW_TAG_unspecified_type: { -type_sp = ParseTypeModifier(sc, die, attrs); -break; - } - - case DW_TAG_structure_type: - case DW_TAG_union_type: - case DW_TAG_class_type: { -type_sp = ParseStructureLikeDIE(sc, die, attrs); -break; - } + } else { +if (type_is_new_ptr) + *type_is_new_ptr = true; - case DW_TAG_enumeration_type: { -type_sp = ParseEnum(sc, die, attrs); -break; - } +const dw_tag_t tag = die.Tag(); - case DW_TAG_inlined_subroutine: - case DW_TAG_subprogram: - case DW_TAG_subroutine_type: { -type_sp = ParseSubroutine(die, attrs); -break; - } - case DW_TAG_array_type: { -type_sp = ParseArrayType(die, attrs); -break; - } - case DW_TAG_ptr_to_member_type: { -type_sp = ParsePointerToMemberType(die, attrs); -break; +switch (tag) { +case DW_TAG_typedef: +case DW_TAG_base_type: +case DW_TAG_pointer_type: +case DW_TAG_reference_type: +case DW_TAG_rvalue_reference_type: +case DW_TAG_const_type: +case DW_TAG_restrict_type: +case DW_TAG_volatile_type: +case DW_TAG_LLVM_ptrauth_type: +case DW_TAG_atomic_type: +case DW_TAG_unspecified_type: + type_sp = ParseTypeModifier(sc, die, attrs); + break; +case DW_TAG_structure_type: +case DW_TAG_union_type: +case DW_TAG_class_type: + type_sp = ParseStructureLikeDIE(sc, die, attrs); + break; +case DW_TAG_enumeration_type: + type_sp = ParseEn
[Lldb-commits] [lldb] [lldb/DWARF] Optimize DIEToType handling (PR #96308)
llvmbot wrote: @llvm/pr-subscribers-lldb Author: Pavel Labath (labath) Changes - move type insertion from individual parse methods into ParseTypeFromDWARF - optimize sentinel (TYPE_IS_BEING_PARSED) insertion to avoid double map lookup - as this requires the map to not have nullptr values, I've replaced all `operator[]` queries with calls to `lookup`. --- Full diff: https://github.com/llvm/llvm-project/pull/96308.diff 1 Files Affected: - (modified) lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp (+74-104) ``diff diff --git a/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp b/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp index ae3eaf88ff4a8..52f4d765cbbd4 100644 --- a/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp +++ b/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp @@ -223,7 +223,6 @@ TypeSP DWARFASTParserClang::ParseTypeFromClangModule(const SymbolContext &sc, nullptr, LLDB_INVALID_UID, Type::eEncodingInvalid, &pcm_type_sp->GetDeclaration(), type, Type::ResolveState::Forward, TypePayloadClang(GetOwningClangModule(die))); - dwarf->GetDIEToType()[die.GetDIE()] = type_sp.get(); clang::TagDecl *tag_decl = TypeSystemClang::GetAsTagDecl(type); if (tag_decl) { LinkDeclContextToDIE(tag_decl, die); @@ -458,90 +457,78 @@ TypeSP DWARFASTParserClang::ParseTypeFromDWARF(const SymbolContext &sc, DW_TAG_value_to_name(die.Tag()), die.Tag(), die.GetName()); } - Type *type_ptr = dwarf->GetDIEToType().lookup(die.GetDIE()); - if (type_ptr == DIE_IS_BEING_PARSED) -return nullptr; - if (type_ptr) -return type_ptr->shared_from_this(); // Set a bit that lets us know that we are currently parsing this - dwarf->GetDIEToType()[die.GetDIE()] = DIE_IS_BEING_PARSED; + if (auto [it, inserted] = + dwarf->GetDIEToType().try_emplace(die.GetDIE(), DIE_IS_BEING_PARSED); + !inserted) { +if (it->getSecond() == nullptr || it->getSecond() == DIE_IS_BEING_PARSED) + return nullptr; +return it->getSecond()->shared_from_this(); + } ParsedDWARFTypeAttributes attrs(die); + TypeSP type_sp; if (DWARFDIE signature_die = attrs.signature.Reference()) { -if (TypeSP type_sp = -ParseTypeFromDWARF(sc, signature_die, type_is_new_ptr)) { - dwarf->GetDIEToType()[die.GetDIE()] = type_sp.get(); +type_sp = ParseTypeFromDWARF(sc, signature_die, type_is_new_ptr); +if (type_sp) { if (clang::DeclContext *decl_ctx = GetCachedClangDeclContextForDIE(signature_die)) LinkDeclContextToDIE(decl_ctx, die); - return type_sp; } -return nullptr; - } - - if (type_is_new_ptr) -*type_is_new_ptr = true; - - const dw_tag_t tag = die.Tag(); - - TypeSP type_sp; - - switch (tag) { - case DW_TAG_typedef: - case DW_TAG_base_type: - case DW_TAG_pointer_type: - case DW_TAG_reference_type: - case DW_TAG_rvalue_reference_type: - case DW_TAG_const_type: - case DW_TAG_restrict_type: - case DW_TAG_volatile_type: - case DW_TAG_LLVM_ptrauth_type: - case DW_TAG_atomic_type: - case DW_TAG_unspecified_type: { -type_sp = ParseTypeModifier(sc, die, attrs); -break; - } - - case DW_TAG_structure_type: - case DW_TAG_union_type: - case DW_TAG_class_type: { -type_sp = ParseStructureLikeDIE(sc, die, attrs); -break; - } + } else { +if (type_is_new_ptr) + *type_is_new_ptr = true; - case DW_TAG_enumeration_type: { -type_sp = ParseEnum(sc, die, attrs); -break; - } +const dw_tag_t tag = die.Tag(); - case DW_TAG_inlined_subroutine: - case DW_TAG_subprogram: - case DW_TAG_subroutine_type: { -type_sp = ParseSubroutine(die, attrs); -break; - } - case DW_TAG_array_type: { -type_sp = ParseArrayType(die, attrs); -break; - } - case DW_TAG_ptr_to_member_type: { -type_sp = ParsePointerToMemberType(die, attrs); -break; +switch (tag) { +case DW_TAG_typedef: +case DW_TAG_base_type: +case DW_TAG_pointer_type: +case DW_TAG_reference_type: +case DW_TAG_rvalue_reference_type: +case DW_TAG_const_type: +case DW_TAG_restrict_type: +case DW_TAG_volatile_type: +case DW_TAG_LLVM_ptrauth_type: +case DW_TAG_atomic_type: +case DW_TAG_unspecified_type: + type_sp = ParseTypeModifier(sc, die, attrs); + break; +case DW_TAG_structure_type: +case DW_TAG_union_type: +case DW_TAG_class_type: + type_sp = ParseStructureLikeDIE(sc, die, attrs); + break; +case DW_TAG_enumeration_type: + type_sp = ParseEnum(sc, die, attrs); + break; +case DW_TAG_inlined_subroutine: +case DW_TAG_subprogram: +case DW_TAG_subroutine_type: + type_sp = ParseSubroutine(die, attrs); + break; +case DW_TAG_array_type: + type_sp = ParseArrayType(die, attrs); + break; +case DW_TAG_ptr_to_member_type: + type_sp = ParsePointerToMemberType(die, attrs); + break; +default: +
[Lldb-commits] [lldb] [API] add GetSyntheticValue (PR #95959)
@@ -155,6 +155,18 @@ def cleanup(): ], ) v-bulle wrote: I don't think we can have a conflict. In this test we have several categories which are enabled one after the other. I just add a new one (with a new name CCCSynth2). https://github.com/llvm/llvm-project/pull/95959 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb] Unify Platform::ResolveExecutable (PR #96256)
@@ -1004,10 +1004,7 @@ class Platform : public PluginInterface { virtual const char *GetCacheHostname(); - virtual Status - ResolveRemoteExecutable(const ModuleSpec &module_spec, - lldb::ModuleSP &exe_module_sp, - const FileSpecList *module_search_paths_ptr); + /// The method is virtual for mocking in the unit tests. JDevlieghere wrote: This comment is outdated. It was for `ResolveRemoteExecutable` which was virtual but only overridden in the unit test. I'll remove it. https://github.com/llvm/llvm-project/pull/96256 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb][ExpressionParser][NFCI] Add new DoPrepareForExecution interface to be implemented by language plugins (PR #96290)
@@ -0,0 +1,73 @@ +//===-- ExpressionParser.cpp --===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===--===// + +#include "lldb/Expression/ExpressionParser.h" +#include "lldb/Expression/DiagnosticManager.h" +#include "lldb/Expression/IRExecutionUnit.h" +#include "lldb/Target/ExecutionContext.h" +#include "lldb/Target/ThreadPlanCallFunction.h" + +using namespace lldb_private; + +Status ExpressionParser::PrepareForExecution( +lldb::addr_t &func_addr, lldb::addr_t &func_end, +std::shared_ptr &execution_unit_sp, +ExecutionContext &exe_ctx, bool &can_interpret, +lldb_private::ExecutionPolicy execution_policy) { + Status status = + DoPrepareForExecution(func_addr, func_end, execution_unit_sp, exe_ctx, +can_interpret, execution_policy); + if (status.Success() && exe_ctx.GetProcessPtr() && exe_ctx.HasThreadScope()) { +status = RunStaticInitializers(execution_unit_sp, exe_ctx); + } + return status; +} + +Status ExpressionParser::RunStaticInitializers( +lldb::IRExecutionUnitSP &execution_unit_sp, ExecutionContext &exe_ctx) { + lldb_private::Status err; + + lldbassert(execution_unit_sp.get()); + lldbassert(exe_ctx.HasThreadScope()); + + if (!execution_unit_sp.get()) { +err.SetErrorString( +"can't run static initializers for a NULL execution unit"); +return err; + } + + if (!exe_ctx.HasThreadScope()) { +err.SetErrorString("can't run static initializers without a thread"); +return err; + } JDevlieghere wrote: If we're going to handle the error graciously, then I don't see the point of the `lldbassert` above. If we want to avoid this situation in the test suite we can make them regular asserts, or just omit them altogether. https://github.com/llvm/llvm-project/pull/96290 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb][ExpressionParser][NFCI] Add new DoPrepareForExecution interface to be implemented by language plugins (PR #96290)
@@ -0,0 +1,73 @@ +//===-- ExpressionParser.cpp --===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===--===// + +#include "lldb/Expression/ExpressionParser.h" +#include "lldb/Expression/DiagnosticManager.h" +#include "lldb/Expression/IRExecutionUnit.h" +#include "lldb/Target/ExecutionContext.h" +#include "lldb/Target/ThreadPlanCallFunction.h" + +using namespace lldb_private; + +Status ExpressionParser::PrepareForExecution( +lldb::addr_t &func_addr, lldb::addr_t &func_end, +std::shared_ptr &execution_unit_sp, +ExecutionContext &exe_ctx, bool &can_interpret, +lldb_private::ExecutionPolicy execution_policy) { + Status status = + DoPrepareForExecution(func_addr, func_end, execution_unit_sp, exe_ctx, +can_interpret, execution_policy); + if (status.Success() && exe_ctx.GetProcessPtr() && exe_ctx.HasThreadScope()) { +status = RunStaticInitializers(execution_unit_sp, exe_ctx); + } JDevlieghere wrote: Nit: no braces. https://github.com/llvm/llvm-project/pull/96290 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb][ExpressionParser][NFCI] Add new DoPrepareForExecution interface to be implemented by language plugins (PR #96290)
@@ -0,0 +1,73 @@ +//===-- ExpressionParser.cpp --===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===--===// + +#include "lldb/Expression/ExpressionParser.h" +#include "lldb/Expression/DiagnosticManager.h" +#include "lldb/Expression/IRExecutionUnit.h" +#include "lldb/Target/ExecutionContext.h" +#include "lldb/Target/ThreadPlanCallFunction.h" + +using namespace lldb_private; JDevlieghere wrote: If you add `using namespace lldb` you could drop some `lldb::` prefixes. https://github.com/llvm/llvm-project/pull/96290 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb][ExpressionParser][NFCI] Add new DoPrepareForExecution interface to be implemented by language plugins (PR #96290)
@@ -0,0 +1,73 @@ +//===-- ExpressionParser.cpp --===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===--===// + +#include "lldb/Expression/ExpressionParser.h" +#include "lldb/Expression/DiagnosticManager.h" +#include "lldb/Expression/IRExecutionUnit.h" +#include "lldb/Target/ExecutionContext.h" +#include "lldb/Target/ThreadPlanCallFunction.h" + +using namespace lldb_private; + +Status ExpressionParser::PrepareForExecution( +lldb::addr_t &func_addr, lldb::addr_t &func_end, +std::shared_ptr &execution_unit_sp, +ExecutionContext &exe_ctx, bool &can_interpret, +lldb_private::ExecutionPolicy execution_policy) { + Status status = + DoPrepareForExecution(func_addr, func_end, execution_unit_sp, exe_ctx, +can_interpret, execution_policy); + if (status.Success() && exe_ctx.GetProcessPtr() && exe_ctx.HasThreadScope()) { +status = RunStaticInitializers(execution_unit_sp, exe_ctx); + } + return status; +} + +Status ExpressionParser::RunStaticInitializers( +lldb::IRExecutionUnitSP &execution_unit_sp, ExecutionContext &exe_ctx) { + lldb_private::Status err; JDevlieghere wrote: Nit: Drop `lldb_private::` https://github.com/llvm/llvm-project/pull/96290 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb] Unify Platform::ResolveExecutable (PR #96256)
https://github.com/JDevlieghere updated https://github.com/llvm/llvm-project/pull/96256 >From 41f7b780548ccfc15ad22da51742f1809c34c103 Mon Sep 17 00:00:00 2001 From: Jonas Devlieghere Date: Thu, 20 Jun 2024 13:51:53 -0700 Subject: [PATCH 1/2] [lldb] Unify Platform::ResolveExecutable duplication The Platform class currently has two functions to resolve an executable: `ResolveExecutable` and `ResolveRemoteExecutable`. The former strictly deals with local files while the latter can handle potentially remote files. I couldn't figure out why the distinction matters, at the latter is a super-set of the former. To make things even more confusion, we had a similar but not identical implementation in RemoteAwarePlatform where its implementation of `ResolveExecutable` could handle remote files. To top it all off, we had copy-pasted implementation, dead code included in `PlatformAppleSimulator` and `PlatformRemoteDarwinDevice`. I went ahead and unified all the different implementation on the original `ResolveRemoteExecutable` implementation. As far as I can tell, it should work for every other platform, and the test suite (on macOS) seems to agree with me, except for a small wording change. --- lldb/include/lldb/Target/Platform.h | 7 +- .../include/lldb/Target/RemoteAwarePlatform.h | 4 - .../MacOSX/PlatformAppleSimulator.cpp | 75 -- .../Platform/MacOSX/PlatformAppleSimulator.h | 4 - .../MacOSX/PlatformRemoteDarwinDevice.cpp | 65 .../MacOSX/PlatformRemoteDarwinDevice.h | 4 - lldb/source/Target/Platform.cpp | 48 +- lldb/source/Target/RemoteAwarePlatform.cpp| 139 -- .../TestAssertMessages.py | 2 +- .../tools/lldb-dap/launch/TestDAP_launch.py | 2 +- .../Target/RemoteAwarePlatformTest.cpp| 13 +- 11 files changed, 16 insertions(+), 347 deletions(-) diff --git a/lldb/include/lldb/Target/Platform.h b/lldb/include/lldb/Target/Platform.h index e05c79cb501bf..e54e1460acee7 100644 --- a/lldb/include/lldb/Target/Platform.h +++ b/lldb/include/lldb/Target/Platform.h @@ -139,7 +139,7 @@ class Platform : public PluginInterface { /// Returns \b true if this Platform plug-in was able to find /// a suitable executable, \b false otherwise. virtual Status ResolveExecutable(const ModuleSpec &module_spec, - lldb::ModuleSP &module_sp, + lldb::ModuleSP &exe_module_sp, const FileSpecList *module_search_paths_ptr); /// Find a symbol file given a symbol file module specification. @@ -1004,10 +1004,7 @@ class Platform : public PluginInterface { virtual const char *GetCacheHostname(); - virtual Status - ResolveRemoteExecutable(const ModuleSpec &module_spec, - lldb::ModuleSP &exe_module_sp, - const FileSpecList *module_search_paths_ptr); + /// The method is virtual for mocking in the unit tests. private: typedef std::function ModuleResolver; diff --git a/lldb/include/lldb/Target/RemoteAwarePlatform.h b/lldb/include/lldb/Target/RemoteAwarePlatform.h index 0b9d79f9ff038..6fbeec7888a98 100644 --- a/lldb/include/lldb/Target/RemoteAwarePlatform.h +++ b/lldb/include/lldb/Target/RemoteAwarePlatform.h @@ -23,10 +23,6 @@ class RemoteAwarePlatform : public Platform { bool GetModuleSpec(const FileSpec &module_file_spec, const ArchSpec &arch, ModuleSpec &module_spec) override; - Status - ResolveExecutable(const ModuleSpec &module_spec, lldb::ModuleSP &module_sp, -const FileSpecList *module_search_paths_ptr) override; - lldb::user_id_t OpenFile(const FileSpec &file_spec, File::OpenOptions flags, uint32_t mode, Status &error) override; diff --git a/lldb/source/Plugins/Platform/MacOSX/PlatformAppleSimulator.cpp b/lldb/source/Plugins/Platform/MacOSX/PlatformAppleSimulator.cpp index 0c4b566b7d535..c27a34b7201a2 100644 --- a/lldb/source/Plugins/Platform/MacOSX/PlatformAppleSimulator.cpp +++ b/lldb/source/Plugins/Platform/MacOSX/PlatformAppleSimulator.cpp @@ -383,81 +383,6 @@ PlatformSP PlatformAppleSimulator::CreateInstance( return PlatformSP(); } -Status PlatformAppleSimulator::ResolveExecutable( -const ModuleSpec &module_spec, lldb::ModuleSP &exe_module_sp, -const FileSpecList *module_search_paths_ptr) { - Status error; - // Nothing special to do here, just use the actual file and architecture - - ModuleSpec resolved_module_spec(module_spec); - - // If we have "ls" as the exe_file, resolve the executable loation based on - // the current path variables - // TODO: resolve bare executables in the Platform SDK - //if (!resolved_exe_file.Exists()) - //resolved_exe_file.ResolveExecutableLocation (); - - // Resolve any executable within a bundle on MacOSX - // TODO: verify that this handles shallow bundles, if not
[Lldb-commits] [lldb] a083e50 - [lldb] Fix SBAddressRange validation checks. (#95997)
Author: Miro Bucko Date: 2024-06-21T11:24:48-04:00 New Revision: a083e50f53f0f9eb9ad0c5b65f3c627cf97043e6 URL: https://github.com/llvm/llvm-project/commit/a083e50f53f0f9eb9ad0c5b65f3c627cf97043e6 DIFF: https://github.com/llvm/llvm-project/commit/a083e50f53f0f9eb9ad0c5b65f3c627cf97043e6.diff LOG: [lldb] Fix SBAddressRange validation checks. (#95997) Added: Modified: lldb/include/lldb/API/SBAddressRange.h lldb/include/lldb/API/SBAddressRangeList.h lldb/source/API/SBAddressRange.cpp lldb/source/API/SBAddressRangeList.cpp lldb/test/API/python_api/address_range/TestAddressRange.py Removed: diff --git a/lldb/include/lldb/API/SBAddressRange.h b/lldb/include/lldb/API/SBAddressRange.h index 152bd82426af1..5c4d6b8c5683d 100644 --- a/lldb/include/lldb/API/SBAddressRange.h +++ b/lldb/include/lldb/API/SBAddressRange.h @@ -11,6 +11,10 @@ #include "lldb/API/SBDefines.h" +namespace lldb_private { +class AddressRange; +} + namespace lldb { class LLDB_API SBAddressRange { @@ -58,6 +62,8 @@ class LLDB_API SBAddressRange { friend class SBFunction; friend class SBProcess; + lldb_private::AddressRange &ref() const; + AddressRangeUP m_opaque_up; }; diff --git a/lldb/include/lldb/API/SBAddressRangeList.h b/lldb/include/lldb/API/SBAddressRangeList.h index a123287ef1b4f..5a4eeecf37dc9 100644 --- a/lldb/include/lldb/API/SBAddressRangeList.h +++ b/lldb/include/lldb/API/SBAddressRangeList.h @@ -46,6 +46,8 @@ class LLDB_API SBAddressRangeList { friend class SBBlock; friend class SBProcess; + lldb_private::AddressRangeListImpl &ref() const; + std::unique_ptr m_opaque_up; }; diff --git a/lldb/source/API/SBAddressRange.cpp b/lldb/source/API/SBAddressRange.cpp index 9b1affdade439..5834ebe5e63c0 100644 --- a/lldb/source/API/SBAddressRange.cpp +++ b/lldb/source/API/SBAddressRange.cpp @@ -50,9 +50,7 @@ const SBAddressRange &SBAddressRange::operator=(const SBAddressRange &rhs) { bool SBAddressRange::operator==(const SBAddressRange &rhs) { LLDB_INSTRUMENT_VA(this, rhs); - if (!IsValid() || !rhs.IsValid()) -return false; - return m_opaque_up->operator==(*(rhs.m_opaque_up)); + return ref().operator==(rhs.ref()); } bool SBAddressRange::operator!=(const SBAddressRange &rhs) { @@ -64,40 +62,35 @@ bool SBAddressRange::operator!=(const SBAddressRange &rhs) { void SBAddressRange::Clear() { LLDB_INSTRUMENT_VA(this); - m_opaque_up.reset(); + ref().Clear(); } bool SBAddressRange::IsValid() const { LLDB_INSTRUMENT_VA(this); - return m_opaque_up && m_opaque_up->IsValid(); + return ref().IsValid(); } lldb::SBAddress SBAddressRange::GetBaseAddress() const { LLDB_INSTRUMENT_VA(this); - if (!IsValid()) -return lldb::SBAddress(); - return lldb::SBAddress(m_opaque_up->GetBaseAddress()); + return lldb::SBAddress(ref().GetBaseAddress()); } lldb::addr_t SBAddressRange::GetByteSize() const { LLDB_INSTRUMENT_VA(this); - if (!IsValid()) -return 0; - return m_opaque_up->GetByteSize(); + return ref().GetByteSize(); } bool SBAddressRange::GetDescription(SBStream &description, const SBTarget target) { LLDB_INSTRUMENT_VA(this, description, target); - Stream &stream = description.ref(); - if (!IsValid()) { -stream << ""; -return true; - } - m_opaque_up->GetDescription(&stream, target.GetSP().get()); - return true; + return ref().GetDescription(&description.ref(), target.GetSP().get()); +} + +lldb_private::AddressRange &SBAddressRange::ref() const { + assert(m_opaque_up && "opaque pointer must always be valid"); + return *m_opaque_up; } diff --git a/lldb/source/API/SBAddressRangeList.cpp b/lldb/source/API/SBAddressRangeList.cpp index 20660b3ff2088..957155d5125ef 100644 --- a/lldb/source/API/SBAddressRangeList.cpp +++ b/lldb/source/API/SBAddressRangeList.cpp @@ -37,40 +37,40 @@ SBAddressRangeList::operator=(const SBAddressRangeList &rhs) { LLDB_INSTRUMENT_VA(this, rhs); if (this != &rhs) -*m_opaque_up = *rhs.m_opaque_up; +ref() = rhs.ref(); return *this; } uint32_t SBAddressRangeList::GetSize() const { LLDB_INSTRUMENT_VA(this); - return m_opaque_up->GetSize(); + return ref().GetSize(); } SBAddressRange SBAddressRangeList::GetAddressRangeAtIndex(uint64_t idx) { LLDB_INSTRUMENT_VA(this, idx); SBAddressRange sb_addr_range; - (*sb_addr_range.m_opaque_up) = m_opaque_up->GetAddressRangeAtIndex(idx); + (*sb_addr_range.m_opaque_up) = ref().GetAddressRangeAtIndex(idx); return sb_addr_range; } void SBAddressRangeList::Clear() { LLDB_INSTRUMENT_VA(this); - m_opaque_up->Clear(); + ref().Clear(); } void SBAddressRangeList::Append(const SBAddressRange &sb_addr_range) { LLDB_INSTRUMENT_VA(this, sb_addr_range); - m_opaque_up->Append(*sb_addr_range.m_opaque_up); + ref().Append(*sb_addr_range.m_opaque_up); } void SBAddres
[Lldb-commits] [lldb] [lldb] Fix SBAddressRange validation checks. (PR #95997)
https://github.com/mbucko closed https://github.com/llvm/llvm-project/pull/95997 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [API] add GetSyntheticValue (PR #95959)
@@ -155,6 +155,18 @@ def cleanup(): ], ) labath wrote: You have two categories, but they both have a summary provider for the same type (`CCC`). (Enabling one category does not automatically disable the other ones.) Right now, lldb seems to pick the one you want, but I don't think we promise that anywhere (in fact, I wouldn't be surprised if this comes down to some (nondeterministic) ordering in some hash container). By disabling the first category, we make sure that lldb always pick the one we want (in case, e.g., the container ordering changes). Alternatively, you could just attach the summary provider to a different type (CCC2?) https://github.com/llvm/llvm-project/pull/95959 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [API] add GetSyntheticValue (PR #95959)
https://github.com/v-bulle updated https://github.com/llvm/llvm-project/pull/95959 >From 27a00b54bc991dfb4747e0d37b15878beebaabba Mon Sep 17 00:00:00 2001 From: Vincent Belliard Date: Wed, 12 Jun 2024 14:23:15 -0700 Subject: [PATCH 1/4] [API] add GetSyntheticValue --- lldb/include/lldb/API/SBValue.h | 2 ++ lldb/source/API/SBValue.cpp | 12 2 files changed, 14 insertions(+) diff --git a/lldb/include/lldb/API/SBValue.h b/lldb/include/lldb/API/SBValue.h index 65920c76df7a8..bec816fb45184 100644 --- a/lldb/include/lldb/API/SBValue.h +++ b/lldb/include/lldb/API/SBValue.h @@ -89,6 +89,8 @@ class LLDB_API SBValue { lldb::SBValue GetNonSyntheticValue(); + lldb::SBValue GetSyntheticValue(); + lldb::DynamicValueType GetPreferDynamicValue(); void SetPreferDynamicValue(lldb::DynamicValueType use_dynamic); diff --git a/lldb/source/API/SBValue.cpp b/lldb/source/API/SBValue.cpp index 9d7efba024d11..6b77c0e95cedd 100644 --- a/lldb/source/API/SBValue.cpp +++ b/lldb/source/API/SBValue.cpp @@ -761,6 +761,18 @@ lldb::SBValue SBValue::GetNonSyntheticValue() { return value_sb; } +lldb::SBValue SBValue::GetSyntheticValue() { + LLDB_INSTRUMENT_VA(this); + + SBValue value_sb; + if (IsValid()) { +ValueImplSP proxy_sp(new ValueImpl(m_opaque_sp->GetRootSP(), + m_opaque_sp->GetUseDynamic(), true)); +value_sb.SetSP(proxy_sp); + } + return value_sb; +} + lldb::DynamicValueType SBValue::GetPreferDynamicValue() { LLDB_INSTRUMENT_VA(this); >From e0ed752849486f67d9fddbef3767a1756afd1ab2 Mon Sep 17 00:00:00 2001 From: Vincent Belliard Date: Thu, 20 Jun 2024 17:04:15 -0700 Subject: [PATCH 2/4] add test --- .../formatters/TestFormattersSBAPI.py | 12 lldb/test/API/python_api/formatters/synth.py | 28 +-- 2 files changed, 38 insertions(+), 2 deletions(-) diff --git a/lldb/test/API/python_api/formatters/TestFormattersSBAPI.py b/lldb/test/API/python_api/formatters/TestFormattersSBAPI.py index 7e802f92da352..460afbc1202cf 100644 --- a/lldb/test/API/python_api/formatters/TestFormattersSBAPI.py +++ b/lldb/test/API/python_api/formatters/TestFormattersSBAPI.py @@ -155,6 +155,18 @@ def cleanup(): ], ) +self.dbg.GetCategory("CCCSynth2").SetEnabled(True) +self.expect( +"frame variable ccc", +matching=True, +substrs=[ +"CCC object with leading synthetic value (int) b = 222", +"a = 111", +"b = 222", +"c = 333", +], +) + foo_var = ( self.dbg.GetSelectedTarget() .GetProcess() diff --git a/lldb/test/API/python_api/formatters/synth.py b/lldb/test/API/python_api/formatters/synth.py index 474c18bc62ebd..2b8f7c86ac6f1 100644 --- a/lldb/test/API/python_api/formatters/synth.py +++ b/lldb/test/API/python_api/formatters/synth.py @@ -29,11 +29,19 @@ def ccc_summary(sbvalue, internal_dict): # This tests that the SBValue.GetNonSyntheticValue() actually returns a # non-synthetic value. If it does not, then sbvalue.GetChildMemberWithName("a") # in the following statement will call the 'get_child_index' method of the -# synthetic child provider CCCSynthProvider below (which raises an -# exception). +# synthetic child provider CCCSynthProvider below (which return the "b" field"). return "CCC object with leading value " + str(sbvalue.GetChildMemberWithName("a")) +def ccc_synthetic(sbvalue, internal_dict): +sbvalue = sbvalue.GetSyntheticValue() +# This tests that the SBValue.GetNonSyntheticValue() actually returns a +# synthetic value. If it does, then sbvalue.GetChildMemberWithName("a") +# in the following statement will call the 'get_child_index' method of the +# synthetic child provider CCCSynthProvider below (which return the "b" field"). +return "CCC object with leading synthetic value " + str(sbvalue.GetChildMemberWithName("a")) + + class CCCSynthProvider(object): def __init__(self, sbvalue, internal_dict): self._sbvalue = sbvalue @@ -42,6 +50,9 @@ def num_children(self): return 3 def get_child_index(self, name): +if name == "a": +# Return b for test. +return 1 raise RuntimeError("I don't want to be called!") def get_child_at_index(self, index): @@ -119,3 +130,16 @@ def __lldb_init_module(debugger, dict): "synth.empty2_summary", lldb.eTypeOptionHideEmptyAggregates ), ) +cat2 = debugger.CreateCategory("CCCSynth2") +cat2.AddTypeSynthetic( +lldb.SBTypeNameSpecifier("CCC"), +lldb.SBTypeSynthetic.CreateWithClassName( +"synth.CCCSynthProvider", lldb.eTypeOptionCascade +), +) +cat2.AddTypeSummary( +lldb.SBTypeNameSpecifier("CCC"), +lldb.SBTypeSummary.CreateWithFunctionName( +"synth.ccc_synthetic"
[Lldb-commits] [lldb] [lldb][ExpressionParser][NFCI] Add new DoPrepareForExecution interface to be implemented by language plugins (PR #96290)
https://github.com/adrian-prantl approved this pull request. https://github.com/llvm/llvm-project/pull/96290 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb][API] Add Find(Ranges)InMemory() to Process SB API (PR #95007)
https://github.com/mbucko updated https://github.com/llvm/llvm-project/pull/95007 >From 26e19d848937564ae74cf9c42e2ee51a224c3133 Mon Sep 17 00:00:00 2001 From: Miro Bucko Date: Tue, 4 Jun 2024 12:01:48 -0700 Subject: [PATCH] [lldb][API] Add Find(Ranges)InMemory() to Process SB API Test Plan: llvm-lit llvm-project/lldb/test/API/python_api/find_in_memory/TestFindInMemory.py llvm-project/lldb/test/API/python_api/find_in_memory/TestFindRangesInMemory.py Reviewers: clayborg Tasks: lldb --- lldb/bindings/python/python-typemaps.swig | 3 +- lldb/include/lldb/API/SBProcess.h | 10 + lldb/include/lldb/Core/AddressRangeListImpl.h | 4 + lldb/include/lldb/Target/Process.h| 14 ++ lldb/source/API/SBProcess.cpp | 58 - lldb/source/Target/Process.cpp| 129 ++ .../API/python_api/find_in_memory/Makefile| 3 + .../find_in_memory/TestFindInMemory.py| 131 +++ .../find_in_memory/TestFindRangesInMemory.py | 221 ++ .../find_in_memory/address_ranges_helper.py | 73 ++ .../API/python_api/find_in_memory/main.cpp| 27 +++ 11 files changed, 667 insertions(+), 6 deletions(-) create mode 100644 lldb/test/API/python_api/find_in_memory/Makefile create mode 100644 lldb/test/API/python_api/find_in_memory/TestFindInMemory.py create mode 100644 lldb/test/API/python_api/find_in_memory/TestFindRangesInMemory.py create mode 100644 lldb/test/API/python_api/find_in_memory/address_ranges_helper.py create mode 100644 lldb/test/API/python_api/find_in_memory/main.cpp diff --git a/lldb/bindings/python/python-typemaps.swig b/lldb/bindings/python/python-typemaps.swig index c39594c7df041..f8c33e15c03e6 100644 --- a/lldb/bindings/python/python-typemaps.swig +++ b/lldb/bindings/python/python-typemaps.swig @@ -257,7 +257,8 @@ AND call SWIG_fail at the same time, because it will result in a double free. } // For SBProcess::WriteMemory, SBTarget::GetInstructions and SBDebugger::DispatchInput. %typemap(in) (const void *buf, size_t size), - (const void *data, size_t data_len) { + (const void *data, size_t data_len), + (const void *buf, uint64_t size) { if (PythonString::Check($input)) { PythonString str(PyRefType::Borrowed, $input); $1 = (void *)str.GetString().data(); diff --git a/lldb/include/lldb/API/SBProcess.h b/lldb/include/lldb/API/SBProcess.h index f1b5d1fb92ce2..a6ab7ae759918 100644 --- a/lldb/include/lldb/API/SBProcess.h +++ b/lldb/include/lldb/API/SBProcess.h @@ -209,6 +209,16 @@ class LLDB_API SBProcess { lldb::addr_t ReadPointerFromMemory(addr_t addr, lldb::SBError &error); + lldb::SBAddressRangeList FindRangesInMemory(const void *buf, uint64_t size, + const SBAddressRangeList &ranges, + uint32_t alignment, + uint32_t max_matches, + SBError &error); + + lldb::addr_t FindInMemory(const void *buf, uint64_t size, +const SBAddressRange &range, uint32_t alignment, +SBError &error); + // Events static lldb::StateType GetStateFromEvent(const lldb::SBEvent &event); diff --git a/lldb/include/lldb/Core/AddressRangeListImpl.h b/lldb/include/lldb/Core/AddressRangeListImpl.h index 46ebfe73d4d92..6742e6ead87de 100644 --- a/lldb/include/lldb/Core/AddressRangeListImpl.h +++ b/lldb/include/lldb/Core/AddressRangeListImpl.h @@ -13,7 +13,9 @@ #include namespace lldb { +class SBAddressRangeList; class SBBlock; +class SBProcess; } namespace lldb_private { @@ -39,7 +41,9 @@ class AddressRangeListImpl { lldb_private::AddressRange GetAddressRangeAtIndex(size_t index); private: + friend class lldb::SBAddressRangeList; friend class lldb::SBBlock; + friend class lldb::SBProcess; AddressRanges &ref(); diff --git a/lldb/include/lldb/Target/Process.h b/lldb/include/lldb/Target/Process.h index eec337c15f7ed..ceaf547ebddaf 100644 --- a/lldb/include/lldb/Target/Process.h +++ b/lldb/include/lldb/Target/Process.h @@ -2685,6 +2685,15 @@ void PruneThreadPlans(); lldb::addr_t FindInMemory(lldb::addr_t low, lldb::addr_t high, const uint8_t *buf, size_t size); + AddressRanges FindRangesInMemory(const uint8_t *buf, uint64_t size, + const AddressRanges &ranges, + size_t alignment, size_t max_matches, + Status &error); + + lldb::addr_t FindInMemory(const uint8_t *buf, uint64_t size, +const AddressRange &range, size_t alignment, +Status &error); + protected: friend class Trace; @@ -2800,6 +2809,11 @@ void PruneThreadPlans(); virtual size_t DoReadMemory(lldb::addr_t vm_addr, void *buf, size_t size,
[Lldb-commits] [lldb] Reapply PR/87550 (again) (PR #95571)
https://github.com/oontvoo updated https://github.com/llvm/llvm-project/pull/95571 >From 018c7a6052add708e0b0d09b911a904b52199da5 Mon Sep 17 00:00:00 2001 From: Vy Nguyen Date: Tue, 11 Jun 2024 14:15:43 -0400 Subject: [PATCH 1/4] Reapply "Reapply PR/87550 (#94625)" This reverts commit adcf33f8fbcc0f068bd4b8254994b16dda525009. --- lldb/include/lldb/API/SBDebugger.h| 2 + lldb/include/lldb/Symbol/TypeSystem.h | 1 + lldb/source/API/SBDebugger.cpp| 4 ++ lldb/source/Symbol/TypeSystem.cpp | 11 + lldb/tools/lldb-dap/DAP.cpp | 61 ++- lldb/tools/lldb-dap/DAP.h | 5 ++- lldb/tools/lldb-dap/lldb-dap.cpp | 6 ++- 7 files changed, 77 insertions(+), 13 deletions(-) diff --git a/lldb/include/lldb/API/SBDebugger.h b/lldb/include/lldb/API/SBDebugger.h index af19b1faf3bf5..84ea9c0f772e1 100644 --- a/lldb/include/lldb/API/SBDebugger.h +++ b/lldb/include/lldb/API/SBDebugger.h @@ -57,6 +57,8 @@ class LLDB_API SBDebugger { static const char *GetBroadcasterClass(); + static bool SupportsLanguage(lldb::LanguageType language); + lldb::SBBroadcaster GetBroadcaster(); /// Get progress data from a SBEvent whose type is eBroadcastBitProgress. diff --git a/lldb/include/lldb/Symbol/TypeSystem.h b/lldb/include/lldb/Symbol/TypeSystem.h index b4025c173a186..7d48f9b316138 100644 --- a/lldb/include/lldb/Symbol/TypeSystem.h +++ b/lldb/include/lldb/Symbol/TypeSystem.h @@ -209,6 +209,7 @@ class TypeSystem : public PluginInterface, // TypeSystems can support more than one language virtual bool SupportsLanguage(lldb::LanguageType language) = 0; + static bool SupportsLanguageStatic(lldb::LanguageType language); // Type Completion virtual bool GetCompleteType(lldb::opaque_compiler_type_t type) = 0; diff --git a/lldb/source/API/SBDebugger.cpp b/lldb/source/API/SBDebugger.cpp index 7ef0d6efd4aaa..29da7d33dd80b 100644 --- a/lldb/source/API/SBDebugger.cpp +++ b/lldb/source/API/SBDebugger.cpp @@ -1742,3 +1742,7 @@ bool SBDebugger::InterruptRequested() { return m_opaque_sp->InterruptRequested(); return false; } + +bool SBDebugger::SupportsLanguage(lldb::LanguageType language) { + return TypeSystem::SupportsLanguageStatic(language); +} diff --git a/lldb/source/Symbol/TypeSystem.cpp b/lldb/source/Symbol/TypeSystem.cpp index 4956f10a0b0a7..5d56d9b1829da 100644 --- a/lldb/source/Symbol/TypeSystem.cpp +++ b/lldb/source/Symbol/TypeSystem.cpp @@ -335,3 +335,14 @@ TypeSystemMap::GetTypeSystemForLanguage(lldb::LanguageType language, } return GetTypeSystemForLanguage(language); } + +bool TypeSystem::SupportsLanguageStatic(lldb::LanguageType language) { + if (language == eLanguageTypeUnknown) +return false; + + LanguageSet languages = + PluginManager::GetAllTypeSystemSupportedLanguagesForTypes(); + if (languages.Empty()) +return false; + return languages[language]; +} diff --git a/lldb/tools/lldb-dap/DAP.cpp b/lldb/tools/lldb-dap/DAP.cpp index d419f821999e6..263e841b7254d 100644 --- a/lldb/tools/lldb-dap/DAP.cpp +++ b/lldb/tools/lldb-dap/DAP.cpp @@ -32,14 +32,7 @@ namespace lldb_dap { DAP g_dap; DAP::DAP() -: broadcaster("lldb-dap"), - exception_breakpoints( - {{"cpp_catch", "C++ Catch", lldb::eLanguageTypeC_plus_plus}, - {"cpp_throw", "C++ Throw", lldb::eLanguageTypeC_plus_plus}, - {"objc_catch", "Objective-C Catch", lldb::eLanguageTypeObjC}, - {"objc_throw", "Objective-C Throw", lldb::eLanguageTypeObjC}, - {"swift_catch", "Swift Catch", lldb::eLanguageTypeSwift}, - {"swift_throw", "Swift Throw", lldb::eLanguageTypeSwift}}), +: broadcaster("lldb-dap"), exception_breakpoints(), focus_tid(LLDB_INVALID_THREAD_ID), stop_at_entry(false), is_attach(false), enable_auto_variable_summaries(false), enable_synthetic_child_debugging(false), @@ -65,8 +58,51 @@ DAP::DAP() DAP::~DAP() = default; +void DAP::PopulateExceptionBreakpoints() { + llvm::call_once(initExceptionBreakpoints, [this]() { +exception_breakpoints = {}; +if (lldb::SBDebugger::SupportsLanguage(lldb::eLanguageTypeC_plus_plus)) { + exception_breakpoints->emplace_back("cpp_catch", "C++ Catch", + lldb::eLanguageTypeC_plus_plus); + exception_breakpoints->emplace_back("cpp_throw", "C++ Throw", + lldb::eLanguageTypeC_plus_plus); +} +if (lldb::SBDebugger::SupportsLanguage(lldb::eLanguageTypeObjC)) { + exception_breakpoints->emplace_back("objc_catch", "Objective-C Catch", + lldb::eLanguageTypeObjC); + exception_breakpoints->emplace_back("objc_throw", "Objective-C Throw", + lldb::eLanguageTypeObjC); +} +if (lldb::SBDebugger::SupportsLanguage(lldb::eLanguageTypeSwift)) { + exception_breakpoints->emplace_back("swift_catch", "Swift Catch", +
[Lldb-commits] [lldb] Reapply PR/87550 (again) (PR #95571)
oontvoo wrote: Ran all the tests: ``` Unresolved Tests (23): lldb-api :: api/multithreaded/TestMultithreaded.py lldb-api :: commands/expression/multiline-completion/TestMultilineCompletion.py lldb-api :: commands/expression/multiline-navigation/TestMultilineNavigation.py lldb-api :: commands/gui/basic/TestGuiBasic.py lldb-api :: commands/gui/breakpoints/TestGuiBreakpoints.py lldb-api :: commands/gui/spawn-threads/TestGuiSpawnThreads.py lldb-api :: commands/gui/viewlarge/TestGuiViewLarge.py lldb-api :: driver/batch_mode/TestBatchMode.py lldb-api :: driver/job_control/TestJobControl.py lldb-api :: driver/quit_speed/TestQuitWithProcess.py lldb-api :: functionalities/breakpoint/breakpoint_callback_command_source/TestBreakpointCallbackCommandSource.py lldb-api :: functionalities/progress_reporting/TestTrimmedProgressReporting.py lldb-api :: iohandler/autosuggestion/TestAutosuggestion.py lldb-api :: iohandler/completion/TestIOHandlerCompletion.py lldb-api :: iohandler/resize/TestIOHandlerResize.py lldb-api :: iohandler/sigint/TestIOHandlerPythonREPLSigint.py lldb-api :: iohandler/sigint/TestProcessIOHandlerInterrupt.py lldb-api :: iohandler/stdio/TestIOHandlerProcessSTDIO.py lldb-api :: iohandler/unicode/TestUnicode.py lldb-api :: macosx/nslog/TestDarwinNSLogOutput.py lldb-api :: repl/clang/TestClangREPL.py lldb-api :: terminal/TestEditline.py lldb-api :: terminal/TestSTTYBeforeAndAfter.py Failed Tests (1): lldb-api :: commands/platform/sdk/TestPlatformSDK.py Testing Time: 11310.46s Total Discovered Tests: 1183 Unsupported : 155 (13.10%) Passed : 988 (83.52%) Expectedly Failed: 16 (1.35%) Unresolved : 23 (1.94%) Failed : 1 (0.08%) ``` (Compared to main branch: ``` Unresolved Tests (27): lldb-api :: api/multithreaded/TestMultithreaded.py lldb-api :: commands/expression/import-std-module/deque-dbg-info-content/TestDbgInfoContentDequeFromStdModule.py lldb-api :: commands/expression/import-std-module/list-dbg-info-content/TestDbgInfoContentListFromStdModule.py lldb-api :: commands/expression/import-std-module/vector-dbg-info-content/TestDbgInfoContentVectorFromStdModule.py lldb-api :: commands/expression/multiline-completion/TestMultilineCompletion.py lldb-api :: commands/expression/multiline-navigation/TestMultilineNavigation.py lldb-api :: commands/gui/basic/TestGuiBasic.py lldb-api :: commands/gui/breakpoints/TestGuiBreakpoints.py lldb-api :: commands/gui/spawn-threads/TestGuiSpawnThreads.py lldb-api :: commands/gui/viewlarge/TestGuiViewLarge.py lldb-api :: driver/batch_mode/TestBatchMode.py lldb-api :: driver/job_control/TestJobControl.py lldb-api :: driver/quit_speed/TestQuitWithProcess.py lldb-api :: functionalities/breakpoint/breakpoint_callback_command_source/TestBreakpointCallbackCommandSource.py lldb-api :: functionalities/progress_reporting/TestTrimmedProgressReporting.py lldb-api :: iohandler/autosuggestion/TestAutosuggestion.py lldb-api :: iohandler/completion/TestIOHandlerCompletion.py lldb-api :: iohandler/resize/TestIOHandlerResize.py lldb-api :: iohandler/sigint/TestIOHandlerPythonREPLSigint.py lldb-api :: iohandler/sigint/TestProcessIOHandlerInterrupt.py lldb-api :: iohandler/stdio/TestIOHandlerProcessSTDIO.py lldb-api :: iohandler/unicode/TestUnicode.py lldb-api :: macosx/nslog/TestDarwinNSLogOutput.py lldb-api :: python_api/thread/TestThreadAPI.py lldb-api :: repl/clang/TestClangREPL.py lldb-api :: terminal/TestEditline.py lldb-api :: terminal/TestSTTYBeforeAndAfter.py Failed Tests (5): lldb-api :: commands/platform/sdk/TestPlatformSDK.py lldb-api :: functionalities/thread/concurrent_events/TestConcurrentBreakpointsDelayedBreakpointOneWatchpoint.py lldb-api :: lang/cpp/constructors/TestCppConstructors.py lldb-api :: lang/objc/modules-non-objc-target/TestObjCModulesNonObjCTarget.py lldb-api :: python_api/lldbutil/iter/TestLLDBIterator.py Testing Time: 11040.07s Total Discovered Tests: 1183 Unsupported : 155 (13.10%) Passed : 980 (82.84%) Expectedly Failed: 16 (1.35%) Unresolved : 27 (2.28%) Failed : 5 (0.42%) ``` ) https://github.com/llvm/llvm-project/pull/95571 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [llvm] Add support for using foreign type units in .debug_names. (PR #87740)
https://github.com/clayborg updated https://github.com/llvm/llvm-project/pull/87740 >From badd915257bb192add91696e0b8530c057bd385f Mon Sep 17 00:00:00 2001 From: Greg Clayton Date: Sat, 30 Mar 2024 10:50:34 -0700 Subject: [PATCH 01/12] Add support for using foreign type units in .debug_names. This patch adds support for the new foreign type unit support in .debug_names. Features include: - don't manually index foreign TUs if we have info for them - only use the type unit entries that match the .dwo files when we have a .dwp file - fix crashers that happen due to PeekDIEName() using wrong offsets --- .../SymbolFile/DWARF/DWARFDebugInfo.cpp | 18 .../Plugins/SymbolFile/DWARF/DWARFDebugInfo.h | 2 + .../SymbolFile/DWARF/DebugNamesDWARFIndex.cpp | 65 - .../SymbolFile/DWARF/DebugNamesDWARFIndex.h | 6 +- .../SymbolFile/DWARF/ManualDWARFIndex.cpp | 6 +- .../SymbolFile/DWARF/ManualDWARFIndex.h | 7 +- .../SymbolFile/DWARF/SymbolFileDWARF.cpp | 66 -- .../SymbolFile/DWARF/SymbolFileDWARF.h| 9 ++ .../DWARF/x86/dwp-foreign-type-units.cpp | 91 +++ .../DebugInfo/DWARF/DWARFAcceleratorTable.h | 11 +++ .../DebugInfo/DWARF/DWARFAcceleratorTable.cpp | 13 +++ 11 files changed, 257 insertions(+), 37 deletions(-) create mode 100644 lldb/test/Shell/SymbolFile/DWARF/x86/dwp-foreign-type-units.cpp diff --git a/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugInfo.cpp b/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugInfo.cpp index c37cc91e08ed1..056c6d4b0605f 100644 --- a/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugInfo.cpp +++ b/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugInfo.cpp @@ -222,6 +222,20 @@ DWARFUnit *DWARFDebugInfo::GetUnitAtOffset(DIERef::Section section, return result; } +DWARFUnit *DWARFDebugInfo::GetUnit(const DIERef &die_ref) { + // Make sure we get the correct SymbolFileDWARF from the DIERef before + // asking for information from a debug info object. We might start with the + // DWARFDebugInfo for the main executable in a split DWARF and the DIERef + // might be pointing to a specific .dwo file or to the .dwp file. So this + // makes sure we get the right SymbolFileDWARF instance before finding the + // DWARFUnit that contains the offset. If we just use this object to do the + // search, we might be using the wrong .debug_info section from the wrong + // file with an offset meant for a different section. + SymbolFileDWARF *dwarf = m_dwarf.GetDIERefSymbolFile(die_ref); + return dwarf->DebugInfo().GetUnitContainingDIEOffset(die_ref.section(), + die_ref.die_offset()); +} + DWARFUnit * DWARFDebugInfo::GetUnitContainingDIEOffset(DIERef::Section section, dw_offset_t die_offset) { @@ -232,6 +246,10 @@ DWARFDebugInfo::GetUnitContainingDIEOffset(DIERef::Section section, return result; } +const std::shared_ptr DWARFDebugInfo::GetDwpSymbolFile() { + return m_dwarf.GetDwpSymbolFile(); +} + DWARFTypeUnit *DWARFDebugInfo::GetTypeUnitForHash(uint64_t hash) { auto pos = llvm::lower_bound(m_type_hash_to_unit_index, std::make_pair(hash, 0u), llvm::less_first()); diff --git a/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugInfo.h b/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugInfo.h index 4706b55d38ea9..4d4555a338252 100644 --- a/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugInfo.h +++ b/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugInfo.h @@ -52,6 +52,8 @@ class DWARFDebugInfo { const DWARFDebugAranges &GetCompileUnitAranges(); + const std::shared_ptr GetDwpSymbolFile(); + protected: typedef std::vector UnitColl; diff --git a/lldb/source/Plugins/SymbolFile/DWARF/DebugNamesDWARFIndex.cpp b/lldb/source/Plugins/SymbolFile/DWARF/DebugNamesDWARFIndex.cpp index 1d17f20670eed..d815d345b08ee 100644 --- a/lldb/source/Plugins/SymbolFile/DWARF/DebugNamesDWARFIndex.cpp +++ b/lldb/source/Plugins/SymbolFile/DWARF/DebugNamesDWARFIndex.cpp @@ -34,6 +34,18 @@ DebugNamesDWARFIndex::Create(Module &module, DWARFDataExtractor debug_names, module, std::move(index_up), debug_names, debug_str, dwarf)); } + +llvm::DenseSet +DebugNamesDWARFIndex::GetTypeUnitSigs(const DebugNames &debug_names) { + llvm::DenseSet result; + for (const DebugNames::NameIndex &ni : debug_names) { +const uint32_t num_tus = ni.getForeignTUCount(); +for (uint32_t tu = 0; tu < num_tus; ++tu) + result.insert(ni.getForeignTUSignature(tu)); + } + return result; +} + llvm::DenseSet DebugNamesDWARFIndex::GetUnits(const DebugNames &debug_names) { llvm::DenseSet result; @@ -48,17 +60,22 @@ DebugNamesDWARFIndex::GetUnits(const DebugNames &debug_names) { return result; } +DWARFTypeUnit * +DebugNamesDWARFIndex::GetForeignTypeUnit(const DebugNames::Entry &entry) const { + std::optional type_sig = entry.getForeignTUTypeSignature(); + if (type_sig) +if (auto d
[Lldb-commits] [lldb] [llvm] Add support for using foreign type units in .debug_names. (PR #87740)
@@ -1727,45 +1727,61 @@ lldb::ModuleSP SymbolFileDWARF::GetExternalModule(ConstString name) { return pos->second; } -DWARFDIE -SymbolFileDWARF::GetDIE(const DIERef &die_ref) { - // This method can be called without going through the symbol vendor so we - // need to lock the module. - std::lock_guard guard(GetModuleMutex()); - - SymbolFileDWARF *symbol_file = nullptr; - +SymbolFileDWARF *SymbolFileDWARF::GetDIERefSymbolFile(const DIERef &die_ref) { // Anytime we get a "lldb::user_id_t" from an lldb_private::SymbolFile API we // must make sure we use the correct DWARF file when resolving things. On // MacOSX, when using SymbolFileDWARFDebugMap, we will use multiple // SymbolFileDWARF classes, one for each .o file. We can often end up with // references to other DWARF objects and we must be ready to receive a // "lldb::user_id_t" that specifies a DIE from another SymbolFileDWARF // instance. + std::optional file_index = die_ref.file_index(); + + // If the file index matches, then we have the right SymbolFileDWARF already. + // This will work for both .dwo file and DWARF in .o files for mac. Also if + // both the file indexes are invalid, then we have a match. + if (GetFileIndex() == file_index) +return this; + + // If we are currently in a .dwo file and our file index doesn't match we need + // to let the base symbol file handle this. + SymbolFileDWARFDwo *dwo = llvm::dyn_cast_or_null(this); + if (dwo) +return dwo->GetDIERefSymbolFile(die_ref); + if (file_index) { -if (SymbolFileDWARFDebugMap *debug_map = GetDebugMapSymfile()) { - symbol_file = debug_map->GetSymbolFileByOSOIndex(*file_index); // OSO case - if (symbol_file) -return symbol_file->DebugInfo().GetDIE(die_ref.section(), - die_ref.die_offset()); - return DWARFDIE(); +SymbolFileDWARFDebugMap *debug_map = GetDebugMapSymfile(); +if (debug_map) { + // We have a SymbolFileDWARFDebugMap, so let it find the right file + return debug_map->GetSymbolFileByOSOIndex(*file_index); +} else { + // Handle the .dwp file case correctly + if (*file_index == DIERef::k_file_index_mask) +return GetDwpSymbolFile().get(); // DWP case + + // Handle the .dwo file case correctly + return DebugInfo() + .GetUnitAtIndex(*die_ref.file_index()) + ->GetDwoSymbolFile(); // DWO case } + } + return this; +} -if (*file_index == DIERef::k_file_index_mask) - symbol_file = GetDwpSymbolFile().get(); // DWP case -else - symbol_file = this->DebugInfo() -.GetUnitAtIndex(*die_ref.file_index()) -->GetDwoSymbolFile(); // DWO case - } else if (die_ref.die_offset() == DW_INVALID_OFFSET) { +DWARFDIE +SymbolFileDWARF::GetDIE(const DIERef &die_ref) { + if (die_ref.die_offset() == DW_INVALID_OFFSET) return DWARFDIE(); - } + // This method can be called without going through the symbol vendor so we + // need to lock the module. + std::lock_guard guard(GetModuleMutex()); + SymbolFileDWARF *symbol_file = GetDIERefSymbolFile(die_ref); clayborg wrote: It only uses the file index component, but that component might not be set in the `DIERef` object and if it isn't, it returns the current SymbolFileDWARF object. We can make a function like: ``` SymbolFileDWARF *GetSymbolFileByFileIndex(std::optional file_index); ``` The file index only makes sense if it comes from a DIERef object as it understands the value and knows the magic value for the .dwp file, so the above API is much less clear as who else knows what a file index is and would actaully know to ask for the symbol file using such an index? Seems less clear to me than the existing API. Let me know if feel we should still change this https://github.com/llvm/llvm-project/pull/87740 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [llvm] Add support for using foreign type units in .debug_names. (PR #87740)
clayborg wrote: All issues resolved except the change of `GetDIERefSymbolFile`. Let me know if you agree with my comments, or want a `GetSymbolFileByFileIndex(std::optional file_idx)`. https://github.com/llvm/llvm-project/pull/87740 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb][API] Add Find(Ranges)InMemory() to Process SB API (PR #95007)
@@ -2007,6 +2007,135 @@ size_t Process::ReadMemory(addr_t addr, void *buf, size_t size, Status &error) { } } +void Process::DoFindInMemory(lldb::addr_t start_addr, lldb::addr_t end_addr, + const uint8_t *buf, size_t size, + AddressRanges &matches, size_t alignment, + size_t max_matches) { + // Inputs are already validated in FindInMemory() functions. + assert(buf != nullptr); + assert(size > 0); + assert(alignment > 0); + assert(max_matches > 0); + assert(start_addr != LLDB_INVALID_ADDRESS); + assert(end_addr != LLDB_INVALID_ADDRESS); + assert(start_addr < end_addr); + + lldb::addr_t start = start_addr; + if (alignment > 1) { +// Align to an address alignment boundary +const uint64_t align_offset = start % alignment; +if (align_offset > 0) + start += alignment - align_offset; + } + while (matches.size() < max_matches && (start + size) < end_addr) { +const lldb::addr_t found_addr = FindInMemory(start, end_addr, buf, size); +if (found_addr == LLDB_INVALID_ADDRESS) + break; + +if (found_addr % alignment) { + ++start; + continue; +} + +matches.emplace_back(found_addr, size); +start = found_addr + alignment; + } +} + +AddressRanges Process::FindRangesInMemory(const uint8_t *buf, uint64_t size, + const AddressRanges &ranges, + size_t alignment, size_t max_matches, + Status &error) { + AddressRanges matches; + if (buf == nullptr) { +error.SetErrorString("buffer is null"); +return matches; + } + if (size == 0) { +error.SetErrorString("buffer size is zero"); +return matches; + } + if (ranges.empty()) { +error.SetErrorString("empty ranges"); +return matches; + } + if (alignment == 0) { +error.SetErrorString("alignment must be greater than zero"); +return matches; + } + if (max_matches == 0) { +error.SetErrorString("max_matches must be greater than zero"); +return matches; + } + + int resolved_ranges = 0; + Target &target = GetTarget(); + for (size_t i = 0; i < ranges.size(); ++i) { +if (matches.size() >= max_matches) { + break; +} clayborg wrote: remove single if statement '{}' per llvm coding guidelines https://github.com/llvm/llvm-project/pull/95007 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb][API] Add Find(Ranges)InMemory() to Process SB API (PR #95007)
@@ -2007,6 +2007,135 @@ size_t Process::ReadMemory(addr_t addr, void *buf, size_t size, Status &error) { } } +void Process::DoFindInMemory(lldb::addr_t start_addr, lldb::addr_t end_addr, + const uint8_t *buf, size_t size, + AddressRanges &matches, size_t alignment, + size_t max_matches) { + // Inputs are already validated in FindInMemory() functions. + assert(buf != nullptr); + assert(size > 0); + assert(alignment > 0); + assert(max_matches > 0); + assert(start_addr != LLDB_INVALID_ADDRESS); + assert(end_addr != LLDB_INVALID_ADDRESS); + assert(start_addr < end_addr); + + lldb::addr_t start = start_addr; + if (alignment > 1) { +// Align to an address alignment boundary +const uint64_t align_offset = start % alignment; +if (align_offset > 0) + start += alignment - align_offset; + } clayborg wrote: All these lines can be: ``` lldb::addr_t start = llvm::alignTo(start_addr, alignment); ``` https://github.com/llvm/llvm-project/pull/95007 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb][API] Add Find(Ranges)InMemory() to Process SB API (PR #95007)
@@ -2007,6 +2007,135 @@ size_t Process::ReadMemory(addr_t addr, void *buf, size_t size, Status &error) { } } +void Process::DoFindInMemory(lldb::addr_t start_addr, lldb::addr_t end_addr, + const uint8_t *buf, size_t size, + AddressRanges &matches, size_t alignment, + size_t max_matches) { + // Inputs are already validated in FindInMemory() functions. + assert(buf != nullptr); + assert(size > 0); + assert(alignment > 0); + assert(max_matches > 0); + assert(start_addr != LLDB_INVALID_ADDRESS); + assert(end_addr != LLDB_INVALID_ADDRESS); + assert(start_addr < end_addr); + + lldb::addr_t start = start_addr; + if (alignment > 1) { +// Align to an address alignment boundary +const uint64_t align_offset = start % alignment; +if (align_offset > 0) + start += alignment - align_offset; + } + while (matches.size() < max_matches && (start + size) < end_addr) { +const lldb::addr_t found_addr = FindInMemory(start, end_addr, buf, size); +if (found_addr == LLDB_INVALID_ADDRESS) + break; + +if (found_addr % alignment) { + ++start; + continue; +} + +matches.emplace_back(found_addr, size); +start = found_addr + alignment; + } +} + +AddressRanges Process::FindRangesInMemory(const uint8_t *buf, uint64_t size, + const AddressRanges &ranges, + size_t alignment, size_t max_matches, + Status &error) { + AddressRanges matches; + if (buf == nullptr) { +error.SetErrorString("buffer is null"); +return matches; + } + if (size == 0) { +error.SetErrorString("buffer size is zero"); +return matches; + } + if (ranges.empty()) { +error.SetErrorString("empty ranges"); +return matches; + } + if (alignment == 0) { +error.SetErrorString("alignment must be greater than zero"); +return matches; + } + if (max_matches == 0) { +error.SetErrorString("max_matches must be greater than zero"); +return matches; + } + + int resolved_ranges = 0; + Target &target = GetTarget(); + for (size_t i = 0; i < ranges.size(); ++i) { +if (matches.size() >= max_matches) { + break; +} +const AddressRange &range = ranges[i]; +if (range.IsValid() == false) { + continue; +} + +const lldb::addr_t start_addr = +range.GetBaseAddress().GetLoadAddress(&target); +if (start_addr == LLDB_INVALID_ADDRESS) { + continue; +} clayborg wrote: remove single if statement '{}' per llvm coding guidelines https://github.com/llvm/llvm-project/pull/95007 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb][API] Add Find(Ranges)InMemory() to Process SB API (PR #95007)
@@ -2007,6 +2007,135 @@ size_t Process::ReadMemory(addr_t addr, void *buf, size_t size, Status &error) { } } +void Process::DoFindInMemory(lldb::addr_t start_addr, lldb::addr_t end_addr, + const uint8_t *buf, size_t size, + AddressRanges &matches, size_t alignment, + size_t max_matches) { + // Inputs are already validated in FindInMemory() functions. + assert(buf != nullptr); + assert(size > 0); + assert(alignment > 0); + assert(max_matches > 0); + assert(start_addr != LLDB_INVALID_ADDRESS); + assert(end_addr != LLDB_INVALID_ADDRESS); + assert(start_addr < end_addr); + + lldb::addr_t start = start_addr; + if (alignment > 1) { +// Align to an address alignment boundary +const uint64_t align_offset = start % alignment; +if (align_offset > 0) + start += alignment - align_offset; + } + while (matches.size() < max_matches && (start + size) < end_addr) { +const lldb::addr_t found_addr = FindInMemory(start, end_addr, buf, size); +if (found_addr == LLDB_INVALID_ADDRESS) + break; + +if (found_addr % alignment) { + ++start; + continue; +} + +matches.emplace_back(found_addr, size); +start = found_addr + alignment; + } +} + +AddressRanges Process::FindRangesInMemory(const uint8_t *buf, uint64_t size, + const AddressRanges &ranges, + size_t alignment, size_t max_matches, + Status &error) { + AddressRanges matches; + if (buf == nullptr) { +error.SetErrorString("buffer is null"); +return matches; + } + if (size == 0) { +error.SetErrorString("buffer size is zero"); +return matches; + } + if (ranges.empty()) { +error.SetErrorString("empty ranges"); +return matches; + } + if (alignment == 0) { +error.SetErrorString("alignment must be greater than zero"); +return matches; + } + if (max_matches == 0) { +error.SetErrorString("max_matches must be greater than zero"); +return matches; + } + + int resolved_ranges = 0; + Target &target = GetTarget(); + for (size_t i = 0; i < ranges.size(); ++i) { +if (matches.size() >= max_matches) { + break; +} +const AddressRange &range = ranges[i]; +if (range.IsValid() == false) { + continue; +} clayborg wrote: remove single if statement '{}' per llvm coding guidelines https://github.com/llvm/llvm-project/pull/95007 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb][API] Add Find(Ranges)InMemory() to Process SB API (PR #95007)
@@ -2007,6 +2007,135 @@ size_t Process::ReadMemory(addr_t addr, void *buf, size_t size, Status &error) { } } +void Process::DoFindInMemory(lldb::addr_t start_addr, lldb::addr_t end_addr, + const uint8_t *buf, size_t size, + AddressRanges &matches, size_t alignment, + size_t max_matches) { + // Inputs are already validated in FindInMemory() functions. + assert(buf != nullptr); + assert(size > 0); + assert(alignment > 0); + assert(max_matches > 0); + assert(start_addr != LLDB_INVALID_ADDRESS); + assert(end_addr != LLDB_INVALID_ADDRESS); + assert(start_addr < end_addr); + + lldb::addr_t start = start_addr; + if (alignment > 1) { +// Align to an address alignment boundary +const uint64_t align_offset = start % alignment; +if (align_offset > 0) + start += alignment - align_offset; + } + while (matches.size() < max_matches && (start + size) < end_addr) { +const lldb::addr_t found_addr = FindInMemory(start, end_addr, buf, size); +if (found_addr == LLDB_INVALID_ADDRESS) + break; + +if (found_addr % alignment) { + ++start; clayborg wrote: No sense in just incrementing by 1, lets increment by an aligned value. ``` start = llvm::alignTo(start+1, alignment); ``` https://github.com/llvm/llvm-project/pull/95007 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb][API] Add Find(Ranges)InMemory() to Process SB API (PR #95007)
@@ -2007,6 +2007,135 @@ size_t Process::ReadMemory(addr_t addr, void *buf, size_t size, Status &error) { } } +void Process::DoFindInMemory(lldb::addr_t start_addr, lldb::addr_t end_addr, + const uint8_t *buf, size_t size, + AddressRanges &matches, size_t alignment, + size_t max_matches) { + // Inputs are already validated in FindInMemory() functions. + assert(buf != nullptr); + assert(size > 0); + assert(alignment > 0); + assert(max_matches > 0); + assert(start_addr != LLDB_INVALID_ADDRESS); + assert(end_addr != LLDB_INVALID_ADDRESS); + assert(start_addr < end_addr); + + lldb::addr_t start = start_addr; + if (alignment > 1) { +// Align to an address alignment boundary +const uint64_t align_offset = start % alignment; +if (align_offset > 0) + start += alignment - align_offset; + } + while (matches.size() < max_matches && (start + size) < end_addr) { +const lldb::addr_t found_addr = FindInMemory(start, end_addr, buf, size); +if (found_addr == LLDB_INVALID_ADDRESS) + break; + +if (found_addr % alignment) { + ++start; + continue; +} + +matches.emplace_back(found_addr, size); +start = found_addr + alignment; + } +} + +AddressRanges Process::FindRangesInMemory(const uint8_t *buf, uint64_t size, + const AddressRanges &ranges, + size_t alignment, size_t max_matches, + Status &error) { + AddressRanges matches; + if (buf == nullptr) { +error.SetErrorString("buffer is null"); +return matches; + } + if (size == 0) { +error.SetErrorString("buffer size is zero"); +return matches; + } + if (ranges.empty()) { +error.SetErrorString("empty ranges"); +return matches; + } + if (alignment == 0) { +error.SetErrorString("alignment must be greater than zero"); +return matches; + } + if (max_matches == 0) { +error.SetErrorString("max_matches must be greater than zero"); +return matches; + } + + int resolved_ranges = 0; + Target &target = GetTarget(); + for (size_t i = 0; i < ranges.size(); ++i) { +if (matches.size() >= max_matches) { + break; +} +const AddressRange &range = ranges[i]; +if (range.IsValid() == false) { + continue; +} + +const lldb::addr_t start_addr = +range.GetBaseAddress().GetLoadAddress(&target); +if (start_addr == LLDB_INVALID_ADDRESS) { + continue; +} +++resolved_ranges; +const lldb::addr_t end_addr = start_addr + range.GetByteSize(); +DoFindInMemory(start_addr, end_addr, buf, size, matches, alignment, + max_matches); + } + + if (resolved_ranges > 0) { +error.Clear(); + } else { +error.SetErrorString("unable to resolve any ranges"); + } clayborg wrote: remove single if/else statement '{}' per llvm coding guidelines https://github.com/llvm/llvm-project/pull/95007 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb][API] Add Find(Ranges)InMemory() to Process SB API (PR #95007)
@@ -2007,6 +2007,135 @@ size_t Process::ReadMemory(addr_t addr, void *buf, size_t size, Status &error) { } } +void Process::DoFindInMemory(lldb::addr_t start_addr, lldb::addr_t end_addr, + const uint8_t *buf, size_t size, + AddressRanges &matches, size_t alignment, + size_t max_matches) { + // Inputs are already validated in FindInMemory() functions. + assert(buf != nullptr); + assert(size > 0); + assert(alignment > 0); + assert(max_matches > 0); + assert(start_addr != LLDB_INVALID_ADDRESS); + assert(end_addr != LLDB_INVALID_ADDRESS); + assert(start_addr < end_addr); + + lldb::addr_t start = start_addr; + if (alignment > 1) { +// Align to an address alignment boundary +const uint64_t align_offset = start % alignment; +if (align_offset > 0) + start += alignment - align_offset; + } + while (matches.size() < max_matches && (start + size) < end_addr) { +const lldb::addr_t found_addr = FindInMemory(start, end_addr, buf, size); +if (found_addr == LLDB_INVALID_ADDRESS) + break; + +if (found_addr % alignment) { clayborg wrote: Add a comment about why we need to check the alignment here: ``` // We need to check the alignment because the FindInMemory uses a special algorithm to efficiently search mememory but doesn't support alignment. ``` https://github.com/llvm/llvm-project/pull/95007 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [llvm] Add support for using foreign type units in .debug_names. (PR #87740)
https://github.com/labath edited https://github.com/llvm/llvm-project/pull/87740 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [llvm] Add support for using foreign type units in .debug_names. (PR #87740)
https://github.com/labath approved this pull request. https://github.com/llvm/llvm-project/pull/87740 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [llvm] Add support for using foreign type units in .debug_names. (PR #87740)
@@ -241,6 +241,15 @@ class SymbolFileDWARF : public SymbolFileCommon { return m_external_type_modules; } + /// Given a DIERef, find the correct SymbolFileDWARF. + /// + /// A DIERef contains a file index that can uniquely identify a N_OSO file for + /// DWARF in .o files on mac, or a .dwo or .dwp file index for split DWARF. + /// Calling this function will find the correct symbol file to use so that + /// further lookups can be done on the correct symbol file so that the DIE + /// offset makes sense in the DIERef. + virtual SymbolFileDWARF *GetDIERefSymbolFile(const DIERef &die_ref); + virtual DWARFDIE GetDIE(const DIERef &die_ref); labath wrote: Now GetDIE is virtual and handles SymbolFile resolution, this one doesn't need to be. https://github.com/llvm/llvm-project/pull/87740 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [llvm] Add support for using foreign type units in .debug_names. (PR #87740)
@@ -1727,45 +1727,61 @@ lldb::ModuleSP SymbolFileDWARF::GetExternalModule(ConstString name) { return pos->second; } -DWARFDIE -SymbolFileDWARF::GetDIE(const DIERef &die_ref) { - // This method can be called without going through the symbol vendor so we - // need to lock the module. - std::lock_guard guard(GetModuleMutex()); - - SymbolFileDWARF *symbol_file = nullptr; - +SymbolFileDWARF *SymbolFileDWARF::GetDIERefSymbolFile(const DIERef &die_ref) { // Anytime we get a "lldb::user_id_t" from an lldb_private::SymbolFile API we // must make sure we use the correct DWARF file when resolving things. On // MacOSX, when using SymbolFileDWARFDebugMap, we will use multiple // SymbolFileDWARF classes, one for each .o file. We can often end up with // references to other DWARF objects and we must be ready to receive a // "lldb::user_id_t" that specifies a DIE from another SymbolFileDWARF // instance. + std::optional file_index = die_ref.file_index(); + + // If the file index matches, then we have the right SymbolFileDWARF already. + // This will work for both .dwo file and DWARF in .o files for mac. Also if + // both the file indexes are invalid, then we have a match. + if (GetFileIndex() == file_index) +return this; + + // If we are currently in a .dwo file and our file index doesn't match we need + // to let the base symbol file handle this. + SymbolFileDWARFDwo *dwo = llvm::dyn_cast_or_null(this); + if (dwo) +return dwo->GetDIERefSymbolFile(die_ref); + if (file_index) { -if (SymbolFileDWARFDebugMap *debug_map = GetDebugMapSymfile()) { - symbol_file = debug_map->GetSymbolFileByOSOIndex(*file_index); // OSO case - if (symbol_file) -return symbol_file->DebugInfo().GetDIE(die_ref.section(), - die_ref.die_offset()); - return DWARFDIE(); +SymbolFileDWARFDebugMap *debug_map = GetDebugMapSymfile(); +if (debug_map) { + // We have a SymbolFileDWARFDebugMap, so let it find the right file + return debug_map->GetSymbolFileByOSOIndex(*file_index); +} else { + // Handle the .dwp file case correctly + if (*file_index == DIERef::k_file_index_mask) +return GetDwpSymbolFile().get(); // DWP case + + // Handle the .dwo file case correctly + return DebugInfo() + .GetUnitAtIndex(*die_ref.file_index()) + ->GetDwoSymbolFile(); // DWO case } + } + return this; +} -if (*file_index == DIERef::k_file_index_mask) - symbol_file = GetDwpSymbolFile().get(); // DWP case -else - symbol_file = this->DebugInfo() -.GetUnitAtIndex(*die_ref.file_index()) -->GetDwoSymbolFile(); // DWO case - } else if (die_ref.die_offset() == DW_INVALID_OFFSET) { +DWARFDIE +SymbolFileDWARF::GetDIE(const DIERef &die_ref) { + if (die_ref.die_offset() == DW_INVALID_OFFSET) return DWARFDIE(); - } + // This method can be called without going through the symbol vendor so we + // need to lock the module. + std::lock_guard guard(GetModuleMutex()); + SymbolFileDWARF *symbol_file = GetDIERefSymbolFile(die_ref); labath wrote: I don't think the file index needs to necessarily come from a DIERef. I can imagine other scenarios where it might be interesting to ask for a symbol file, but I think we can deal with it when the time comes. https://github.com/llvm/llvm-project/pull/87740 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] bf3e328 - [lldb] Unify Platform::ResolveExecutable (#96256)
Author: Jonas Devlieghere Date: 2024-06-21T11:29:49-07:00 New Revision: bf3e3289d67cb0fe136b0660cac39c24c9f65069 URL: https://github.com/llvm/llvm-project/commit/bf3e3289d67cb0fe136b0660cac39c24c9f65069 DIFF: https://github.com/llvm/llvm-project/commit/bf3e3289d67cb0fe136b0660cac39c24c9f65069.diff LOG: [lldb] Unify Platform::ResolveExecutable (#96256) The Platform class currently has two functions to resolve an executable: `ResolveExecutable` and `ResolveRemoteExecutable`. The former strictly deals with local files while the latter can handle potentially remote files. I couldn't figure out why the distinction matters, at the latter is a super-set of the former. To make things even more confusion, we had a similar but not identical implementation in RemoteAwarePlatform where its implementation of `ResolveExecutable` could handle remote files. To top it all off, we had copy-pasted implementation, dead code included in `PlatformAppleSimulator` and `PlatformRemoteDarwinDevice`. I went ahead and unified all the different implementation on the original `ResolveRemoteExecutable` implementation. As far as I can tell, it should work for every other platform, and the test suite (on macOS) seems to agree with me, except for a small wording change. Added: Modified: lldb/include/lldb/Target/Platform.h lldb/include/lldb/Target/RemoteAwarePlatform.h lldb/source/Plugins/Platform/MacOSX/PlatformAppleSimulator.cpp lldb/source/Plugins/Platform/MacOSX/PlatformAppleSimulator.h lldb/source/Plugins/Platform/MacOSX/PlatformRemoteDarwinDevice.cpp lldb/source/Plugins/Platform/MacOSX/PlatformRemoteDarwinDevice.h lldb/source/Target/Platform.cpp lldb/source/Target/RemoteAwarePlatform.cpp lldb/test/API/assert_messages_test/TestAssertMessages.py lldb/test/API/tools/lldb-dap/launch/TestDAP_launch.py lldb/unittests/Target/RemoteAwarePlatformTest.cpp Removed: diff --git a/lldb/include/lldb/Target/Platform.h b/lldb/include/lldb/Target/Platform.h index e05c79cb501bf..48988b838f67a 100644 --- a/lldb/include/lldb/Target/Platform.h +++ b/lldb/include/lldb/Target/Platform.h @@ -139,7 +139,7 @@ class Platform : public PluginInterface { /// Returns \b true if this Platform plug-in was able to find /// a suitable executable, \b false otherwise. virtual Status ResolveExecutable(const ModuleSpec &module_spec, - lldb::ModuleSP &module_sp, + lldb::ModuleSP &exe_module_sp, const FileSpecList *module_search_paths_ptr); /// Find a symbol file given a symbol file module specification. @@ -1004,11 +1004,6 @@ class Platform : public PluginInterface { virtual const char *GetCacheHostname(); - virtual Status - ResolveRemoteExecutable(const ModuleSpec &module_spec, - lldb::ModuleSP &exe_module_sp, - const FileSpecList *module_search_paths_ptr); - private: typedef std::function ModuleResolver; diff --git a/lldb/include/lldb/Target/RemoteAwarePlatform.h b/lldb/include/lldb/Target/RemoteAwarePlatform.h index 0b9d79f9ff038..6fbeec7888a98 100644 --- a/lldb/include/lldb/Target/RemoteAwarePlatform.h +++ b/lldb/include/lldb/Target/RemoteAwarePlatform.h @@ -23,10 +23,6 @@ class RemoteAwarePlatform : public Platform { bool GetModuleSpec(const FileSpec &module_file_spec, const ArchSpec &arch, ModuleSpec &module_spec) override; - Status - ResolveExecutable(const ModuleSpec &module_spec, lldb::ModuleSP &module_sp, -const FileSpecList *module_search_paths_ptr) override; - lldb::user_id_t OpenFile(const FileSpec &file_spec, File::OpenOptions flags, uint32_t mode, Status &error) override; diff --git a/lldb/source/Plugins/Platform/MacOSX/PlatformAppleSimulator.cpp b/lldb/source/Plugins/Platform/MacOSX/PlatformAppleSimulator.cpp index 0c4b566b7d535..c27a34b7201a2 100644 --- a/lldb/source/Plugins/Platform/MacOSX/PlatformAppleSimulator.cpp +++ b/lldb/source/Plugins/Platform/MacOSX/PlatformAppleSimulator.cpp @@ -383,81 +383,6 @@ PlatformSP PlatformAppleSimulator::CreateInstance( return PlatformSP(); } -Status PlatformAppleSimulator::ResolveExecutable( -const ModuleSpec &module_spec, lldb::ModuleSP &exe_module_sp, -const FileSpecList *module_search_paths_ptr) { - Status error; - // Nothing special to do here, just use the actual file and architecture - - ModuleSpec resolved_module_spec(module_spec); - - // If we have "ls" as the exe_file, resolve the executable loation based on - // the current path variables - // TODO: resolve bare executables in the Platform SDK - //if (!resolved_exe_file.Exists()) - //resolved_exe_file.ResolveExecutableLocation (); - - // Resolve any executable within a bundle on MacOSX - // TODO: verif
[Lldb-commits] [lldb] [lldb] Unify Platform::ResolveExecutable (PR #96256)
https://github.com/JDevlieghere closed https://github.com/llvm/llvm-project/pull/96256 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb][ExpressionParser][NFCI] Add new DoPrepareForExecution interface to be implemented by language plugins (PR #96290)
https://github.com/Michael137 updated https://github.com/llvm/llvm-project/pull/96290 >From 67d8bab2d2d42ca3ec5d07efd3be94e614dde2e9 Mon Sep 17 00:00:00 2001 From: Michael Buch Date: Thu, 20 Jun 2024 18:29:15 +0100 Subject: [PATCH 1/3] [lldb][ExpressionParser] Add DoPrepareForExecution API --- .../lldb/Expression/ExpressionParser.h| 25 ++- lldb/source/Expression/CMakeLists.txt | 1 + lldb/source/Expression/ExpressionParser.cpp | 73 +++ .../Clang/ClangExpressionParser.cpp | 46 +--- .../Clang/ClangExpressionParser.h | 23 ++ .../Clang/ClangUserExpression.cpp | 15 6 files changed, 103 insertions(+), 80 deletions(-) create mode 100644 lldb/source/Expression/ExpressionParser.cpp diff --git a/lldb/include/lldb/Expression/ExpressionParser.h b/lldb/include/lldb/Expression/ExpressionParser.h index ab5223c915530..2ef7e036909c7 100644 --- a/lldb/include/lldb/Expression/ExpressionParser.h +++ b/lldb/include/lldb/Expression/ExpressionParser.h @@ -119,14 +119,35 @@ class ExpressionParser { /// \return /// An error code indicating the success or failure of the operation. /// Test with Success(). - virtual Status + Status PrepareForExecution(lldb::addr_t &func_addr, lldb::addr_t &func_end, std::shared_ptr &execution_unit_sp, ExecutionContext &exe_ctx, bool &can_interpret, - lldb_private::ExecutionPolicy execution_policy) = 0; + lldb_private::ExecutionPolicy execution_policy); bool GetGenerateDebugInfo() const { return m_generate_debug_info; } +protected: + virtual Status + DoPrepareForExecution(lldb::addr_t &func_addr, lldb::addr_t &func_end, +std::shared_ptr &execution_unit_sp, +ExecutionContext &exe_ctx, bool &can_interpret, +lldb_private::ExecutionPolicy execution_policy) = 0; + +private: + /// Run all static initializers for an execution unit. + /// + /// \param[in] execution_unit_sp + /// The execution unit. + /// + /// \param[in] exe_ctx + /// The execution context to use when running them. Thread can't be null. + /// + /// \return + /// The error code indicating the + Status RunStaticInitializers(lldb::IRExecutionUnitSP &execution_unit_sp, + ExecutionContext &exe_ctx); + protected: Expression &m_expr; ///< The expression to be parsed bool m_generate_debug_info; diff --git a/lldb/source/Expression/CMakeLists.txt b/lldb/source/Expression/CMakeLists.txt index 9ba5fefc09b6a..be1e132f7aaad 100644 --- a/lldb/source/Expression/CMakeLists.txt +++ b/lldb/source/Expression/CMakeLists.txt @@ -3,6 +3,7 @@ add_lldb_library(lldbExpression NO_PLUGIN_DEPENDENCIES DWARFExpression.cpp DWARFExpressionList.cpp Expression.cpp + ExpressionParser.cpp ExpressionTypeSystemHelper.cpp ExpressionVariable.cpp FunctionCaller.cpp diff --git a/lldb/source/Expression/ExpressionParser.cpp b/lldb/source/Expression/ExpressionParser.cpp new file mode 100644 index 0..ac727be78e8d3 --- /dev/null +++ b/lldb/source/Expression/ExpressionParser.cpp @@ -0,0 +1,73 @@ +//===-- ExpressionParser.cpp --===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===--===// + +#include "lldb/Expression/ExpressionParser.h" +#include "lldb/Expression/DiagnosticManager.h" +#include "lldb/Expression/IRExecutionUnit.h" +#include "lldb/Target/ExecutionContext.h" +#include "lldb/Target/ThreadPlanCallFunction.h" + +using namespace lldb_private; + +Status ExpressionParser::PrepareForExecution( +lldb::addr_t &func_addr, lldb::addr_t &func_end, +std::shared_ptr &execution_unit_sp, +ExecutionContext &exe_ctx, bool &can_interpret, +lldb_private::ExecutionPolicy execution_policy) { + Status status = + DoPrepareForExecution(func_addr, func_end, execution_unit_sp, exe_ctx, +can_interpret, execution_policy); + if (status.Success() && exe_ctx.GetProcessPtr() && exe_ctx.HasThreadScope()) { +status = RunStaticInitializers(execution_unit_sp, exe_ctx); + } + return status; +} + +Status ExpressionParser::RunStaticInitializers( +lldb::IRExecutionUnitSP &execution_unit_sp, ExecutionContext &exe_ctx) { + lldb_private::Status err; + + lldbassert(execution_unit_sp.get()); + lldbassert(exe_ctx.HasThreadScope()); + + if (!execution_unit_sp.get()) { +err.SetErrorString( +"can't run static initializers for a NULL execution unit"); +return err; + } + + if (!exe_ctx.HasThreadScope()) { +err.SetErrorString("can't run static initializers without a thread"); +
[Lldb-commits] [lldb] 9e6ea38 - Reland "[lldb][ObjC] Don't query objective-c runtime for decls in C++ contexts"
Author: Michael Buch Date: 2024-06-21T20:35:30+01:00 New Revision: 9e6ea387c877a50394aca4b02f18a05e88cf2690 URL: https://github.com/llvm/llvm-project/commit/9e6ea387c877a50394aca4b02f18a05e88cf2690 DIFF: https://github.com/llvm/llvm-project/commit/9e6ea387c877a50394aca4b02f18a05e88cf2690.diff LOG: Reland "[lldb][ObjC] Don't query objective-c runtime for decls in C++ contexts" This relands https://github.com/llvm/llvm-project/pull/95963. It had to be reverted because the `TestEarlyProcessLaunch.py` test was failing on the incremental macOS bots. The test failed because it was relying on expression log output from the ObjC introspection routines (but was the expression was called from a C++ context). The relanded patch simply ensures that the test runs the expressions as `ObjC` expressions. When LLDB isn't able to find a `clang::Decl` in response to a `FindExternalVisibleDeclsByName`, it will fall-back to looking into the Objective-C runtime for that decl. This ends up doing a lot of work which isn't necessary when we're debugging a C++ program. This patch makes the ObjC lookup conditional on the language that the ExpressionParser deduced (which can be explicitly set using the `expr --language` option or is set implicitly if we're stopped in an ObjC frame or a C++ frame without debug-info). rdar://96236519 Added: lldb/test/Shell/Expr/TestObjCInCXXContext.test Modified: lldb/source/Plugins/ExpressionParser/Clang/ClangASTSource.cpp lldb/test/API/lang/objcxx/objc-from-cpp-frames-without-debuginfo/TestObjCFromCppFramesWithoutDebugInfo.py lldb/test/API/macosx/early-process-launch/TestEarlyProcessLaunch.py Removed: diff --git a/lldb/source/Plugins/ExpressionParser/Clang/ClangASTSource.cpp b/lldb/source/Plugins/ExpressionParser/Clang/ClangASTSource.cpp index 82a7a2cc3f1ef..1fdd272dcbece 100644 --- a/lldb/source/Plugins/ExpressionParser/Clang/ClangASTSource.cpp +++ b/lldb/source/Plugins/ExpressionParser/Clang/ClangASTSource.cpp @@ -637,7 +637,7 @@ void ClangASTSource::FindExternalVisibleDecls( FindDeclInModules(context, name); } - if (!context.m_found_type) { + if (!context.m_found_type && m_ast_context->getLangOpts().ObjC) { FindDeclInObjCRuntime(context, name); } } diff --git a/lldb/test/API/lang/objcxx/objc-from-cpp-frames-without-debuginfo/TestObjCFromCppFramesWithoutDebugInfo.py b/lldb/test/API/lang/objcxx/objc-from-cpp-frames-without-debuginfo/TestObjCFromCppFramesWithoutDebugInfo.py index ef8d5540fa4ef..497c0dd128f48 100644 --- a/lldb/test/API/lang/objcxx/objc-from-cpp-frames-without-debuginfo/TestObjCFromCppFramesWithoutDebugInfo.py +++ b/lldb/test/API/lang/objcxx/objc-from-cpp-frames-without-debuginfo/TestObjCFromCppFramesWithoutDebugInfo.py @@ -15,4 +15,11 @@ def test(self): (_, process, _, _) = lldbutil.run_to_name_breakpoint(self, "main") self.assertState(process.GetState(), lldb.eStateStopped) + +# Tests that we can use builtin Objective-C identifiers. self.expect("expr id", error=False) + +# Tests that we can lookup Objective-C decls in the ObjC runtime plugin. +self.expect_expr( +"NSString *c; c == nullptr", result_value="true", result_type="bool" +) diff --git a/lldb/test/API/macosx/early-process-launch/TestEarlyProcessLaunch.py b/lldb/test/API/macosx/early-process-launch/TestEarlyProcessLaunch.py index 32a7bc82f4745..c15abbabc2374 100644 --- a/lldb/test/API/macosx/early-process-launch/TestEarlyProcessLaunch.py +++ b/lldb/test/API/macosx/early-process-launch/TestEarlyProcessLaunch.py @@ -38,14 +38,14 @@ def test_early_process_launch(self): logfile_early = os.path.join(self.getBuildDir(), "types-log-early.txt") self.addTearDownHook(lambda: self.runCmd("log disable lldb types")) self.runCmd("log enable -f %s lldb types" % logfile_early) -self.runCmd("expression global = 15") +self.runCmd("expression --language objc -- global = 15") err = process.Continue() self.assertTrue(err.Success()) logfile_later = os.path.join(self.getBuildDir(), "types-log-later.txt") self.runCmd("log enable -f %s lldb types" % logfile_later) -self.runCmd("expression global = 25") +self.runCmd("expression --language objc -- global = 25") self.assertTrue(os.path.exists(logfile_early)) self.assertTrue(os.path.exists(logfile_later)) diff --git a/lldb/test/Shell/Expr/TestObjCInCXXContext.test b/lldb/test/Shell/Expr/TestObjCInCXXContext.test new file mode 100644 index 0..8537799bdeb67 --- /dev/null +++ b/lldb/test/Shell/Expr/TestObjCInCXXContext.test @@ -0,0 +1,21 @@ +// UNSUPPORTED: system-linux, system-windows + +// Tests that we don't consult the the Objective-C runtime +// plugin when in a purely C++ context. +// +// RUN: %clangxx_host %p/Inputs/objc-cast.cpp -g -o %t +// RU
[Lldb-commits] [clang] [lldb] [llvm] [BOLT][DWARF] Refactor legacy ranges writers (PR #96006)
https://github.com/sayhaan updated https://github.com/llvm/llvm-project/pull/96006 >From 2f1db023b70fc0bd8e0c220ebc966584bda13236 Mon Sep 17 00:00:00 2001 From: Sayhaan Siddiqui Date: Mon, 17 Jun 2024 10:16:44 -0700 Subject: [PATCH 01/15] [BOLT][DWARF][NFC] Refactor updateDWARFObjectAddressRanges Summary: Test Plan: Reviewers: Subscribers: Tasks: Tags: Differential Revision: https://phabricator.intern.facebook.com/D58679290 --- bolt/include/bolt/Core/DebugData.h| 2 + bolt/include/bolt/Rewrite/DWARFRewriter.h | 7 ++ bolt/lib/Core/DebugData.cpp | 7 ++ bolt/lib/Rewrite/DWARFRewriter.cpp| 110 +++--- bolt/test/X86/debug-fission-single-convert.s | 6 +- bolt/test/X86/dwarf4-df-dualcu.test | 34 +++--- .../X86/dwarf4-df-input-lowpc-ranges-cus.test | 78 +++-- .../X86/dwarf4-df-input-lowpc-ranges.test | 37 +++--- 8 files changed, 163 insertions(+), 118 deletions(-) diff --git a/bolt/include/bolt/Core/DebugData.h b/bolt/include/bolt/Core/DebugData.h index 585bafa088849..5c730e63ae0aa 100644 --- a/bolt/include/bolt/Core/DebugData.h +++ b/bolt/include/bolt/Core/DebugData.h @@ -210,6 +210,8 @@ class DebugRangesSectionWriter { static bool classof(const DebugRangesSectionWriter *Writer) { return Writer->getKind() == RangesWriterKind::DebugRangesWriter; } + + void updateRangeBuffer(std::unique_ptr &CUBuffer); /// Writes out range lists for a current CU being processed. void virtual finalizeSection(){}; diff --git a/bolt/include/bolt/Rewrite/DWARFRewriter.h b/bolt/include/bolt/Rewrite/DWARFRewriter.h index 8dec32de9008e..c97f25125c099 100644 --- a/bolt/include/bolt/Rewrite/DWARFRewriter.h +++ b/bolt/include/bolt/Rewrite/DWARFRewriter.h @@ -89,6 +89,13 @@ class DWARFRewriter { /// Store Rangelists writer for each DWO CU. RangeListsDWOWriers RangeListsWritersByCU; + using LegacyRangesDWOWriers = + std::unordered_map>; + /// Store Rangelists writer for each DWO CU. + LegacyRangesDWOWriers LegacyRangesWritersByCU; + + std::unordered_map UpdatedDIEsByDWO; + std::mutex LocListDebugInfoPatchesMutex; /// Dwo id specific its RangesBase. diff --git a/bolt/lib/Core/DebugData.cpp b/bolt/lib/Core/DebugData.cpp index f502a50312470..8895b4923294a 100644 --- a/bolt/lib/Core/DebugData.cpp +++ b/bolt/lib/Core/DebugData.cpp @@ -177,6 +177,13 @@ uint64_t DebugRangesSectionWriter::getSectionOffset() { return SectionOffset; } +void DebugRangesSectionWriter::updateRangeBuffer(std::unique_ptr &CUBuffer) { + for(auto DebugInfo : *CUBuffer){ +RangesBuffer->push_back(DebugInfo); + } + SectionOffset = RangesBuffer->size(); +} + DebugAddrWriter *DebugRangeListsSectionWriter::AddrWriter = nullptr; uint64_t DebugRangeListsSectionWriter::addRanges( diff --git a/bolt/lib/Rewrite/DWARFRewriter.cpp b/bolt/lib/Rewrite/DWARFRewriter.cpp index 8814ebbd10aa5..e4e54f521ee19 100644 --- a/bolt/lib/Rewrite/DWARFRewriter.cpp +++ b/bolt/lib/Rewrite/DWARFRewriter.cpp @@ -646,6 +646,15 @@ void DWARFRewriter::updateDebugInfo() { } else { LocListWritersByCU[CUIndex] = std::make_unique(); + if (std::optional DWOId = CU.getDWOId()) { +assert(LegacyRangesWritersByCU.count(*DWOId) == 0 && + "LegacyRangeLists writer for DWO unit already exists."); +auto LegacyRangesSectionWriterByCU = +std::make_unique(); +LegacyRangesSectionWriterByCU->initSection(CU); +LegacyRangesWritersByCU[*DWOId] = +std::move(LegacyRangesSectionWriterByCU); + } } return LocListWritersByCU[CUIndex++].get(); }; @@ -692,6 +701,7 @@ void DWARFRewriter::updateDebugInfo() { if (Unit->getVersion() >= 5) { TempRangesSectionWriter = RangeListsWritersByCU[*DWOId].get(); } else { +TempRangesSectionWriter = LegacyRangesWritersByCU[*DWOId].get(); RangesBase = RangesSectionWriter->getSectionOffset(); setDwoRangesBase(*DWOId, *RangesBase); } @@ -1270,10 +1280,14 @@ void DWARFRewriter::updateDWARFObjectAddressRanges( } if (RangesBaseInfo) { - DIEBldr.replaceValue(&Die, RangesBaseInfo.getAttribute(), - RangesBaseInfo.getForm(), - DIEInteger(static_cast(*RangesBase))); - RangesBase = std::nullopt; + if (RangesBaseInfo.getAttribute() == dwarf::DW_AT_GNU_ranges_base) { +UpdatedDIEsByDWO[*Unit.getDWOId()] = &Die; + } else { +DIEBldr.replaceValue(&Die, RangesBaseInfo.getAttribute(), + RangesBaseInfo.getForm(), + DIEInteger(static_cast(*RangesBase))); +RangesBase = std::nullopt; + } } } @@ -1290,11 +1304,9 @@ void DWARFRewriter::updateDWARFObjectAddressRanges( RangesAttrInfo.getForm() == dwarf::DW_FORM_sec_offset) NeedConverted = true; -uint64_t CurRangeBase = 0; if (Unit.isDWOUnit()) {
[Lldb-commits] [lldb] [lldb][API] Add Find(Ranges)InMemory() to Process SB API (PR #95007)
@@ -2007,6 +2007,135 @@ size_t Process::ReadMemory(addr_t addr, void *buf, size_t size, Status &error) { } } +void Process::DoFindInMemory(lldb::addr_t start_addr, lldb::addr_t end_addr, + const uint8_t *buf, size_t size, + AddressRanges &matches, size_t alignment, + size_t max_matches) { + // Inputs are already validated in FindInMemory() functions. + assert(buf != nullptr); + assert(size > 0); + assert(alignment > 0); + assert(max_matches > 0); + assert(start_addr != LLDB_INVALID_ADDRESS); + assert(end_addr != LLDB_INVALID_ADDRESS); + assert(start_addr < end_addr); + + lldb::addr_t start = start_addr; + if (alignment > 1) { +// Align to an address alignment boundary +const uint64_t align_offset = start % alignment; +if (align_offset > 0) + start += alignment - align_offset; + } mbucko wrote: nice! https://github.com/llvm/llvm-project/pull/95007 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb][API] Add Find(Ranges)InMemory() to Process SB API (PR #95007)
https://github.com/mbucko updated https://github.com/llvm/llvm-project/pull/95007 >From ad93faf460e37bd717dc0ab9070af774c24b1ade Mon Sep 17 00:00:00 2001 From: Miro Bucko Date: Tue, 4 Jun 2024 12:01:48 -0700 Subject: [PATCH] [lldb][API] Add Find(Ranges)InMemory() to Process SB API Test Plan: llvm-lit llvm-project/lldb/test/API/python_api/find_in_memory/TestFindInMemory.py llvm-project/lldb/test/API/python_api/find_in_memory/TestFindRangesInMemory.py Reviewers: clayborg Tasks: lldb --- lldb/bindings/python/python-typemaps.swig | 3 +- lldb/include/lldb/API/SBProcess.h | 10 + lldb/include/lldb/Core/AddressRangeListImpl.h | 4 + lldb/include/lldb/Target/Process.h| 14 ++ lldb/source/API/SBProcess.cpp | 58 - lldb/source/Target/Process.cpp| 123 ++ .../API/python_api/find_in_memory/Makefile| 3 + .../find_in_memory/TestFindInMemory.py| 131 +++ .../find_in_memory/TestFindRangesInMemory.py | 221 ++ .../find_in_memory/address_ranges_helper.py | 73 ++ .../API/python_api/find_in_memory/main.cpp| 27 +++ 11 files changed, 661 insertions(+), 6 deletions(-) create mode 100644 lldb/test/API/python_api/find_in_memory/Makefile create mode 100644 lldb/test/API/python_api/find_in_memory/TestFindInMemory.py create mode 100644 lldb/test/API/python_api/find_in_memory/TestFindRangesInMemory.py create mode 100644 lldb/test/API/python_api/find_in_memory/address_ranges_helper.py create mode 100644 lldb/test/API/python_api/find_in_memory/main.cpp diff --git a/lldb/bindings/python/python-typemaps.swig b/lldb/bindings/python/python-typemaps.swig index c39594c7df041..f8c33e15c03e6 100644 --- a/lldb/bindings/python/python-typemaps.swig +++ b/lldb/bindings/python/python-typemaps.swig @@ -257,7 +257,8 @@ AND call SWIG_fail at the same time, because it will result in a double free. } // For SBProcess::WriteMemory, SBTarget::GetInstructions and SBDebugger::DispatchInput. %typemap(in) (const void *buf, size_t size), - (const void *data, size_t data_len) { + (const void *data, size_t data_len), + (const void *buf, uint64_t size) { if (PythonString::Check($input)) { PythonString str(PyRefType::Borrowed, $input); $1 = (void *)str.GetString().data(); diff --git a/lldb/include/lldb/API/SBProcess.h b/lldb/include/lldb/API/SBProcess.h index f1b5d1fb92ce2..a6ab7ae759918 100644 --- a/lldb/include/lldb/API/SBProcess.h +++ b/lldb/include/lldb/API/SBProcess.h @@ -209,6 +209,16 @@ class LLDB_API SBProcess { lldb::addr_t ReadPointerFromMemory(addr_t addr, lldb::SBError &error); + lldb::SBAddressRangeList FindRangesInMemory(const void *buf, uint64_t size, + const SBAddressRangeList &ranges, + uint32_t alignment, + uint32_t max_matches, + SBError &error); + + lldb::addr_t FindInMemory(const void *buf, uint64_t size, +const SBAddressRange &range, uint32_t alignment, +SBError &error); + // Events static lldb::StateType GetStateFromEvent(const lldb::SBEvent &event); diff --git a/lldb/include/lldb/Core/AddressRangeListImpl.h b/lldb/include/lldb/Core/AddressRangeListImpl.h index 46ebfe73d4d92..6742e6ead87de 100644 --- a/lldb/include/lldb/Core/AddressRangeListImpl.h +++ b/lldb/include/lldb/Core/AddressRangeListImpl.h @@ -13,7 +13,9 @@ #include namespace lldb { +class SBAddressRangeList; class SBBlock; +class SBProcess; } namespace lldb_private { @@ -39,7 +41,9 @@ class AddressRangeListImpl { lldb_private::AddressRange GetAddressRangeAtIndex(size_t index); private: + friend class lldb::SBAddressRangeList; friend class lldb::SBBlock; + friend class lldb::SBProcess; AddressRanges &ref(); diff --git a/lldb/include/lldb/Target/Process.h b/lldb/include/lldb/Target/Process.h index eec337c15f7ed..ceaf547ebddaf 100644 --- a/lldb/include/lldb/Target/Process.h +++ b/lldb/include/lldb/Target/Process.h @@ -2685,6 +2685,15 @@ void PruneThreadPlans(); lldb::addr_t FindInMemory(lldb::addr_t low, lldb::addr_t high, const uint8_t *buf, size_t size); + AddressRanges FindRangesInMemory(const uint8_t *buf, uint64_t size, + const AddressRanges &ranges, + size_t alignment, size_t max_matches, + Status &error); + + lldb::addr_t FindInMemory(const uint8_t *buf, uint64_t size, +const AddressRange &range, size_t alignment, +Status &error); + protected: friend class Trace; @@ -2800,6 +2809,11 @@ void PruneThreadPlans(); virtual size_t DoReadMemory(lldb::addr_t vm_addr, void *buf, size_t size,
[Lldb-commits] [lldb] [lldb] Change lldb's breakpoint handling behavior (PR #96260)
jasonmolenda wrote: > > @AlexK0 if you have a setup to build and run the testsuite on windows, > > could you try it with this patch some time when you're able? I can't see > > this being merged for at least another 5-6 days, there's no rush. You can > > download the unidiff style diff of the patch from > > https://patch-diff.githubusercontent.com/raw/llvm/llvm-project/pull/96260.diff > > @jasonmolenda I checked the tests with VS2022/x86-64/win11 in a debug build > with assertions enabled. Unfortunately, the main branch is a bit unstable, > and some tests constantly fail :( . Nonetheless, I noticed one new failure > with the applied patch: > > `functionalities/breakpoint/consecutive_breakpoints/TestConsecutiveBreakpoints.py` > These TestConcurrent / TestConsecutiveBreakpoints tests are great for finding corner cases with these changes, thanks so much. I was a little uncertain about one part of my ProcessWindows change, where the pc is *past* the breakpoint when a software breakpoint instruction is used, on Windows. For a moment, I thought, "oh, I don't need to record that we hit the breakpoint because we're already past it and we don't need to instruction past it" but of course that was wrong -- ProcessWindows::RefreshStateAfterStop decrements the $pc value by the size of its breakpoint instruction, which is necessary because e.g. the size of an x86 breakpoint instruction is 1 byte (0xcc) but x86_64 instructions can be between 1 to 15 bytes long, so stopping 1 byte after the BreakpointSite means we are possibly in the middle of the real instruction. We must set the pc to the BreakpointSite address and use lldb's normal logic. Anyway, tl;dr, I believe this will fix it: ``` --- a/lldb/source/Plugins/Process/Windows/Common/ProcessWindows.cpp +++ b/lldb/source/Plugins/Process/Windows/Common/ProcessWindows.cpp @@ -442,6 +442,7 @@ void ProcessWindows::RefreshStateAfterStop() { m_session_data->m_debugger->GetProcess().GetProcessId(), pc, site->GetID()); + stop_thread->SetThreadHitBreakpointAtAddr(pc); if (site->ValidForThisThread(*stop_thread)) { LLDB_LOG(log, "Breakpoint site {0} is valid for this thread ({1:x}), " ``` I'll push it right now. Sorry for my confusion, and thanks again for looking at it, this was a big help. https://github.com/llvm/llvm-project/pull/96260 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb] Change lldb's breakpoint handling behavior (PR #96260)
https://github.com/jasonmolenda updated https://github.com/llvm/llvm-project/pull/96260 >From 9b541e6a035635e26c6a24eca022de8552fa4c17 Mon Sep 17 00:00:00 2001 From: Jason Molenda Date: Thu, 20 Jun 2024 17:53:17 -0700 Subject: [PATCH 1/3] [lldb] Change lldb's breakpoint handling behavior lldb today has two rules: When a thread stops at a BreakpointSite, we set the thread's StopReason to be "breakpoint hit" (regardless if we've actually hit the breakpoint, or if we've merely stopped *at* the breakpoint instruction/point and haven't tripped it yet). And second, when resuming a process, any thread sitting at a BreakpointSite is silently stepped over the BreakpointSite -- because we've already flagged the breakpoint hit when we stopped there originally. In this patch, I change lldb to only set a thread's stop reason to breakpoint-hit when we've actually executed the instruction/triggered the breakpoint. When we resume, we only silently step past a BreakpointSite that we've registered as hit. We preserve this state across inferior function calls that the user may do while stopped, etc. Also, when a user adds a new breakpoint at $pc while stopped, or changes $pc to be the address of a BreakpointSite, we will silently step past that breakpoint when the process resumes. This is purely a UX call, I don't think there's any person who wants to set a breakpoint at $pc and then hit it immediately on resuming. One non-intuitive UX from this change, but I'm convinced it is necessary: If you're stopped at a BreakpointSite that has not yet executed, you `stepi`, you will hit the breakpoint and the pc will not yet advance. This thread has not completed its stepi, and the thread plan is still on the stack. If you then `continue` the thread, lldb will now stop and say, "instruction step completed", one instruction past the BreakpointSite. You can continue a second time to resume execution. I discussed this with Jim, and trying to paper over this behavior will lead to more complicated scenarios behaving non-intuitively. And mostly it's the testsuite that was trying to instruction step past a breakpoint and getting thrown off -- and I changed those tests to expect the new behavior. The bugs driving this change are all from lldb dropping the real stop reason for a thread and setting it to breakpoint-hit when that was not the case. Jim hit one where we have an aarch64 watchpoint that triggers one instruction before a BreakpointSite. On this arch we are notified of the watchpoint hit after the instruction has been unrolled -- we disable the watchpoint, instruction step, re-enable the watchpoint and collect the new value. But now we're on a BreakpointSite so the watchpoint-hit stop reason is lost. Another was reported by ZequanWu in https://discourse.llvm.org/t/lldb-unable-to-break-at-start/78282 we attach to/launch a process with the pc at a BreakpointSite and misbehave. Caroline Tice mentioned it is also a problem they've had with putting a breakpoint on _dl_debug_state. The change to each Process plugin that does execution control is that 1. If we've stopped at a BreakpointSite (whether we hit it or not), we call Thread::SetThreadStoppedAtBreakpointSite(pc) to record the state at the point when the thread stopped. (so we can detect newly-added breakpoints, or when the pc is changed to an instruction that is a BreakpointSite) 2. When we have actually hit a breakpoint, and it is enabled for this thread, we call Thread::SetThreadHitBreakpointAtAddr(pc) so we know that it should be silently stepped past when we resume execution. When resuming, we silently step over a breakpoint if we've hit it, or if it is newly added (or the pc was changed to an existing BreakpointSite). The biggest set of changes is to StopInfoMachException where we translate a Mach Exception into a stop reason. The Mach exception codes differ in a few places depending on the target (unambiguously), and I didn't want to duplicate the new code for each target so I've tested what mach exceptions we get for each action on each target, and reorganized StopInfoMachException::CreateStopReasonWithMachException to document these possible values, and handle them without specializing based on the target arch. rdar://123942164 --- lldb/include/lldb/Target/Thread.h | 29 ++ .../Process/Utility/StopInfoMachException.cpp | 296 +++--- .../Process/Windows/Common/ProcessWindows.cpp | 16 +- .../Process/gdb-remote/ProcessGDBRemote.cpp | 118 +++ .../Process/scripted/ScriptedThread.cpp | 9 + lldb/source/Target/Thread.cpp | 17 +- .../TestConsecutiveBreakpoints.py | 26 +- .../TestStepOverBreakpoint.py | 6 +- 8 files changed, 235 insertions(+), 282 deletions(-) diff --git a/lldb/include/lldb/Target/Thread.h b/lldb/include/lldb/Target/Thread.h index c17bddf4d98b8..1e1aead896018 100644 --- a/lldb/include/lldb/Target/Thread.h +++ b/lldb/include/lldb/Target/Thread
[Lldb-commits] [lldb] Add a unit test for SBBreakpoint::SetCallback (PR #96001)
https://github.com/chelcassanova updated https://github.com/llvm/llvm-project/pull/96001 >From 86dcffcc7a1820756fe8104d8239f25185a27733 Mon Sep 17 00:00:00 2001 From: Chelsea Cassanova Date: Thu, 13 Jun 2024 16:02:07 -0700 Subject: [PATCH] add unit test for breakpoint::setcallback --- lldb/include/lldb/lldb-private-interfaces.h | 8 +- lldb/source/Breakpoint/BreakpointOptions.cpp | 18 ++-- lldb/unittests/CMakeLists.txt | 1 + lldb/unittests/Callback/CMakeLists.txt| 12 +++ .../Callback/TestBreakpointSetCallback.cpp| 89 +++ 5 files changed, 111 insertions(+), 17 deletions(-) create mode 100644 lldb/unittests/Callback/CMakeLists.txt create mode 100644 lldb/unittests/Callback/TestBreakpointSetCallback.cpp diff --git a/lldb/include/lldb/lldb-private-interfaces.h b/lldb/include/lldb/lldb-private-interfaces.h index 53d5fbb84cc92..cdd9b51d9329c 100644 --- a/lldb/include/lldb/lldb-private-interfaces.h +++ b/lldb/include/lldb/lldb-private-interfaces.h @@ -99,10 +99,10 @@ typedef std::optional (*SymbolLocatorLocateExecutableSymbolFile)( typedef bool (*SymbolLocatorDownloadObjectAndSymbolFile)( ModuleSpec &module_spec, Status &error, bool force_lookup, bool copy_executable); -typedef bool (*BreakpointHitCallback)(void *baton, - StoppointCallbackContext *context, - lldb::user_id_t break_id, - lldb::user_id_t break_loc_id); +using BreakpointHitCallback = +std::function; + typedef bool (*WatchpointHitCallback)(void *baton, StoppointCallbackContext *context, lldb::user_id_t watch_id); diff --git a/lldb/source/Breakpoint/BreakpointOptions.cpp b/lldb/source/Breakpoint/BreakpointOptions.cpp index 6c6037dd9edd3..1db8401698114 100644 --- a/lldb/source/Breakpoint/BreakpointOptions.cpp +++ b/lldb/source/Breakpoint/BreakpointOptions.cpp @@ -102,19 +102,11 @@ const char *BreakpointOptions::g_option_names[( "ConditionText", "IgnoreCount", "EnabledState", "OneShotState", "AutoContinue"}; -bool BreakpointOptions::NullCallback(void *baton, - StoppointCallbackContext *context, - lldb::user_id_t break_id, - lldb::user_id_t break_loc_id) { - return true; -} - // BreakpointOptions constructor BreakpointOptions::BreakpointOptions(bool all_flags_set) -: m_callback(BreakpointOptions::NullCallback), - m_baton_is_command_baton(false), m_callback_is_synchronous(false), - m_enabled(true), m_one_shot(false), m_ignore_count(0), - m_condition_text_hash(0), m_inject_condition(false), +: m_callback(nullptr), m_baton_is_command_baton(false), + m_callback_is_synchronous(false), m_enabled(true), m_one_shot(false), + m_ignore_count(0), m_condition_text_hash(0), m_inject_condition(false), m_auto_continue(false), m_set_flags(0) { if (all_flags_set) m_set_flags.Set(~((Flags::ValueType)0)); @@ -420,7 +412,7 @@ void BreakpointOptions::SetCallback( } void BreakpointOptions::ClearCallback() { - m_callback = BreakpointOptions::NullCallback; + m_callback = nullptr; m_callback_is_synchronous = false; m_callback_baton_sp.reset(); m_baton_is_command_baton = false; @@ -449,7 +441,7 @@ bool BreakpointOptions::InvokeCallback(StoppointCallbackContext *context, } bool BreakpointOptions::HasCallback() const { - return m_callback != BreakpointOptions::NullCallback; + return static_cast(m_callback); } bool BreakpointOptions::GetCommandLineCallbacks(StringList &command_list) { diff --git a/lldb/unittests/CMakeLists.txt b/lldb/unittests/CMakeLists.txt index a2585a94b6155..cc9d45ebf981d 100644 --- a/lldb/unittests/CMakeLists.txt +++ b/lldb/unittests/CMakeLists.txt @@ -52,6 +52,7 @@ if (NOT CMAKE_SYSTEM_NAME MATCHES "Windows") add_subdirectory(API) endif() add_subdirectory(Breakpoint) +add_subdirectory(Callback) add_subdirectory(Core) add_subdirectory(DataFormatter) add_subdirectory(Disassembler) diff --git a/lldb/unittests/Callback/CMakeLists.txt b/lldb/unittests/Callback/CMakeLists.txt new file mode 100644 index 0..b9e0ef5a396e3 --- /dev/null +++ b/lldb/unittests/Callback/CMakeLists.txt @@ -0,0 +1,12 @@ +add_lldb_unittest(LLDBCallbackTests + TestBreakpointSetCallback.cpp + + LINK_LIBS +lldbBreakpoint +lldbCore +LLVMTestingSupport +lldbUtilityHelpers +lldbPluginPlatformMacOSX + LINK_COMPONENTS +Support + ) diff --git a/lldb/unittests/Callback/TestBreakpointSetCallback.cpp b/lldb/unittests/Callback/TestBreakpointSetCallback.cpp new file mode 100644 index 0..998b001d400c5 --- /dev/null +++ b/lldb/unittests/Callback/TestBreakpointSetCallback.cpp @@ -0,0 +1,89 @@ +//===-- TestBreakpointSetCallback.cpp +//===// +// +//
[Lldb-commits] [clang-tools-extra] [compiler-rt] [lldb] [llvm] [Memprof] Adds the option to collect AccessCountHistograms for memprof. (PR #94264)
@@ -216,6 +228,35 @@ u64 GetShadowCount(uptr p, u32 size) { return count; } +// Accumulates the access count from the shadow for the given pointer and size. +// See memprof_mapping.h for an overview on histogram counters. +u64 GetShadowCountHistogram(uptr p, u32 size) { + u8 *shadow = (u8 *)HISTOGRAM_MEM_TO_SHADOW(p); + u8 *shadow_end = (u8 *)HISTOGRAM_MEM_TO_SHADOW(p + size); + u64 count = 0; + for (; shadow <= shadow_end; shadow++) +count += *shadow; + return count; +} + +// If we use the normal approach from clearCountersWithoutHistogram, the +// histogram will clear too much data and may overwrite shadow counters that are +// in use. Likely because of rounding up the shadow_end pointer. +// See memprof_mapping.h for an overview on histogram counters. +void clearCountersHistogram(uptr addr, uptr size) { + u8 *shadow_8 = (u8 *)HISTOGRAM_MEM_TO_SHADOW(addr); + u8 *shadow_end_8 = (u8 *)HISTOGRAM_MEM_TO_SHADOW(addr + size); + for (; shadow_8 < shadow_end_8; shadow_8++) { teresajohnson wrote: Why not use REAL(memset) like the non-histogram version below? https://github.com/llvm/llvm-project/pull/94264 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [clang-tools-extra] [compiler-rt] [lldb] [llvm] [Memprof] Adds the option to collect AccessCountHistograms for memprof. (PR #94264)
@@ -508,7 +519,26 @@ void createProfileFileNameVar(Module &M) { } } +// Set MemprofHistogramFlag as a Global veriable in IR. This makes it accessible +// to +// the runtime, changing shadow count behavior. +void createMemprofHistogramFlagVar(Module &M) { + const StringRef VarName(MemProfHistogramFlagVar); + Type *IntTy1 = Type::getInt1Ty(M.getContext()); + auto MemprofHistogramFlag = new GlobalVariable( + M, IntTy1, true, GlobalValue::WeakAnyLinkage, + Constant::getIntegerValue(IntTy1, APInt(1, ClHistogram)), VarName); + // MemprofHistogramFlag->setVisibility(GlobalValue::HiddenVisibility); teresajohnson wrote: remove? https://github.com/llvm/llvm-project/pull/94264 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [clang-tools-extra] [compiler-rt] [lldb] [llvm] [Memprof] Adds the option to collect AccessCountHistograms for memprof. (PR #94264)
@@ -20,25 +20,25 @@ CHECK-NEXT: - CHECK: Records: CHECK-NEXT: - -CHECK-NEXT:FunctionGUID: 15505678318020221912 +CHECK-NEXT:FunctionGUID: 3873612792189045660 CHECK-NEXT:AllocSites: CHECK-NEXT:- CHECK-NEXT: Callstack: CHECK-NEXT: - -CHECK-NEXT:Function: 15505678318020221912 -CHECK-NEXT:SymbolName: qux +CHECK-NEXT:Function: 3873612792189045660 +CHECK-NEXT:SymbolName: _Z3quxi teresajohnson wrote: Why did the function symbol names change with your patch? https://github.com/llvm/llvm-project/pull/94264 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [clang-tools-extra] [compiler-rt] [lldb] [llvm] [Memprof] Adds the option to collect AccessCountHistograms for memprof. (PR #94264)
@@ -96,19 +102,63 @@ llvm::SmallVector readSegmentEntries(const char *Ptr) { } llvm::SmallVector> -readMemInfoBlocks(const char *Ptr) { +readMemInfoBlocksV3(const char *Ptr) { using namespace support; const uint64_t NumItemsToRead = - endian::readNext(Ptr); + endian::readNext(Ptr); + llvm::SmallVector> Items; for (uint64_t I = 0; I < NumItemsToRead; I++) { const uint64_t Id = -endian::readNext(Ptr); -const MemInfoBlock MIB = *reinterpret_cast(Ptr); +endian::readNext(Ptr); + +// We cheat a bit here and remove the const from cast to set the +// Histogram Pointer to newly allocated buffer. We also cheat, since V3 and +// V4 do not have the same fields. V3 is missing AccessHistogramSize and +// AccessHistogram. This means we read "dirty" data in here, but it should +// not segfault, since there will be callstack data placed after this in the +// binary format. +MemInfoBlock MIB = *reinterpret_cast(Ptr); +// Overwrite dirty data. teresajohnson wrote: Isn't this going to overwrite some callstack data? https://github.com/llvm/llvm-project/pull/94264 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [clang-tools-extra] [compiler-rt] [lldb] [llvm] [Memprof] Adds the option to collect AccessCountHistograms for memprof. (PR #94264)
@@ -508,7 +519,26 @@ void createProfileFileNameVar(Module &M) { } } +// Set MemprofHistogramFlag as a Global veriable in IR. This makes it accessible +// to teresajohnson wrote: nit: fix line wrapping https://github.com/llvm/llvm-project/pull/94264 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [clang-tools-extra] [compiler-rt] [lldb] [llvm] [Memprof] Adds the option to collect AccessCountHistograms for memprof. (PR #94264)
@@ -124,6 +124,13 @@ struct PortableMemInfoBlock { OS << "" << #Name << ": " << Name << "\n"; #include "llvm/ProfileData/MIBEntryDef.inc" #undef MIBEntryDef +if (AccessHistogramSize > 0) { + OS << "" << "AccessHistogramValues" << ":"; + for (uint32_t I = 0; I < AccessHistogramSize; ++I) { +OS << " -" << ((uint64_t *)AccessHistogram)[I]; teresajohnson wrote: Why the " -" in the outputs? I noticed when looking at the text that they look like negative values as a result. Any reason not to just delimit with the space? https://github.com/llvm/llvm-project/pull/94264 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [clang-tools-extra] [compiler-rt] [lldb] [llvm] [Memprof] Adds the option to collect AccessCountHistograms for memprof. (PR #94264)
@@ -216,6 +228,35 @@ u64 GetShadowCount(uptr p, u32 size) { return count; } +// Accumulates the access count from the shadow for the given pointer and size. +// See memprof_mapping.h for an overview on histogram counters. +u64 GetShadowCountHistogram(uptr p, u32 size) { + u8 *shadow = (u8 *)HISTOGRAM_MEM_TO_SHADOW(p); + u8 *shadow_end = (u8 *)HISTOGRAM_MEM_TO_SHADOW(p + size); + u64 count = 0; + for (; shadow <= shadow_end; shadow++) +count += *shadow; + return count; +} + +// If we use the normal approach from clearCountersWithoutHistogram, the +// histogram will clear too much data and may overwrite shadow counters that are +// in use. Likely because of rounding up the shadow_end pointer. +// See memprof_mapping.h for an overview on histogram counters. +void clearCountersHistogram(uptr addr, uptr size) { + u8 *shadow_8 = (u8 *)HISTOGRAM_MEM_TO_SHADOW(addr); + u8 *shadow_end_8 = (u8 *)HISTOGRAM_MEM_TO_SHADOW(addr + size); + for (; shadow_8 < shadow_end_8; shadow_8++) { +*shadow_8 = 0; + } +} + +void clearCountersWithoutHistogram(uptr addr, uptr size) { + uptr shadow_beg = MEM_TO_SHADOW(addr); + uptr shadow_end = MEM_TO_SHADOW(addr + size - SHADOW_GRANULARITY) + 1; + REAL(memset)((void *)shadow_beg, 0, shadow_end - shadow_beg); +} + // Clears the shadow counters (when memory is allocated). void ClearShadow(uptr addr, uptr size) { teresajohnson wrote: Looking at this function more, there are a lot of uses of the MEM_TO_SHADOW computed values, which is not the right mapping function to use with the smaller granularity of the histogram case. I think you probably need to version the calls to MEM_TO_SHADOW here, then all of the rest of the code can work as is? I.e. you wouldn't need the 2 versions of `clearCounters*` https://github.com/llvm/llvm-project/pull/94264 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [clang-tools-extra] [compiler-rt] [lldb] [llvm] [Memprof] Adds the option to collect AccessCountHistograms for memprof. (PR #94264)
@@ -0,0 +1,101 @@ +REQUIRES: x86_64-linux + +This is a copy of memprof-basict.test with slight changes to check that we can still read v3 of memprofraw. teresajohnson wrote: typo: basict https://github.com/llvm/llvm-project/pull/94264 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [clang-tools-extra] [compiler-rt] [lldb] [llvm] [Memprof] Adds the option to collect AccessCountHistograms for memprof. (PR #94264)
@@ -610,13 +670,33 @@ RawMemProfReader::peekBuildIds(MemoryBuffer *DataBuffer) { return BuildIds.takeVector(); } +// FIXME: Add a schema for serializing similiar to IndexedMemprofReader. This +// will help being able to deserialize different versions raw memprof versions +// more easily. +llvm::SmallVector> +RawMemProfReader::readMemInfoBlocks(const char *Ptr) { + if (MemprofRawVersion == 3ULL) { +errs() << "Reading V3\n"; teresajohnson wrote: Leftover debugging message that should be removed? https://github.com/llvm/llvm-project/pull/94264 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [clang-tools-extra] [compiler-rt] [lldb] [llvm] [Memprof] Adds the option to collect AccessCountHistograms for memprof. (PR #94264)
@@ -610,13 +670,33 @@ RawMemProfReader::peekBuildIds(MemoryBuffer *DataBuffer) { return BuildIds.takeVector(); } +// FIXME: Add a schema for serializing similiar to IndexedMemprofReader. This +// will help being able to deserialize different versions raw memprof versions +// more easily. +llvm::SmallVector> +RawMemProfReader::readMemInfoBlocks(const char *Ptr) { + if (MemprofRawVersion == 3ULL) { +errs() << "Reading V3\n"; teresajohnson wrote: Once you do that, the braces can be removed from all of the if else conditions here which have single statement bodies https://github.com/llvm/llvm-project/pull/94264 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [clang-tools-extra] [compiler-rt] [lldb] [llvm] [Memprof] Adds the option to collect AccessCountHistograms for memprof. (PR #94264)
@@ -205,8 +205,14 @@ class RawMemProfReader final : public MemProfReader { object::SectionedAddress getModuleOffset(uint64_t VirtualAddress); + llvm::SmallVector> + readMemInfoBlocks(const char *Ptr); + // The profiled binary. object::OwningBinary Binary; + // Version of raw memprof binary currently being read. Defaults to most update teresajohnson wrote: typo: s/update to date/up to date/ https://github.com/llvm/llvm-project/pull/94264 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [clang-tools-extra] [compiler-rt] [lldb] [llvm] [Memprof] Adds the option to collect AccessCountHistograms for memprof. (PR #94264)
@@ -38,4 +38,5 @@ MEMPROF_FLAG(bool, allocator_frees_and_returns_null_on_realloc_zero, true, MEMPROF_FLAG(bool, print_text, false, "If set, prints the heap profile in text format. Else use the raw binary serialization format.") MEMPROF_FLAG(bool, print_terse, false, - "If set, prints memory profile in a terse format. Only applicable if print_text = true.") + "If set, prints memory profile in a terse format. Only applicable " teresajohnson wrote: Formatting change only, remove from patch https://github.com/llvm/llvm-project/pull/94264 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [clang-tools-extra] [compiler-rt] [lldb] [llvm] [Memprof] Adds the option to collect AccessCountHistograms for memprof. (PR #94264)
@@ -0,0 +1,101 @@ +REQUIRES: x86_64-linux + +This is a copy of memprof-basict.test with slight changes to check that we can still read v3 of memprofraw. + +To update the inputs used below run Inputs/update_memprof_inputs.sh /path/to/updated/clang teresajohnson wrote: I think this comment is wrong - we can't update the v3 version, is that correct? Nor would we want to. https://github.com/llvm/llvm-project/pull/94264 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] Add a unit test for SBBreakpoint::SetCallback (PR #96001)
https://github.com/medismailben approved this pull request. https://github.com/llvm/llvm-project/pull/96001 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] Add a unit test for SBBreakpoint::SetCallback (PR #96001)
@@ -0,0 +1,89 @@ +//===-- TestBreakpointSetCallback.cpp +//===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===--===// + +#include "Plugins/Platform/MacOSX/PlatformMacOSX.h" +#include "Plugins/Platform/MacOSX/PlatformRemoteMacOSX.h" +#include "TestingSupport/SubsystemRAII.h" +#include "TestingSupport/TestUtilities.h" +#include "lldb/Breakpoint/StoppointCallbackContext.h" +#include "lldb/Core/Debugger.h" +#include "lldb/Core/Progress.h" +#include "lldb/Host/FileSystem.h" +#include "lldb/Host/HostInfo.h" +#include "lldb/Target/ExecutionContext.h" +#include "lldb/lldb-private-enumerations.h" +#include "lldb/lldb-types.h" +#include "gtest/gtest.h" +#include +#include +#include + +using namespace lldb_private; +using namespace lldb; + +#define EXPECTED_BREAKPOINT_ID 1 medismailben wrote: You can make these `static constexpr lldb::user_id_t` if you want https://github.com/llvm/llvm-project/pull/96001 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] Add a unit test for SBBreakpoint::SetCallback (PR #96001)
https://github.com/medismailben requested changes to this pull request. https://github.com/llvm/llvm-project/pull/96001 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] Add a unit test for SBBreakpoint::SetCallback (PR #96001)
@@ -0,0 +1,89 @@ +//===-- TestBreakpointSetCallback.cpp +//===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===--===// + +#include "Plugins/Platform/MacOSX/PlatformMacOSX.h" +#include "Plugins/Platform/MacOSX/PlatformRemoteMacOSX.h" +#include "TestingSupport/SubsystemRAII.h" +#include "TestingSupport/TestUtilities.h" +#include "lldb/Breakpoint/StoppointCallbackContext.h" +#include "lldb/Core/Debugger.h" +#include "lldb/Core/Progress.h" +#include "lldb/Host/FileSystem.h" +#include "lldb/Host/HostInfo.h" +#include "lldb/Target/ExecutionContext.h" +#include "lldb/lldb-private-enumerations.h" +#include "lldb/lldb-types.h" +#include "gtest/gtest.h" +#include +#include +#include + +using namespace lldb_private; +using namespace lldb; + +#define EXPECTED_BREAKPOINT_ID 1 +#define EXPECTED_BREAKPOINT_LOCATION_ID 0 + +class BreakpointSetCallbackTest : public ::testing::Test { +public: + static void CheckCallbackArgs(void *baton, StoppointCallbackContext *context, +lldb::user_id_t break_id, +lldb::user_id_t break_loc_id, +lldb::user_id_t expected_breakpoint_id, +lldb::user_id_t expected_breakpoint_loc_id, +TargetSP expected_target_sp) { +EXPECT_EQ(context->exe_ctx_ref.GetTargetSP(), expected_target_sp); +EXPECT_EQ(baton, "hello"); +EXPECT_EQ(break_id, expected_breakpoint_id); +EXPECT_EQ(break_loc_id, expected_breakpoint_loc_id); + } + +protected: + void SetUp() override { +std::call_once(TestUtilities::g_debugger_initialize_flag, + []() { Debugger::Initialize(nullptr); }); + }; + + DebuggerSP m_debugger_sp; + PlatformSP m_platform_sp; + BreakpointSP m_breakpoint_sp; + SubsystemRAII + subsystems; +}; + +TEST_F(BreakpointSetCallbackTest, TestBreakpointSetCallback) { + void *baton = (void *)"hello"; + // Set up the debugger, make sure that was done properly. + TargetSP m_target_sp; medismailben wrote: It's not an class member, why prepend the `m_` https://github.com/llvm/llvm-project/pull/96001 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] Add a unit test for SBBreakpoint::SetCallback (PR #96001)
@@ -0,0 +1,89 @@ +//===-- TestBreakpointSetCallback.cpp +//===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===--===// + +#include "Plugins/Platform/MacOSX/PlatformMacOSX.h" +#include "Plugins/Platform/MacOSX/PlatformRemoteMacOSX.h" +#include "TestingSupport/SubsystemRAII.h" +#include "TestingSupport/TestUtilities.h" +#include "lldb/Breakpoint/StoppointCallbackContext.h" +#include "lldb/Core/Debugger.h" +#include "lldb/Core/Progress.h" +#include "lldb/Host/FileSystem.h" +#include "lldb/Host/HostInfo.h" +#include "lldb/Target/ExecutionContext.h" +#include "lldb/lldb-private-enumerations.h" +#include "lldb/lldb-types.h" +#include "gtest/gtest.h" +#include +#include +#include + +using namespace lldb_private; +using namespace lldb; + +#define EXPECTED_BREAKPOINT_ID 1 +#define EXPECTED_BREAKPOINT_LOCATION_ID 0 + +class BreakpointSetCallbackTest : public ::testing::Test { +public: + static void CheckCallbackArgs(void *baton, StoppointCallbackContext *context, +lldb::user_id_t break_id, +lldb::user_id_t break_loc_id, +lldb::user_id_t expected_breakpoint_id, +lldb::user_id_t expected_breakpoint_loc_id, +TargetSP expected_target_sp) { +EXPECT_EQ(context->exe_ctx_ref.GetTargetSP(), expected_target_sp); +EXPECT_EQ(baton, "hello"); +EXPECT_EQ(break_id, expected_breakpoint_id); +EXPECT_EQ(break_loc_id, expected_breakpoint_loc_id); + } + +protected: + void SetUp() override { +std::call_once(TestUtilities::g_debugger_initialize_flag, + []() { Debugger::Initialize(nullptr); }); + }; + + DebuggerSP m_debugger_sp; + PlatformSP m_platform_sp; + BreakpointSP m_breakpoint_sp; + SubsystemRAII + subsystems; +}; + +TEST_F(BreakpointSetCallbackTest, TestBreakpointSetCallback) { + void *baton = (void *)"hello"; + // Set up the debugger, make sure that was done properly. + TargetSP m_target_sp; + ArchSpec arch("x86_64-apple-macosx-"); + Platform::SetHostPlatform(PlatformRemoteMacOSX::CreateInstance(true, &arch)); + + m_debugger_sp = Debugger::CreateInstance(); + + // Create target + m_debugger_sp->GetTargetList().CreateTarget(*m_debugger_sp, "", arch, + lldb_private::eLoadDependentsNo, + m_platform_sp, m_target_sp); + + // Create breakpoint + m_breakpoint_sp = m_target_sp->CreateBreakpoint(0xDEADBEEF, false, false); medismailben wrote: I guess you don't need to make the breakpoint a class member here https://github.com/llvm/llvm-project/pull/96001 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] Add a unit test for SBBreakpoint::SetCallback (PR #96001)
@@ -0,0 +1,89 @@ +//===-- TestBreakpointSetCallback.cpp +//===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===--===// + +#include "Plugins/Platform/MacOSX/PlatformMacOSX.h" +#include "Plugins/Platform/MacOSX/PlatformRemoteMacOSX.h" +#include "TestingSupport/SubsystemRAII.h" +#include "TestingSupport/TestUtilities.h" +#include "lldb/Breakpoint/StoppointCallbackContext.h" +#include "lldb/Core/Debugger.h" +#include "lldb/Core/Progress.h" +#include "lldb/Host/FileSystem.h" +#include "lldb/Host/HostInfo.h" +#include "lldb/Target/ExecutionContext.h" +#include "lldb/lldb-private-enumerations.h" +#include "lldb/lldb-types.h" +#include "gtest/gtest.h" +#include +#include +#include + +using namespace lldb_private; +using namespace lldb; + +#define EXPECTED_BREAKPOINT_ID 1 +#define EXPECTED_BREAKPOINT_LOCATION_ID 0 + +class BreakpointSetCallbackTest : public ::testing::Test { +public: + static void CheckCallbackArgs(void *baton, StoppointCallbackContext *context, +lldb::user_id_t break_id, +lldb::user_id_t break_loc_id, +lldb::user_id_t expected_breakpoint_id, +lldb::user_id_t expected_breakpoint_loc_id, +TargetSP expected_target_sp) { +EXPECT_EQ(context->exe_ctx_ref.GetTargetSP(), expected_target_sp); +EXPECT_EQ(baton, "hello"); +EXPECT_EQ(break_id, expected_breakpoint_id); +EXPECT_EQ(break_loc_id, expected_breakpoint_loc_id); + } + +protected: + void SetUp() override { +std::call_once(TestUtilities::g_debugger_initialize_flag, + []() { Debugger::Initialize(nullptr); }); + }; + + DebuggerSP m_debugger_sp; + PlatformSP m_platform_sp; + BreakpointSP m_breakpoint_sp; + SubsystemRAII + subsystems; +}; + +TEST_F(BreakpointSetCallbackTest, TestBreakpointSetCallback) { + void *baton = (void *)"hello"; + // Set up the debugger, make sure that was done properly. + TargetSP m_target_sp; + ArchSpec arch("x86_64-apple-macosx-"); + Platform::SetHostPlatform(PlatformRemoteMacOSX::CreateInstance(true, &arch)); + + m_debugger_sp = Debugger::CreateInstance(); + + // Create target + m_debugger_sp->GetTargetList().CreateTarget(*m_debugger_sp, "", arch, + lldb_private::eLoadDependentsNo, + m_platform_sp, m_target_sp); + + // Create breakpoint + m_breakpoint_sp = m_target_sp->CreateBreakpoint(0xDEADBEEF, false, false); + + m_breakpoint_sp->SetCallback( + [m_target_sp](void *baton, StoppointCallbackContext *context, +lldb::user_id_t break_id, lldb::user_id_t break_loc_id) { +CheckCallbackArgs(baton, context, break_id, break_loc_id, + EXPECTED_BREAKPOINT_ID, + EXPECTED_BREAKPOINT_LOCATION_ID, m_target_sp); +return true; + }, + baton, true); + ExecutionContext m_exe_ctx(m_target_sp, false); medismailben wrote: Ditto https://github.com/llvm/llvm-project/pull/96001 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] Add a unit test for SBBreakpoint::SetCallback (PR #96001)
https://github.com/chelcassanova updated https://github.com/llvm/llvm-project/pull/96001 >From 44ea5e0d0a319fa12463129ff072bcaef6112544 Mon Sep 17 00:00:00 2001 From: Chelsea Cassanova Date: Thu, 13 Jun 2024 16:02:07 -0700 Subject: [PATCH] add unit test for breakpoint::setcallback --- lldb/include/lldb/lldb-private-interfaces.h | 8 +- lldb/source/Breakpoint/BreakpointOptions.cpp | 18 ++-- lldb/unittests/CMakeLists.txt | 1 + lldb/unittests/Callback/CMakeLists.txt| 12 +++ .../Callback/TestBreakpointSetCallback.cpp| 89 +++ 5 files changed, 111 insertions(+), 17 deletions(-) create mode 100644 lldb/unittests/Callback/CMakeLists.txt create mode 100644 lldb/unittests/Callback/TestBreakpointSetCallback.cpp diff --git a/lldb/include/lldb/lldb-private-interfaces.h b/lldb/include/lldb/lldb-private-interfaces.h index 53d5fbb84cc92..cdd9b51d9329c 100644 --- a/lldb/include/lldb/lldb-private-interfaces.h +++ b/lldb/include/lldb/lldb-private-interfaces.h @@ -99,10 +99,10 @@ typedef std::optional (*SymbolLocatorLocateExecutableSymbolFile)( typedef bool (*SymbolLocatorDownloadObjectAndSymbolFile)( ModuleSpec &module_spec, Status &error, bool force_lookup, bool copy_executable); -typedef bool (*BreakpointHitCallback)(void *baton, - StoppointCallbackContext *context, - lldb::user_id_t break_id, - lldb::user_id_t break_loc_id); +using BreakpointHitCallback = +std::function; + typedef bool (*WatchpointHitCallback)(void *baton, StoppointCallbackContext *context, lldb::user_id_t watch_id); diff --git a/lldb/source/Breakpoint/BreakpointOptions.cpp b/lldb/source/Breakpoint/BreakpointOptions.cpp index 6c6037dd9edd3..1db8401698114 100644 --- a/lldb/source/Breakpoint/BreakpointOptions.cpp +++ b/lldb/source/Breakpoint/BreakpointOptions.cpp @@ -102,19 +102,11 @@ const char *BreakpointOptions::g_option_names[( "ConditionText", "IgnoreCount", "EnabledState", "OneShotState", "AutoContinue"}; -bool BreakpointOptions::NullCallback(void *baton, - StoppointCallbackContext *context, - lldb::user_id_t break_id, - lldb::user_id_t break_loc_id) { - return true; -} - // BreakpointOptions constructor BreakpointOptions::BreakpointOptions(bool all_flags_set) -: m_callback(BreakpointOptions::NullCallback), - m_baton_is_command_baton(false), m_callback_is_synchronous(false), - m_enabled(true), m_one_shot(false), m_ignore_count(0), - m_condition_text_hash(0), m_inject_condition(false), +: m_callback(nullptr), m_baton_is_command_baton(false), + m_callback_is_synchronous(false), m_enabled(true), m_one_shot(false), + m_ignore_count(0), m_condition_text_hash(0), m_inject_condition(false), m_auto_continue(false), m_set_flags(0) { if (all_flags_set) m_set_flags.Set(~((Flags::ValueType)0)); @@ -420,7 +412,7 @@ void BreakpointOptions::SetCallback( } void BreakpointOptions::ClearCallback() { - m_callback = BreakpointOptions::NullCallback; + m_callback = nullptr; m_callback_is_synchronous = false; m_callback_baton_sp.reset(); m_baton_is_command_baton = false; @@ -449,7 +441,7 @@ bool BreakpointOptions::InvokeCallback(StoppointCallbackContext *context, } bool BreakpointOptions::HasCallback() const { - return m_callback != BreakpointOptions::NullCallback; + return static_cast(m_callback); } bool BreakpointOptions::GetCommandLineCallbacks(StringList &command_list) { diff --git a/lldb/unittests/CMakeLists.txt b/lldb/unittests/CMakeLists.txt index a2585a94b6155..cc9d45ebf981d 100644 --- a/lldb/unittests/CMakeLists.txt +++ b/lldb/unittests/CMakeLists.txt @@ -52,6 +52,7 @@ if (NOT CMAKE_SYSTEM_NAME MATCHES "Windows") add_subdirectory(API) endif() add_subdirectory(Breakpoint) +add_subdirectory(Callback) add_subdirectory(Core) add_subdirectory(DataFormatter) add_subdirectory(Disassembler) diff --git a/lldb/unittests/Callback/CMakeLists.txt b/lldb/unittests/Callback/CMakeLists.txt new file mode 100644 index 0..b9e0ef5a396e3 --- /dev/null +++ b/lldb/unittests/Callback/CMakeLists.txt @@ -0,0 +1,12 @@ +add_lldb_unittest(LLDBCallbackTests + TestBreakpointSetCallback.cpp + + LINK_LIBS +lldbBreakpoint +lldbCore +LLVMTestingSupport +lldbUtilityHelpers +lldbPluginPlatformMacOSX + LINK_COMPONENTS +Support + ) diff --git a/lldb/unittests/Callback/TestBreakpointSetCallback.cpp b/lldb/unittests/Callback/TestBreakpointSetCallback.cpp new file mode 100644 index 0..d82ca660ab73f --- /dev/null +++ b/lldb/unittests/Callback/TestBreakpointSetCallback.cpp @@ -0,0 +1,89 @@ +//===-- TestBreakpointSetCallback.cpp +//===// +// +//
[Lldb-commits] [lldb] Add a unit test for SBBreakpoint::SetCallback (PR #96001)
https://github.com/medismailben edited https://github.com/llvm/llvm-project/pull/96001 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] Add a unit test for SBBreakpoint::SetCallback (PR #96001)
@@ -0,0 +1,89 @@ +//===-- TestBreakpointSetCallback.cpp +//===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===--===// + +#include "Plugins/Platform/MacOSX/PlatformMacOSX.h" +#include "Plugins/Platform/MacOSX/PlatformRemoteMacOSX.h" +#include "TestingSupport/SubsystemRAII.h" +#include "TestingSupport/TestUtilities.h" +#include "lldb/Breakpoint/StoppointCallbackContext.h" +#include "lldb/Core/Debugger.h" +#include "lldb/Core/Progress.h" +#include "lldb/Host/FileSystem.h" +#include "lldb/Host/HostInfo.h" +#include "lldb/Target/ExecutionContext.h" +#include "lldb/lldb-private-enumerations.h" +#include "lldb/lldb-types.h" +#include "gtest/gtest.h" +#include +#include +#include + +using namespace lldb_private; +using namespace lldb; + +static constexpr lldb::user_id_t expected_breakpoint_id = 1; +static constexpr lldb::user_id_t expected_breakpoint_location_id = 0; + +class BreakpointSetCallbackTest : public ::testing::Test { +public: + static void CheckCallbackArgs(void *baton, StoppointCallbackContext *context, +lldb::user_id_t break_id, +lldb::user_id_t break_loc_id, +lldb::user_id_t expected_breakpoint_id, +lldb::user_id_t expected_breakpoint_loc_id, medismailben wrote: no need to pass them here, since they're static https://github.com/llvm/llvm-project/pull/96001 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] Add a unit test for SBBreakpoint::SetCallback (PR #96001)
https://github.com/medismailben approved this pull request. LGTM with comment https://github.com/llvm/llvm-project/pull/96001 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] Reapply [lldb][DWARF] Delay struct/class/union definition DIE searching when parsing declaration DIEs. (PR #92328)
jeffreytan81 wrote: @ZequanWu, @labath, since this PR got reverted due to crash for `--gsimple-template-names`, do you guys have a timeline to revise a new version without crashing? I ask this because our internal customers have many forward declarations that are suffering from the slow definition lookup. cc @clayborg https://github.com/llvm/llvm-project/pull/92328 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits