[haiku-commits] haiku: hrev45020 - src/apps/debugger/user_interface/cli

  • From: anevilyak@xxxxxxxxx
  • To: haiku-commits@xxxxxxxxxxxxx
  • Date: Mon, 17 Dec 2012 04:03:52 +0100 (CET)

hrev45020 adds 2 changesets to branch 'master'
old head: 74f911be7405f34a43bcc173e00d7981e2bd269a
new head: 287cda6f721210e5b380c674fbd3f365b0ff71d6
overview: http://cgit.haiku-os.org/haiku/log/?qt=range&q=287cda6+%5E74f911b

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

1325ad5: Various improvements to CliContext.
  
  - CliContext now tracks the current stack trace and frame if applicable.
  
  - CliContext now carries a value node manager. This allows it to track
    the variables in the currently active frame.

287cda6: Add some more commands to the CLI.
  
  - Added 'frame' command for setting/printing the context's current stack
    frame within the active stack trace.
  - Added 'variables' command for printing the list of variables visible
    within the current frame.

                                      [ Rene Gollent <anevilyak@xxxxxxxxx> ]

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

7 files changed, 239 insertions(+), 10 deletions(-)
src/apps/debugger/Jamfile                        |  2 +
.../debugger/user_interface/cli/CliContext.cpp   | 77 +++++++++++++++++++-
.../debugger/user_interface/cli/CliContext.h     | 27 +++++--
.../user_interface/cli/CliStackFrameCommand.cpp  | 64 ++++++++++++++++
.../user_interface/cli/CliStackFrameCommand.h    | 20 +++++
.../user_interface/cli/CliVariablesCommand.cpp   | 52 +++++++++++++
.../cli/CommandLineUserInterface.cpp             |  7 +-

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

Commit:      1325ad5fe84c9aa5e3300eeef5098cb89d0b7e72
URL:         http://cgit.haiku-os.org/haiku/commit/?id=1325ad5
Author:      Rene Gollent <anevilyak@xxxxxxxxx>
Date:        Mon Dec 17 02:56:22 2012 UTC

Various improvements to CliContext.

- CliContext now tracks the current stack trace and frame if applicable.

- CliContext now carries a value node manager. This allows it to track
  the variables in the currently active frame.

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

diff --git a/src/apps/debugger/user_interface/cli/CliContext.cpp 
b/src/apps/debugger/user_interface/cli/CliContext.cpp
index 6623300..7b430dc 100644
--- a/src/apps/debugger/user_interface/cli/CliContext.cpp
+++ b/src/apps/debugger/user_interface/cli/CliContext.cpp
@@ -1,4 +1,5 @@
 /*
+ * Copyright 2012, Rene Gollent, rene@xxxxxxxxxxx.
  * Copyright 2012, Ingo Weinhold, ingo_weinhold@xxxxxx.
  * Distributed under the terms of the MIT License.
  */
@@ -9,8 +10,9 @@
 #include <AutoDeleter.h>
 #include <AutoLocker.h>
 
+#include "StackTrace.h"
 #include "UserInterface.h"
-
+#include "ValueNodeManager.h"
 
 // NOTE: This is a simple work-around for EditLine not having any kind of user
 // data field. Hence in _GetPrompt() we don't have access to the context 
object.
@@ -55,6 +57,7 @@ CliContext::CliContext()
        fLock("CliContext"),
        fTeam(NULL),
        fListener(NULL),
+       fNodeManager(NULL),
        fEditLine(NULL),
        fHistory(NULL),
        fPrompt(NULL),
@@ -63,7 +66,9 @@ CliContext::CliContext()
        fEventsOccurred(0),
        fInputLoopWaiting(false),
        fTerminating(false),
-       fCurrentThread(NULL)
+       fCurrentThread(NULL),
+       fCurrentStackTrace(NULL),
+       fCurrentStackFrameIndex(-1)
 {
        sCurrentContext = this;
 }
@@ -110,6 +115,10 @@ CliContext::Init(Team* team, UserInterfaceListener* 
listener)
        el_set(fEditLine, EL_EDITOR, "emacs");
        el_set(fEditLine, EL_PROMPT, &_GetPrompt);
 
+       fNodeManager = new(std::nothrow) ValueNodeManager();
+       if (fNodeManager == NULL)
+               return B_NO_MEMORY;
+
        return B_OK;
 }
 
@@ -136,6 +145,11 @@ CliContext::Cleanup()
                fTeam->RemoveListener(this);
                fTeam = NULL;
        }
+
+       if (fNodeManager != NULL) {
+               fNodeManager->ReleaseReference();
+               fNodeManager = NULL;
+       }
 }
 
 
@@ -168,8 +182,25 @@ CliContext::SetCurrentThread(Thread* thread)
 
        fCurrentThread = thread;
 
-       if (fCurrentThread != NULL)
+       if (fCurrentStackTrace != NULL) {
+               fCurrentStackTrace->ReleaseReference();
+               fCurrentStackTrace = NULL;
+               fCurrentStackFrameIndex = -1;
+               fNodeManager->SetStackFrame(NULL, NULL);
+       }
+
+       if (fCurrentThread != NULL) {
                fCurrentThread->AcquireReference();
+               StackTrace* stackTrace = fCurrentThread->GetStackTrace();
+               // if the thread's stack trace has already been loaded,
+               // set it, otherwise we'll set it when we process the thread's
+               // stack trace changed event.
+               if (stackTrace != NULL) {
+                       fCurrentStackTrace = stackTrace;
+                       fCurrentStackTrace->AcquireReference();
+                       SetCurrentStackFrameIndex(0);
+               }
+       }
 }
 
 
@@ -186,6 +217,24 @@ CliContext::PrintCurrentThread()
 }
 
 
+void
+CliContext::SetCurrentStackFrameIndex(int32 index)
+{
+       AutoLocker<BLocker> locker(fLock);
+
+       if (fCurrentStackTrace == NULL)
+               return;
+       else if (index < 0 || index >= fCurrentStackTrace->CountFrames())
+               return;
+
+       fCurrentStackFrameIndex = index;
+
+       StackFrame* frame = fCurrentStackTrace->FrameAt(index);
+       if (frame != NULL)
+               fNodeManager->SetStackFrame(fCurrentThread, frame);
+}
+
+
 const char*
 CliContext::PromptUser(const char* prompt)
 {
@@ -253,7 +302,7 @@ CliContext::WaitForThreadOrUser()
 
                if (stoppedThread != NULL) {
                        if (fCurrentThread == NULL)
-                               fCurrentThread = stoppedThread;
+                               SetCurrentThread(stoppedThread);
 
                        _SignalInputLoop(EVENT_THREAD_STOPPED);
                }
@@ -300,6 +349,13 @@ CliContext::ProcessPendingEvents()
                                printf("[thread stopped: %" B_PRId32 " 
\"%s\"]\n",
                                        thread->ID(), thread->Name());
                                break;
+                       case EVENT_THREAD_STACK_TRACE_CHANGED:
+                               if (thread == fCurrentThread) {
+                                       fCurrentStackTrace = 
thread->GetStackTrace();
+                                       fCurrentStackTrace->AcquireReference();
+                                       SetCurrentStackFrameIndex(0);
+                               }
+                               break;
                }
        }
 }
@@ -336,6 +392,19 @@ CliContext::ThreadStateChanged(const Team::ThreadEvent& 
threadEvent)
 
 
 void
+CliContext::ThreadStackTraceChanged(const Team::ThreadEvent& threadEvent)
+{
+       if (threadEvent.GetThread()->State() != THREAD_STATE_STOPPED)
+               return;
+
+       _QueueEvent(
+               new(std::nothrow) Event(EVENT_THREAD_STACK_TRACE_CHANGED,
+                       threadEvent.GetThread()));
+       _SignalInputLoop(EVENT_THREAD_STACK_TRACE_CHANGED);
+}
+
+
+void
 CliContext::_QueueEvent(Event* event)
 {
        if (event == NULL) {
diff --git a/src/apps/debugger/user_interface/cli/CliContext.h 
b/src/apps/debugger/user_interface/cli/CliContext.h
index 3a7c98d..faf6bfa 100644
--- a/src/apps/debugger/user_interface/cli/CliContext.h
+++ b/src/apps/debugger/user_interface/cli/CliContext.h
@@ -15,18 +15,22 @@
 #include "Team.h"
 
 
+class StackFrame;
+class StackTrace;
 class Team;
 class UserInterfaceListener;
+class ValueNodeManager;
 
 
 class CliContext : private Team::Listener {
 public:
                        enum {
-                               EVENT_QUIT                                      
= 0x01,
-                               EVENT_USER_INTERRUPT            = 0x02,
-                               EVENT_THREAD_ADDED                      = 0x04,
-                               EVENT_THREAD_REMOVED            = 0x08,
-                               EVENT_THREAD_STOPPED            = 0x10,
+                               EVENT_QUIT                                      
                = 0x01,
+                               EVENT_USER_INTERRUPT                            
= 0x02,
+                               EVENT_THREAD_ADDED                              
        = 0x04,
+                               EVENT_THREAD_REMOVED                            
= 0x08,
+                               EVENT_THREAD_STOPPED                            
= 0x10,
+                               EVENT_THREAD_STACK_TRACE_CHANGED        = 0x20
                        };
 
 public:
@@ -46,12 +50,20 @@ public:
                        Team*                           GetTeam() const { 
return fTeam; }
                        UserInterfaceListener* GetUserInterfaceListener() const
                                                                        { 
return fListener; }
+                       ValueNodeManager*       GetValueNodeManager() const
+                                                                       { 
return fNodeManager; }
+                       StackTrace*                     GetStackTrace() const
+                                                                       { 
return fCurrentStackTrace; }
 
                        Thread*                         CurrentThread() const { 
return fCurrentThread; }
                        thread_id                       CurrentThreadID() const;
                        void                            
SetCurrentThread(Thread* thread);
                        void                            PrintCurrentThread();
 
+                       int32                           
CurrentStackFrameIndex() const
+                                                                       { 
return fCurrentStackFrameIndex; }
+                       void                            
SetCurrentStackFrameIndex(int32 index);
+
                        const char*                     PromptUser(const char* 
prompt);
                        void                            
AddLineToInputHistory(const char* line);
 
@@ -72,6 +84,8 @@ private:
 
        virtual void                            ThreadStateChanged(
                                                                        const 
Team::ThreadEvent& event);
+       virtual void                            ThreadStackTraceChanged(
+                                                                       const 
Team::ThreadEvent& event);
 
 private:
                        void                            _QueueEvent(Event* 
event);
@@ -86,6 +100,7 @@ private:
                        BLocker                         fLock;
                        Team*                           fTeam;
                        UserInterfaceListener* fListener;
+                       ValueNodeManager*       fNodeManager;
                        EditLine*                       fEditLine;
                        History*                        fHistory;
                        const char*                     fPrompt;
@@ -96,6 +111,8 @@ private:
        volatile bool                           fTerminating;
 
                        Thread*                         fCurrentThread;
+                       StackTrace*                     fCurrentStackTrace;
+                       int32                           fCurrentStackFrameIndex;
 
                        EventList                       fPendingEvents;
 };

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

Revision:    hrev45020
Commit:      287cda6f721210e5b380c674fbd3f365b0ff71d6
URL:         http://cgit.haiku-os.org/haiku/commit/?id=287cda6
Author:      Rene Gollent <anevilyak@xxxxxxxxx>
Date:        Mon Dec 17 02:57:53 2012 UTC

Add some more commands to the CLI.

- Added 'frame' command for setting/printing the context's current stack
  frame within the active stack trace.
- Added 'variables' command for printing the list of variables visible
  within the current frame.

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

diff --git a/src/apps/debugger/Jamfile b/src/apps/debugger/Jamfile
index 1eb7571..4a3795c 100644
--- a/src/apps/debugger/Jamfile
+++ b/src/apps/debugger/Jamfile
@@ -193,11 +193,13 @@ Application Debugger :
        CliContext.cpp
        CliContinueCommand.cpp
        CliDebugReportCommand.cpp
+       CliStackFrameCommand.cpp
        CliStackTraceCommand.cpp
        CliStopCommand.cpp
        CliThreadCommand.cpp
        CliThreadsCommand.cpp
        CliQuitCommand.cpp
+       CliVariablesCommand.cpp
        CommandLineUserInterface.cpp
 
        # user_interface/gui
diff --git a/src/apps/debugger/user_interface/cli/CliStackFrameCommand.cpp 
b/src/apps/debugger/user_interface/cli/CliStackFrameCommand.cpp
new file mode 100644
index 0000000..cc8dcc7
--- /dev/null
+++ b/src/apps/debugger/user_interface/cli/CliStackFrameCommand.cpp
@@ -0,0 +1,64 @@
+/*
+ * Copyright 2012, Rene Gollent, rene@xxxxxxxxxxx.
+ * Distributed under the terms of the MIT License.
+ */
+
+
+#include "CliStackFrameCommand.h"
+
+#include <stdio.h>
+
+#include <AutoLocker.h>
+
+#include "CliContext.h"
+#include "FunctionInstance.h"
+#include "StackFrame.h"
+#include "StackTrace.h"
+#include "Team.h"
+
+
+CliStackFrameCommand::CliStackFrameCommand()
+       :
+       CliCommand("set current stack frame",
+               "%s [ <frame number> ]\n"
+               "Sets the current stack frame to <frame number>, if supplied. "
+               "Otherwise\n prints the current frame.")
+{
+}
+
+
+void
+CliStackFrameCommand::Execute(int argc, const char* const* argv,
+       CliContext& context)
+{
+       if (argc > 2) {
+               PrintUsage(argv[0]);
+               return;
+       }
+
+       StackTrace* stackTrace = context.GetStackTrace();
+       if (argc == 1) {
+               int32 currentFrameIndex = context.CurrentStackFrameIndex();
+               if (currentFrameIndex < 0)
+                       printf("No current frame.\n");
+               else {
+                       StackFrame* frame = 
stackTrace->FrameAt(currentFrameIndex);
+                       printf("Current frame: %" B_PRId32 ": %s\n", 
currentFrameIndex,
+                               frame->Function()->PrettyName().String());
+               }
+               return;
+       }
+       // parse the argument
+       char* endPointer;
+       int32 frameNumber = strtol(argv[1], &endPointer, 0);
+       if (*endPointer != '\0' || frameNumber < 0) {
+               printf("Error: Invalid parameter \"%s\"\n", argv[1]);
+               return;
+       }
+
+       if (stackTrace == NULL || frameNumber >= stackTrace->CountFrames()) {
+               printf("Error: Index %" B_PRId32 " out of range\n", 
frameNumber);
+               return;
+       } else
+               context.SetCurrentStackFrameIndex(frameNumber);
+}
diff --git a/src/apps/debugger/user_interface/cli/CliStackFrameCommand.h 
b/src/apps/debugger/user_interface/cli/CliStackFrameCommand.h
new file mode 100644
index 0000000..e6b41de
--- /dev/null
+++ b/src/apps/debugger/user_interface/cli/CliStackFrameCommand.h
@@ -0,0 +1,20 @@
+/*
+ * Copyright 2012, Rene Gollent, rene@xxxxxxxxxxx.
+ * Distributed under the terms of the MIT License.
+ */
+#ifndef CLI_STACK_FRAME_COMMAND_H
+#define CLI_STACK_FRAME_COMMAND_H
+
+
+#include "CliCommand.h"
+
+
+class CliStackFrameCommand : public CliCommand {
+public:
+                                                               
CliStackFrameCommand();
+       virtual void                            Execute(int argc, const char* 
const* argv,
+                                                                       
CliContext& context);
+};
+
+
+#endif // CLI_STACK_FRAME_COMMAND_H
diff --git a/src/apps/debugger/user_interface/cli/CliVariablesCommand.cpp 
b/src/apps/debugger/user_interface/cli/CliVariablesCommand.cpp
new file mode 100644
index 0000000..d513c26
--- /dev/null
+++ b/src/apps/debugger/user_interface/cli/CliVariablesCommand.cpp
@@ -0,0 +1,52 @@
+/*
+ * Copyright 2012, Rene Gollent, rene@xxxxxxxxxxx.
+ * Distributed under the terms of the MIT License.
+ */
+
+
+#include "CliVariablesCommand.h"
+
+#include <stdio.h>
+
+#include <AutoLocker.h>
+
+#include "CliContext.h"
+#include "Team.h"
+#include "ValueNode.h"
+#include "ValueNodeContainer.h"
+#include "ValueNodeManager.h"
+
+
+CliVariablesCommand::CliVariablesCommand()
+       :
+       CliCommand("show current frame variables",
+               "%s\n"
+               "Prints the parameters and variables of the current frame, if "
+                       " available.")
+{
+}
+
+
+void
+CliVariablesCommand::Execute(int argc, const char* const* argv,
+       CliContext& context)
+{
+       if (argc > 1) {
+               PrintUsage(argv[0]);
+               return;
+       }
+
+       ValueNodeManager* manager = context.GetValueNodeManager();
+
+       ValueNodeContainer* container = manager->GetContainer();
+       AutoLocker<ValueNodeContainer> containerLocker(container);
+       if (container == NULL || container->CountChildren() == 0) {
+               printf("No variables available.\n");
+               return;
+       }
+
+       printf("Variables:\n");
+       for (int32 i = 0; ValueNodeChild* child = container->ChildAt(i); i++) {
+               printf("  %s\n", child->Name().String());
+       }
+}
diff --git a/src/apps/debugger/user_interface/cli/CommandLineUserInterface.cpp 
b/src/apps/debugger/user_interface/cli/CommandLineUserInterface.cpp
index 54f7d4c..de84647 100644
--- a/src/apps/debugger/user_interface/cli/CommandLineUserInterface.cpp
+++ b/src/apps/debugger/user_interface/cli/CommandLineUserInterface.cpp
@@ -19,10 +19,12 @@
 #include "CliContinueCommand.h"
 #include "CliDebugReportCommand.h"
 #include "CliQuitCommand.h"
+#include "CliStackFrameCommand.h"
 #include "CliStackTraceCommand.h"
 #include "CliStopCommand.h"
 #include "CliThreadCommand.h"
 #include "CliThreadsCommand.h"
+#include "CliVariablesCommand.h"
 
 
 static const char* kDebuggerPrompt = "debugger> ";
@@ -309,6 +311,7 @@ CommandLineUserInterface::_RegisterCommands()
 
        if (_RegisterCommand("bt", stackTraceCommandReference.Detach())
                && _RegisterCommand("continue", new(std::nothrow) 
CliContinueCommand)
+               && _RegisterCommand("frame", new(std::nothrow) 
CliStackFrameCommand)
                && _RegisterCommand("help", new(std::nothrow) HelpCommand(this))
                && _RegisterCommand("quit", new(std::nothrow) CliQuitCommand)
                && _RegisterCommand("save-report",
@@ -316,7 +319,9 @@ CommandLineUserInterface::_RegisterCommands()
                && _RegisterCommand("sc", stackTraceCommandReference2.Detach())
                && _RegisterCommand("stop", new(std::nothrow) CliStopCommand)
                && _RegisterCommand("thread", new(std::nothrow) 
CliThreadCommand)
-               && _RegisterCommand("threads", new(std::nothrow) 
CliThreadsCommand)) {
+               && _RegisterCommand("threads", new(std::nothrow) 
CliThreadsCommand)
+               && _RegisterCommand("variables",
+                       new(std::nothrow) CliVariablesCommand)) {
                return B_OK;
        }
 


Other related posts:

  • » [haiku-commits] haiku: hrev45020 - src/apps/debugger/user_interface/cli - anevilyak