diff --git a/src/apps/debugger/Jamfile b/src/apps/debugger/Jamfile index 0d7ea52b64..b219fe4034 100644 --- a/src/apps/debugger/Jamfile +++ b/src/apps/debugger/Jamfile @@ -193,6 +193,7 @@ Application Debugger : CliContext.cpp CliContinueCommand.cpp CliDebugReportCommand.cpp + CliDumpMemoryCommand.cpp CliPrintVariableCommand.cpp CliQuitCommand.cpp CliStackFrameCommand.cpp diff --git a/src/apps/debugger/user_interface/cli/CliDumpMemoryCommand.cpp b/src/apps/debugger/user_interface/cli/CliDumpMemoryCommand.cpp new file mode 100644 index 0000000000..cd9049a1c2 --- /dev/null +++ b/src/apps/debugger/user_interface/cli/CliDumpMemoryCommand.cpp @@ -0,0 +1,127 @@ +/* + * Copyright 2012, Rene Gollent, rene@gollent.com. + * Distributed under the terms of the MIT License. + */ + + +#include "CliDumpMemoryCommand.h" + +#include +#include + +#include +#include + +#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()); + } +} diff --git a/src/apps/debugger/user_interface/cli/CliDumpMemoryCommand.h b/src/apps/debugger/user_interface/cli/CliDumpMemoryCommand.h new file mode 100644 index 0000000000..5c8a0fb00f --- /dev/null +++ b/src/apps/debugger/user_interface/cli/CliDumpMemoryCommand.h @@ -0,0 +1,22 @@ +/* + * Copyright 2012, Rene Gollent, rene@gollent.com. + * 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 diff --git a/src/apps/debugger/user_interface/cli/CommandLineUserInterface.cpp b/src/apps/debugger/user_interface/cli/CommandLineUserInterface.cpp index 92ef51139c..85a204b3d6 100644 --- a/src/apps/debugger/user_interface/cli/CommandLineUserInterface.cpp +++ b/src/apps/debugger/user_interface/cli/CommandLineUserInterface.cpp @@ -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 stackTraceCommandReference2( stackTraceCommandReference.Get()); + BReference dumpCommandReference( + new(std::nothrow) CliDumpMemoryCommand, true); + BReference 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)