diff options
Diffstat (limited to 'lldb')
36 files changed, 343 insertions, 70 deletions
diff --git a/lldb/bindings/python/python-swigsafecast.swig b/lldb/bindings/python/python-swigsafecast.swig index 7a4f7e81f1cc..429baad158ca 100644 --- a/lldb/bindings/python/python-swigsafecast.swig +++ b/lldb/bindings/python/python-swigsafecast.swig @@ -23,6 +23,11 @@ PythonObject SWIGBridge::ToSWIGWrapper(lldb::ProcessSP process_sp) { SWIGTYPE_p_lldb__SBProcess); } +PythonObject SWIGBridge::ToSWIGWrapper(lldb::ModuleSP module_sp) { + return ToSWIGHelper(new lldb::SBModule(std::move(module_sp)), + SWIGTYPE_p_lldb__SBModule); +} + PythonObject SWIGBridge::ToSWIGWrapper(lldb::ThreadPlanSP thread_plan_sp) { return ToSWIGHelper(new lldb::SBThreadPlan(std::move(thread_plan_sp)), SWIGTYPE_p_lldb__SBThreadPlan); diff --git a/lldb/docs/resources/formatterbytecode.rst b/lldb/docs/resources/formatterbytecode.rst index 20e148363ef9..34fb0f7ee924 100644 --- a/lldb/docs/resources/formatterbytecode.rst +++ b/lldb/docs/resources/formatterbytecode.rst @@ -75,6 +75,7 @@ These manipulate the control stack and program counter. Both `if` and `ifelse` e 0x12 `ifelse` `(UInt -> )` pop two blocks from the control stack, if the top of the data stack is nonzero, execute the first, otherwise the second. + 0x13 `return` pop the entire control stack and return ======== ========== ============================================================ Literals for basic types diff --git a/lldb/docs/use/map.rst b/lldb/docs/use/map.rst index fe9c3f53022f..ed285b2d1f6e 100644 --- a/lldb/docs/use/map.rst +++ b/lldb/docs/use/map.rst @@ -235,6 +235,38 @@ Do a source level single step in the currently selected thread (lldb) step (lldb) s +Ignore a function when doing a source level single step in +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +.. code-block:: shell + + (gdb) skip abc + Function abc will be skipped when stepping. + +.. code-block:: shell + + (lldb) settings show target.process.thread.step-avoid-regexp + target.process.thread.step-avoid-regexp (regex) = ^std:: + (lldb) settings set target.process.thread.step-avoid-regexp ^std::|^abc + +You can ignore a function once using: + +.. code-block:: shell + + (lldb) thread step-in -r ^abc + +Or you can do the opposite, only step into functions matching a certain name: + +.. code-block:: shell + + # Step in if abc is a substring of the function name. + (lldb) sif abc + # Which is equivalent to: + (lldb) thread step-in -t abc + +``thread step-in`` has more options which cover some of ``skip``'s other +features. See ``help thread step-in`` for details. + Do a source level single step over in the currently selected thread ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ diff --git a/lldb/examples/python/formatter_bytecode.py b/lldb/examples/python/formatter_bytecode.py index ccd0c68a7548..36a14be283f3 100644 --- a/lldb/examples/python/formatter_bytecode.py +++ b/lldb/examples/python/formatter_bytecode.py @@ -35,6 +35,7 @@ define_opcode(6, "rot", "rot") define_opcode(0x10, "{", "begin") define_opcode(0x11, "if", "if") define_opcode(0x12, "ifelse", "ifelse") +define_opcode(0x13, "return", "return") define_opcode(0x20, None, "lit_uint") define_opcode(0x21, None, "lit_int") @@ -342,6 +343,9 @@ def interpret(bytecode: bytearray, control: list, data: list, tracing: bool = Fa else: frame.append(control.pop()) control.pop() + elif b == op_return: + control.clear() + return data[-1] # Literals. elif b == op_lit_uint: diff --git a/lldb/include/lldb/API/SBModule.h b/lldb/include/lldb/API/SBModule.h index 7200a1ef53fd..85332066ee68 100644 --- a/lldb/include/lldb/API/SBModule.h +++ b/lldb/include/lldb/API/SBModule.h @@ -301,9 +301,12 @@ private: friend class SBFrame; friend class SBSection; friend class SBSymbolContext; + friend class SBPlatform; friend class SBTarget; friend class SBType; + friend class lldb_private::python::SWIGBridge; + explicit SBModule(const lldb::ModuleSP &module_sp); ModuleSP GetSP() const; diff --git a/lldb/include/lldb/Core/Progress.h b/lldb/include/lldb/Core/Progress.h index f6cea282842e..5876eae717e9 100644 --- a/lldb/include/lldb/Core/Progress.h +++ b/lldb/include/lldb/Core/Progress.h @@ -59,6 +59,12 @@ namespace lldb_private { class Progress { public: + /// Enum to indicate the origin of a progress event, internal or external. + enum class Origin : uint8_t { + eInternal = 0, + eExternal = 1, + }; + /// Construct a progress object that will report information. /// /// The constructor will create a unique progress reporting object and @@ -83,7 +89,8 @@ public: Progress(std::string title, std::string details = {}, std::optional<uint64_t> total = std::nullopt, lldb_private::Debugger *debugger = nullptr, - Timeout<std::nano> minimum_report_time = std::nullopt); + Timeout<std::nano> minimum_report_time = std::nullopt, + Origin origin = Origin::eInternal); /// Destroy the progress object. /// @@ -118,6 +125,9 @@ public: /// The optional debugger ID to report progress to. If this has no value /// then all debuggers will receive this event. std::optional<lldb::user_id_t> debugger_id; + + /// The origin of the progress event, wheter it is internal or external. + Origin origin; }; private: diff --git a/lldb/include/lldb/Host/aix/HostInfoAIX.h b/lldb/include/lldb/Host/aix/HostInfoAIX.h new file mode 100644 index 000000000000..7796a1523780 --- /dev/null +++ b/lldb/include/lldb/Host/aix/HostInfoAIX.h @@ -0,0 +1,28 @@ +//===-- HostInfoAIX.h -----------------------------------------*- C++ -*-===// +// +// 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 +// +//===----------------------------------------------------------------------===// + +#ifndef LLDB_HOST_AIX_HOSTINFOAIX_H_ +#define LLDB_HOST_AIX_HOSTINFOAIX_H_ + +#include "lldb/Host/posix/HostInfoPosix.h" +#include "lldb/Utility/FileSpec.h" + +namespace lldb_private { + +class HostInfoAIX : public HostInfoPosix { + friend class HostInfoBase; + +public: + static void Initialize(SharedLibraryDirectoryHelper *helper = nullptr); + static void Terminate(); + + static FileSpec GetProgramFileSpec(); +}; +} // namespace lldb_private + +#endif // LLDB_HOST_AIX_HOSTINFOAIX_H_ diff --git a/lldb/include/lldb/lldb-enumerations.h b/lldb/include/lldb/lldb-enumerations.h index 0094fcd596fd..50d2233509de 100644 --- a/lldb/include/lldb/lldb-enumerations.h +++ b/lldb/include/lldb/lldb-enumerations.h @@ -1357,6 +1357,8 @@ enum DebuggerBroadcastBit { eBroadcastBitError = (1 << 2), eBroadcastSymbolChange = (1 << 3), eBroadcastBitProgressCategory = (1 << 4), + eBroadcastBitExternalProgress = (1 << 5), + eBroadcastBitExternalProgressCategory = (1 << 6), }; /// Used for expressing severity in logs and diagnostics. diff --git a/lldb/packages/Python/lldbsuite/test/tools/lldb-server/gdbremote_testcase.py b/lldb/packages/Python/lldbsuite/test/tools/lldb-server/gdbremote_testcase.py index d6cb68f55bf2..cbe430c92fa7 100644 --- a/lldb/packages/Python/lldbsuite/test/tools/lldb-server/gdbremote_testcase.py +++ b/lldb/packages/Python/lldbsuite/test/tools/lldb-server/gdbremote_testcase.py @@ -1410,7 +1410,17 @@ class GdbRemoteTestCaseBase(Base, metaclass=GdbRemoteTestCaseFactory): p_response = context.get("p_response") self.assertIsNotNone(p_response) self.assertTrue(len(p_response) > 0) - self.assertFalse(p_response[0] == "E") + + # on x86 Darwin, 4 GPR registers are often + # unavailable, this is expected and correct. + if ( + self.getArchitecture() == "x86_64" + and self.platformIsDarwin() + and p_response[0] == "E" + ): + values[reg_index] = 0 + else: + self.assertFalse(p_response[0] == "E") values[reg_index] = unpack_register_hex_unsigned(endian, p_response) diff --git a/lldb/source/Core/Progress.cpp b/lldb/source/Core/Progress.cpp index ed8dfb85639b..63f980432080 100644 --- a/lldb/source/Core/Progress.cpp +++ b/lldb/source/Core/Progress.cpp @@ -28,12 +28,14 @@ static llvm::ManagedStatic<llvm::SignpostEmitter> g_progress_signposts; Progress::Progress(std::string title, std::string details, std::optional<uint64_t> total, lldb_private::Debugger *debugger, - Timeout<std::nano> minimum_report_time) + Timeout<std::nano> minimum_report_time, + Progress::Origin origin) : m_total(total.value_or(Progress::kNonDeterministicTotal)), m_minimum_report_time(minimum_report_time), m_progress_data{title, ++g_id, debugger ? std::optional<user_id_t>(debugger->GetID()) - : std::nullopt}, + : std::nullopt, + origin}, m_last_report_time_ns( std::chrono::nanoseconds( std::chrono::steady_clock::now().time_since_epoch()) @@ -106,9 +108,15 @@ void Progress::ReportProgress() { if (completed < m_prev_completed) return; // An overflow in the m_completed counter. Just ignore these events. + // Change the category bit if we're an internal or external progress. + uint32_t progress_category_bit = + m_progress_data.origin == Progress::Origin::eExternal + ? lldb::eBroadcastBitExternalProgress + : lldb::eBroadcastBitProgress; + Debugger::ReportProgress(m_progress_data.progress_id, m_progress_data.title, m_details, completed, m_total, - m_progress_data.debugger_id); + m_progress_data.debugger_id, progress_category_bit); m_prev_completed = completed; } @@ -201,10 +209,13 @@ void ProgressManager::ReportProgress( // broadcasting to it since that bit doesn't need that information. const uint64_t completed = (type == EventType::Begin) ? 0 : Progress::kNonDeterministicTotal; + const uint32_t progress_category_bit = + progress_data.origin == Progress::Origin::eExternal + ? lldb::eBroadcastBitExternalProgressCategory + : lldb::eBroadcastBitProgressCategory; Debugger::ReportProgress(progress_data.progress_id, progress_data.title, "", completed, Progress::kNonDeterministicTotal, - progress_data.debugger_id, - lldb::eBroadcastBitProgressCategory); + progress_data.debugger_id, progress_category_bit); } void ProgressManager::Expire(llvm::StringRef key) { diff --git a/lldb/source/DataFormatters/FormatterBytecode.cpp b/lldb/source/DataFormatters/FormatterBytecode.cpp index e49c75067818..7f3dbe0dba37 100644 --- a/lldb/source/DataFormatters/FormatterBytecode.cpp +++ b/lldb/source/DataFormatters/FormatterBytecode.cpp @@ -304,6 +304,9 @@ llvm::Error Interpret(std::vector<ControlStackElement> &control, control.pop_back(); activate_block(); continue; + case op_return: + control.clear(); + return pc.takeError(); // Literals. case op_lit_uint: diff --git a/lldb/source/DataFormatters/FormatterBytecode.def b/lldb/source/DataFormatters/FormatterBytecode.def index c6645631fa00..29e0bee541c7 100644 --- a/lldb/source/DataFormatters/FormatterBytecode.def +++ b/lldb/source/DataFormatters/FormatterBytecode.def @@ -27,6 +27,7 @@ DEFINE_OPCODE(0x06, "rot", rot) DEFINE_OPCODE(0x10, "{", begin) DEFINE_OPCODE(0x11, "if", if) DEFINE_OPCODE(0x12, "ifelse", ifelse) +DEFINE_OPCODE(0x13, "return", return) DEFINE_OPCODE(0x20, nullptr, lit_uint) DEFINE_OPCODE(0x21, nullptr, lit_int) diff --git a/lldb/source/Host/CMakeLists.txt b/lldb/source/Host/CMakeLists.txt index c2e091ee8555..e0cd8569bf95 100644 --- a/lldb/source/Host/CMakeLists.txt +++ b/lldb/source/Host/CMakeLists.txt @@ -133,6 +133,11 @@ else() openbsd/Host.cpp openbsd/HostInfoOpenBSD.cpp ) + + elseif (CMAKE_SYSTEM_NAME MATCHES "AIX") + add_host_subdirectory(aix + aix/HostInfoAIX.cpp + ) endif() endif() diff --git a/lldb/source/Host/aix/HostInfoAIX.cpp b/lldb/source/Host/aix/HostInfoAIX.cpp new file mode 100644 index 000000000000..61b47462dd64 --- /dev/null +++ b/lldb/source/Host/aix/HostInfoAIX.cpp @@ -0,0 +1,22 @@ +//===-- HostInfoAIX.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/Host/aix/HostInfoAIX.h" + +using namespace lldb_private; + +void HostInfoAIX::Initialize(SharedLibraryDirectoryHelper *helper) { + HostInfoPosix::Initialize(helper); +} + +void HostInfoAIX::Terminate() { HostInfoBase::Terminate(); } + +FileSpec HostInfoAIX::GetProgramFileSpec() { + static FileSpec g_program_filespec; + return g_program_filespec; +} diff --git a/lldb/source/Host/openbsd/Host.cpp b/lldb/source/Host/openbsd/Host.cpp index a4dc3918acfd..24650ff97075 100644 --- a/lldb/source/Host/openbsd/Host.cpp +++ b/lldb/source/Host/openbsd/Host.cpp @@ -41,18 +41,7 @@ namespace lldb_private { class ProcessLaunchInfo; } -Environment Host::GetEnvironment() { - Environment env; - char *v; - char **var = environ; - for (; var != NULL && *var != NULL; ++var) { - v = strchr(*var, (int)'-'); - if (v == NULL) - continue; - env.insert(v); - } - return env; -} +Environment Host::GetEnvironment() { return Environment(environ); } static bool GetOpenBSDProcessArgs(const ProcessInstanceInfoMatch *match_info_ptr, @@ -127,7 +116,7 @@ static bool GetOpenBSDProcessUserAndGroup(ProcessInstanceInfo &process_info) { process_info.SetUserID(proc_kinfo.p_ruid); process_info.SetGroupID(proc_kinfo.p_rgid); process_info.SetEffectiveUserID(proc_kinfo.p_uid); - process_info.SetEffectiveGroupID(proc_kinfo.p_gid); + process_info.SetEffectiveGroupID(proc_kinfo.p_gid); return true; } } diff --git a/lldb/source/Host/posix/ConnectionFileDescriptorPosix.cpp b/lldb/source/Host/posix/ConnectionFileDescriptorPosix.cpp index ab4ddbfe1fb2..0ed201666716 100644 --- a/lldb/source/Host/posix/ConnectionFileDescriptorPosix.cpp +++ b/lldb/source/Host/posix/ConnectionFileDescriptorPosix.cpp @@ -730,9 +730,19 @@ ConnectionStatus ConnectionFileDescriptor::ConnectFile( struct termios options; ::tcgetattr(fd, &options); - // Set port speed to maximum + // Set port speed to the available maximum +#ifdef B115200 ::cfsetospeed(&options, B115200); ::cfsetispeed(&options, B115200); +#elif B57600 + ::cfsetospeed(&options, B57600); + ::cfsetispeed(&options, B57600); +#elif B38400 + ::cfsetospeed(&options, B38400); + ::cfsetispeed(&options, B38400); +#else +#error "Maximum Baud rate is Unknown" +#endif // Raw input, disable echo and signals options.c_lflag &= ~(ICANON | ECHO | ECHOE | ISIG); diff --git a/lldb/source/Host/posix/DomainSocket.cpp b/lldb/source/Host/posix/DomainSocket.cpp index f85e1b9bbdc5..be8fcdf2c8f2 100644 --- a/lldb/source/Host/posix/DomainSocket.cpp +++ b/lldb/source/Host/posix/DomainSocket.cpp @@ -182,7 +182,7 @@ std::vector<std::string> DomainSocket::GetListeningConnectionURI() const { return {}; struct sockaddr_un addr; - bzero(&addr, sizeof(struct sockaddr_un)); + memset(&addr, 0, sizeof(struct sockaddr_un)); addr.sun_family = AF_UNIX; socklen_t addr_len = sizeof(struct sockaddr_un); if (::getsockname(m_socket, (struct sockaddr *)&addr, &addr_len) != 0) diff --git a/lldb/source/Host/posix/FileSystemPosix.cpp b/lldb/source/Host/posix/FileSystemPosix.cpp index 945e2affc837..4c326a29812f 100644 --- a/lldb/source/Host/posix/FileSystemPosix.cpp +++ b/lldb/source/Host/posix/FileSystemPosix.cpp @@ -9,16 +9,8 @@ #include "lldb/Host/FileSystem.h" // C includes -#include <dirent.h> #include <fcntl.h> -#include <sys/mount.h> -#include <sys/param.h> -#include <sys/stat.h> -#include <sys/types.h> #include <unistd.h> -#if defined(__NetBSD__) -#include <sys/statvfs.h> -#endif // lldb Includes #include "lldb/Host/Host.h" diff --git a/lldb/source/Plugins/InstrumentationRuntime/ASanLibsanitizers/InstrumentationRuntimeASanLibsanitizers.cpp b/lldb/source/Plugins/InstrumentationRuntime/ASanLibsanitizers/InstrumentationRuntimeASanLibsanitizers.cpp index cd91f4a6ff1b..b1151febb7cc 100644 --- a/lldb/source/Plugins/InstrumentationRuntime/ASanLibsanitizers/InstrumentationRuntimeASanLibsanitizers.cpp +++ b/lldb/source/Plugins/InstrumentationRuntime/ASanLibsanitizers/InstrumentationRuntimeASanLibsanitizers.cpp @@ -90,17 +90,9 @@ void InstrumentationRuntimeASanLibsanitizers::Activate() { if (!process_sp) return; - lldb::ModuleSP module_sp = GetRuntimeModuleSP(); - Breakpoint *breakpoint = ReportRetriever::SetupBreakpoint( - module_sp, process_sp, ConstString("sanitizers_address_on_report")); - - if (!breakpoint) { - breakpoint = ReportRetriever::SetupBreakpoint( - module_sp, process_sp, - ConstString("_Z22raise_sanitizers_error23sanitizer_error_context")); - } - + GetRuntimeModuleSP(), process_sp, + ConstString("sanitizers_address_on_report")); if (!breakpoint) return; diff --git a/lldb/source/Plugins/InstrumentationRuntime/Utility/ReportRetriever.cpp b/lldb/source/Plugins/InstrumentationRuntime/Utility/ReportRetriever.cpp index 04ce339d8f66..74e0fa7d49f8 100644 --- a/lldb/source/Plugins/InstrumentationRuntime/Utility/ReportRetriever.cpp +++ b/lldb/source/Plugins/InstrumentationRuntime/Utility/ReportRetriever.cpp @@ -219,7 +219,6 @@ bool ReportRetriever::NotifyBreakpointHit(ProcessSP process_sp, return true; // Return true to stop the target } -// FIXME: Setup the breakpoint using a less fragile SPI. rdar://124399066 Breakpoint *ReportRetriever::SetupBreakpoint(ModuleSP module_sp, ProcessSP process_sp, ConstString symbol_name) { @@ -235,19 +234,13 @@ Breakpoint *ReportRetriever::SetupBreakpoint(ModuleSP module_sp, if (!symbol->ValueIsAddress() || !symbol->GetAddressRef().IsValid()) return nullptr; - Target &target = process_sp->GetTarget(); - addr_t symbol_address = symbol->GetAddressRef().GetOpcodeLoadAddress(&target); - - if (symbol_address == LLDB_INVALID_ADDRESS) - return nullptr; - + const Address &address = symbol->GetAddressRef(); const bool internal = true; const bool hardware = false; - Breakpoint *breakpoint = - process_sp->GetTarget() - .CreateBreakpoint(symbol_address, internal, hardware) - .get(); + Breakpoint *breakpoint = process_sp->GetTarget() + .CreateBreakpoint(address, internal, hardware) + .get(); return breakpoint; } diff --git a/lldb/source/Plugins/Language/ObjC/Cocoa.cpp b/lldb/source/Plugins/Language/ObjC/Cocoa.cpp index b35e27ad8123..1d79edbede5d 100644 --- a/lldb/source/Plugins/Language/ObjC/Cocoa.cpp +++ b/lldb/source/Plugins/Language/ObjC/Cocoa.cpp @@ -1226,7 +1226,7 @@ bool lldb_private::formatters::ObjCSELSummaryProvider( time_t lldb_private::formatters::GetOSXEpoch() { static time_t epoch = 0; if (!epoch) { -#ifndef _WIN32 +#if !defined(_WIN32) && !defined(_AIX) tzset(); tm tm_epoch; tm_epoch.tm_sec = 0; diff --git a/lldb/source/Plugins/ObjectContainer/BSD-Archive/ObjectContainerBSDArchive.cpp b/lldb/source/Plugins/ObjectContainer/BSD-Archive/ObjectContainerBSDArchive.cpp index 3835f2b08a05..b202898ff438 100644 --- a/lldb/source/Plugins/ObjectContainer/BSD-Archive/ObjectContainerBSDArchive.cpp +++ b/lldb/source/Plugins/ObjectContainer/BSD-Archive/ObjectContainerBSDArchive.cpp @@ -8,7 +8,7 @@ #include "ObjectContainerBSDArchive.h" -#if defined(_WIN32) || defined(__ANDROID__) +#if defined(_WIN32) || defined(__ANDROID__) || defined(_AIX) // Defines from ar, missing on Windows #define SARMAG 8 #define ARFMAG "`\n" diff --git a/lldb/source/Plugins/ObjectFile/Minidump/MinidumpFileBuilder.cpp b/lldb/source/Plugins/ObjectFile/Minidump/MinidumpFileBuilder.cpp index bcac5edbc1a7..c5013ea5e3be 100644 --- a/lldb/source/Plugins/ObjectFile/Minidump/MinidumpFileBuilder.cpp +++ b/lldb/source/Plugins/ObjectFile/Minidump/MinidumpFileBuilder.cpp @@ -58,8 +58,8 @@ Status MinidumpFileBuilder::AddHeaderAndCalculateDirectories() { // First set the offset on the file, and on the bytes saved m_saved_data_size = HEADER_SIZE; // We know we will have at least Misc, SystemInfo, Modules, and ThreadList - // (corresponding memory list for stacks) And an additional memory list for - // non-stacks. + // (corresponding memory list for stacks), an additional memory list for + // non-stacks, and a stream to mark this minidump was generated by LLDB. lldb_private::Target &target = m_process_sp->GetTarget(); m_expected_directories = 6; // Check if OS is linux and reserve directory space for all linux specific @@ -90,7 +90,10 @@ Status MinidumpFileBuilder::AddHeaderAndCalculateDirectories() { "sections. Written / Expected (%" PRIx64 " / %" PRIx64 ")", new_offset, m_saved_data_size); - return error; + if (error.Fail()) + return error; + + return AddLLDBGeneratedStream(); } Status MinidumpFileBuilder::AddDirectory(StreamType type, @@ -126,6 +129,12 @@ Status MinidumpFileBuilder::AddDirectory(StreamType type, return error; } +Status MinidumpFileBuilder::AddLLDBGeneratedStream() { + Status error; + StreamType type = StreamType::LLDBGenerated; + return AddDirectory(type, 0); +} + Status MinidumpFileBuilder::AddSystemInfo() { Status error; const llvm::Triple &target_triple = diff --git a/lldb/source/Plugins/ObjectFile/Minidump/MinidumpFileBuilder.h b/lldb/source/Plugins/ObjectFile/Minidump/MinidumpFileBuilder.h index 58b284608bd5..48293ee1bf5e 100644 --- a/lldb/source/Plugins/ObjectFile/Minidump/MinidumpFileBuilder.h +++ b/lldb/source/Plugins/ObjectFile/Minidump/MinidumpFileBuilder.h @@ -120,6 +120,7 @@ public: void DeleteFile() noexcept; private: + lldb_private::Status AddLLDBGeneratedStream(); // Add data to the end of the buffer, if the buffer exceeds the flush level, // trigger a flush. lldb_private::Status AddData(const void *data, uint64_t size); diff --git a/lldb/source/Plugins/Platform/Android/PlatformAndroidRemoteGDBServer.cpp b/lldb/source/Plugins/Platform/Android/PlatformAndroidRemoteGDBServer.cpp index d18b718d4a56..0cf64807ec0d 100644 --- a/lldb/source/Plugins/Platform/Android/PlatformAndroidRemoteGDBServer.cpp +++ b/lldb/source/Plugins/Platform/Android/PlatformAndroidRemoteGDBServer.cpp @@ -64,7 +64,7 @@ static Status DeleteForwardPortWithAdb(uint16_t local_port, static Status FindUnusedPort(uint16_t &port) { Status error; - std::unique_ptr<TCPSocket> tcp_socket(new TCPSocket(true, false)); + std::unique_ptr<TCPSocket> tcp_socket(new TCPSocket(true)); if (error.Fail()) return error; diff --git a/lldb/source/Plugins/Process/elf-core/ProcessElfCore.cpp b/lldb/source/Plugins/Process/elf-core/ProcessElfCore.cpp index b3916cc913f7..5f85f99ce7bd 100644 --- a/lldb/source/Plugins/Process/elf-core/ProcessElfCore.cpp +++ b/lldb/source/Plugins/Process/elf-core/ProcessElfCore.cpp @@ -1031,6 +1031,8 @@ UUID ProcessElfCore::FindBuidIdInCoreMemory(lldb::addr_t address) { std::vector<uint8_t> ph_bytes; ph_bytes.resize(elf_header.e_phentsize); + lldb::addr_t base_addr = 0; + bool found_first_load_segment = false; for (unsigned int i = 0; i < elf_header.e_phnum; ++i) { byte_read = ReadMemory(ph_addr + i * elf_header.e_phentsize, ph_bytes.data(), elf_header.e_phentsize, error); @@ -1041,6 +1043,11 @@ UUID ProcessElfCore::FindBuidIdInCoreMemory(lldb::addr_t address) { offset = 0; elf::ELFProgramHeader program_header; program_header.Parse(program_header_data, &offset); + if (program_header.p_type == llvm::ELF::PT_LOAD && + !found_first_load_segment) { + base_addr = program_header.p_vaddr; + found_first_load_segment = true; + } if (program_header.p_type != llvm::ELF::PT_NOTE) continue; @@ -1049,7 +1056,7 @@ UUID ProcessElfCore::FindBuidIdInCoreMemory(lldb::addr_t address) { // We need to slide the address of the p_vaddr as these values don't get // relocated in memory. - const lldb::addr_t vaddr = program_header.p_vaddr + address; + const lldb::addr_t vaddr = program_header.p_vaddr + address - base_addr; byte_read = ReadMemory(vaddr, note_bytes.data(), program_header.p_memsz, error); if (byte_read != program_header.p_memsz) diff --git a/lldb/source/Plugins/Process/minidump/MinidumpParser.cpp b/lldb/source/Plugins/Process/minidump/MinidumpParser.cpp index afc095ddbb2f..94c0a5f11e43 100644 --- a/lldb/source/Plugins/Process/minidump/MinidumpParser.cpp +++ b/lldb/source/Plugins/Process/minidump/MinidumpParser.cpp @@ -49,6 +49,11 @@ llvm::ArrayRef<uint8_t> MinidumpParser::GetStream(StreamType stream_type) { return m_file->getRawStream(stream_type).value_or(llvm::ArrayRef<uint8_t>()); } +std::optional<llvm::ArrayRef<uint8_t>> +MinidumpParser::GetRawStream(StreamType stream_type) { + return m_file->getRawStream(stream_type); +} + UUID MinidumpParser::GetModuleUUID(const minidump::Module *module) { auto cv_record = GetData().slice(module->CvRecord.RVA, module->CvRecord.DataSize); @@ -651,6 +656,7 @@ MinidumpParser::GetStreamTypeAsString(StreamType stream_type) { ENUM_TO_CSTR(FacebookAbortReason); ENUM_TO_CSTR(FacebookThreadName); ENUM_TO_CSTR(FacebookLogcat); + ENUM_TO_CSTR(LLDBGenerated); } return "unknown stream type"; } diff --git a/lldb/source/Plugins/Process/minidump/MinidumpParser.h b/lldb/source/Plugins/Process/minidump/MinidumpParser.h index f0b6e6027c52..2c5e6f19ff9a 100644 --- a/lldb/source/Plugins/Process/minidump/MinidumpParser.h +++ b/lldb/source/Plugins/Process/minidump/MinidumpParser.h @@ -59,6 +59,7 @@ public: llvm::ArrayRef<uint8_t> GetData(); llvm::ArrayRef<uint8_t> GetStream(StreamType stream_type); + std::optional<llvm::ArrayRef<uint8_t>> GetRawStream(StreamType stream_type); UUID GetModuleUUID(const minidump::Module *module); diff --git a/lldb/source/Plugins/Process/minidump/ProcessMinidump.cpp b/lldb/source/Plugins/Process/minidump/ProcessMinidump.cpp index 5b0df72130c1..05b3bb9f54f9 100644 --- a/lldb/source/Plugins/Process/minidump/ProcessMinidump.cpp +++ b/lldb/source/Plugins/Process/minidump/ProcessMinidump.cpp @@ -354,6 +354,22 @@ DataExtractor ProcessMinidump::GetAuxvData() { GetAddressByteSize(), GetAddressByteSize()); } +bool ProcessMinidump::IsLLDBMinidump() { + std::optional<llvm::ArrayRef<uint8_t>> lldb_generated_section = + m_minidump_parser->GetRawStream(StreamType::LLDBGenerated); + return lldb_generated_section.has_value(); +} + +DynamicLoader *ProcessMinidump::GetDynamicLoader() { + // This is a workaround for the dynamic loader not playing nice in issue + // #119598. The specific reason we use the dynamic loader is to get the TLS + // info sections, which we can assume are not being written to the minidump + // unless it's an LLDB generate minidump. + if (IsLLDBMinidump()) + return PostMortemProcess::GetDynamicLoader(); + return nullptr; +} + void ProcessMinidump::BuildMemoryRegions() { if (m_memory_regions) return; diff --git a/lldb/source/Plugins/Process/minidump/ProcessMinidump.h b/lldb/source/Plugins/Process/minidump/ProcessMinidump.h index 3d235670a33a..ad8d0ed7a483 100644 --- a/lldb/source/Plugins/Process/minidump/ProcessMinidump.h +++ b/lldb/source/Plugins/Process/minidump/ProcessMinidump.h @@ -53,6 +53,8 @@ public: Status DoLoadCore() override; + DynamicLoader *GetDynamicLoader() override; + // Returns AUXV structure found in the core file lldb_private::DataExtractor GetAuxvData() override; @@ -74,8 +76,8 @@ public: ArchSpec GetArchitecture(); - Status GetMemoryRegions( - lldb_private::MemoryRegionInfos ®ion_list) override; + Status + GetMemoryRegions(lldb_private::MemoryRegionInfos ®ion_list) override; bool GetProcessInfo(ProcessInstanceInfo &info) override; @@ -113,6 +115,7 @@ private: std::optional<MemoryRegionInfos> m_memory_regions; void BuildMemoryRegions(); + bool IsLLDBMinidump(); }; } // namespace minidump diff --git a/lldb/source/Plugins/ScriptInterpreter/Python/SWIGPythonBridge.h b/lldb/source/Plugins/ScriptInterpreter/Python/SWIGPythonBridge.h index 518a478af5f6..0f0e4a563e8b 100644 --- a/lldb/source/Plugins/ScriptInterpreter/Python/SWIGPythonBridge.h +++ b/lldb/source/Plugins/ScriptInterpreter/Python/SWIGPythonBridge.h @@ -84,6 +84,7 @@ public: static PythonObject ToSWIGWrapper(lldb::ValueObjectSP value_sp); static PythonObject ToSWIGWrapper(lldb::TargetSP target_sp); static PythonObject ToSWIGWrapper(lldb::ProcessSP process_sp); + static PythonObject ToSWIGWrapper(lldb::ModuleSP module_sp); static PythonObject ToSWIGWrapper(lldb::ThreadPlanSP thread_plan_sp); static PythonObject ToSWIGWrapper(lldb::BreakpointSP breakpoint_sp); static PythonObject ToSWIGWrapper(Status &&status); diff --git a/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp b/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp index 28e7cceb3971..e2f76e88dd6f 100644 --- a/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp +++ b/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp @@ -1222,11 +1222,9 @@ DWARFASTParserClang::ParseSubroutine(const DWARFDIE &die, } if (die.HasChildren()) { - bool skip_artificial = true; - ParseChildParameters(containing_decl_ctx, die, skip_artificial, is_static, - is_variadic, has_template_params, - function_param_types, function_param_decls, - type_quals); + ParseChildParameters(containing_decl_ctx, die, is_static, is_variadic, + has_template_params, function_param_types, + function_param_decls, type_quals); } bool ignore_containing_context = false; @@ -2325,7 +2323,7 @@ DWARFASTParserClang::ConstructDemangledNameFromDWARF(const DWARFDIE &die) { clang::DeclContext *containing_decl_ctx = GetClangDeclContextContainingDIE(die, nullptr); - ParseChildParameters(containing_decl_ctx, die, true, is_static, is_variadic, + ParseChildParameters(containing_decl_ctx, die, is_static, is_variadic, has_template_params, param_types, param_decls, type_quals); sstr << "("; @@ -3069,8 +3067,8 @@ bool DWARFASTParserClang::ParseChildMembers( size_t DWARFASTParserClang::ParseChildParameters( clang::DeclContext *containing_decl_ctx, const DWARFDIE &parent_die, - bool skip_artificial, bool &is_static, bool &is_variadic, - bool &has_template_params, std::vector<CompilerType> &function_param_types, + bool &is_static, bool &is_variadic, bool &has_template_params, + std::vector<CompilerType> &function_param_types, std::vector<clang::ParmVarDecl *> &function_param_decls, unsigned &type_quals) { if (!parent_die) @@ -3125,7 +3123,7 @@ size_t DWARFASTParserClang::ParseChildParameters( } bool skip = false; - if (skip_artificial && is_artificial) { + if (is_artificial) { // In order to determine if a C++ member function is "const" we // have to look at the const-ness of "this"... if (arg_idx == 0 && diff --git a/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.h b/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.h index 55f8e38d7486..5b1c204bbe81 100644 --- a/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.h +++ b/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.h @@ -189,7 +189,7 @@ protected: size_t ParseChildParameters(clang::DeclContext *containing_decl_ctx, const lldb_private::plugin::dwarf::DWARFDIE &parent_die, - bool skip_artificial, bool &is_static, bool &is_variadic, + bool &is_static, bool &is_variadic, bool &has_template_params, std::vector<lldb_private::CompilerType> &function_args, std::vector<clang::ParmVarDecl *> &function_param_decls, diff --git a/lldb/test/API/commands/register/register/register_command/TestRegisters.py b/lldb/test/API/commands/register/register/register_command/TestRegisters.py index 0b80a0953437..99290e02cd2b 100644 --- a/lldb/test/API/commands/register/register/register_command/TestRegisters.py +++ b/lldb/test/API/commands/register/register/register_command/TestRegisters.py @@ -58,6 +58,13 @@ class RegisterCommandsTestCase(TestBase): # could not be read. This is expected. error_str_matched = True + if self.getArchitecture() == "x86_64" and self.platformIsDarwin(): + # debugserver on x86 will provide ds/es/ss/gsbase when the + # kernel provides them, but most of the time they will be + # unavailable. So "register read -a" will report that + # 4 registers were unavailable, it is expected. + error_str_matched = True + self.expect( "register read -a", MISSING_EXPECTED_REGISTERS, diff --git a/lldb/unittests/Core/ProgressReportTest.cpp b/lldb/unittests/Core/ProgressReportTest.cpp index 20324e925238..0943d7b99080 100644 --- a/lldb/unittests/Core/ProgressReportTest.cpp +++ b/lldb/unittests/Core/ProgressReportTest.cpp @@ -425,3 +425,104 @@ TEST_F(ProgressReportTest, TestProgressManagerDisjointReports) { ASSERT_FALSE(listener_sp->GetEvent(event_sp, TIMEOUT)); } + +TEST_F(ProgressReportTest, TestExternalReportCreation) { + ListenerSP listener_sp = + CreateListenerFor(lldb::eBroadcastBitExternalProgress); + EventSP event_sp; + const ProgressEventData *data; + + // Scope this for RAII on the progress objects. + // Create progress reports and check that their respective events for having + // started and ended are broadcasted. + { + Progress progress1("Progress report 1", "Starting report 1", + /*total=*/std::nullopt, /*debugger=*/nullptr, + /*minimum_report_time=*/std::chrono::seconds(0), + Progress::Origin::eExternal); + Progress progress2("Progress report 2", "Starting report 2", + /*total=*/std::nullopt, /*debugger=*/nullptr, + /*minimum_report_time=*/std::chrono::seconds(0), + Progress::Origin::eExternal); + Progress progress3("Progress report 3", "Starting report 3", + /*total=*/std::nullopt, /*debugger=*/nullptr, + /*minimum_report_time=*/std::chrono::seconds(0), + Progress::Origin::eExternal); + } + + // Start popping events from the queue, they should have been recevied + // in this order: + // Starting progress: 1, 2, 3 + // Ending progress: 3, 2, 1 + ASSERT_TRUE(listener_sp->GetEvent(event_sp, TIMEOUT)); + data = ProgressEventData::GetEventDataFromEvent(event_sp.get()); + + EXPECT_EQ(data->GetDetails(), "Starting report 1"); + EXPECT_FALSE(data->IsFinite()); + EXPECT_FALSE(data->GetCompleted()); + EXPECT_EQ(data->GetTotal(), Progress::kNonDeterministicTotal); + EXPECT_EQ(data->GetMessage(), "Progress report 1: Starting report 1"); + + ASSERT_TRUE(listener_sp->GetEvent(event_sp, TIMEOUT)); + data = ProgressEventData::GetEventDataFromEvent(event_sp.get()); + + EXPECT_EQ(data->GetDetails(), "Starting report 2"); + EXPECT_FALSE(data->IsFinite()); + EXPECT_FALSE(data->GetCompleted()); + EXPECT_EQ(data->GetTotal(), Progress::kNonDeterministicTotal); + EXPECT_EQ(data->GetMessage(), "Progress report 2: Starting report 2"); + + ASSERT_TRUE(listener_sp->GetEvent(event_sp, TIMEOUT)); + data = ProgressEventData::GetEventDataFromEvent(event_sp.get()); + + EXPECT_EQ(data->GetDetails(), "Starting report 3"); + EXPECT_FALSE(data->IsFinite()); + EXPECT_FALSE(data->GetCompleted()); + EXPECT_EQ(data->GetTotal(), Progress::kNonDeterministicTotal); + EXPECT_EQ(data->GetMessage(), "Progress report 3: Starting report 3"); + + // Progress report objects should be destroyed at this point so + // get each report from the queue and check that they've been + // destroyed in reverse order. + ASSERT_TRUE(listener_sp->GetEvent(event_sp, TIMEOUT)); + data = ProgressEventData::GetEventDataFromEvent(event_sp.get()); + + EXPECT_EQ(data->GetTitle(), "Progress report 3"); + EXPECT_TRUE(data->GetCompleted()); + EXPECT_FALSE(data->IsFinite()); + EXPECT_EQ(data->GetMessage(), "Progress report 3: Starting report 3"); + + ASSERT_TRUE(listener_sp->GetEvent(event_sp, TIMEOUT)); + data = ProgressEventData::GetEventDataFromEvent(event_sp.get()); + + EXPECT_EQ(data->GetTitle(), "Progress report 2"); + EXPECT_TRUE(data->GetCompleted()); + EXPECT_FALSE(data->IsFinite()); + EXPECT_EQ(data->GetMessage(), "Progress report 2: Starting report 2"); + + ASSERT_TRUE(listener_sp->GetEvent(event_sp, TIMEOUT)); + data = ProgressEventData::GetEventDataFromEvent(event_sp.get()); + + EXPECT_EQ(data->GetTitle(), "Progress report 1"); + EXPECT_TRUE(data->GetCompleted()); + EXPECT_FALSE(data->IsFinite()); + EXPECT_EQ(data->GetMessage(), "Progress report 1: Starting report 1"); +} + +TEST_F(ProgressReportTest, TestExternalReportNotReceived) { + ListenerSP listener_sp = CreateListenerFor(lldb::eBroadcastBitProgress); + EventSP event_sp; + + // Scope this for RAII on the progress objects. + // Create progress reports and check that their respective events for having + // started and ended are broadcasted. + { + Progress progress1("External Progress report 1", + "Starting external report 1", + /*total=*/std::nullopt, /*debugger=*/nullptr, + /*minimum_report_time=*/std::chrono::seconds(0), + Progress::Origin::eExternal); + } + + ASSERT_FALSE(listener_sp->GetEvent(event_sp, TIMEOUT)); +} diff --git a/lldb/unittests/DataFormatter/FormatterBytecodeTest.cpp b/lldb/unittests/DataFormatter/FormatterBytecodeTest.cpp index 7307db650c16..5e980c3e1913 100644 --- a/lldb/unittests/DataFormatter/FormatterBytecodeTest.cpp +++ b/lldb/unittests/DataFormatter/FormatterBytecodeTest.cpp @@ -98,6 +98,16 @@ TEST_F(FormatterBytecodeTest, ControlOps) { ASSERT_EQ(data.Pop<uint64_t>(), 42u); } { + DataStack data; + ASSERT_TRUE(Interpret({op_lit_uint, 1, op_begin, 3, op_lit_uint, 42, + op_return, op_if, op_lit_uint, 23}, + data)); + ASSERT_EQ(data.Pop<uint64_t>(), 42u); + } +} + +TEST_F(FormatterBytecodeTest, ConversionOps) { + { DataStack data(lldb::ValueObjectSP{}); ASSERT_TRUE(Interpret({op_is_null}, data)); ASSERT_EQ(data.Pop<uint64_t>(), 1u); |
