forked from OSchip/llvm-project
Add new bugreport command to lldb
The new command add functionality to print out domain specific information for reporting a bug. Currently the only supported domain is stack unwinding (with "bugreport unwind") but adding new domains is fairly easy. Differential revision: http://reviews.llvm.org/D10868 llvm-svn: 241252
This commit is contained in:
parent
1023668bc2
commit
3937bc650c
|
@ -694,6 +694,7 @@
|
||||||
6D55BAED1A8CD0A800A70529 /* PlatformAndroid.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 6D55BAE91A8CD08C00A70529 /* PlatformAndroid.cpp */; };
|
6D55BAED1A8CD0A800A70529 /* PlatformAndroid.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 6D55BAE91A8CD08C00A70529 /* PlatformAndroid.cpp */; };
|
||||||
6D55BAEE1A8CD0B200A70529 /* PlatformAndroidRemoteGDBServer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 6D55BAEB1A8CD08C00A70529 /* PlatformAndroidRemoteGDBServer.cpp */; };
|
6D55BAEE1A8CD0B200A70529 /* PlatformAndroidRemoteGDBServer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 6D55BAEB1A8CD08C00A70529 /* PlatformAndroidRemoteGDBServer.cpp */; };
|
||||||
6D762BEE1B1605D2006C929D /* LLDBServerUtilities.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 6D762BEC1B1605CD006C929D /* LLDBServerUtilities.cpp */; };
|
6D762BEE1B1605D2006C929D /* LLDBServerUtilities.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 6D762BEC1B1605CD006C929D /* LLDBServerUtilities.cpp */; };
|
||||||
|
6D86CEA01B440F8500A7FBFA /* CommandObjectBugreport.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 6D86CE9E1B440F6B00A7FBFA /* CommandObjectBugreport.cpp */; };
|
||||||
8C2D6A53197A1EAF006989C9 /* MemoryHistory.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8C2D6A52197A1EAF006989C9 /* MemoryHistory.cpp */; };
|
8C2D6A53197A1EAF006989C9 /* MemoryHistory.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8C2D6A52197A1EAF006989C9 /* MemoryHistory.cpp */; };
|
||||||
8C2D6A5E197A250F006989C9 /* MemoryHistoryASan.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8C2D6A5A197A1FDC006989C9 /* MemoryHistoryASan.cpp */; };
|
8C2D6A5E197A250F006989C9 /* MemoryHistoryASan.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8C2D6A5A197A1FDC006989C9 /* MemoryHistoryASan.cpp */; };
|
||||||
8CCB017E19BA28A80009FD44 /* ThreadCollection.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8CCB017A19BA283D0009FD44 /* ThreadCollection.cpp */; };
|
8CCB017E19BA28A80009FD44 /* ThreadCollection.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8CCB017A19BA283D0009FD44 /* ThreadCollection.cpp */; };
|
||||||
|
@ -2340,6 +2341,8 @@
|
||||||
6D55BAEC1A8CD08C00A70529 /* PlatformAndroidRemoteGDBServer.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = PlatformAndroidRemoteGDBServer.h; sourceTree = "<group>"; };
|
6D55BAEC1A8CD08C00A70529 /* PlatformAndroidRemoteGDBServer.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = PlatformAndroidRemoteGDBServer.h; sourceTree = "<group>"; };
|
||||||
6D762BEC1B1605CD006C929D /* LLDBServerUtilities.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = LLDBServerUtilities.cpp; path = "tools/lldb-server/LLDBServerUtilities.cpp"; sourceTree = "<group>"; };
|
6D762BEC1B1605CD006C929D /* LLDBServerUtilities.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = LLDBServerUtilities.cpp; path = "tools/lldb-server/LLDBServerUtilities.cpp"; sourceTree = "<group>"; };
|
||||||
6D762BED1B1605CD006C929D /* LLDBServerUtilities.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = LLDBServerUtilities.h; path = "tools/lldb-server/LLDBServerUtilities.h"; sourceTree = "<group>"; };
|
6D762BED1B1605CD006C929D /* LLDBServerUtilities.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = LLDBServerUtilities.h; path = "tools/lldb-server/LLDBServerUtilities.h"; sourceTree = "<group>"; };
|
||||||
|
6D86CE9E1B440F6B00A7FBFA /* CommandObjectBugreport.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = CommandObjectBugreport.cpp; path = source/Commands/CommandObjectBugreport.cpp; sourceTree = "<group>"; };
|
||||||
|
6D86CE9F1B440F6B00A7FBFA /* CommandObjectBugreport.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = CommandObjectBugreport.h; path = source/Commands/CommandObjectBugreport.h; sourceTree = "<group>"; };
|
||||||
8C2D6A52197A1EAF006989C9 /* MemoryHistory.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = MemoryHistory.cpp; path = source/Target/MemoryHistory.cpp; sourceTree = "<group>"; };
|
8C2D6A52197A1EAF006989C9 /* MemoryHistory.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = MemoryHistory.cpp; path = source/Target/MemoryHistory.cpp; sourceTree = "<group>"; };
|
||||||
8C2D6A54197A1EBE006989C9 /* MemoryHistory.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = MemoryHistory.h; path = include/lldb/Target/MemoryHistory.h; sourceTree = "<group>"; };
|
8C2D6A54197A1EBE006989C9 /* MemoryHistory.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = MemoryHistory.h; path = include/lldb/Target/MemoryHistory.h; sourceTree = "<group>"; };
|
||||||
8C2D6A5A197A1FDC006989C9 /* MemoryHistoryASan.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = MemoryHistoryASan.cpp; sourceTree = "<group>"; };
|
8C2D6A5A197A1FDC006989C9 /* MemoryHistoryASan.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = MemoryHistoryASan.cpp; sourceTree = "<group>"; };
|
||||||
|
@ -4232,6 +4235,8 @@
|
||||||
26BC7E2D10F1B84700F91463 /* CommandObjectBreakpoint.cpp */,
|
26BC7E2D10F1B84700F91463 /* CommandObjectBreakpoint.cpp */,
|
||||||
9A42976111861A9F00FE05CD /* CommandObjectBreakpointCommand.h */,
|
9A42976111861A9F00FE05CD /* CommandObjectBreakpointCommand.h */,
|
||||||
9A42976211861AA600FE05CD /* CommandObjectBreakpointCommand.cpp */,
|
9A42976211861AA600FE05CD /* CommandObjectBreakpointCommand.cpp */,
|
||||||
|
6D86CE9F1B440F6B00A7FBFA /* CommandObjectBugreport.h */,
|
||||||
|
6D86CE9E1B440F6B00A7FBFA /* CommandObjectBugreport.cpp */,
|
||||||
4C5DBBC711E3FEC60035160F /* CommandObjectCommands.h */,
|
4C5DBBC711E3FEC60035160F /* CommandObjectCommands.h */,
|
||||||
4C5DBBC611E3FEC60035160F /* CommandObjectCommands.cpp */,
|
4C5DBBC611E3FEC60035160F /* CommandObjectCommands.cpp */,
|
||||||
26BC7D1710F1B76300F91463 /* CommandObjectDisassemble.h */,
|
26BC7D1710F1B76300F91463 /* CommandObjectDisassemble.h */,
|
||||||
|
@ -6393,6 +6398,7 @@
|
||||||
260CC64A15D0440D002BF2E0 /* OptionValueBoolean.cpp in Sources */,
|
260CC64A15D0440D002BF2E0 /* OptionValueBoolean.cpp in Sources */,
|
||||||
260CC64B15D0440D002BF2E0 /* OptionValueProperties.cpp in Sources */,
|
260CC64B15D0440D002BF2E0 /* OptionValueProperties.cpp in Sources */,
|
||||||
3FDFED0C19B7C8E7009756A7 /* ThisThread.cpp in Sources */,
|
3FDFED0C19B7C8E7009756A7 /* ThisThread.cpp in Sources */,
|
||||||
|
6D86CEA01B440F8500A7FBFA /* CommandObjectBugreport.cpp in Sources */,
|
||||||
260CC64C15D0440D002BF2E0 /* OptionValueDictionary.cpp in Sources */,
|
260CC64C15D0440D002BF2E0 /* OptionValueDictionary.cpp in Sources */,
|
||||||
49DCF6FE170E6B4A0092F75E /* IRMemoryMap.cpp in Sources */,
|
49DCF6FE170E6B4A0092F75E /* IRMemoryMap.cpp in Sources */,
|
||||||
260CC64D15D0440D002BF2E0 /* OptionValueEnumeration.cpp in Sources */,
|
260CC64D15D0440D002BF2E0 /* OptionValueEnumeration.cpp in Sources */,
|
||||||
|
|
|
@ -6,6 +6,7 @@ add_lldb_library(lldbCommands
|
||||||
CommandObjectArgs.cpp
|
CommandObjectArgs.cpp
|
||||||
CommandObjectBreakpoint.cpp
|
CommandObjectBreakpoint.cpp
|
||||||
CommandObjectBreakpointCommand.cpp
|
CommandObjectBreakpointCommand.cpp
|
||||||
|
CommandObjectBugreport.cpp
|
||||||
CommandObjectCommands.cpp
|
CommandObjectCommands.cpp
|
||||||
CommandObjectDisassemble.cpp
|
CommandObjectDisassemble.cpp
|
||||||
CommandObjectExpression.cpp
|
CommandObjectExpression.cpp
|
||||||
|
|
|
@ -0,0 +1,145 @@
|
||||||
|
//===-- CommandObjectBugreport.cpp ------------------------------*- C++ -*-===//
|
||||||
|
//
|
||||||
|
// The LLVM Compiler Infrastructure
|
||||||
|
//
|
||||||
|
// This file is distributed under the University of Illinois Open Source
|
||||||
|
// License. See LICENSE.TXT for details.
|
||||||
|
//
|
||||||
|
//===----------------------------------------------------------------------===//
|
||||||
|
|
||||||
|
#include "CommandObjectBugreport.h"
|
||||||
|
|
||||||
|
// C Includes
|
||||||
|
#include <cstdio>
|
||||||
|
|
||||||
|
// C++ Includes
|
||||||
|
// Other libraries and framework includes
|
||||||
|
|
||||||
|
// Project includes
|
||||||
|
#include "lldb/Interpreter/CommandInterpreter.h"
|
||||||
|
#include "lldb/Interpreter/CommandReturnObject.h"
|
||||||
|
#include "lldb/Interpreter/OptionGroupOutputFile.h"
|
||||||
|
#include "lldb/Target/Thread.h"
|
||||||
|
|
||||||
|
using namespace lldb;
|
||||||
|
using namespace lldb_private;
|
||||||
|
|
||||||
|
//-------------------------------------------------------------------------
|
||||||
|
// "bugreport unwind"
|
||||||
|
//-------------------------------------------------------------------------
|
||||||
|
|
||||||
|
class CommandObjectBugreportUnwind : public CommandObjectParsed
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
CommandObjectBugreportUnwind(CommandInterpreter &interpreter) :
|
||||||
|
CommandObjectParsed(interpreter,
|
||||||
|
"bugreport unwind",
|
||||||
|
"Create a bugreport for a bug in the stack unwinding code.",
|
||||||
|
nullptr),
|
||||||
|
m_option_group(interpreter),
|
||||||
|
m_outfile_options()
|
||||||
|
{
|
||||||
|
m_option_group.Append (&m_outfile_options, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1 | LLDB_OPT_SET_2 | LLDB_OPT_SET_3);
|
||||||
|
m_option_group.Finalize();
|
||||||
|
}
|
||||||
|
|
||||||
|
~CommandObjectBugreportUnwind()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
Options *
|
||||||
|
GetOptions() override
|
||||||
|
{
|
||||||
|
return &m_option_group;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected:
|
||||||
|
bool
|
||||||
|
DoExecute(Args& command, CommandReturnObject &result) override
|
||||||
|
{
|
||||||
|
StringList commands;
|
||||||
|
commands.AppendString("thread backtrace");
|
||||||
|
|
||||||
|
Thread *thread = m_exe_ctx.GetThreadPtr();
|
||||||
|
if (thread)
|
||||||
|
{
|
||||||
|
char command_buffer[256];
|
||||||
|
|
||||||
|
uint32_t frame_count = thread->GetStackFrameCount();
|
||||||
|
for (uint32_t i = 0; i < frame_count; ++i)
|
||||||
|
{
|
||||||
|
StackFrameSP frame = thread->GetStackFrameAtIndex(i);
|
||||||
|
lldb::addr_t pc = frame->GetStackID().GetPC();
|
||||||
|
|
||||||
|
snprintf(command_buffer, sizeof(command_buffer), "disassemble --bytes --address 0x%" PRIx64, pc);
|
||||||
|
commands.AppendString(command_buffer);
|
||||||
|
|
||||||
|
snprintf(command_buffer, sizeof(command_buffer), "image show-unwind --address 0x%" PRIx64, pc);
|
||||||
|
commands.AppendString(command_buffer);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const FileSpec &outfile_spec = m_outfile_options.GetFile().GetCurrentValue();
|
||||||
|
if (outfile_spec)
|
||||||
|
{
|
||||||
|
char path[PATH_MAX];
|
||||||
|
outfile_spec.GetPath (path, sizeof(path));
|
||||||
|
|
||||||
|
uint32_t open_options = File::eOpenOptionWrite |
|
||||||
|
File::eOpenOptionCanCreate |
|
||||||
|
File::eOpenOptionAppend |
|
||||||
|
File::eOpenOptionCloseOnExec;
|
||||||
|
|
||||||
|
const bool append = m_outfile_options.GetAppend().GetCurrentValue();
|
||||||
|
if (!append)
|
||||||
|
open_options |= File::eOpenOptionTruncate;
|
||||||
|
|
||||||
|
StreamFileSP outfile_stream = std::make_shared<StreamFile>();
|
||||||
|
Error error = outfile_stream->GetFile().Open(path, open_options);
|
||||||
|
if (error.Fail())
|
||||||
|
{
|
||||||
|
result.AppendErrorWithFormat("Failed to open file '%s' for %s: %s\n",
|
||||||
|
path,
|
||||||
|
append ? "append" : "write",
|
||||||
|
error.AsCString());
|
||||||
|
result.SetStatus(eReturnStatusFailed);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
result.SetImmediateOutputStream(outfile_stream);
|
||||||
|
}
|
||||||
|
|
||||||
|
CommandInterpreterRunOptions options;
|
||||||
|
options.SetStopOnError(false);
|
||||||
|
options.SetEchoCommands(true);
|
||||||
|
options.SetPrintResults(true);
|
||||||
|
options.SetAddToHistory(false);
|
||||||
|
m_interpreter.HandleCommands(commands, &m_exe_ctx, options, result);
|
||||||
|
|
||||||
|
return result.Succeeded();
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
OptionGroupOptions m_option_group;
|
||||||
|
OptionGroupOutputFile m_outfile_options;
|
||||||
|
};
|
||||||
|
|
||||||
|
#pragma mark CommandObjectMultiwordBugreport
|
||||||
|
|
||||||
|
//-------------------------------------------------------------------------
|
||||||
|
// CommandObjectMultiwordBugreport
|
||||||
|
//-------------------------------------------------------------------------
|
||||||
|
|
||||||
|
CommandObjectMultiwordBugreport::CommandObjectMultiwordBugreport(CommandInterpreter &interpreter) :
|
||||||
|
CommandObjectMultiword(interpreter,
|
||||||
|
"bugreport",
|
||||||
|
"Set of commands for creating domain specific bugreports.",
|
||||||
|
"bugreport <subcommand> [<subcommand-options>]")
|
||||||
|
{
|
||||||
|
|
||||||
|
LoadSubCommand("unwind", CommandObjectSP(new CommandObjectBugreportUnwind(interpreter)));
|
||||||
|
}
|
||||||
|
|
||||||
|
CommandObjectMultiwordBugreport::~CommandObjectMultiwordBugreport ()
|
||||||
|
{
|
||||||
|
}
|
|
@ -0,0 +1,36 @@
|
||||||
|
//===-- CommandObjectBugreport.h --------------------------------*- C++ -*-===//
|
||||||
|
//
|
||||||
|
// The LLVM Compiler Infrastructure
|
||||||
|
//
|
||||||
|
// This file is distributed under the University of Illinois Open Source
|
||||||
|
// License. See LICENSE.TXT for details.
|
||||||
|
//
|
||||||
|
//===----------------------------------------------------------------------===//
|
||||||
|
|
||||||
|
#ifndef liblldb_CommandObjectBugreport_h_
|
||||||
|
#define liblldb_CommandObjectBugreport_h_
|
||||||
|
|
||||||
|
// C Includes
|
||||||
|
// C++ Includes
|
||||||
|
// Other libraries and framework includes
|
||||||
|
// Project includes
|
||||||
|
#include "lldb/Interpreter/CommandObjectMultiword.h"
|
||||||
|
|
||||||
|
namespace lldb_private {
|
||||||
|
|
||||||
|
//-------------------------------------------------------------------------
|
||||||
|
// CommandObjectMultiwordBugreport
|
||||||
|
//-------------------------------------------------------------------------
|
||||||
|
|
||||||
|
class CommandObjectMultiwordBugreport : public CommandObjectMultiword
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
CommandObjectMultiwordBugreport(CommandInterpreter &interpreter);
|
||||||
|
|
||||||
|
virtual
|
||||||
|
~CommandObjectMultiwordBugreport();
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace lldb_private
|
||||||
|
|
||||||
|
#endif // liblldb_CommandObjectBugreport_h_
|
|
@ -17,6 +17,7 @@
|
||||||
#include "../Commands/CommandObjectApropos.h"
|
#include "../Commands/CommandObjectApropos.h"
|
||||||
#include "../Commands/CommandObjectArgs.h"
|
#include "../Commands/CommandObjectArgs.h"
|
||||||
#include "../Commands/CommandObjectBreakpoint.h"
|
#include "../Commands/CommandObjectBreakpoint.h"
|
||||||
|
#include "../Commands/CommandObjectBugreport.h"
|
||||||
#include "../Commands/CommandObjectDisassemble.h"
|
#include "../Commands/CommandObjectDisassemble.h"
|
||||||
#include "../Commands/CommandObjectExpression.h"
|
#include "../Commands/CommandObjectExpression.h"
|
||||||
#include "../Commands/CommandObjectFrame.h"
|
#include "../Commands/CommandObjectFrame.h"
|
||||||
|
@ -421,6 +422,7 @@ CommandInterpreter::LoadCommandDictionary ()
|
||||||
|
|
||||||
m_command_dict["apropos"] = CommandObjectSP (new CommandObjectApropos (*this));
|
m_command_dict["apropos"] = CommandObjectSP (new CommandObjectApropos (*this));
|
||||||
m_command_dict["breakpoint"]= CommandObjectSP (new CommandObjectMultiwordBreakpoint (*this));
|
m_command_dict["breakpoint"]= CommandObjectSP (new CommandObjectMultiwordBreakpoint (*this));
|
||||||
|
m_command_dict["bugreport"] = CommandObjectSP (new CommandObjectMultiwordBugreport (*this));
|
||||||
m_command_dict["command"] = CommandObjectSP (new CommandObjectMultiwordCommands (*this));
|
m_command_dict["command"] = CommandObjectSP (new CommandObjectMultiwordCommands (*this));
|
||||||
m_command_dict["disassemble"] = CommandObjectSP (new CommandObjectDisassemble (*this));
|
m_command_dict["disassemble"] = CommandObjectSP (new CommandObjectDisassemble (*this));
|
||||||
m_command_dict["expression"]= CommandObjectSP (new CommandObjectExpression (*this));
|
m_command_dict["expression"]= CommandObjectSP (new CommandObjectExpression (*this));
|
||||||
|
|
Loading…
Reference in New Issue