summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGreg Clayton <gclayton@apple.com>2018-12-18 00:50:11 +0000
committerGreg Clayton <gclayton@apple.com>2018-12-18 00:50:11 +0000
commit48a28c166518e238bb7c7b305f1473e75bc5ea7d (patch)
tree2129bf011f75f252e740535b3cf89bd44af6da82
parent44ea4f574428766ecfa32494c15388436017dfdc (diff)
downloadbcm5719-llvm-48a28c166518e238bb7c7b305f1473e75bc5ea7d.tar.gz
bcm5719-llvm-48a28c166518e238bb7c7b305f1473e75bc5ea7d.zip
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
-rw-r--r--lldb/lit/Minidump/Inputs/dump-content.dmpbin0 -> 664 bytes
-rw-r--r--lldb/lit/Minidump/dump-all.test86
-rw-r--r--lldb/source/Plugins/Process/minidump/MinidumpParser.cpp45
-rw-r--r--lldb/source/Plugins/Process/minidump/MinidumpParser.h7
-rw-r--r--lldb/source/Plugins/Process/minidump/MinidumpTypes.h5
-rw-r--r--lldb/source/Plugins/Process/minidump/ProcessMinidump.cpp241
-rw-r--r--lldb/source/Plugins/Process/minidump/ProcessMinidump.h3
-rw-r--r--lldb/unittests/Process/minidump/Inputs/dump-content.dmpbin0 -> 664 bytes
8 files changed, 386 insertions, 1 deletions
diff --git a/lldb/lit/Minidump/Inputs/dump-content.dmp b/lldb/lit/Minidump/Inputs/dump-content.dmp
new file mode 100644
index 00000000000..18eb59ffb7e
--- /dev/null
+++ b/lldb/lit/Minidump/Inputs/dump-content.dmp
Binary files differ
diff --git a/lldb/lit/Minidump/dump-all.test b/lldb/lit/Minidump/dump-all.test
new file mode 100644
index 00000000000..9af31976045
--- /dev/null
+++ b/lldb/lit/Minidump/dump-all.test
@@ -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
diff --git a/lldb/source/Plugins/Process/minidump/MinidumpParser.cpp b/lldb/source/Plugins/Process/minidump/MinidumpParser.cpp
index bae5989a08f..441b794a409 100644
--- a/lldb/source/Plugins/Process/minidump/MinidumpParser.cpp
+++ b/lldb/source/Plugins/Process/minidump/MinidumpParser.cpp
@@ -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";
+}
diff --git a/lldb/source/Plugins/Process/minidump/MinidumpParser.h b/lldb/source/Plugins/Process/minidump/MinidumpParser.h
index bc819cde24a..148a7aed03e 100644
--- a/lldb/source/Plugins/Process/minidump/MinidumpParser.h
+++ b/lldb/source/Plugins/Process/minidump/MinidumpParser.h
@@ -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);
diff --git a/lldb/source/Plugins/Process/minidump/MinidumpTypes.h b/lldb/source/Plugins/Process/minidump/MinidumpTypes.h
index 82e126dee26..a5ea215d254 100644
--- a/lldb/source/Plugins/Process/minidump/MinidumpTypes.h
+++ b/lldb/source/Plugins/Process/minidump/MinidumpTypes.h
@@ -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
diff --git a/lldb/source/Plugins/Process/minidump/ProcessMinidump.cpp b/lldb/source/Plugins/Process/minidump/ProcessMinidump.cpp
index 1744b65e38b..4a03fc86e25 100644
--- a/lldb/source/Plugins/Process/minidump/ProcessMinidump.cpp
+++ b/lldb/source/Plugins/Process/minidump/ProcessMinidump.cpp
@@ -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();
+}
diff --git a/lldb/source/Plugins/Process/minidump/ProcessMinidump.h b/lldb/source/Plugins/Process/minidump/ProcessMinidump.h
index 88a7c85e16c..93e2130a6f5 100644
--- a/lldb/source/Plugins/Process/minidump/ProcessMinidump.h
+++ b/lldb/source/Plugins/Process/minidump/ProcessMinidump.h
@@ -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;
};
diff --git a/lldb/unittests/Process/minidump/Inputs/dump-content.dmp b/lldb/unittests/Process/minidump/Inputs/dump-content.dmp
new file mode 100644
index 00000000000..18eb59ffb7e
--- /dev/null
+++ b/lldb/unittests/Process/minidump/Inputs/dump-content.dmp
Binary files differ
OpenPOWER on IntegriCloud