Author: Andy Yankovsky Date: 2021-08-31T13:36:53+02:00 New Revision: 1f986f60573c6f4355c2d8a5c7ddcb2d32dfd43c
URL: https://github.com/llvm/llvm-project/commit/1f986f60573c6f4355c2d8a5c7ddcb2d32dfd43c DIFF: https://github.com/llvm/llvm-project/commit/1f986f60573c6f4355c2d8a5c7ddcb2d32dfd43c.diff LOG: Revert "[lldb] Add minidump save-core functionality to ELF object files" This reverts commit aafa05e03d629cc6605718c54575256d9d683659. Broke builder on aarch64 -- https://lab.llvm.org/buildbot/#/builders/96/builds/10926 Added: Modified: lldb/include/lldb/Core/PluginManager.h lldb/source/API/SBProcess.cpp lldb/source/Commands/CommandObjectProcess.cpp lldb/source/Commands/Options.td lldb/source/Core/PluginManager.cpp lldb/source/Plugins/ObjectFile/CMakeLists.txt Removed: lldb/source/Plugins/ObjectFile/Minidump/CMakeLists.txt lldb/source/Plugins/ObjectFile/Minidump/MinidumpFileBuilder.cpp lldb/source/Plugins/ObjectFile/Minidump/MinidumpFileBuilder.h lldb/source/Plugins/ObjectFile/Minidump/ObjectFileMinidump.cpp lldb/source/Plugins/ObjectFile/Minidump/ObjectFileMinidump.h lldb/test/API/functionalities/process_save_core_minidump/Makefile lldb/test/API/functionalities/process_save_core_minidump/TestProcessSaveCoreMinidump.py lldb/test/API/functionalities/process_save_core_minidump/main.cpp ################################################################################ diff --git a/lldb/include/lldb/Core/PluginManager.h b/lldb/include/lldb/Core/PluginManager.h index 2bee2edea6360..be91929c62e13 100644 --- a/lldb/include/lldb/Core/PluginManager.h +++ b/lldb/include/lldb/Core/PluginManager.h @@ -192,8 +192,7 @@ class PluginManager { static Status SaveCore(const lldb::ProcessSP &process_sp, const FileSpec &outfile, - lldb::SaveCoreStyle &core_style, - const ConstString plugin_name); + lldb::SaveCoreStyle &core_style); // ObjectContainer static bool diff --git a/lldb/source/API/SBProcess.cpp b/lldb/source/API/SBProcess.cpp index a965814be1b98..47c35a23b0781 100644 --- a/lldb/source/API/SBProcess.cpp +++ b/lldb/source/API/SBProcess.cpp @@ -1228,8 +1228,7 @@ lldb::SBError SBProcess::SaveCore(const char *file_name) { FileSpec core_file(file_name); SaveCoreStyle core_style = SaveCoreStyle::eSaveCoreFull; - error.ref() = - PluginManager::SaveCore(process_sp, core_file, core_style, ConstString()); + error.ref() = PluginManager::SaveCore(process_sp, core_file, core_style); return LLDB_RECORD_RESULT(error); } diff --git a/lldb/source/Commands/CommandObjectProcess.cpp b/lldb/source/Commands/CommandObjectProcess.cpp index b3e2f6a1a02b7..bb6220a53d4e8 100644 --- a/lldb/source/Commands/CommandObjectProcess.cpp +++ b/lldb/source/Commands/CommandObjectProcess.cpp @@ -1180,13 +1180,12 @@ static constexpr OptionEnumValues SaveCoreStyles() { class CommandObjectProcessSaveCore : public CommandObjectParsed { public: CommandObjectProcessSaveCore(CommandInterpreter &interpreter) - : CommandObjectParsed( - interpreter, "process save-core", - "Save the current process as a core file using an " - "appropriate file type.", - "process save-core [-s corefile-style -p plugin-name] FILE", - eCommandRequiresProcess | eCommandTryTargetAPILock | - eCommandProcessMustBeLaunched) {} + : CommandObjectParsed(interpreter, "process save-core", + "Save the current process as a core file using an " + "appropriate file type.", + "process save-core [-s corefile-style] FILE", + eCommandRequiresProcess | eCommandTryTargetAPILock | + eCommandProcessMustBeLaunched) {} ~CommandObjectProcessSaveCore() override = default; @@ -1209,9 +1208,6 @@ class CommandObjectProcessSaveCore : public CommandObjectParsed { Status error; switch (short_option) { - case 'p': - m_requested_plugin_name.SetString(option_arg); - break; case 's': m_requested_save_core_style = (lldb::SaveCoreStyle)OptionArgParser::ToOptionEnum( @@ -1227,12 +1223,10 @@ class CommandObjectProcessSaveCore : public CommandObjectParsed { void OptionParsingStarting(ExecutionContext *execution_context) override { m_requested_save_core_style = eSaveCoreUnspecified; - m_requested_plugin_name.Clear(); } // Instance variables to hold the values for command options. SaveCoreStyle m_requested_save_core_style; - ConstString m_requested_plugin_name; }; protected: @@ -1243,8 +1237,7 @@ class CommandObjectProcessSaveCore : public CommandObjectParsed { FileSpec output_file(command.GetArgumentAtIndex(0)); SaveCoreStyle corefile_style = m_options.m_requested_save_core_style; Status error = - PluginManager::SaveCore(process_sp, output_file, corefile_style, - m_options.m_requested_plugin_name); + PluginManager::SaveCore(process_sp, output_file, corefile_style); if (error.Success()) { if (corefile_style == SaveCoreStyle::eSaveCoreDirtyOnly || corefile_style == SaveCoreStyle::eSaveCoreStackOnly) { diff --git a/lldb/source/Commands/Options.td b/lldb/source/Commands/Options.td index 67cfc60f9d1b5..5cef8f93b6989 100644 --- a/lldb/source/Commands/Options.td +++ b/lldb/source/Commands/Options.td @@ -749,9 +749,6 @@ let Command = "process save_core" in { def process_save_core_style : Option<"style", "s">, Group<1>, EnumArg<"SaveCoreStyle", "SaveCoreStyles()">, Desc<"Request a specific style " "of corefile to be saved.">; - def process_save_core_plugin_name : Option<"plugin-name", "p">, - OptionalArg<"Plugin">, Desc<"Specify a plugin name to create the core file." - "This allows core files to be saved in diff erent formats.">; } let Command = "process trace save" in { diff --git a/lldb/source/Core/PluginManager.cpp b/lldb/source/Core/PluginManager.cpp index f65ec9fae277f..fcaa868b083ed 100644 --- a/lldb/source/Core/PluginManager.cpp +++ b/lldb/source/Core/PluginManager.cpp @@ -685,13 +685,10 @@ PluginManager::GetObjectFileCreateMemoryCallbackForPluginName( Status PluginManager::SaveCore(const lldb::ProcessSP &process_sp, const FileSpec &outfile, - lldb::SaveCoreStyle &core_style, - const ConstString plugin_name) { + lldb::SaveCoreStyle &core_style) { Status error; auto &instances = GetObjectFileInstances().GetInstances(); for (auto &instance : instances) { - if (plugin_name && instance.name != plugin_name) - continue; if (instance.save_core && instance.save_core(process_sp, outfile, core_style, error)) return error; diff --git a/lldb/source/Plugins/ObjectFile/CMakeLists.txt b/lldb/source/Plugins/ObjectFile/CMakeLists.txt index 34ad087173f01..3b2cc6177d313 100644 --- a/lldb/source/Plugins/ObjectFile/CMakeLists.txt +++ b/lldb/source/Plugins/ObjectFile/CMakeLists.txt @@ -1,7 +1,6 @@ add_subdirectory(Breakpad) add_subdirectory(ELF) add_subdirectory(Mach-O) -add_subdirectory(Minidump) add_subdirectory(PDB) add_subdirectory(PECOFF) add_subdirectory(JIT) diff --git a/lldb/source/Plugins/ObjectFile/Minidump/CMakeLists.txt b/lldb/source/Plugins/ObjectFile/Minidump/CMakeLists.txt deleted file mode 100644 index ac5fba200f351..0000000000000 --- a/lldb/source/Plugins/ObjectFile/Minidump/CMakeLists.txt +++ /dev/null @@ -1,14 +0,0 @@ -add_lldb_library(lldbPluginObjectFileMinidump PLUGIN - ObjectFileMinidump.cpp - MinidumpFileBuilder.cpp - - LINK_LIBS - lldbCore - lldbHost - lldbSymbol - lldbTarget - lldbUtility - lldbPluginProcessUtility - LINK_COMPONENTS - Support - ) diff --git a/lldb/source/Plugins/ObjectFile/Minidump/MinidumpFileBuilder.cpp b/lldb/source/Plugins/ObjectFile/Minidump/MinidumpFileBuilder.cpp deleted file mode 100644 index ea3edfa1b09aa..0000000000000 --- a/lldb/source/Plugins/ObjectFile/Minidump/MinidumpFileBuilder.cpp +++ /dev/null @@ -1,767 +0,0 @@ -//===-- MinidumpFileBuilder.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 "MinidumpFileBuilder.h" - -#include "Plugins/Process/minidump/RegisterContextMinidump_x86_64.h" - -#include "lldb/Core/Module.h" -#include "lldb/Core/ModuleList.h" -#include "lldb/Core/Section.h" -#include "lldb/Target/MemoryRegionInfo.h" -#include "lldb/Target/Process.h" -#include "lldb/Target/RegisterContext.h" -#include "lldb/Target/StopInfo.h" -#include "lldb/Target/ThreadList.h" -#include "lldb/Utility/DataExtractor.h" -#include "lldb/Utility/RegisterValue.h" - -#include "llvm/ADT/StringRef.h" -#include "llvm/BinaryFormat/Minidump.h" -#include "llvm/Support/ConvertUTF.h" -#include "llvm/Support/Error.h" - -#include "Plugins/Process/minidump/MinidumpTypes.h" - -using namespace lldb; -using namespace lldb_private; -using namespace llvm::minidump; - -void MinidumpFileBuilder::AddDirectory(StreamType type, size_t stream_size) { - LocationDescriptor loc; - loc.DataSize = static_cast<llvm::support::ulittle32_t>(stream_size); - // Stream will begin at the current end of data section - loc.RVA = static_cast<llvm::support::ulittle32_t>(GetCurrentDataEndOffset()); - - Directory dir; - dir.Type = static_cast<llvm::support::little_t<StreamType>>(type); - dir.Location = loc; - - m_directories.push_back(dir); -} - -Status MinidumpFileBuilder::AddSystemInfo(const llvm::Triple &target_triple) { - Status error; - AddDirectory(StreamType::SystemInfo, sizeof(llvm::minidump::SystemInfo)); - - llvm::minidump::ProcessorArchitecture arch; - switch (target_triple.getArch()) { - case llvm::Triple::ArchType::x86_64: - arch = ProcessorArchitecture::AMD64; - break; - case llvm::Triple::ArchType::x86: - arch = ProcessorArchitecture::X86; - break; - case llvm::Triple::ArchType::arm: - arch = ProcessorArchitecture::ARM; - break; - case llvm::Triple::ArchType::mips64: - case llvm::Triple::ArchType::mips64el: - case llvm::Triple::ArchType::mips: - case llvm::Triple::ArchType::mipsel: - arch = ProcessorArchitecture::MIPS; - break; - case llvm::Triple::ArchType::ppc64: - case llvm::Triple::ArchType::ppc: - case llvm::Triple::ArchType::ppc64le: - arch = ProcessorArchitecture::PPC; - break; - default: - error.SetErrorStringWithFormat("Architecture %s not supported.", - target_triple.getArchName().str().c_str()); - return error; - }; - - llvm::support::little_t<OSPlatform> platform_id; - switch (target_triple.getOS()) { - case llvm::Triple::OSType::Linux: - if (target_triple.getEnvironment() == - llvm::Triple::EnvironmentType::Android) - platform_id = OSPlatform::Android; - else - platform_id = OSPlatform::Linux; - break; - case llvm::Triple::OSType::Win32: - platform_id = OSPlatform::Win32NT; - break; - case llvm::Triple::OSType::MacOSX: - platform_id = OSPlatform::MacOSX; - break; - case llvm::Triple::OSType::IOS: - platform_id = OSPlatform::IOS; - break; - default: - error.SetErrorStringWithFormat("OS %s not supported.", - target_triple.getOSName().str().c_str()); - return error; - }; - - llvm::minidump::SystemInfo sys_info; - sys_info.ProcessorArch = - static_cast<llvm::support::little_t<ProcessorArchitecture>>(arch); - // Global offset to beginning of a csd_string in a data section - sys_info.CSDVersionRVA = static_cast<llvm::support::ulittle32_t>( - GetCurrentDataEndOffset() + sizeof(llvm::minidump::SystemInfo)); - sys_info.PlatformId = platform_id; - m_data.AppendData(&sys_info, sizeof(llvm::minidump::SystemInfo)); - - std::string csd_string = ""; - - error = WriteString(csd_string, &m_data); - if (error.Fail()) { - error.SetErrorString("Unable to convert the csd string to UTF16."); - return error; - } - - return error; -} - -Status WriteString(const std::string &to_write, - lldb_private::DataBufferHeap *buffer) { - Status error; - // let the StringRef eat also null termination char - llvm::StringRef to_write_ref(to_write.c_str(), to_write.size() + 1); - llvm::SmallVector<llvm::UTF16, 128> to_write_utf16; - - bool converted = convertUTF8ToUTF16String(to_write_ref, to_write_utf16); - if (!converted) { - error.SetErrorStringWithFormat( - "Unable to convert the string to UTF16. Failed to convert %s", - to_write.c_str()); - return error; - } - - // size of the UTF16 string should be written without the null termination - // character that is stored in 2 bytes - llvm::support::ulittle32_t to_write_size(to_write_utf16.size_in_bytes() - 2); - - buffer->AppendData(&to_write_size, sizeof(llvm::support::ulittle32_t)); - buffer->AppendData(to_write_utf16.data(), to_write_utf16.size_in_bytes()); - - return error; -} - -llvm::Expected<uint64_t> getModuleFileSize(Target &target, - const ModuleSP &mod) { - SectionSP sect_sp = mod->GetObjectFile()->GetBaseAddress().GetSection(); - uint64_t SizeOfImage = 0; - - if (!sect_sp) { - return llvm::createStringError(std::errc::operation_not_supported, - "Couldn't obtain the section information."); - } - lldb::addr_t sect_addr = sect_sp->GetLoadBaseAddress(&target); - // Use memory size since zero fill sections, like ".bss", will be smaller on - // disk. - lldb::addr_t sect_size = sect_sp->GetByteSize(); - // This will usually be zero, but make sure to calculate the BaseOfImage - // offset. - const lldb::addr_t base_sect_offset = - mod->GetObjectFile()->GetBaseAddress().GetLoadAddress(&target) - - sect_addr; - SizeOfImage = sect_size - base_sect_offset; - lldb::addr_t next_sect_addr = sect_addr + sect_size; - Address sect_so_addr; - target.ResolveLoadAddress(next_sect_addr, sect_so_addr); - lldb::SectionSP next_sect_sp = sect_so_addr.GetSection(); - while (next_sect_sp && - next_sect_sp->GetLoadBaseAddress(&target) == next_sect_addr) { - sect_size = sect_sp->GetByteSize(); - SizeOfImage += sect_size; - next_sect_addr += sect_size; - target.ResolveLoadAddress(next_sect_addr, sect_so_addr); - next_sect_sp = sect_so_addr.GetSection(); - } - - return SizeOfImage; -} - -// ModuleList stream consists of a number of modules, followed by an array -// of llvm::minidump::Module's structures. Every structure informs about a -// single module. Additional data of variable length, such as module's names, -// are stored just after the ModuleList stream. The llvm::minidump::Module -// structures point to this helper data by global offset. -Status MinidumpFileBuilder::AddModuleList(Target &target) { - constexpr size_t minidump_module_size = sizeof(llvm::minidump::Module); - Status error; - - const ModuleList &modules = target.GetImages(); - llvm::support::ulittle32_t modules_count = - static_cast<llvm::support::ulittle32_t>(modules.GetSize()); - - // This helps us with getting the correct global offset in minidump - // file later, when we will be setting up offsets from the - // the llvm::minidump::Module's structures into helper data - size_t size_before = GetCurrentDataEndOffset(); - - // This is the size of the main part of the ModuleList stream. - // It consists of a module number and corresponding number of - // structs describing individual modules - size_t module_stream_size = - sizeof(llvm::support::ulittle32_t) + modules_count * minidump_module_size; - - // Adding directory describing this stream. - AddDirectory(StreamType::ModuleList, module_stream_size); - - m_data.AppendData(&modules_count, sizeof(llvm::support::ulittle32_t)); - - // Temporary storage for the helper data (of variable length) - // as these cannot be dumped to m_data before dumping entire - // array of module structures. - DataBufferHeap helper_data; - - for (size_t i = 0; i < modules_count; ++i) { - ModuleSP mod = modules.GetModuleAtIndex(i); - std::string module_name = mod->GetSpecificationDescription(); - auto maybe_mod_size = getModuleFileSize(target, mod); - if (!maybe_mod_size) { - error.SetErrorStringWithFormat("Unable to get the size of module %s.", - module_name.c_str()); - return error; - } - - uint64_t mod_size = std::move(*maybe_mod_size); - - llvm::support::ulittle32_t signature = - static_cast<llvm::support::ulittle32_t>( - static_cast<uint32_t>(minidump::CvSignature::ElfBuildId)); - auto uuid = mod->GetUUID().GetBytes(); - - VSFixedFileInfo info; - info.Signature = static_cast<llvm::support::ulittle32_t>(0u); - info.StructVersion = static_cast<llvm::support::ulittle32_t>(0u); - info.FileVersionHigh = static_cast<llvm::support::ulittle32_t>(0u); - info.FileVersionLow = static_cast<llvm::support::ulittle32_t>(0u); - info.ProductVersionHigh = static_cast<llvm::support::ulittle32_t>(0u); - info.ProductVersionLow = static_cast<llvm::support::ulittle32_t>(0u); - info.FileFlagsMask = static_cast<llvm::support::ulittle32_t>(0u); - info.FileFlags = static_cast<llvm::support::ulittle32_t>(0u); - info.FileOS = static_cast<llvm::support::ulittle32_t>(0u); - info.FileType = static_cast<llvm::support::ulittle32_t>(0u); - info.FileSubtype = static_cast<llvm::support::ulittle32_t>(0u); - info.FileDateHigh = static_cast<llvm::support::ulittle32_t>(0u); - info.FileDateLow = static_cast<llvm::support::ulittle32_t>(0u); - - LocationDescriptor ld; - ld.DataSize = static_cast<llvm::support::ulittle32_t>(0u); - ld.RVA = static_cast<llvm::support::ulittle32_t>(0u); - - // Setting up LocationDescriptor for uuid string. The global offset into - // minidump file is calculated. - LocationDescriptor ld_cv; - ld_cv.DataSize = static_cast<llvm::support::ulittle32_t>( - sizeof(llvm::support::ulittle32_t) + uuid.size()); - ld_cv.RVA = static_cast<llvm::support::ulittle32_t>( - size_before + module_stream_size + helper_data.GetByteSize()); - - helper_data.AppendData(&signature, sizeof(llvm::support::ulittle32_t)); - helper_data.AppendData(uuid.begin(), uuid.size()); - - llvm::minidump::Module m; - m.BaseOfImage = static_cast<llvm::support::ulittle64_t>( - mod->GetObjectFile()->GetBaseAddress().GetLoadAddress(&target)); - m.SizeOfImage = static_cast<llvm::support::ulittle32_t>(mod_size); - m.Checksum = static_cast<llvm::support::ulittle32_t>(0); - m.TimeDateStamp = static_cast<llvm::support::ulittle32_t>(std::time(0)); - m.ModuleNameRVA = static_cast<llvm::support::ulittle32_t>( - size_before + module_stream_size + helper_data.GetByteSize()); - m.VersionInfo = info; - m.CvRecord = ld_cv; - m.MiscRecord = ld; - - error = WriteString(module_name, &helper_data); - - if (error.Fail()) - return error; - - m_data.AppendData(&m, sizeof(llvm::minidump::Module)); - } - - m_data.AppendData(helper_data.GetBytes(), helper_data.GetByteSize()); - return error; -} - -uint16_t read_register_u16_raw(RegisterContext *reg_ctx, - const std::string ®_name) { - const RegisterInfo *reg_info = reg_ctx->GetRegisterInfoByName(reg_name); - if (!reg_info) - return 0; - lldb_private::RegisterValue reg_value; - bool success = reg_ctx->ReadRegister(reg_info, reg_value); - if (!success) - return 0; - return reg_value.GetAsUInt16(); -} - -uint32_t read_register_u32_raw(RegisterContext *reg_ctx, - const std::string ®_name) { - const RegisterInfo *reg_info = reg_ctx->GetRegisterInfoByName(reg_name); - if (!reg_info) - return 0; - lldb_private::RegisterValue reg_value; - bool success = reg_ctx->ReadRegister(reg_info, reg_value); - if (!success) - return 0; - return reg_value.GetAsUInt32(); -} - -uint64_t read_register_u64_raw(RegisterContext *reg_ctx, - const std::string ®_name) { - const RegisterInfo *reg_info = reg_ctx->GetRegisterInfoByName(reg_name); - if (!reg_info) - return 0; - lldb_private::RegisterValue reg_value; - bool success = reg_ctx->ReadRegister(reg_info, reg_value); - if (!success) - return 0; - return reg_value.GetAsUInt64(); -} - -llvm::support::ulittle16_t read_register_u16(RegisterContext *reg_ctx, - const std::string ®_name) { - return static_cast<llvm::support::ulittle16_t>( - read_register_u16_raw(reg_ctx, reg_name)); -} - -llvm::support::ulittle32_t read_register_u32(RegisterContext *reg_ctx, - const std::string ®_name) { - return static_cast<llvm::support::ulittle32_t>( - read_register_u32_raw(reg_ctx, reg_name)); -} - -llvm::support::ulittle64_t read_register_u64(RegisterContext *reg_ctx, - const std::string ®_name) { - return static_cast<llvm::support::ulittle64_t>( - read_register_u64_raw(reg_ctx, reg_name)); -} - -lldb_private::minidump::MinidumpContext_x86_64 -GetThreadContext_64(RegisterContext *reg_ctx) { - lldb_private::minidump::MinidumpContext_x86_64 thread_context; - thread_context.context_flags = static_cast<uint32_t>( - lldb_private::minidump::MinidumpContext_x86_64_Flags::x86_64_Flag | - lldb_private::minidump::MinidumpContext_x86_64_Flags::Control | - lldb_private::minidump::MinidumpContext_x86_64_Flags::Segments | - lldb_private::minidump::MinidumpContext_x86_64_Flags::Integer); - thread_context.rax = read_register_u64(reg_ctx, "rax"); - thread_context.rbx = read_register_u64(reg_ctx, "rbx"); - thread_context.rcx = read_register_u64(reg_ctx, "rcx"); - thread_context.rdx = read_register_u64(reg_ctx, "rdx"); - thread_context.rdi = read_register_u64(reg_ctx, "rdi"); - thread_context.rsi = read_register_u64(reg_ctx, "rsi"); - thread_context.rbp = read_register_u64(reg_ctx, "rbp"); - thread_context.rsp = read_register_u64(reg_ctx, "rsp"); - thread_context.r8 = read_register_u64(reg_ctx, "r8"); - thread_context.r9 = read_register_u64(reg_ctx, "r9"); - thread_context.r10 = read_register_u64(reg_ctx, "r10"); - thread_context.r11 = read_register_u64(reg_ctx, "r11"); - thread_context.r12 = read_register_u64(reg_ctx, "r12"); - thread_context.r13 = read_register_u64(reg_ctx, "r13"); - thread_context.r14 = read_register_u64(reg_ctx, "r14"); - thread_context.r15 = read_register_u64(reg_ctx, "r15"); - thread_context.rip = read_register_u64(reg_ctx, "rip"); - thread_context.eflags = read_register_u32(reg_ctx, "rflags"); - thread_context.cs = read_register_u16(reg_ctx, "cs"); - thread_context.fs = read_register_u16(reg_ctx, "fs"); - thread_context.gs = read_register_u16(reg_ctx, "gs"); - thread_context.ss = read_register_u16(reg_ctx, "ss"); - thread_context.ds = read_register_u16(reg_ctx, "ds"); - return thread_context; -} - -// Function returns start and size of the memory region that contains -// memory location pointed to by the current stack pointer. -llvm::Expected<std::pair<addr_t, addr_t>> -findStackHelper(const lldb::ProcessSP &process_sp, uint64_t rsp) { - MemoryRegionInfo range_info; - Status error = process_sp->GetMemoryRegionInfo(rsp, range_info); - // Skip failed memory region requests or any regions with no permissions. - if (error.Fail() || range_info.GetLLDBPermissions() == 0) - return llvm::createStringError( - std::errc::not_supported, - "unable to load stack segment of the process"); - - const addr_t addr = range_info.GetRange().GetRangeBase(); - const addr_t size = range_info.GetRange().GetByteSize(); - - if (size == 0) - return llvm::createStringError(std::errc::not_supported, - "stack segment of the process is empty"); - - return std::make_pair(addr, size); -} - -Status MinidumpFileBuilder::AddThreadList(const lldb::ProcessSP &process_sp) { - constexpr size_t minidump_thread_size = sizeof(llvm::minidump::Thread); - lldb_private::ThreadList thread_list = process_sp->GetThreadList(); - - // size of the entire thread stream consists of: - // number of threads and threads array - size_t thread_stream_size = sizeof(llvm::support::ulittle32_t) + - thread_list.GetSize() * minidump_thread_size; - // save for the ability to set up RVA - size_t size_before = GetCurrentDataEndOffset(); - - AddDirectory(StreamType::ThreadList, thread_stream_size); - - llvm::support::ulittle32_t thread_count = - static_cast<llvm::support::ulittle32_t>(thread_list.GetSize()); - m_data.AppendData(&thread_count, sizeof(llvm::support::ulittle32_t)); - - DataBufferHeap helper_data; - - const uint32_t num_threads = thread_list.GetSize(); - - for (uint32_t thread_idx = 0; thread_idx < num_threads; ++thread_idx) { - ThreadSP thread_sp(thread_list.GetThreadAtIndex(thread_idx)); - RegisterContextSP reg_ctx_sp(thread_sp->GetRegisterContext()); - Status error; - - if (!reg_ctx_sp) { - error.SetErrorString("Unable to get the register context."); - return error; - } - RegisterContext *reg_ctx = reg_ctx_sp.get(); - auto thread_context = GetThreadContext_64(reg_ctx); - uint64_t rsp = read_register_u64_raw(reg_ctx, "rsp"); - auto expected_address_range = findStackHelper(process_sp, rsp); - - if (!expected_address_range) { - error.SetErrorString("Unable to get the stack address."); - return error; - } - - std::pair<uint64_t, uint64_t> range = std::move(*expected_address_range); - uint64_t addr = range.first; - uint64_t size = range.second; - - auto data_up = std::make_unique<DataBufferHeap>(size, 0); - const size_t stack_bytes_read = - process_sp->ReadMemory(addr, data_up->GetBytes(), size, error); - - if (error.Fail()) - return error; - - LocationDescriptor stack_memory; - stack_memory.DataSize = - static_cast<llvm::support::ulittle32_t>(stack_bytes_read); - stack_memory.RVA = static_cast<llvm::support::ulittle32_t>( - size_before + thread_stream_size + helper_data.GetByteSize()); - - MemoryDescriptor stack; - stack.StartOfMemoryRange = static_cast<llvm::support::ulittle64_t>(addr); - stack.Memory = stack_memory; - - helper_data.AppendData(data_up->GetBytes(), size); - - LocationDescriptor thread_context_memory_locator; - thread_context_memory_locator.DataSize = - static_cast<llvm::support::ulittle32_t>(sizeof(thread_context)); - thread_context_memory_locator.RVA = static_cast<llvm::support::ulittle32_t>( - size_before + thread_stream_size + helper_data.GetByteSize()); - - helper_data.AppendData( - &thread_context, - sizeof(lldb_private::minidump::MinidumpContext_x86_64)); - - llvm::minidump::Thread t; - t.ThreadId = static_cast<llvm::support::ulittle32_t>(thread_sp->GetID()); - t.SuspendCount = static_cast<llvm::support::ulittle32_t>( - (thread_sp->GetState() == StateType::eStateSuspended) ? 1 : 0); - t.PriorityClass = static_cast<llvm::support::ulittle32_t>(0); - t.Priority = static_cast<llvm::support::ulittle32_t>(0); - t.EnvironmentBlock = static_cast<llvm::support::ulittle64_t>(0); - t.Stack = stack, t.Context = thread_context_memory_locator; - - m_data.AppendData(&t, sizeof(llvm::minidump::Thread)); - } - - m_data.AppendData(helper_data.GetBytes(), helper_data.GetByteSize()); - return Status(); -} - -Status MinidumpFileBuilder::AddException(const lldb::ProcessSP &process_sp) { - Status error; - lldb_private::ThreadList thread_list = process_sp->GetThreadList(); - - const uint32_t num_threads = thread_list.GetSize(); - uint32_t stop_reason_thread_idx = 0; - for (stop_reason_thread_idx = 0; stop_reason_thread_idx < num_threads; - ++stop_reason_thread_idx) { - ThreadSP thread_sp(thread_list.GetThreadAtIndex(stop_reason_thread_idx)); - StopInfoSP stop_info_sp = thread_sp->GetStopInfo(); - - if (stop_info_sp && stop_info_sp->IsValid()) - break; - } - - if (stop_reason_thread_idx == num_threads) { - error.SetErrorString("No stop reason thread found."); - return error; - } - - constexpr size_t minidump_exception_size = - sizeof(llvm::minidump::ExceptionStream); - AddDirectory(StreamType::Exception, minidump_exception_size); - size_t size_before = GetCurrentDataEndOffset(); - - ThreadSP thread_sp(thread_list.GetThreadAtIndex(stop_reason_thread_idx)); - RegisterContextSP reg_ctx_sp(thread_sp->GetRegisterContext()); - RegisterContext *reg_ctx = reg_ctx_sp.get(); - auto thread_context = GetThreadContext_64(reg_ctx); - StopInfoSP stop_info_sp = thread_sp->GetStopInfo(); - - DataBufferHeap helper_data; - - LocationDescriptor thread_context_memory_locator; - thread_context_memory_locator.DataSize = - static_cast<llvm::support::ulittle32_t>(sizeof(thread_context)); - thread_context_memory_locator.RVA = static_cast<llvm::support::ulittle32_t>( - size_before + minidump_exception_size + helper_data.GetByteSize()); - - helper_data.AppendData( - &thread_context, sizeof(lldb_private::minidump::MinidumpContext_x86_64)); - - Exception exp_record; - exp_record.ExceptionCode = - static_cast<llvm::support::ulittle32_t>(stop_info_sp->GetValue()); - exp_record.ExceptionFlags = static_cast<llvm::support::ulittle32_t>(0); - exp_record.ExceptionRecord = static_cast<llvm::support::ulittle64_t>(0); - exp_record.ExceptionAddress = read_register_u64(reg_ctx, "rip"); - exp_record.NumberParameters = static_cast<llvm::support::ulittle32_t>(0); - exp_record.UnusedAlignment = static_cast<llvm::support::ulittle32_t>(0); - // exp_record.ExceptionInformation; - - ExceptionStream exp_stream; - exp_stream.ThreadId = - static_cast<llvm::support::ulittle32_t>(thread_sp->GetID()); - exp_stream.UnusedAlignment = static_cast<llvm::support::ulittle32_t>(0); - exp_stream.ExceptionRecord = exp_record; - exp_stream.ThreadContext = thread_context_memory_locator; - - m_data.AppendData(&exp_stream, minidump_exception_size); - m_data.AppendData(helper_data.GetBytes(), helper_data.GetByteSize()); - return error; -} - -lldb_private::Status -MinidumpFileBuilder::AddMemoryList(const lldb::ProcessSP &process_sp) { - Status error; - - if (error.Fail()) { - error.SetErrorString("Process doesn't support getting memory region info."); - return error; - } - - // Get interesting addresses - std::vector<size_t> interesting_addresses; - auto thread_list = process_sp->GetThreadList(); - for (size_t i = 0; i < thread_list.GetSize(); ++i) { - ThreadSP thread_sp(thread_list.GetThreadAtIndex(i)); - RegisterContextSP reg_ctx_sp(thread_sp->GetRegisterContext()); - RegisterContext *reg_ctx = reg_ctx_sp.get(); - - interesting_addresses.push_back(read_register_u64(reg_ctx, "rsp")); - interesting_addresses.push_back(read_register_u64(reg_ctx, "rip")); - } - - DataBufferHeap helper_data; - std::vector<MemoryDescriptor> mem_descriptors; - - std::set<addr_t> visited_region_base_addresses; - for (size_t interesting_address : interesting_addresses) { - MemoryRegionInfo range_info; - error = process_sp->GetMemoryRegionInfo(interesting_address, range_info); - // Skip failed memory region requests or any regions with no permissions. - if (error.Fail() || range_info.GetLLDBPermissions() == 0) - continue; - const addr_t addr = range_info.GetRange().GetRangeBase(); - // Skip any regions we have already saved out. - if (visited_region_base_addresses.insert(addr).second == false) - continue; - const addr_t size = range_info.GetRange().GetByteSize(); - if (size == 0) - continue; - auto data_up = std::make_unique<DataBufferHeap>(size, 0); - const size_t bytes_read = - process_sp->ReadMemory(addr, data_up->GetBytes(), size, error); - if (bytes_read == 0) - continue; - // We have a good memory region with valid bytes to store. - LocationDescriptor memory_dump; - memory_dump.DataSize = static_cast<llvm::support::ulittle32_t>(size); - memory_dump.RVA = - static_cast<llvm::support::ulittle32_t>(GetCurrentDataEndOffset()); - MemoryDescriptor memory_desc; - memory_desc.StartOfMemoryRange = - static_cast<llvm::support::ulittle64_t>(addr); - memory_desc.Memory = memory_dump; - mem_descriptors.push_back(memory_desc); - m_data.AppendData(data_up->GetBytes(), bytes_read); - } - - AddDirectory(StreamType::MemoryList, - sizeof(llvm::support::ulittle32_t) + - mem_descriptors.size() * - sizeof(llvm::minidump::MemoryDescriptor)); - llvm::support::ulittle32_t memory_ranges_num(mem_descriptors.size()); - - m_data.AppendData(&memory_ranges_num, sizeof(llvm::support::ulittle32_t)); - for (auto memory_descriptor : mem_descriptors) { - m_data.AppendData(&memory_descriptor, - sizeof(llvm::minidump::MemoryDescriptor)); - } - - return error; -} - -void MinidumpFileBuilder::AddMiscInfo(const lldb::ProcessSP &process_sp) { - AddDirectory(StreamType::MiscInfo, - sizeof(lldb_private::minidump::MinidumpMiscInfo)); - - lldb_private::minidump::MinidumpMiscInfo misc_info; - misc_info.size = static_cast<llvm::support::ulittle32_t>( - sizeof(lldb_private::minidump::MinidumpMiscInfo)); - // Default set flags1 to 0, in case that we will not be able to - // get any information - misc_info.flags1 = static_cast<llvm::support::ulittle32_t>(0); - - lldb_private::ProcessInstanceInfo process_info; - process_sp->GetProcessInfo(process_info); - if (process_info.ProcessIDIsValid()) { - // Set flags1 to reflect that PID is filled in - misc_info.flags1 = - static_cast<llvm::support::ulittle32_t>(static_cast<uint32_t>( - lldb_private::minidump::MinidumpMiscInfoFlags::ProcessID)); - misc_info.process_id = - static_cast<llvm::support::ulittle32_t>(process_info.GetProcessID()); - } - - m_data.AppendData(&misc_info, - sizeof(lldb_private::minidump::MinidumpMiscInfo)); -} - -std::unique_ptr<llvm::MemoryBuffer> -getFileStreamHelper(const std::string &path) { - auto maybe_stream = llvm::MemoryBuffer::getFileAsStream(path); - if (!maybe_stream) - return nullptr; - return std::move(maybe_stream.get()); -} - -void MinidumpFileBuilder::AddLinuxFileStreams( - const lldb::ProcessSP &process_sp) { - std::vector<std::pair<StreamType, std::string>> files_with_stream_types = { - {StreamType::LinuxCPUInfo, "/proc/cpuinfo"}, - {StreamType::LinuxLSBRelease, "/etc/lsb-release"}, - }; - - lldb_private::ProcessInstanceInfo process_info; - process_sp->GetProcessInfo(process_info); - if (process_info.ProcessIDIsValid()) { - lldb::pid_t pid = process_info.GetProcessID(); - std::string pid_str = std::to_string(pid); - files_with_stream_types.push_back( - {StreamType::LinuxProcStatus, "/proc/" + pid_str + "/status"}); - files_with_stream_types.push_back( - {StreamType::LinuxCMDLine, "/proc/" + pid_str + "/cmdline"}); - files_with_stream_types.push_back( - {StreamType::LinuxEnviron, "/proc/" + pid_str + "/environ"}); - files_with_stream_types.push_back( - {StreamType::LinuxAuxv, "/proc/" + pid_str + "/auxv"}); - files_with_stream_types.push_back( - {StreamType::LinuxMaps, "/proc/" + pid_str + "/maps"}); - files_with_stream_types.push_back( - {StreamType::LinuxProcStat, "/proc/" + pid_str + "/stat"}); - files_with_stream_types.push_back( - {StreamType::LinuxProcFD, "/proc/" + pid_str + "/fd"}); - } - - for (const auto &entry : files_with_stream_types) { - StreamType stream = entry.first; - std::string path = entry.second; - auto memory_buffer = getFileStreamHelper(path); - - if (memory_buffer) { - size_t size = memory_buffer->getBufferSize(); - if (size == 0) - continue; - AddDirectory(stream, size); - m_data.AppendData(memory_buffer->getBufferStart(), size); - } - } -} - -Status MinidumpFileBuilder::Dump(lldb::FileUP &core_file) const { - constexpr size_t header_size = sizeof(llvm::minidump::Header); - constexpr size_t directory_size = sizeof(llvm::minidump::Directory); - - // write header - llvm::minidump::Header header; - header.Signature = static_cast<llvm::support::ulittle32_t>( - llvm::minidump::Header::MagicSignature); - header.Version = static_cast<llvm::support::ulittle32_t>( - llvm::minidump::Header::MagicVersion); - header.NumberOfStreams = - static_cast<llvm::support::ulittle32_t>(GetDirectoriesNum()); - header.StreamDirectoryRVA = - static_cast<llvm::support::ulittle32_t>(GetCurrentDataEndOffset()); - header.Checksum = static_cast<llvm::support::ulittle32_t>( - 0u), // not used in most of the writers - header.TimeDateStamp = - static_cast<llvm::support::ulittle32_t>(std::time(0)); - header.Flags = - static_cast<llvm::support::ulittle64_t>(0u); // minidump normal flag - - Status error; - size_t bytes_written; - - bytes_written = header_size; - error = core_file->Write(&header, bytes_written); - if (error.Fail() || bytes_written != header_size) { - if (bytes_written != header_size) - error.SetErrorStringWithFormat( - "Unable to write the header. (written %ld/%ld).", bytes_written, - header_size); - return error; - } - - // write data - bytes_written = m_data.GetByteSize(); - error = core_file->Write(m_data.GetBytes(), bytes_written); - if (error.Fail() || bytes_written != m_data.GetByteSize()) { - if (bytes_written != m_data.GetByteSize()) - error.SetErrorStringWithFormat( - "Unable to write the data. (written %ld/%ld).", bytes_written, - m_data.GetByteSize()); - return error; - } - - // write directories - for (const Directory &dir : m_directories) { - bytes_written = directory_size; - error = core_file->Write(&dir, bytes_written); - if (error.Fail() || bytes_written != directory_size) { - if (bytes_written != directory_size) - error.SetErrorStringWithFormat( - "Unable to write the directory. (written %ld/%ld).", bytes_written, - directory_size); - return error; - } - } - - return error; -} - -size_t MinidumpFileBuilder::GetDirectoriesNum() const { - return m_directories.size(); -} - -size_t MinidumpFileBuilder::GetCurrentDataEndOffset() const { - return sizeof(llvm::minidump::Header) + m_data.GetByteSize(); -} \ No newline at end of file diff --git a/lldb/source/Plugins/ObjectFile/Minidump/MinidumpFileBuilder.h b/lldb/source/Plugins/ObjectFile/Minidump/MinidumpFileBuilder.h deleted file mode 100644 index 1d67505d736ec..0000000000000 --- a/lldb/source/Plugins/ObjectFile/Minidump/MinidumpFileBuilder.h +++ /dev/null @@ -1,92 +0,0 @@ -//===-- MinidumpFileBuilder.h ---------------------------------------------===// -// -// 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 -// -//===----------------------------------------------------------------------===// -// -/// \file -/// Structure holding data neccessary for minidump file creation. -/// -/// The class MinidumpFileWriter is used to hold the data that will eventually -/// be dumped to the file. -//===----------------------------------------------------------------------===// - -#ifndef LLDB_SOURCE_PLUGINS_OBJECTFILE_MINIDUMP_MINIDUMPFILEBUILDER_H -#define LLDB_SOURCE_PLUGINS_OBJECTFILE_MINIDUMP_MINIDUMPFILEBUILDER_H - -#include <cstddef> - -#include "lldb/Target/Target.h" -#include "lldb/Utility/DataBufferHeap.h" -#include "lldb/Utility/Status.h" - -#include "llvm/Object/Minidump.h" - -// Write std::string to minidump in the UTF16 format(with null termination char) -// with the size(without null termination char) preceding the UTF16 string. -// Empty strings are also printed with zero length and just null termination -// char. -lldb_private::Status WriteString(const std::string &to_write, - lldb_private::DataBufferHeap *buffer); - -/// \class MinidumpFileBuilder -/// Minidump writer for Linux -/// -/// This class provides a Minidump writer that is able to -/// snapshot the current process state. For the whole time, it stores all -/// the data on heap. -class MinidumpFileBuilder { -public: - MinidumpFileBuilder() = default; - - MinidumpFileBuilder(const MinidumpFileBuilder &) = delete; - MinidumpFileBuilder &operator=(const MinidumpFileBuilder &) = delete; - - MinidumpFileBuilder(MinidumpFileBuilder &&other) = default; - MinidumpFileBuilder &operator=(MinidumpFileBuilder &&other) = default; - - ~MinidumpFileBuilder() = default; - - // Add SystemInfo stream, used for storing the most basic information - // about the system, platform etc... - lldb_private::Status AddSystemInfo(const llvm::Triple &target_triple); - // Add ModuleList stream, containing information about all loaded modules - // at the time of saving minidump. - lldb_private::Status AddModuleList(lldb_private::Target &target); - // Add ThreadList stream, containing information about all threads running - // at the moment of core saving. Contains information about thread - // contexts. - lldb_private::Status AddThreadList(const lldb::ProcessSP &process_sp); - // Add Exception stream, this contains information about the exception - // that stopped the process. In case no thread made exception it return - // failed status. - lldb_private::Status AddException(const lldb::ProcessSP &process_sp); - // Add MemoryList stream, containing dumps of important memory segments - lldb_private::Status AddMemoryList(const lldb::ProcessSP &process_sp); - // Add MiscInfo stream, mainly providing ProcessId - void AddMiscInfo(const lldb::ProcessSP &process_sp); - // Add informative files about a Linux process - void AddLinuxFileStreams(const lldb::ProcessSP &process_sp); - // Dump the prepared data into file. In case of the failure data are - // intact. - lldb_private::Status Dump(lldb::FileUP &core_file) const; - // Returns the current number of directories(streams) that have been so far - // created. This number of directories will be dumped when calling Dump() - size_t GetDirectoriesNum() const; - -private: - // Add directory of StreamType pointing to the current end of the prepared - // file with the specified size. - void AddDirectory(llvm::minidump::StreamType type, size_t stream_size); - size_t GetCurrentDataEndOffset() const; - - // Stores directories to later put them at the end of minidump file - std::vector<llvm::minidump::Directory> m_directories; - // Main data buffer consisting of data without the minidump header and - // directories - lldb_private::DataBufferHeap m_data; -}; - -#endif // LLDB_SOURCE_PLUGINS_OBJECTFILE_MINIDUMP_MINIDUMPFILEBUILDER_H \ No newline at end of file diff --git a/lldb/source/Plugins/ObjectFile/Minidump/ObjectFileMinidump.cpp b/lldb/source/Plugins/ObjectFile/Minidump/ObjectFileMinidump.cpp deleted file mode 100644 index 22b5ae0fa2576..0000000000000 --- a/lldb/source/Plugins/ObjectFile/Minidump/ObjectFileMinidump.cpp +++ /dev/null @@ -1,119 +0,0 @@ -//===-- ObjectFileMinidump.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 "ObjectFileMinidump.h" - -#include "MinidumpFileBuilder.h" - -#include "lldb/Core/ModuleSpec.h" -#include "lldb/Core/PluginManager.h" -#include "lldb/Core/Section.h" -#include "lldb/Target/Process.h" - -#include "llvm/Support/FileSystem.h" - -using namespace lldb; -using namespace lldb_private; - -LLDB_PLUGIN_DEFINE(ObjectFileMinidump) - -void ObjectFileMinidump::Initialize() { - PluginManager::RegisterPlugin( - GetPluginNameStatic(), GetPluginDescriptionStatic(), CreateInstance, - CreateMemoryInstance, GetModuleSpecifications, SaveCore); -} - -void ObjectFileMinidump::Terminate() { - PluginManager::UnregisterPlugin(CreateInstance); -} - -ConstString ObjectFileMinidump::GetPluginNameStatic() { - static ConstString g_name("minidump"); - return g_name; -} - -ObjectFile *ObjectFileMinidump::CreateInstance( - const lldb::ModuleSP &module_sp, lldb::DataBufferSP &data_sp, - lldb::offset_t data_offset, const lldb_private::FileSpec *file, - lldb::offset_t offset, lldb::offset_t length) { - return nullptr; -} - -ObjectFile *ObjectFileMinidump::CreateMemoryInstance( - const lldb::ModuleSP &module_sp, DataBufferSP &data_sp, - const ProcessSP &process_sp, lldb::addr_t header_addr) { - return nullptr; -} - -size_t ObjectFileMinidump::GetModuleSpecifications( - const lldb_private::FileSpec &file, lldb::DataBufferSP &data_sp, - lldb::offset_t data_offset, lldb::offset_t file_offset, - lldb::offset_t length, lldb_private::ModuleSpecList &specs) { - specs.Clear(); - return 0; -} - -bool ObjectFileMinidump::SaveCore(const lldb::ProcessSP &process_sp, - const lldb_private::FileSpec &outfile, - lldb::SaveCoreStyle &core_style, - lldb_private::Status &error) { - if (core_style != SaveCoreStyle::eSaveCoreStackOnly) { - error.SetErrorString("Only stack minidumps supported yet."); - return false; - } - - if (!process_sp) - return false; - - MinidumpFileBuilder builder; - - Target &target = process_sp->GetTarget(); - - error = builder.AddSystemInfo(target.GetArchitecture().GetTriple()); - if (error.Fail()) - return false; - - error = builder.AddModuleList(target); - if (error.Fail()) - return false; - - builder.AddMiscInfo(process_sp); - - if (target.GetArchitecture().GetMachine() == llvm::Triple::ArchType::x86_64) { - error = builder.AddThreadList(process_sp); - if (error.Fail()) - return false; - - error = builder.AddException(process_sp); - if (error.Fail()) - return false; - - error = builder.AddMemoryList(process_sp); - if (error.Fail()) - return false; - } - - if (target.GetArchitecture().GetTriple().getOS() == - llvm::Triple::OSType::Linux) { - builder.AddLinuxFileStreams(process_sp); - } - - llvm::Expected<lldb::FileUP> maybe_core_file = FileSystem::Instance().Open( - outfile, File::eOpenOptionWriteOnly | File::eOpenOptionCanCreate); - if (!maybe_core_file) { - error = maybe_core_file.takeError(); - return false; - } - lldb::FileUP core_file = std::move(maybe_core_file.get()); - - error = builder.Dump(core_file); - if (error.Fail()) - return false; - - return true; -} diff --git a/lldb/source/Plugins/ObjectFile/Minidump/ObjectFileMinidump.h b/lldb/source/Plugins/ObjectFile/Minidump/ObjectFileMinidump.h deleted file mode 100644 index d48600e0c6586..0000000000000 --- a/lldb/source/Plugins/ObjectFile/Minidump/ObjectFileMinidump.h +++ /dev/null @@ -1,70 +0,0 @@ -//===-- ObjectFileMinidump.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 -// -//===----------------------------------------------------------------------===// -// -/// \file -/// Placeholder plugin for the save core functionality. -/// -/// ObjectFileMinidump is created only to be able to save minidump core files -/// from existing processes with the ObjectFileMinidump::SaveCore function. -/// Minidump files are not ObjectFile objects, but they are core files and -/// currently LLDB's ObjectFile plug-ins handle emitting core files. If the -/// core file saving ever moves into a new plug-in type within LLDB, this code -/// should move as well, but for now this is the best place architecturally. -//===----------------------------------------------------------------------===// - -#ifndef LLDB_SOURCE_PLUGINS_OBJECTFILE_MINIDUMP_OBJECTFILEMINIDUMP_H -#define LLDB_SOURCE_PLUGINS_OBJECTFILE_MINIDUMP_OBJECTFILEMINIDUMP_H - -#include "lldb/Symbol/ObjectFile.h" -#include "lldb/Utility/ArchSpec.h" - -class ObjectFileMinidump : public lldb_private::PluginInterface { -public: - // Static Functions - static void Initialize(); - static void Terminate(); - - static lldb_private::ConstString GetPluginNameStatic(); - static const char *GetPluginDescriptionStatic() { - return "Minidump object file."; - } - - // PluginInterface protocol - lldb_private::ConstString GetPluginName() override { - return GetPluginNameStatic(); - } - - static lldb_private::ObjectFile * - CreateInstance(const lldb::ModuleSP &module_sp, lldb::DataBufferSP &data_sp, - lldb::offset_t data_offset, const lldb_private::FileSpec *file, - lldb::offset_t offset, lldb::offset_t length); - - static lldb_private::ObjectFile *CreateMemoryInstance( - const lldb::ModuleSP &module_sp, lldb::DataBufferSP &data_sp, - const lldb::ProcessSP &process_sp, lldb::addr_t header_addr); - - static size_t GetModuleSpecifications(const lldb_private::FileSpec &file, - lldb::DataBufferSP &data_sp, - lldb::offset_t data_offset, - lldb::offset_t file_offset, - lldb::offset_t length, - lldb_private::ModuleSpecList &specs); - - uint32_t GetPluginVersion() override { return 1; } - - // Saves dump in Minidump file format - static bool SaveCore(const lldb::ProcessSP &process_sp, - const lldb_private::FileSpec &outfile, - lldb::SaveCoreStyle &core_style, - lldb_private::Status &error); - -private: - ObjectFileMinidump() = default; -}; - -#endif // LLDB_SOURCE_PLUGINS_OBJECTFILE_MINIDUMP_OBJECTFILEMINIDUMP_H \ No newline at end of file diff --git a/lldb/test/API/functionalities/process_save_core_minidump/Makefile b/lldb/test/API/functionalities/process_save_core_minidump/Makefile deleted file mode 100644 index 2d177981fdde1..0000000000000 --- a/lldb/test/API/functionalities/process_save_core_minidump/Makefile +++ /dev/null @@ -1,6 +0,0 @@ -CXX_SOURCES := main.cpp - -CFLAGS_EXTRAS := -lpthread - -include Makefile.rules - diff --git a/lldb/test/API/functionalities/process_save_core_minidump/TestProcessSaveCoreMinidump.py b/lldb/test/API/functionalities/process_save_core_minidump/TestProcessSaveCoreMinidump.py deleted file mode 100644 index 43a28d20f2d3d..0000000000000 --- a/lldb/test/API/functionalities/process_save_core_minidump/TestProcessSaveCoreMinidump.py +++ /dev/null @@ -1,78 +0,0 @@ -""" -Test saving a mini dump. -""" - - -import os -import lldb -from lldbsuite.test.decorators import * -from lldbsuite.test.lldbtest import * -from lldbsuite.test import lldbutil - - -class ProcessSaveCoreMinidumpTestCase(TestBase): - - mydir = TestBase.compute_mydir(__file__) - - @skipUnlessPlatform(['linux']) - def test_save_linux_mini_dump(self): - """Test that we can save a Linux mini dump.""" - self.build() - exe = self.getBuildArtifact("a.out") - core = self.getBuildArtifact("core.dmp") - try: - target = self.dbg.CreateTarget(exe) - process = target.LaunchSimple( - None, None, self.get_process_working_directory()) - self.assertEqual(process.GetState(), lldb.eStateStopped) - - # get neccessary data for the verification phase - process_info = process.GetProcessInfo() - expected_pid = process_info.GetProcessID() if process_info.IsValid() else -1 - expected_number_of_modules = target.GetNumModules() - expected_modules = target.modules - expected_number_of_threads = process.GetNumThreads() - expected_threads = [] - - for thread_idx in range(process.GetNumThreads()): - thread = process.GetThreadAtIndex(thread_idx) - thread_id = thread.GetThreadID() - expected_threads.append(thread_id) - - # save core and, kill process and verify corefile existence - self.runCmd("process save-core --plugin-name=minidump --style=stack " + core) - self.assertTrue(os.path.isfile(core)) - self.assertTrue(process.Kill().Success()) - - # To verify, we'll launch with the mini dump - target = self.dbg.CreateTarget(None) - process = target.LoadCore(core) - - # check if the core is in desired state - self.assertTrue(process, PROCESS_IS_VALID) - self.assertTrue(process.GetProcessInfo().IsValid()) - self.assertEqual(process.GetProcessInfo().GetProcessID(), expected_pid) - self.assertTrue(target.GetTriple().find("linux") != -1) - self.assertTrue(target.GetNumModules(), expected_number_of_modules) - self.assertEqual(process.GetNumThreads(), expected_number_of_threads) - - for module, expected in zip(target.modules, expected_modules): - self.assertTrue(module.IsValid()) - module_file_name = module.GetFileSpec().GetFilename() - expected_file_name = expected.GetFileSpec().GetFilename() - # skip kernel virtual dynamic shared objects - if "vdso" in expected_file_name: - continue - self.assertEqual(module_file_name, expected_file_name) - self.assertEqual(module.GetUUIDString(), expected.GetUUIDString()) - - for thread_idx in range(process.GetNumThreads()): - thread = process.GetThreadAtIndex(thread_idx) - self.assertTrue(thread.IsValid()) - thread_id = thread.GetThreadID() - self.assertTrue(thread_id in expected_threads) - finally: - # Clean up the mini dump file. - self.assertTrue(self.dbg.DeleteTarget(target)) - if (os.path.isfile(core)): - os.unlink(core) diff --git a/lldb/test/API/functionalities/process_save_core_minidump/main.cpp b/lldb/test/API/functionalities/process_save_core_minidump/main.cpp deleted file mode 100644 index 49b471a4cc517..0000000000000 --- a/lldb/test/API/functionalities/process_save_core_minidump/main.cpp +++ /dev/null @@ -1,30 +0,0 @@ -#include <cassert> -#include <iostream> -#include <thread> - -using namespace std; - -void g() { assert(false); } - -void f() { g(); } - -size_t h() { - size_t sum = 0; - for (size_t i = 0; i < 1000000; ++i) - for (size_t j = 0; j < 1000000; ++j) - if ((i * j) % 2 == 0) { - sum += 1; - } - return sum; -} - -int main() { - thread t1(f); - - size_t x = h(); - - t1.join(); - - cout << "X is " << x << "\n"; - return 0; -} \ No newline at end of file _______________________________________________ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits