Skip to content

Commit

Permalink
Various improvements to CliContext.
Browse files Browse the repository at this point in the history
- 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.
  • Loading branch information
anevilyak committed Dec 17, 2012
1 parent 74f911b commit 1325ad5
Show file tree
Hide file tree
Showing 2 changed files with 95 additions and 9 deletions.
77 changes: 73 additions & 4 deletions src/apps/debugger/user_interface/cli/CliContext.cpp
@@ -1,4 +1,5 @@
/*
* Copyright 2012, Rene Gollent, rene@gollent.com.
* Copyright 2012, Ingo Weinhold, ingo_weinhold@gmx.de.
* Distributed under the terms of the MIT License.
*/
Expand All @@ -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.
Expand Down Expand Up @@ -55,6 +57,7 @@ CliContext::CliContext()
fLock("CliContext"),
fTeam(NULL),
fListener(NULL),
fNodeManager(NULL),
fEditLine(NULL),
fHistory(NULL),
fPrompt(NULL),
Expand All @@ -63,7 +66,9 @@ CliContext::CliContext()
fEventsOccurred(0),
fInputLoopWaiting(false),
fTerminating(false),
fCurrentThread(NULL)
fCurrentThread(NULL),
fCurrentStackTrace(NULL),
fCurrentStackFrameIndex(-1)
{
sCurrentContext = this;
}
Expand Down Expand Up @@ -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;
}

Expand All @@ -136,6 +145,11 @@ CliContext::Cleanup()
fTeam->RemoveListener(this);
fTeam = NULL;
}

if (fNodeManager != NULL) {
fNodeManager->ReleaseReference();
fNodeManager = NULL;
}
}


Expand Down Expand Up @@ -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);
}
}
}


Expand All @@ -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)
{
Expand Down Expand Up @@ -253,7 +302,7 @@ CliContext::WaitForThreadOrUser()

if (stoppedThread != NULL) {
if (fCurrentThread == NULL)
fCurrentThread = stoppedThread;
SetCurrentThread(stoppedThread);

_SignalInputLoop(EVENT_THREAD_STOPPED);
}
Expand Down Expand Up @@ -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;
}
}
}
Expand Down Expand Up @@ -335,6 +391,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)
{
Expand Down
27 changes: 22 additions & 5 deletions src/apps/debugger/user_interface/cli/CliContext.h
Expand Up @@ -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:
Expand All @@ -46,12 +50,20 @@ class CliContext : private Team::Listener {
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);

Expand All @@ -72,6 +84,8 @@ class CliContext : private Team::Listener {

virtual void ThreadStateChanged(
const Team::ThreadEvent& event);
virtual void ThreadStackTraceChanged(
const Team::ThreadEvent& event);

private:
void _QueueEvent(Event* event);
Expand All @@ -86,6 +100,7 @@ class CliContext : private Team::Listener {
BLocker fLock;
Team* fTeam;
UserInterfaceListener* fListener;
ValueNodeManager* fNodeManager;
EditLine* fEditLine;
History* fHistory;
const char* fPrompt;
Expand All @@ -96,6 +111,8 @@ class CliContext : private Team::Listener {
volatile bool fTerminating;

Thread* fCurrentThread;
StackTrace* fCurrentStackTrace;
int32 fCurrentStackFrameIndex;

EventList fPendingEvents;
};
Expand Down

0 comments on commit 1325ad5

Please sign in to comment.