[haiku-commits] haiku: hrev45030 - in src/apps/debugger/user_interface: cli util src

  • From: anevilyak@xxxxxxxxx
  • To: haiku-commits@xxxxxxxxxxxxx
  • Date: Wed, 19 Dec 2012 03:38:23 +0100 (CET)

hrev45030 adds 4 changesets to branch 'master'
old head: 03289a339ceabd34eb4f909f13585a780ac4bef2
new head: ec7c59ca09cff4de780eb06a10144ff75c86ac5a
overview: http://cgit.haiku-os.org/haiku/log/?qt=range&q=ec7c59c+%5E03289a3

----------------------------------------------------------------------------

55751d0: Move Tokenizer/Token into ExpressionParser's namespace.

779b84b: Add memory dumping helper to UiUtils.
  
  - Adapted from KDL's db/dw et al.

c7f5dd6: Add support for memory block events to CliContext.

ec7c59c: Add memory dumping commands similar to those in KDL.

                                      [ Rene Gollent <anevilyak@xxxxxxxxx> ]

----------------------------------------------------------------------------

10 files changed, 292 insertions(+), 10 deletions(-)
headers/private/shared/ExpressionParser.h        |   8 +-
src/apps/debugger/Jamfile                        |   1 +
.../debugger/user_interface/cli/CliContext.cpp   |  36 +++++-
.../debugger/user_interface/cli/CliContext.h     |  12 +-
.../user_interface/cli/CliDumpMemoryCommand.cpp  | 127 +++++++++++++++++++
.../user_interface/cli/CliDumpMemoryCommand.h    |  22 ++++
.../cli/CommandLineUserInterface.cpp             |  19 +++
.../debugger/user_interface/util/UiUtils.cpp     |  62 +++++++++
src/apps/debugger/user_interface/util/UiUtils.h  |   9 ++
src/kits/shared/ExpressionParser.cpp             |   6 +-

############################################################################

Commit:      55751d083a85ed8ee7f09ab06aedc598eea23f23
URL:         http://cgit.haiku-os.org/haiku/commit/?id=55751d0
Author:      Rene Gollent <anevilyak@xxxxxxxxx>
Date:        Wed Dec 19 02:31:43 2012 UTC

Move Tokenizer/Token into ExpressionParser's namespace.

----------------------------------------------------------------------------

diff --git a/headers/private/shared/ExpressionParser.h 
b/headers/private/shared/ExpressionParser.h
index 95df720..b180b87 100644
--- a/headers/private/shared/ExpressionParser.h
+++ b/headers/private/shared/ExpressionParser.h
@@ -14,8 +14,6 @@
 #include <String.h>
 
 
-class Tokenizer;
-
 class ParseException {
  public:
        ParseException(const char* message, int32 position)
@@ -35,10 +33,10 @@ class ParseException {
 };
 
 struct Function;
-struct Token;
 class MAPM;
 
 class ExpressionParser {
+
  public:
                                                                
ExpressionParser();
                                                                
~ExpressionParser();
@@ -53,6 +51,10 @@ class ExpressionParser {
                        double                          EvaluateToDouble(const 
char* expressionString);
 
  private:
+                       struct Token;
+                       class Tokenizer;
+
+ private:
                        MAPM                            _ParseBinary();
                        MAPM                            _ParseSum();
                        MAPM                            _ParseProduct();
diff --git a/src/kits/shared/ExpressionParser.cpp 
b/src/kits/shared/ExpressionParser.cpp
index c49c67d..b75c0e2 100644
--- a/src/kits/shared/ExpressionParser.cpp
+++ b/src/kits/shared/ExpressionParser.cpp
@@ -47,7 +47,7 @@ enum {
        TOKEN_END_OF_LINE
 };
 
-struct Token {
+struct ExpressionParser::Token {
        Token()
                : string(""),
                  type(TOKEN_NONE),
@@ -89,7 +89,7 @@ struct Token {
 };
 
 
-class Tokenizer {
+class ExpressionParser::Tokenizer {
  public:
        Tokenizer()
                : fString(""),
@@ -594,7 +594,7 @@ ExpressionParser::_ParseFunction(const Token& token)
        if (strcmp("e", token.string.String()) == 0)
                return _ParseFactorial(MAPM(MM_E));
        else if (strcasecmp("pi", token.string.String()) == 0
-               || ((unsigned char)token.string.String()[0] == 0xCF 
+               || ((unsigned char)token.string.String()[0] == 0xCF
                        && (unsigned char)token.string.String()[1] == 0x80)) {
                // UTF-8 small greek letter PI
                return _ParseFactorial(MAPM(MM_PI));

############################################################################

Commit:      779b84b17b58a8818cba622a2e416163a06a431f
URL:         http://cgit.haiku-os.org/haiku/commit/?id=779b84b
Author:      Rene Gollent <anevilyak@xxxxxxxxx>
Date:        Wed Dec 19 02:32:04 2012 UTC

Add memory dumping helper to UiUtils.

- Adapted from KDL's db/dw et al.

----------------------------------------------------------------------------

diff --git a/src/apps/debugger/user_interface/util/UiUtils.cpp 
b/src/apps/debugger/user_interface/util/UiUtils.cpp
index d44f46a..2841822 100644
--- a/src/apps/debugger/user_interface/util/UiUtils.cpp
+++ b/src/apps/debugger/user_interface/util/UiUtils.cpp
@@ -7,6 +7,7 @@
 
 #include "UiUtils.h"
 
+#include <ctype.h>
 #include <stdio.h>
 
 #include <DateTime.h>
@@ -18,6 +19,7 @@
 #include "Image.h"
 #include "StackFrame.h"
 #include "Team.h"
+#include "TeamMemoryBlock.h"
 #include "Thread.h"
 #include "Type.h"
 #include "Value.h"
@@ -226,3 +228,63 @@ UiUtils::PrintValueNodeGraph(BString& _output, 
ValueNodeChild* child,
 
        return;
 }
+
+
+/*static*/ void UiUtils::DumpMemory(BString& _output, TeamMemoryBlock* block,
+       target_addr_t address, int32 itemSize, int32 displayWidth, int32 count)
+{
+       BString data;
+
+       int32 j;
+       for (int32 i = 0; i < count; i++) {
+               uint8* value;
+
+               if ((i % displayWidth) == 0) {
+                       int32 displayed = min_c(displayWidth, (count-i)) * 
itemSize;
+                       if (i != 0)
+                               _output.Append("\n");
+
+                       data.SetToFormat("[%#" B_PRIx64 "]  ", address + i * 
itemSize);
+                       _output += data;
+                       char c;
+                       for (j = 0; j < displayed; j++) {
+                               if (!block->Contains(address + displayed))
+                                       break;
+                               c = *(block->Data() + address - 
block->BaseAddress()
+                                       + (i * itemSize) + j);
+                               if (!isprint(c))
+                                       c = '.';
+
+                               _output += c;
+                       }
+                       if (count > displayWidth) {
+                               // make sure the spacing in the last line is 
correct
+                               for (j = displayed; j < displayWidth * 
itemSize; j++)
+                                       _output += ' ';
+                       }
+                       _output.Append("  ");
+               }
+
+               value = block->Data() + address - block->BaseAddress()
+                       + i * itemSize;
+
+               switch (itemSize) {
+                       case 1:
+                               data.SetToFormat(" %02" B_PRIx8, 
*(uint8*)value);
+                               break;
+                       case 2:
+                               data.SetToFormat(" %04" B_PRIx16, 
*(uint16*)value);
+                               break;
+                       case 4:
+                               data.SetToFormat(" %08" B_PRIx32, 
*(uint32*)value);
+                               break;
+                       case 8:
+                               data.SetToFormat(" %016" B_PRIx64, 
*(uint64*)value);
+                               break;
+               }
+
+               _output += data;
+       }
+
+       _output.Append("\n");
+}
diff --git a/src/apps/debugger/user_interface/util/UiUtils.h 
b/src/apps/debugger/user_interface/util/UiUtils.h
index 437b34c..cffb700 100644
--- a/src/apps/debugger/user_interface/util/UiUtils.h
+++ b/src/apps/debugger/user_interface/util/UiUtils.h
@@ -9,13 +9,17 @@
 
 #include <image.h>
 
+#include "Types.h"
+
 
 class BString;
 class BVariant;
 class StackFrame;
 class Team;
+class TeamMemoryBlock;
 class ValueNodeChild;
 
+
 class UiUtils {
 public:
        static  const char*                     ThreadStateToString(int state,
@@ -36,6 +40,11 @@ public:
        static  void                            PrintValueNodeGraph(BString& 
_output,
                                                                        
ValueNodeChild* child,
                                                                        int32 
indentLevel, int32 maxDepth);
+
+       static  void                            DumpMemory(BString& _output,
+                                                                       
TeamMemoryBlock* block,
+                                                                       
target_addr_t address, int32 itemSize,
+                                                                       int32 
displayWidth, int32 count);
 };
 
 

############################################################################

Commit:      c7f5dd6207ea0c29c149067fe5f46cb95fd3e576
URL:         http://cgit.haiku-os.org/haiku/commit/?id=c7f5dd6
Author:      Rene Gollent <anevilyak@xxxxxxxxx>
Date:        Wed Dec 19 02:32:47 2012 UTC

Add support for memory block events to CliContext.

----------------------------------------------------------------------------

diff --git a/src/apps/debugger/user_interface/cli/CliContext.cpp 
b/src/apps/debugger/user_interface/cli/CliContext.cpp
index 7654b3e..f939ec1 100644
--- a/src/apps/debugger/user_interface/cli/CliContext.cpp
+++ b/src/apps/debugger/user_interface/cli/CliContext.cpp
@@ -26,10 +26,11 @@ static CliContext* sCurrentContext;
 
 
 struct CliContext::Event : DoublyLinkedListLinkImpl<CliContext::Event> {
-       Event(int type, Thread* thread = NULL)
+       Event(int type, Thread* thread = NULL, TeamMemoryBlock* block = NULL)
                :
                fType(type),
-               fThreadReference(thread)
+               fThreadReference(thread),
+               fMemoryBlockReference(block)
        {
        }
 
@@ -43,9 +44,15 @@ struct CliContext::Event : 
DoublyLinkedListLinkImpl<CliContext::Event> {
                return fThreadReference.Get();
        }
 
+       TeamMemoryBlock* GetMemoryBlock() const
+       {
+               return fMemoryBlockReference.Get();
+       }
+
 private:
        int                                     fType;
        BReference<Thread>      fThreadReference;
+       BReference<TeamMemoryBlock> fMemoryBlockReference;
 };
 
 
@@ -68,7 +75,8 @@ CliContext::CliContext()
        fTerminating(false),
        fCurrentThread(NULL),
        fCurrentStackTrace(NULL),
-       fCurrentStackFrameIndex(-1)
+       fCurrentStackFrameIndex(-1),
+       fCurrentBlock(NULL)
 {
        sCurrentContext = this;
 }
@@ -151,6 +159,11 @@ CliContext::Cleanup()
                fNodeManager->ReleaseReference();
                fNodeManager = NULL;
        }
+
+       if (fCurrentBlock != NULL) {
+               fCurrentBlock->ReleaseReference();
+               fCurrentBlock = NULL;
+       }
 }
 
 
@@ -376,6 +389,13 @@ CliContext::ProcessPendingEvents()
                                        SetCurrentStackFrameIndex(0);
                                }
                                break;
+                       case EVENT_TEAM_MEMORY_BLOCK_RETRIEVED:
+                               if (fCurrentBlock != NULL) {
+                                       fCurrentBlock->ReleaseReference();
+                                       fCurrentBlock = NULL;
+                               }
+                               fCurrentBlock = event->GetMemoryBlock();
+                               break;
                }
        }
 }
@@ -425,6 +445,16 @@ CliContext::ThreadStackTraceChanged(const 
Team::ThreadEvent& threadEvent)
 
 
 void
+CliContext::MemoryBlockRetrieved(TeamMemoryBlock* block)
+{
+       _QueueEvent(
+               new(std::nothrow) Event(EVENT_TEAM_MEMORY_BLOCK_RETRIEVED,
+                       NULL, block));
+       _SignalInputLoop(EVENT_TEAM_MEMORY_BLOCK_RETRIEVED);
+}
+
+
+void
 CliContext::ValueNodeChanged(ValueNodeChild* nodeChild, ValueNode* oldNode,
        ValueNode* newNode)
 {
diff --git a/src/apps/debugger/user_interface/cli/CliContext.h 
b/src/apps/debugger/user_interface/cli/CliContext.h
index 09d79d8..cb4657a 100644
--- a/src/apps/debugger/user_interface/cli/CliContext.h
+++ b/src/apps/debugger/user_interface/cli/CliContext.h
@@ -13,17 +13,20 @@
 #include <Locker.h>
 
 #include "Team.h"
+#include "TeamMemoryBlock.h"
 #include "ValueNodeContainer.h"
 
 
 class StackFrame;
 class StackTrace;
 class Team;
+class TeamMemoryBlock;
 class UserInterfaceListener;
 class ValueNodeManager;
 
 
 class CliContext : private Team::Listener,
+       public TeamMemoryBlock::Listener,
        private ValueNodeContainer::Listener {
 public:
                        enum {
@@ -33,7 +36,8 @@ public:
                                EVENT_THREAD_REMOVED                            
= 0x08,
                                EVENT_THREAD_STOPPED                            
= 0x10,
                                EVENT_THREAD_STACK_TRACE_CHANGED        = 0x20,
-                               EVENT_VALUE_NODE_CHANGED                        
= 0x40
+                               EVENT_VALUE_NODE_CHANGED                        
= 0x40,
+                               EVENT_TEAM_MEMORY_BLOCK_RETRIEVED       = 0x80
                        };
 
 public:
@@ -67,6 +71,8 @@ public:
                                                                        { 
return fCurrentStackFrameIndex; }
                        void                            
SetCurrentStackFrameIndex(int32 index);
 
+                       TeamMemoryBlock*        CurrentBlock() const { return 
fCurrentBlock; }
+
                        const char*                     PromptUser(const char* 
prompt);
                        void                            
AddLineToInputHistory(const char* line);
 
@@ -91,6 +97,9 @@ private:
        virtual void                            ThreadStackTraceChanged(
                                                                        const 
Team::ThreadEvent& event);
 
+       // TeamMemoryBlock::Listener
+       virtual void                            
MemoryBlockRetrieved(TeamMemoryBlock* block);
+
        // ValueNodeContainer::Listener
        virtual void                            
ValueNodeChanged(ValueNodeChild* nodeChild,
                                                                        
ValueNode* oldNode, ValueNode* newNode);
@@ -124,6 +133,7 @@ private:
                        Thread*                         fCurrentThread;
                        StackTrace*                     fCurrentStackTrace;
                        int32                           fCurrentStackFrameIndex;
+                       TeamMemoryBlock*        fCurrentBlock;
 
                        EventList                       fPendingEvents;
 };

############################################################################

Revision:    hrev45030
Commit:      ec7c59ca09cff4de780eb06a10144ff75c86ac5a
URL:         http://cgit.haiku-os.org/haiku/commit/?id=ec7c59c
Author:      Rene Gollent <anevilyak@xxxxxxxxx>
Date:        Wed Dec 19 02:33:21 2012 UTC

Add memory dumping commands similar to those in KDL.

----------------------------------------------------------------------------

diff --git a/src/apps/debugger/Jamfile b/src/apps/debugger/Jamfile
index 0d7ea52..b219fe4 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 0000000..cd9049a
--- /dev/null
+++ b/src/apps/debugger/user_interface/cli/CliDumpMemoryCommand.cpp
@@ -0,0 +1,127 @@
+/*
+ * Copyright 2012, Rene Gollent, rene@xxxxxxxxxxx.
+ * 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());
+       }
+}
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 0000000..5c8a0fb
--- /dev/null
+++ b/src/apps/debugger/user_interface/cli/CliDumpMemoryCommand.h
@@ -0,0 +1,22 @@
+/*
+ * Copyright 2012, Rene Gollent, rene@xxxxxxxxxxx.
+ * 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 92ef511..85a204b 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<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)


Other related posts: