Add memory dumping commands similar to those in KDL.

This commit is contained in:
Rene Gollent
2012-12-18 21:37:55 -05:00
parent c7f5dd6207
commit ec7c59ca09
4 changed files with 169 additions and 0 deletions
+1
View File
@@ -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)