Index: lit/Minidump/dump-all.test =================================================================== --- lit/Minidump/dump-all.test +++ 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//status output + +# CHECKLSB: /etc/lsb-release: +# CHECKLSB-NEXT: /etc/lsb-release output + +# CHECKCMD: /proc/PID/cmdline: +# CHECKCMD-NEXT: /proc//cmdline output + +# CHECKENV: /proc/PID/environ: +# CHECKENV-NEXT: /proc//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//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//stat output + +# CHECKUP: uptime: +# CHECKUP-NEXT: uptime output + +# CHECKFD: /proc/PID/fd: +# CHECKFD-NEXT: /proc//fd output Index: source/Plugins/Process/minidump/MinidumpParser.h =================================================================== --- source/Plugins/Process/minidump/MinidumpParser.h +++ source/Plugins/Process/minidump/MinidumpParser.h @@ -90,6 +90,13 @@ // Perform consistency checks and initialize internal data structures Status Initialize(); + static llvm::StringRef GetStreamTypeAsString(uint32_t stream_type); + + const llvm::DenseMap & + GetDirectoryMap() const { + return m_directory_map; + } + private: MinidumpParser(const lldb::DataBufferSP &data_buf_sp); Index: source/Plugins/Process/minidump/MinidumpParser.cpp =================================================================== --- source/Plugins/Process/minidump/MinidumpParser.cpp +++ source/Plugins/Process/minidump/MinidumpParser.cpp @@ -660,3 +660,48 @@ 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"; +} Index: source/Plugins/Process/minidump/MinidumpTypes.h =================================================================== --- source/Plugins/Process/minidump/MinidumpTypes.h +++ source/Plugins/Process/minidump/MinidumpTypes.h @@ -96,7 +96,10 @@ 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 Index: source/Plugins/Process/minidump/ProcessMinidump.h =================================================================== --- source/Plugins/Process/minidump/ProcessMinidump.h +++ source/Plugins/Process/minidump/ProcessMinidump.h @@ -49,6 +49,8 @@ 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 @@ FileSpec m_core_file; llvm::ArrayRef m_thread_list; const MinidumpExceptionStream *m_active_exception; + lldb::CommandObjectSP m_command_sp; bool m_is_wow64; }; Index: source/Plugins/Process/minidump/ProcessMinidump.cpp =================================================================== --- source/Plugins/Process/minidump/ProcessMinidump.cpp +++ 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 @@ } 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//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//cmdline."), + INIT_BOOL(m_dump_linux_environ, "environ", 'e', + "Dump linux /proc//environ."), + INIT_BOOL(m_dump_linux_auxv, "auxv", 'x', + "Dump linux /proc//auxv."), + INIT_BOOL(m_dump_linux_maps, "maps", 'm', + "Dump linux /proc//maps."), + INIT_BOOL(m_dump_linux_proc_stat, "stat", 'S', + "Dump linux /proc//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//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( + 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 []") { + 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(); +}