Add memory dumping commands similar to those in KDL.
This commit is contained in:
@@ -193,6 +193,7 @@ Application Debugger :
|
|||||||
CliContext.cpp
|
CliContext.cpp
|
||||||
CliContinueCommand.cpp
|
CliContinueCommand.cpp
|
||||||
CliDebugReportCommand.cpp
|
CliDebugReportCommand.cpp
|
||||||
|
CliDumpMemoryCommand.cpp
|
||||||
CliPrintVariableCommand.cpp
|
CliPrintVariableCommand.cpp
|
||||||
CliQuitCommand.cpp
|
CliQuitCommand.cpp
|
||||||
CliStackFrameCommand.cpp
|
CliStackFrameCommand.cpp
|
||||||
|
|||||||
@@ -0,0 +1,127 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2012, Rene Gollent, [email protected].
|
||||||
|
* Distributed under the terms of the MIT License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
#include "CliDumpMemoryCommand.h"
|
||||||
|
|
||||||
|
#include <ctype.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
|
#include <AutoLocker.h>
|
||||||
|
#include <ExpressionParser.h>
|
||||||
|
|
||||||
|
#include "CliContext.h"
|
||||||
|
#include "Team.h"
|
||||||
|
#include "TeamMemoryBlock.h"
|
||||||
|
#include "UiUtils.h"
|
||||||
|
#include "UserInterface.h"
|
||||||
|
|
||||||
|
|
||||||
|
CliDumpMemoryCommand::CliDumpMemoryCommand()
|
||||||
|
:
|
||||||
|
CliCommand("dump contents of debugged team's memory",
|
||||||
|
"%s [\"]address|expression[\"] [num]\n"
|
||||||
|
"Reads and displays the contents of memory at the target address.")
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
CliDumpMemoryCommand::Execute(int argc, const char* const* argv,
|
||||||
|
CliContext& context)
|
||||||
|
{
|
||||||
|
if (argc < 2) {
|
||||||
|
PrintUsage(argv[0]);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
target_addr_t address;
|
||||||
|
ExpressionParser parser;
|
||||||
|
parser.SetSupportHexInput(true);
|
||||||
|
|
||||||
|
try {
|
||||||
|
address = parser.EvaluateToInt64(argv[1]);
|
||||||
|
} catch(...) {
|
||||||
|
printf("Error parsing address/expression.\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
int32 itemSize = 0;
|
||||||
|
int32 displayWidth = 0;
|
||||||
|
|
||||||
|
// build the format string
|
||||||
|
if (strcmp(argv[0], "db") == 0) {
|
||||||
|
itemSize = 1;
|
||||||
|
displayWidth = 16;
|
||||||
|
} else if (strcmp(argv[0], "ds") == 0) {
|
||||||
|
itemSize = 2;
|
||||||
|
displayWidth = 8;
|
||||||
|
} else if (strcmp(argv[0], "dw") == 0) {
|
||||||
|
itemSize = 4;
|
||||||
|
displayWidth = 4;
|
||||||
|
} else if (strcmp(argv[0], "dl") == 0) {
|
||||||
|
itemSize = 8;
|
||||||
|
displayWidth = 2;
|
||||||
|
} else if (strcmp(argv[0], "string") == 0) {
|
||||||
|
itemSize = 1;
|
||||||
|
displayWidth = -1;
|
||||||
|
} else {
|
||||||
|
printf("dump called in an invalid way!\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
int32 num = 0;
|
||||||
|
if (argc == 3) {
|
||||||
|
char *remainder;
|
||||||
|
num = strtol(argv[2], &remainder, 0);
|
||||||
|
if (*remainder != '\0') {
|
||||||
|
printf("Error: invalid parameter \"%s\"\n", argv[2]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (num <= 0)
|
||||||
|
num = displayWidth;
|
||||||
|
|
||||||
|
TeamMemoryBlock* block = context.CurrentBlock();
|
||||||
|
if (block == NULL || !block->Contains(address)) {
|
||||||
|
context.GetUserInterfaceListener()->InspectRequested(address,
|
||||||
|
&context);
|
||||||
|
context.WaitForEvents(CliContext::EVENT_TEAM_MEMORY_BLOCK_RETRIEVED);
|
||||||
|
if (context.IsTerminating())
|
||||||
|
return;
|
||||||
|
block = context.CurrentBlock();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!strcmp(argv[0], "string")) {
|
||||||
|
printf("%p \"", (char*)address);
|
||||||
|
|
||||||
|
target_addr_t offset = address;
|
||||||
|
char c;
|
||||||
|
while (block->Contains(offset)) {
|
||||||
|
c = *(block->Data() + offset - block->BaseAddress());
|
||||||
|
|
||||||
|
if (c == '\0')
|
||||||
|
break;
|
||||||
|
if (c == '\n')
|
||||||
|
printf("\\n");
|
||||||
|
else if (c == '\t')
|
||||||
|
printf("\\t");
|
||||||
|
else {
|
||||||
|
if (!isprint(c))
|
||||||
|
c = '.';
|
||||||
|
|
||||||
|
printf("%c", c);
|
||||||
|
}
|
||||||
|
++offset;
|
||||||
|
}
|
||||||
|
|
||||||
|
printf("\"\n");
|
||||||
|
} else {
|
||||||
|
BString output;
|
||||||
|
UiUtils::DumpMemory(output, block, address, itemSize, displayWidth,
|
||||||
|
num);
|
||||||
|
printf("%s\n", output.String());
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,22 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2012, Rene Gollent, [email protected].
|
||||||
|
* Distributed under the terms of the MIT License.
|
||||||
|
*/
|
||||||
|
#ifndef CLI_DUMP_MEMORY_COMMAND_H
|
||||||
|
#define CLI_DUMP_MEMORY_COMMAND_H
|
||||||
|
|
||||||
|
|
||||||
|
#include "CliCommand.h"
|
||||||
|
|
||||||
|
|
||||||
|
class CliDumpMemoryCommand : public CliCommand {
|
||||||
|
public:
|
||||||
|
CliDumpMemoryCommand();
|
||||||
|
virtual void Execute(int argc, const char* const* argv,
|
||||||
|
CliContext& context);
|
||||||
|
|
||||||
|
private:
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
#endif // CLI_DUMP_MEMORY_COMMAND_H
|
||||||
@@ -18,6 +18,7 @@
|
|||||||
#include "CliContext.h"
|
#include "CliContext.h"
|
||||||
#include "CliContinueCommand.h"
|
#include "CliContinueCommand.h"
|
||||||
#include "CliDebugReportCommand.h"
|
#include "CliDebugReportCommand.h"
|
||||||
|
#include "CliDumpMemoryCommand.h"
|
||||||
#include "CliPrintVariableCommand.h"
|
#include "CliPrintVariableCommand.h"
|
||||||
#include "CliQuitCommand.h"
|
#include "CliQuitCommand.h"
|
||||||
#include "CliStackFrameCommand.h"
|
#include "CliStackFrameCommand.h"
|
||||||
@@ -310,6 +311,24 @@ CommandLineUserInterface::_RegisterCommands()
|
|||||||
BReference<CliCommand> stackTraceCommandReference2(
|
BReference<CliCommand> stackTraceCommandReference2(
|
||||||
stackTraceCommandReference.Get());
|
stackTraceCommandReference.Get());
|
||||||
|
|
||||||
|
BReference<CliCommand> dumpCommandReference(
|
||||||
|
new(std::nothrow) CliDumpMemoryCommand, true);
|
||||||
|
BReference<CliCommand> dumpCommandReference2(
|
||||||
|
dumpCommandReference.Get());
|
||||||
|
if (!_RegisterCommand("db", dumpCommandReference.Detach()))
|
||||||
|
return B_NO_MEMORY;
|
||||||
|
dumpCommandReference = dumpCommandReference2.Get();
|
||||||
|
if (!_RegisterCommand("ds", dumpCommandReference.Detach()))
|
||||||
|
return B_NO_MEMORY;
|
||||||
|
dumpCommandReference = dumpCommandReference2.Get();
|
||||||
|
if (!_RegisterCommand("dw", dumpCommandReference.Detach()))
|
||||||
|
return B_NO_MEMORY;
|
||||||
|
dumpCommandReference = dumpCommandReference2.Get();
|
||||||
|
if (!_RegisterCommand("dl", dumpCommandReference.Detach()))
|
||||||
|
return B_NO_MEMORY;
|
||||||
|
if (!_RegisterCommand("string", dumpCommandReference2.Detach()))
|
||||||
|
return B_NO_MEMORY;
|
||||||
|
|
||||||
if (_RegisterCommand("bt", stackTraceCommandReference.Detach())
|
if (_RegisterCommand("bt", stackTraceCommandReference.Detach())
|
||||||
&& _RegisterCommand("continue", new(std::nothrow) CliContinueCommand)
|
&& _RegisterCommand("continue", new(std::nothrow) CliContinueCommand)
|
||||||
&& _RegisterCommand("frame", new(std::nothrow) CliStackFrameCommand)
|
&& _RegisterCommand("frame", new(std::nothrow) CliStackFrameCommand)
|
||||||
|
|||||||
Reference in New Issue
Block a user