forked from OSchip/llvm-project
Add "dump" command as a custom "process plugin" subcommand when ProcessMinidump is used.
Each process plug-in can create its own custom commands. I figured it would be nice to be able to dump things from the minidump file from the lldb command line, so I added the start of the some custom commands. Currently you can dump: minidump stream directory all linux specifc streams, most of which are strings each linux stream individually if desired, or all with --linux The idea is we can expand the command set to dump more things, search for data in the core file, and much more. This patch gets us started. Differential Revision: https://reviews.llvm.org/D55727 llvm-svn: 349429
This commit is contained in:
parent
44ea4f5744
commit
48a28c1665
Binary file not shown.
|
@ -0,0 +1,86 @@
|
|||
# RUN: %lldb -c %p/Inputs/dump-content.dmp -o 'process plugin dump --all' | \
|
||||
# RUN: FileCheck --check-prefix=CHECKDIR --check-prefix=CHECKCPU \
|
||||
# RUN: --check-prefix=CHECKSTATUS --check-prefix=CHECKLSB \
|
||||
# RUN: --check-prefix=CHECKCMD --check-prefix=CHECKENV \
|
||||
# RUN: --check-prefix=CHECKAUX --check-prefix=CHECKMAP \
|
||||
# RUN: --check-prefix=CHECKSTAT --check-prefix=CHECKUP --check-prefix=CHECKFD %s
|
||||
# RUN: %lldb -c %p/Inputs/dump-content.dmp -o 'process plugin dump -a' | \
|
||||
# RUN: FileCheck --check-prefix=CHECKDIR --check-prefix=CHECKCPU \
|
||||
# RUN: --check-prefix=CHECKSTATUS --check-prefix=CHECKLSB \
|
||||
# RUN: --check-prefix=CHECKCMD --check-prefix=CHECKENV \
|
||||
# RUN: --check-prefix=CHECKAUX --check-prefix=CHECKMAP \
|
||||
# RUN: --check-prefix=CHECKSTAT --check-prefix=CHECKUP --check-prefix=CHECKFD %s
|
||||
# RUN: %lldb -c %p/Inputs/dump-content.dmp -o 'process plugin dump --directory' | FileCheck --check-prefix=CHECKDIR %s
|
||||
# RUN: %lldb -c %p/Inputs/dump-content.dmp -o 'process plugin dump --d' | FileCheck --check-prefix=CHECKDIR %s
|
||||
# RUN: %lldb -c %p/Inputs/dump-content.dmp -o 'process plugin dump --linux' | \
|
||||
# RUN: FileCheck --check-prefix=CHECKCPU --check-prefix=CHECKSTATUS \
|
||||
# RUN: --check-prefix=CHECKLSB --check-prefix=CHECKCMD --check-prefix=CHECKENV \
|
||||
# RUN: --check-prefix=CHECKAUX --check-prefix=CHECKMAP --check-prefix=CHECKSTAT \
|
||||
# RUN: --check-prefix=CHECKUP --check-prefix=CHECKFD %s
|
||||
# RUN: %lldb -c %p/Inputs/dump-content.dmp -o 'process plugin dump --cpuinfo' | FileCheck --check-prefix=CHECKCPU %s
|
||||
# RUN: %lldb -c %p/Inputs/dump-content.dmp -o 'process plugin dump --C' | FileCheck --check-prefix=CHECKCPU %s
|
||||
# RUN: %lldb -c %p/Inputs/dump-content.dmp -o 'process plugin dump --status' | FileCheck --check-prefix=CHECKSTATUS %s
|
||||
# RUN: %lldb -c %p/Inputs/dump-content.dmp -o 'process plugin dump --s' | FileCheck --check-prefix=CHECKSTATUS %s
|
||||
# RUN: %lldb -c %p/Inputs/dump-content.dmp -o 'process plugin dump --lsb-release' | FileCheck --check-prefix=CHECKLSB %s
|
||||
# RUN: %lldb -c %p/Inputs/dump-content.dmp -o 'process plugin dump --r' | FileCheck --check-prefix=CHECKLSB %s
|
||||
# RUN: %lldb -c %p/Inputs/dump-content.dmp -o 'process plugin dump --cmdline' | FileCheck --check-prefix=CHECKCMD %s
|
||||
# RUN: %lldb -c %p/Inputs/dump-content.dmp -o 'process plugin dump --c' | FileCheck --check-prefix=CHECKCMD %s
|
||||
# RUN: %lldb -c %p/Inputs/dump-content.dmp -o 'process plugin dump --environ' | FileCheck --check-prefix=CHECKENV %s
|
||||
# RUN: %lldb -c %p/Inputs/dump-content.dmp -o 'process plugin dump --e' | FileCheck --check-prefix=CHECKENV %s
|
||||
# RUN: %lldb -c %p/Inputs/dump-content.dmp -o 'process plugin dump --auxv' | FileCheck --check-prefix=CHECKAUX %s
|
||||
# RUN: %lldb -c %p/Inputs/dump-content.dmp -o 'process plugin dump --x' | FileCheck --check-prefix=CHECKAUX %s
|
||||
# RUN: %lldb -c %p/Inputs/dump-content.dmp -o 'process plugin dump --maps' | FileCheck --check-prefix=CHECKMAP %s
|
||||
# RUN: %lldb -c %p/Inputs/dump-content.dmp -o 'process plugin dump --m' | FileCheck --check-prefix=CHECKMAP %s
|
||||
# RUN: %lldb -c %p/Inputs/dump-content.dmp -o 'process plugin dump --stat' | FileCheck --check-prefix=CHECKSTAT %s
|
||||
# RUN: %lldb -c %p/Inputs/dump-content.dmp -o 'process plugin dump --S' | FileCheck --check-prefix=CHECKSTAT %s
|
||||
# RUN: %lldb -c %p/Inputs/dump-content.dmp -o 'process plugin dump --uptime' | FileCheck --check-prefix=CHECKUP %s
|
||||
# RUN: %lldb -c %p/Inputs/dump-content.dmp -o 'process plugin dump --u' | FileCheck --check-prefix=CHECKUP %s
|
||||
# RUN: %lldb -c %p/Inputs/dump-content.dmp -o 'process plugin dump --fd' | FileCheck --check-prefix=CHECKFD %s
|
||||
# RUN: %lldb -c %p/Inputs/dump-content.dmp -o 'process plugin dump --f' | FileCheck --check-prefix=CHECKFD %s
|
||||
# CHECKDIR: RVA SIZE TYPE MinidumpStreamType
|
||||
# CHECKDIR-NEXT: ---------- ---------- ---------- --------------------------
|
||||
# CHECKDIR-NEXT: 0x000000b0 0x00000038 0x00000007 SystemInfo
|
||||
# CHECKDIR-NEXT: 0x0000015d 0x0000001b 0x47670007 LinuxEnviron
|
||||
# CHECKDIR-NEXT: 0x00000190 0x000000bc 0x47670009 LinuxMaps
|
||||
# CHECKDIR-NEXT: 0x00000110 0x0000001a 0x47670004 LinuxProcStatus
|
||||
# CHECKDIR-NEXT: 0x0000024c 0x00000018 0x4767000b LinuxProcStat
|
||||
# CHECKDIR-NEXT: 0x00000142 0x0000001b 0x47670006 LinuxCMDLine
|
||||
# CHECKDIR-NEXT: 0x00000272 0x00000016 0x4767000d LinuxProcFD
|
||||
# CHECKDIR-NEXT: 0x00000178 0x00000018 0x47670008 LinuxAuxv
|
||||
# CHECKDIR-NEXT: 0x000000e8 0x00000018 0x0000000f MiscInfo
|
||||
# CHECKDIR-NEXT: 0x00000100 0x00000010 0x47670003 LinuxCPUInfo
|
||||
# CHECKDIR-NEXT: 0x0000012a 0x00000018 0x47670005 LinuxLSBRelease
|
||||
# CHECKDIR-NEXT: 0x00000264 0x0000000e 0x4767000c LinuxProcUptime
|
||||
|
||||
# CHECKCPU: /proc/cpuinfo:
|
||||
# CHECKCPU-NEXT: cpu info output
|
||||
|
||||
# CHECKSTATUS: /proc/PID/status:
|
||||
# CHECKSTATUS-NEXT: /proc/<pid>/status output
|
||||
|
||||
# CHECKLSB: /etc/lsb-release:
|
||||
# CHECKLSB-NEXT: /etc/lsb-release output
|
||||
|
||||
# CHECKCMD: /proc/PID/cmdline:
|
||||
# CHECKCMD-NEXT: /proc/<pid>/cmdline output
|
||||
|
||||
# CHECKENV: /proc/PID/environ:
|
||||
# CHECKENV-NEXT: /proc/<pid>/environ output
|
||||
|
||||
# CHECKAUX: /proc/PID/auxv:
|
||||
# CHECKAUX-NEXT: 0x00000000: 2f 70 72 6f 63 2f 3c 70 69 64 3e 2f 61 75 78 76 /proc/<pid>/auxv
|
||||
# CHECKAUX-NEXT: 0x00000010: 20 6f 75 74 70 75 74 00 output.
|
||||
|
||||
# CHECKMAP: /proc/PID/maps:
|
||||
# CHECKMAP-NEXT: 400d9000-400db000 r-xp 00000000 b3:04 227 /system/bin/app_process
|
||||
# CHECKMAP-NEXT: 400db000-400dc000 r--p 00001000 b3:04 227 /system/bin/app_process
|
||||
# CHECKMAP-NEXT: 400dc000-400dd000 rw-p 00000000 00:00 0
|
||||
|
||||
# CHECKSTAT: /proc/PID/stat:
|
||||
# CHECKSTAT-NEXT: /proc/<pid>/stat output
|
||||
|
||||
# CHECKUP: uptime:
|
||||
# CHECKUP-NEXT: uptime output
|
||||
|
||||
# CHECKFD: /proc/PID/fd:
|
||||
# CHECKFD-NEXT: /proc/<pid>/fd output
|
|
@ -660,3 +660,48 @@ Status MinidumpParser::Initialize() {
|
|||
|
||||
return error;
|
||||
}
|
||||
|
||||
#define ENUM_TO_CSTR(ST) case (uint32_t)MinidumpStreamType::ST: return #ST
|
||||
|
||||
llvm::StringRef
|
||||
MinidumpParser::GetStreamTypeAsString(uint32_t stream_type) {
|
||||
switch (stream_type) {
|
||||
ENUM_TO_CSTR(Unused);
|
||||
ENUM_TO_CSTR(Reserved0);
|
||||
ENUM_TO_CSTR(Reserved1);
|
||||
ENUM_TO_CSTR(ThreadList);
|
||||
ENUM_TO_CSTR(ModuleList);
|
||||
ENUM_TO_CSTR(MemoryList);
|
||||
ENUM_TO_CSTR(Exception);
|
||||
ENUM_TO_CSTR(SystemInfo);
|
||||
ENUM_TO_CSTR(ThreadExList);
|
||||
ENUM_TO_CSTR(Memory64List);
|
||||
ENUM_TO_CSTR(CommentA);
|
||||
ENUM_TO_CSTR(CommentW);
|
||||
ENUM_TO_CSTR(HandleData);
|
||||
ENUM_TO_CSTR(FunctionTable);
|
||||
ENUM_TO_CSTR(UnloadedModuleList);
|
||||
ENUM_TO_CSTR(MiscInfo);
|
||||
ENUM_TO_CSTR(MemoryInfoList);
|
||||
ENUM_TO_CSTR(ThreadInfoList);
|
||||
ENUM_TO_CSTR(HandleOperationList);
|
||||
ENUM_TO_CSTR(Token);
|
||||
ENUM_TO_CSTR(JavascriptData);
|
||||
ENUM_TO_CSTR(SystemMemoryInfo);
|
||||
ENUM_TO_CSTR(ProcessVMCounters);
|
||||
ENUM_TO_CSTR(BreakpadInfo);
|
||||
ENUM_TO_CSTR(AssertionInfo);
|
||||
ENUM_TO_CSTR(LinuxCPUInfo);
|
||||
ENUM_TO_CSTR(LinuxProcStatus);
|
||||
ENUM_TO_CSTR(LinuxLSBRelease);
|
||||
ENUM_TO_CSTR(LinuxCMDLine);
|
||||
ENUM_TO_CSTR(LinuxEnviron);
|
||||
ENUM_TO_CSTR(LinuxAuxv);
|
||||
ENUM_TO_CSTR(LinuxMaps);
|
||||
ENUM_TO_CSTR(LinuxDSODebug);
|
||||
ENUM_TO_CSTR(LinuxProcStat);
|
||||
ENUM_TO_CSTR(LinuxProcUptime);
|
||||
ENUM_TO_CSTR(LinuxProcFD);
|
||||
}
|
||||
return "unknown stream type";
|
||||
}
|
||||
|
|
|
@ -90,6 +90,13 @@ public:
|
|||
// Perform consistency checks and initialize internal data structures
|
||||
Status Initialize();
|
||||
|
||||
static llvm::StringRef GetStreamTypeAsString(uint32_t stream_type);
|
||||
|
||||
const llvm::DenseMap<uint32_t, MinidumpLocationDescriptor> &
|
||||
GetDirectoryMap() const {
|
||||
return m_directory_map;
|
||||
}
|
||||
|
||||
private:
|
||||
MinidumpParser(const lldb::DataBufferSP &data_buf_sp);
|
||||
|
||||
|
|
|
@ -96,7 +96,10 @@ enum class MinidumpStreamType : uint32_t {
|
|||
LinuxEnviron = 0x47670007, /* /proc/$x/environ */
|
||||
LinuxAuxv = 0x47670008, /* /proc/$x/auxv */
|
||||
LinuxMaps = 0x47670009, /* /proc/$x/maps */
|
||||
LinuxDSODebug = 0x4767000A
|
||||
LinuxDSODebug = 0x4767000A,
|
||||
LinuxProcStat = 0x4767000B, /* /proc/$x/stat */
|
||||
LinuxProcUptime = 0x4767000C, /* uptime */
|
||||
LinuxProcFD = 0x4767000D, /* /proc/$x/fb */
|
||||
};
|
||||
|
||||
// for MinidumpSystemInfo.processor_arch
|
||||
|
|
|
@ -10,10 +10,17 @@
|
|||
#include "ProcessMinidump.h"
|
||||
#include "ThreadMinidump.h"
|
||||
|
||||
#include "lldb/Core/DumpDataExtractor.h"
|
||||
#include "lldb/Core/Module.h"
|
||||
#include "lldb/Core/ModuleSpec.h"
|
||||
#include "lldb/Core/PluginManager.h"
|
||||
#include "lldb/Core/Section.h"
|
||||
#include "lldb/Interpreter/CommandInterpreter.h"
|
||||
#include "lldb/Interpreter/CommandObject.h"
|
||||
#include "lldb/Interpreter/CommandObjectMultiword.h"
|
||||
#include "lldb/Interpreter/CommandReturnObject.h"
|
||||
#include "lldb/Interpreter/OptionArgParser.h"
|
||||
#include "lldb/Interpreter/OptionGroupBoolean.h"
|
||||
#include "lldb/Target/JITLoaderList.h"
|
||||
#include "lldb/Target/MemoryRegionInfo.h"
|
||||
#include "lldb/Target/SectionLoadList.h"
|
||||
|
@ -398,3 +405,237 @@ JITLoaderList &ProcessMinidump::GetJITLoaders() {
|
|||
}
|
||||
return *m_jit_loaders_ap;
|
||||
}
|
||||
|
||||
#define INIT_BOOL(VAR, LONG, SHORT, DESC) \
|
||||
VAR(LLDB_OPT_SET_1, false, LONG, SHORT, DESC, false, true)
|
||||
#define APPEND_OPT(VAR) \
|
||||
m_option_group.Append(&VAR, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1)
|
||||
|
||||
class CommandObjectProcessMinidumpDump : public CommandObjectParsed {
|
||||
private:
|
||||
OptionGroupOptions m_option_group;
|
||||
OptionGroupBoolean m_dump_all;
|
||||
OptionGroupBoolean m_dump_directory;
|
||||
OptionGroupBoolean m_dump_linux_cpuinfo;
|
||||
OptionGroupBoolean m_dump_linux_proc_status;
|
||||
OptionGroupBoolean m_dump_linux_lsb_release;
|
||||
OptionGroupBoolean m_dump_linux_cmdline;
|
||||
OptionGroupBoolean m_dump_linux_environ;
|
||||
OptionGroupBoolean m_dump_linux_auxv;
|
||||
OptionGroupBoolean m_dump_linux_maps;
|
||||
OptionGroupBoolean m_dump_linux_proc_stat;
|
||||
OptionGroupBoolean m_dump_linux_proc_uptime;
|
||||
OptionGroupBoolean m_dump_linux_proc_fd;
|
||||
OptionGroupBoolean m_dump_linux_all;
|
||||
|
||||
void SetDefaultOptionsIfNoneAreSet() {
|
||||
if (m_dump_all.GetOptionValue().GetCurrentValue() ||
|
||||
m_dump_linux_all.GetOptionValue().GetCurrentValue() ||
|
||||
m_dump_directory.GetOptionValue().GetCurrentValue() ||
|
||||
m_dump_linux_cpuinfo.GetOptionValue().GetCurrentValue() ||
|
||||
m_dump_linux_proc_status.GetOptionValue().GetCurrentValue() ||
|
||||
m_dump_linux_lsb_release.GetOptionValue().GetCurrentValue() ||
|
||||
m_dump_linux_cmdline.GetOptionValue().GetCurrentValue() ||
|
||||
m_dump_linux_environ.GetOptionValue().GetCurrentValue() ||
|
||||
m_dump_linux_auxv.GetOptionValue().GetCurrentValue() ||
|
||||
m_dump_linux_maps.GetOptionValue().GetCurrentValue() ||
|
||||
m_dump_linux_proc_stat.GetOptionValue().GetCurrentValue() ||
|
||||
m_dump_linux_proc_uptime.GetOptionValue().GetCurrentValue() ||
|
||||
m_dump_linux_proc_fd.GetOptionValue().GetCurrentValue())
|
||||
return;
|
||||
// If no options were set, then dump everything
|
||||
m_dump_all.GetOptionValue().SetCurrentValue(true);
|
||||
}
|
||||
bool DumpAll() const {
|
||||
return m_dump_all.GetOptionValue().GetCurrentValue();
|
||||
}
|
||||
bool DumpDirectory() const {
|
||||
return DumpAll() ||
|
||||
m_dump_directory.GetOptionValue().GetCurrentValue();
|
||||
}
|
||||
bool DumpLinux() const {
|
||||
return DumpAll() || m_dump_linux_all.GetOptionValue().GetCurrentValue();
|
||||
}
|
||||
bool DumpLinuxCPUInfo() const {
|
||||
return DumpLinux() ||
|
||||
m_dump_linux_cpuinfo.GetOptionValue().GetCurrentValue();
|
||||
}
|
||||
bool DumpLinuxProcStatus() const {
|
||||
return DumpLinux() ||
|
||||
m_dump_linux_proc_status.GetOptionValue().GetCurrentValue();
|
||||
}
|
||||
bool DumpLinuxProcStat() const {
|
||||
return DumpLinux() ||
|
||||
m_dump_linux_proc_stat.GetOptionValue().GetCurrentValue();
|
||||
}
|
||||
bool DumpLinuxLSBRelease() const {
|
||||
return DumpLinux() ||
|
||||
m_dump_linux_lsb_release.GetOptionValue().GetCurrentValue();
|
||||
}
|
||||
bool DumpLinuxCMDLine() const {
|
||||
return DumpLinux() ||
|
||||
m_dump_linux_cmdline.GetOptionValue().GetCurrentValue();
|
||||
}
|
||||
bool DumpLinuxEnviron() const {
|
||||
return DumpLinux() ||
|
||||
m_dump_linux_environ.GetOptionValue().GetCurrentValue();
|
||||
}
|
||||
bool DumpLinuxAuxv() const {
|
||||
return DumpLinux() ||
|
||||
m_dump_linux_auxv.GetOptionValue().GetCurrentValue();
|
||||
}
|
||||
bool DumpLinuxMaps() const {
|
||||
return DumpLinux() ||
|
||||
m_dump_linux_maps.GetOptionValue().GetCurrentValue();
|
||||
}
|
||||
bool DumpLinuxProcUptime() const {
|
||||
return DumpLinux() ||
|
||||
m_dump_linux_proc_uptime.GetOptionValue().GetCurrentValue();
|
||||
}
|
||||
bool DumpLinuxProcFD() const {
|
||||
return DumpLinux() ||
|
||||
m_dump_linux_proc_fd.GetOptionValue().GetCurrentValue();
|
||||
}
|
||||
public:
|
||||
|
||||
CommandObjectProcessMinidumpDump(CommandInterpreter &interpreter)
|
||||
: CommandObjectParsed(interpreter, "process plugin dump",
|
||||
"Dump information from the minidump file.", NULL),
|
||||
m_option_group(),
|
||||
INIT_BOOL(m_dump_all, "all", 'a',
|
||||
"Dump the everything in the minidump."),
|
||||
INIT_BOOL(m_dump_directory, "directory", 'd',
|
||||
"Dump the minidump directory map."),
|
||||
INIT_BOOL(m_dump_linux_cpuinfo, "cpuinfo", 'C',
|
||||
"Dump linux /proc/cpuinfo."),
|
||||
INIT_BOOL(m_dump_linux_proc_status, "status", 's',
|
||||
"Dump linux /proc/<pid>/status."),
|
||||
INIT_BOOL(m_dump_linux_lsb_release, "lsb-release", 'r',
|
||||
"Dump linux /etc/lsb-release."),
|
||||
INIT_BOOL(m_dump_linux_cmdline, "cmdline", 'c',
|
||||
"Dump linux /proc/<pid>/cmdline."),
|
||||
INIT_BOOL(m_dump_linux_environ, "environ", 'e',
|
||||
"Dump linux /proc/<pid>/environ."),
|
||||
INIT_BOOL(m_dump_linux_auxv, "auxv", 'x',
|
||||
"Dump linux /proc/<pid>/auxv."),
|
||||
INIT_BOOL(m_dump_linux_maps, "maps", 'm',
|
||||
"Dump linux /proc/<pid>/maps."),
|
||||
INIT_BOOL(m_dump_linux_proc_stat, "stat", 'S',
|
||||
"Dump linux /proc/<pid>/stat."),
|
||||
INIT_BOOL(m_dump_linux_proc_uptime, "uptime", 'u',
|
||||
"Dump linux process uptime."),
|
||||
INIT_BOOL(m_dump_linux_proc_fd, "fd", 'f',
|
||||
"Dump linux /proc/<pid>/fd."),
|
||||
INIT_BOOL(m_dump_linux_all, "linux", 'l',
|
||||
"Dump all linux streams.") {
|
||||
APPEND_OPT(m_dump_all);
|
||||
APPEND_OPT(m_dump_directory);
|
||||
APPEND_OPT(m_dump_linux_cpuinfo);
|
||||
APPEND_OPT(m_dump_linux_proc_status);
|
||||
APPEND_OPT(m_dump_linux_lsb_release);
|
||||
APPEND_OPT(m_dump_linux_cmdline);
|
||||
APPEND_OPT(m_dump_linux_environ);
|
||||
APPEND_OPT(m_dump_linux_auxv);
|
||||
APPEND_OPT(m_dump_linux_maps);
|
||||
APPEND_OPT(m_dump_linux_proc_stat);
|
||||
APPEND_OPT(m_dump_linux_proc_uptime);
|
||||
APPEND_OPT(m_dump_linux_proc_fd);
|
||||
APPEND_OPT(m_dump_linux_all);
|
||||
m_option_group.Finalize();
|
||||
}
|
||||
|
||||
~CommandObjectProcessMinidumpDump() {}
|
||||
|
||||
Options *GetOptions() override { return &m_option_group; }
|
||||
|
||||
bool DoExecute(Args &command, CommandReturnObject &result) override {
|
||||
const size_t argc = command.GetArgumentCount();
|
||||
if (argc > 0) {
|
||||
result.AppendErrorWithFormat("'%s' take no arguments, only options",
|
||||
m_cmd_name.c_str());
|
||||
result.SetStatus(eReturnStatusFailed);
|
||||
return false;
|
||||
}
|
||||
SetDefaultOptionsIfNoneAreSet();
|
||||
|
||||
ProcessMinidump *process = static_cast<ProcessMinidump *>(
|
||||
m_interpreter.GetExecutionContext().GetProcessPtr());
|
||||
result.SetStatus(eReturnStatusSuccessFinishResult);
|
||||
Stream &s = result.GetOutputStream();
|
||||
MinidumpParser &minidump = process->m_minidump_parser;
|
||||
if (DumpDirectory()) {
|
||||
s.Printf("RVA SIZE TYPE MinidumpStreamType\n");
|
||||
s.Printf("---------- ---------- ---------- --------------------------\n");
|
||||
for (const auto &pair: minidump.GetDirectoryMap())
|
||||
s.Printf("0x%8.8x 0x%8.8x 0x%8.8x %s\n", (uint32_t)pair.second.rva,
|
||||
(uint32_t)pair.second.data_size, pair.first,
|
||||
MinidumpParser::GetStreamTypeAsString(pair.first).data());
|
||||
s.Printf("\n");
|
||||
}
|
||||
auto DumpTextStream = [&](MinidumpStreamType stream_type,
|
||||
llvm::StringRef label = llvm::StringRef()) -> void {
|
||||
auto bytes = minidump.GetStream(stream_type);
|
||||
if (!bytes.empty()) {
|
||||
if (label.empty())
|
||||
label = MinidumpParser::GetStreamTypeAsString((uint32_t)stream_type);
|
||||
s.Printf("%s:\n%s\n\n", label.data(), bytes.data());
|
||||
}
|
||||
};
|
||||
auto DumpBinaryStream = [&](MinidumpStreamType stream_type,
|
||||
llvm::StringRef label = llvm::StringRef()) -> void {
|
||||
auto bytes = minidump.GetStream(stream_type);
|
||||
if (!bytes.empty()) {
|
||||
if (label.empty())
|
||||
label = MinidumpParser::GetStreamTypeAsString((uint32_t)stream_type);
|
||||
s.Printf("%s:\n", label.data());
|
||||
DataExtractor data(bytes.data(), bytes.size(), eByteOrderLittle,
|
||||
process->GetAddressByteSize());
|
||||
DumpDataExtractor(data, &s, 0, lldb::eFormatBytesWithASCII, 1,
|
||||
bytes.size(), 16, 0, 0, 0);
|
||||
s.Printf("\n\n");
|
||||
}
|
||||
};
|
||||
|
||||
if (DumpLinuxCPUInfo())
|
||||
DumpTextStream(MinidumpStreamType::LinuxCPUInfo, "/proc/cpuinfo");
|
||||
if (DumpLinuxProcStatus())
|
||||
DumpTextStream(MinidumpStreamType::LinuxProcStatus, "/proc/PID/status");
|
||||
if (DumpLinuxLSBRelease())
|
||||
DumpTextStream(MinidumpStreamType::LinuxLSBRelease, "/etc/lsb-release");
|
||||
if (DumpLinuxCMDLine())
|
||||
DumpTextStream(MinidumpStreamType::LinuxCMDLine, "/proc/PID/cmdline");
|
||||
if (DumpLinuxEnviron())
|
||||
DumpTextStream(MinidumpStreamType::LinuxEnviron, "/proc/PID/environ");
|
||||
if (DumpLinuxAuxv())
|
||||
DumpBinaryStream(MinidumpStreamType::LinuxAuxv, "/proc/PID/auxv");
|
||||
if (DumpLinuxMaps())
|
||||
DumpTextStream(MinidumpStreamType::LinuxMaps, "/proc/PID/maps");
|
||||
if (DumpLinuxProcStat())
|
||||
DumpTextStream(MinidumpStreamType::LinuxProcStat, "/proc/PID/stat");
|
||||
if (DumpLinuxProcUptime())
|
||||
DumpTextStream(MinidumpStreamType::LinuxProcUptime, "uptime");
|
||||
if (DumpLinuxProcFD())
|
||||
DumpTextStream(MinidumpStreamType::LinuxProcFD, "/proc/PID/fd");
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
class CommandObjectMultiwordProcessMinidump : public CommandObjectMultiword {
|
||||
public:
|
||||
CommandObjectMultiwordProcessMinidump(CommandInterpreter &interpreter)
|
||||
: CommandObjectMultiword(interpreter, "process plugin",
|
||||
"Commands for operating on a ProcessMinidump process.",
|
||||
"process plugin <subcommand> [<subcommand-options>]") {
|
||||
LoadSubCommand("dump",
|
||||
CommandObjectSP(new CommandObjectProcessMinidumpDump(interpreter)));
|
||||
}
|
||||
|
||||
~CommandObjectMultiwordProcessMinidump() {}
|
||||
};
|
||||
|
||||
CommandObject *ProcessMinidump::GetPluginCommandObject() {
|
||||
if (!m_command_sp)
|
||||
m_command_sp.reset(new CommandObjectMultiwordProcessMinidump(
|
||||
GetTarget().GetDebugger().GetCommandInterpreter()));
|
||||
return m_command_sp.get();
|
||||
}
|
||||
|
|
|
@ -49,6 +49,8 @@ public:
|
|||
bool CanDebug(lldb::TargetSP target_sp,
|
||||
bool plugin_specified_by_name) override;
|
||||
|
||||
CommandObject *GetPluginCommandObject() override;
|
||||
|
||||
Status DoLoadCore() override;
|
||||
|
||||
DynamicLoader *GetDynamicLoader() override { return nullptr; }
|
||||
|
@ -104,6 +106,7 @@ private:
|
|||
FileSpec m_core_file;
|
||||
llvm::ArrayRef<MinidumpThread> m_thread_list;
|
||||
const MinidumpExceptionStream *m_active_exception;
|
||||
lldb::CommandObjectSP m_command_sp;
|
||||
bool m_is_wow64;
|
||||
};
|
||||
|
||||
|
|
Binary file not shown.
Loading…
Reference in New Issue