Add memory dumping commands similar to those in KDL.
This commit is contained in:
@@ -193,6 +193,7 @@ Application Debugger :
|
||||
CliContext.cpp
|
||||
CliContinueCommand.cpp
|
||||
CliDebugReportCommand.cpp
|
||||
CliDumpMemoryCommand.cpp
|
||||
CliPrintVariableCommand.cpp
|
||||
CliQuitCommand.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 "CliContinueCommand.h"
|
||||
#include "CliDebugReportCommand.h"
|
||||
#include "CliDumpMemoryCommand.h"
|
||||
#include "CliPrintVariableCommand.h"
|
||||
#include "CliQuitCommand.h"
|
||||
#include "CliStackFrameCommand.h"
|
||||
@@ -310,6 +311,24 @@ CommandLineUserInterface::_RegisterCommands()
|
||||
BReference<CliCommand> stackTraceCommandReference2(
|
||||
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())
|
||||
&& _RegisterCommand("continue", new(std::nothrow) CliContinueCommand)
|
||||
&& _RegisterCommand("frame", new(std::nothrow) CliStackFrameCommand)
|
||||
|
||||
Reference in New Issue
Block a user