Files
clang-p2996/lldb/source/Plugins/ObjectFile/Minidump/ObjectFileMinidump.cpp
Andrej Korman aafa05e03d [lldb] Add minidump save-core functionality to ELF object files
This change adds save-core functionality into the ObjectFileELF that enables
saving minidump of a stopped process. This change is mainly targeting Linux
running on x86_64 machines. Minidump should contain basic information needed
to examine state of threads, local variables and stack traces. Full support
for other platforms is not so far implemented. API tests are using LLDB's
MinidumpParser.

Reviewed By: clayborg

Differential Revision: https://reviews.llvm.org/D108233
2021-08-31 13:04:38 +02:00

120 lines
3.4 KiB
C++

//===-- 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;
}