[haiku-commits] haiku: hrev44804 - in src/apps/debugger: . controllers debug_managers jobs util

  • From: anevilyak@xxxxxxxxx
  • To: haiku-commits@xxxxxxxxxxxxx
  • Date: Wed, 7 Nov 2012 23:21:04 +0100 (CET)

hrev44804 adds 2 changesets to branch 'master'
old head: 29468041f9a2dcc863ceb6c52007fff769d8fd97
new head: 4549786bad3ebe97704626f9cc73afa64f92415f

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

2862f14: Added todo list.
  
  Lists missing/incomplete Debugger features. Not exhaustive.

4549786: Code reorganization.

                                      [ Rene Gollent <anevilyak@xxxxxxxxx> ]

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

23 files changed, 785 insertions(+), 705 deletions(-)
docs/develop/debugger/todo.txt                   |  14 +
src/apps/debugger/Jamfile                        |  29 +-
src/apps/debugger/Jobs.cpp                       | 698 -------------------
.../debugger/{ => controllers}/TeamDebugger.cpp  |   0
.../debugger/{ => controllers}/TeamDebugger.h    |   0
.../debugger/{ => controllers}/ThreadHandler.cpp |   0
.../debugger/{ => controllers}/ThreadHandler.h   |   0
.../{ => debug_managers}/BreakpointManager.cpp   |   0
.../{ => debug_managers}/BreakpointManager.h     |   0
.../TeamMemoryBlockManager.cpp                   |   0
.../TeamMemoryBlockManager.h                     |   0
.../{ => debug_managers}/WatchpointManager.cpp   |   0
.../{ => debug_managers}/WatchpointManager.h     |   0
src/apps/debugger/jobs/GetCPUStateJob.cpp        |  56 ++
src/apps/debugger/jobs/GetStackTraceJob.cpp      | 116 +++
src/apps/debugger/jobs/GetThreadStateJob.cpp     |  62 ++
src/apps/debugger/{ => jobs}/Jobs.h              |   0
src/apps/debugger/jobs/LoadImageDebugInfoJob.cpp | 106 +++
src/apps/debugger/jobs/LoadSourceCodeJob.cpp     |  93 +++
src/apps/debugger/jobs/ResolveValueNodeJob.cpp   | 254 +++++++
.../debugger/jobs/RetrieveMemoryBlockJob.cpp     |  62 ++
src/apps/debugger/{ => util}/Worker.cpp          |   0
src/apps/debugger/{ => util}/Worker.h            |   0

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

Commit:      2862f14d6875d949e62282bb52d45588f8185826
URL:         http://cgit.haiku-os.org/haiku/commit/?id=2862f14
Author:      Rene Gollent <anevilyak@xxxxxxxxx>
Date:        Wed Nov  7 18:26:00 2012 UTC

Added todo list.

Lists missing/incomplete Debugger features. Not exhaustive.

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

diff --git a/docs/develop/debugger/todo.txt b/docs/develop/debugger/todo.txt
new file mode 100644
index 0000000..f4b9185
--- /dev/null
+++ b/docs/develop/debugger/todo.txt
@@ -0,0 +1,14 @@
+- Need the ability to save crash reports.
+- CLI needs to be more fully implemented.
+- General expression evaluation parser. Once implemented, should supplant the 
primitive one currently used for C/C++ typecasting support, as well as being 
exposed for user expression input.
+- Conditional breakpoint/watchpoints. Contingent on above general expression 
parser.
+- Remote debug interface support.
+- Kernel debug support.
+- Architecture needs to be able to report back the hardware debugging 
capabilities/limitations of the target platform.
+- WatchpointManager needs to be able to use the aforementioned information 
from Architecture in order to more intelligently
+  manage/restrict watchpoint usage (especially once expression watchpoints 
come into play).
+- More complete DWARF3/4 support.
+- x86-64 support.
+- Support for retrieving/displaying function return values (arch-specific).
+- Syntax highlighting in source view.
+- Detection of mouse hovering over a variable in SourceView and showing value 
in tooltip (probably requires expression parsing support).

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

Revision:    hrev44804
Commit:      4549786bad3ebe97704626f9cc73afa64f92415f
URL:         http://cgit.haiku-os.org/haiku/commit/?id=4549786
Author:      Rene Gollent <anevilyak@xxxxxxxxx>
Date:        Wed Nov  7 22:16:27 2012 UTC

Code reorganization.

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

diff --git a/src/apps/debugger/Jamfile b/src/apps/debugger/Jamfile
index 7ee2bf1..3eb68ae 100644
--- a/src/apps/debugger/Jamfile
+++ b/src/apps/debugger/Jamfile
@@ -9,11 +9,14 @@ UsePrivateSystemHeaders ;
 
 SEARCH_SOURCE += [ FDirName $(SUBDIR) arch ] ;
 SEARCH_SOURCE += [ FDirName $(SUBDIR) arch x86 ] ;
+SEARCH_SOURCE += [ FDirName $(SUBDIR) controllers ] ;
 SEARCH_SOURCE += [ FDirName $(SUBDIR) debug_info ] ;
+SEARCH_SOURCE += [ FDirName $(SUBDIR) debug_managers ] ;
 SEARCH_SOURCE += [ FDirName $(SUBDIR) debugger_interface ] ;
 SEARCH_SOURCE += [ FDirName $(SUBDIR) elf ] ;
 SEARCH_SOURCE += [ FDirName $(SUBDIR) files ] ;
 SEARCH_SOURCE += [ FDirName $(SUBDIR) ids ] ;
+SEARCH_SOURCE += [ FDirName $(SUBDIR) jobs ] ;
 SEARCH_SOURCE += [ FDirName $(SUBDIR) model ] ;
 SEARCH_SOURCE += [ FDirName $(SUBDIR) settings ] ;
 SEARCH_SOURCE += [ FDirName $(SUBDIR) settings generic ] ;
@@ -55,14 +58,7 @@ SourceHdrs
 ;
 
 Application Debugger :
-       BreakpointManager.cpp
        Debugger.cpp
-       Jobs.cpp
-       TeamMemoryBlockManager.cpp
-       TeamDebugger.cpp
-       ThreadHandler.cpp
-       WatchpointManager.cpp
-       Worker.cpp
 
        # arch
        Architecture.cpp
@@ -75,6 +71,15 @@ Application Debugger :
        ArchitectureX86.cpp
        CpuStateX86.cpp
 
+       # controllers
+       TeamDebugger.cpp
+       ThreadHandler.cpp
+
+       # debug_managers
+       BreakpointManager.cpp
+       TeamMemoryBlockManager.cpp
+       WatchpointManager.cpp
+
        # debug_info
        BasicFunctionDebugInfo.cpp
        DebuggerImageDebugInfo.cpp
@@ -117,6 +122,15 @@ Application Debugger :
        ObjectID.cpp
        FunctionParameterID.cpp
 
+       # jobs
+       GetCPUStateJob.cpp
+       GetStackTraceJob.cpp
+       GetThreadStateJob.cpp
+       LoadImageDebugInfoJob.cpp
+       LoadSourceCodeJob.cpp
+       ResolveValueNodeJob.cpp
+       RetrieveMemoryBlockJob.cpp
+
        # model
        Breakpoint.cpp
        DisassembledCode.cpp
@@ -236,6 +250,7 @@ Application Debugger :
        BitBuffer.cpp
        IntegerFormatter.cpp
        StringUtils.cpp
+       Worker.cpp
 
        # value
        TypeHandler.cpp
diff --git a/src/apps/debugger/Jobs.cpp b/src/apps/debugger/Jobs.cpp
deleted file mode 100644
index bfd2fe1..0000000
--- a/src/apps/debugger/Jobs.cpp
+++ /dev/null
@@ -1,698 +0,0 @@
-/*
- * Copyright 2012, Rene Gollent, rene@xxxxxxxxxxxx
- * Copyright 2009, Ingo Weinhold, ingo_weinhold@xxxxxxx
- * Distributed under the terms of the MIT License.
- */
-
-#include "Jobs.h"
-
-#include <AutoLocker.h>
-#include <memory_private.h>
-
-#include "Architecture.h"
-#include "BitBuffer.h"
-#include "CpuState.h"
-#include "DebuggerInterface.h"
-#include "DisassembledCode.h"
-#include "FileSourceCode.h"
-#include "Function.h"
-#include "Image.h"
-#include "ImageDebugInfo.h"
-#include "Register.h"
-#include "SourceCode.h"
-#include "SpecificImageDebugInfo.h"
-#include "StackFrameDebugInfo.h"
-#include "StackFrameValueInfos.h"
-#include "StackFrameValues.h"
-#include "StackTrace.h"
-#include "Team.h"
-#include "TeamDebugInfo.h"
-#include "TeamMemory.h"
-#include "TeamMemoryBlock.h"
-#include "TeamTypeInformation.h"
-#include "Thread.h"
-#include "Tracing.h"
-#include "Type.h"
-#include "TypeComponentPath.h"
-#include "Value.h"
-#include "ValueLoader.h"
-#include "ValueLocation.h"
-#include "ValueNode.h"
-#include "ValueNodeContainer.h"
-#include "Variable.h"
-
-
-// #pragma mark - GetThreadStateJob
-
-
-GetThreadStateJob::GetThreadStateJob(DebuggerInterface* debuggerInterface,
-       Thread* thread)
-       :
-       fKey(thread, JOB_TYPE_GET_THREAD_STATE),
-       fDebuggerInterface(debuggerInterface),
-       fThread(thread)
-{
-       fThread->AcquireReference();
-}
-
-
-GetThreadStateJob::~GetThreadStateJob()
-{
-       fThread->ReleaseReference();
-}
-
-
-const JobKey&
-GetThreadStateJob::Key() const
-{
-       return fKey;
-}
-
-
-status_t
-GetThreadStateJob::Do()
-{
-       CpuState* state = NULL;
-       status_t error = fDebuggerInterface->GetCpuState(fThread->ID(), state);
-       BReference<CpuState> reference(state, true);
-
-       AutoLocker<Team> locker(fThread->GetTeam());
-
-       if (fThread->State() != THREAD_STATE_UNKNOWN)
-               return B_OK;
-
-       if (error == B_OK) {
-               fThread->SetState(THREAD_STATE_STOPPED);
-               fThread->SetCpuState(state);
-       } else if (error == B_BAD_THREAD_STATE) {
-               fThread->SetState(THREAD_STATE_RUNNING);
-       } else
-               return error;
-
-       return B_OK;
-}
-
-
-// #pragma mark - GetCpuStateJob
-
-
-GetCpuStateJob::GetCpuStateJob(DebuggerInterface* debuggerInterface,
-       Thread* thread)
-       :
-       fKey(thread, JOB_TYPE_GET_CPU_STATE),
-       fDebuggerInterface(debuggerInterface),
-       fThread(thread)
-{
-       fThread->AcquireReference();
-}
-
-
-GetCpuStateJob::~GetCpuStateJob()
-{
-       fThread->ReleaseReference();
-}
-
-
-const JobKey&
-GetCpuStateJob::Key() const
-{
-       return fKey;
-}
-
-
-status_t
-GetCpuStateJob::Do()
-{
-       CpuState* state;
-       status_t error = fDebuggerInterface->GetCpuState(fThread->ID(), state);
-       if (error != B_OK)
-               return error;
-       BReference<CpuState> reference(state, true);
-
-       AutoLocker<Team> locker(fThread->GetTeam());
-
-       if (fThread->State() == THREAD_STATE_STOPPED)
-               fThread->SetCpuState(state);
-
-       return B_OK;
-}
-
-
-// #pragma mark - GetStackTraceJob
-
-
-GetStackTraceJob::GetStackTraceJob(DebuggerInterface* debuggerInterface,
-       Architecture* architecture, Thread* thread)
-       :
-       fKey(thread, JOB_TYPE_GET_STACK_TRACE),
-       fDebuggerInterface(debuggerInterface),
-       fArchitecture(architecture),
-       fThread(thread)
-{
-       fThread->AcquireReference();
-
-       fCpuState = fThread->GetCpuState();
-       if (fCpuState != NULL)
-               fCpuState->AcquireReference();
-}
-
-
-GetStackTraceJob::~GetStackTraceJob()
-{
-       if (fCpuState != NULL)
-               fCpuState->ReleaseReference();
-
-       fThread->ReleaseReference();
-}
-
-
-const JobKey&
-GetStackTraceJob::Key() const
-{
-       return fKey;
-}
-
-
-status_t
-GetStackTraceJob::Do()
-{
-       if (fCpuState == NULL)
-               return B_BAD_VALUE;
-
-       // get the stack trace
-       StackTrace* stackTrace;
-       status_t error = fArchitecture->CreateStackTrace(fThread->GetTeam(), 
this,
-               fCpuState, stackTrace);
-       if (error != B_OK)
-               return error;
-       BReference<StackTrace> stackTraceReference(stackTrace, true);
-
-       // set the stack trace, unless something has changed
-       AutoLocker<Team> locker(fThread->GetTeam());
-
-       if (fThread->GetCpuState() == fCpuState)
-               fThread->SetStackTrace(stackTrace);
-
-       return B_OK;
-}
-
-
-status_t
-GetStackTraceJob::GetImageDebugInfo(Image* image, ImageDebugInfo*& _info)
-{
-       AutoLocker<Team> teamLocker(fThread->GetTeam());
-
-       while (image->GetImageDebugInfo() == NULL) {
-               // schedule a job, if not loaded
-               ImageDebugInfo* info;
-               status_t error = 
LoadImageDebugInfoJob::ScheduleIfNecessary(GetWorker(),
-                       image, &info);
-               if (error != B_OK)
-                       return error;
-
-               if (info != NULL) {
-                       _info = info;
-                       return B_OK;
-               }
-
-               teamLocker.Unlock();
-
-               // wait for the job to finish
-               switch (WaitFor(SimpleJobKey(image, 
JOB_TYPE_LOAD_IMAGE_DEBUG_INFO))) {
-                       case JOB_DEPENDENCY_SUCCEEDED:
-                       case JOB_DEPENDENCY_NOT_FOUND:
-                               // "Not found" can happen due to a race 
condition between
-                               // unlocking the worker and starting to wait.
-                               break;
-                       case JOB_DEPENDENCY_FAILED:
-                       case JOB_DEPENDENCY_ABORTED:
-                       default:
-                               return B_ERROR;
-               }
-
-               teamLocker.Lock();
-       }
-
-       _info = image->GetImageDebugInfo();
-       _info->AcquireReference();
-
-       return B_OK;
-}
-
-
-// #pragma mark - LoadImageDebugInfoJob
-
-
-LoadImageDebugInfoJob::LoadImageDebugInfoJob(Image* image)
-       :
-       fKey(image, JOB_TYPE_LOAD_IMAGE_DEBUG_INFO),
-       fImage(image)
-{
-       fImage->AcquireReference();
-}
-
-
-LoadImageDebugInfoJob::~LoadImageDebugInfoJob()
-{
-       fImage->ReleaseReference();
-}
-
-
-const JobKey&
-LoadImageDebugInfoJob::Key() const
-{
-       return fKey;
-}
-
-
-status_t
-LoadImageDebugInfoJob::Do()
-{
-       // get an image info for the image
-       AutoLocker<Team> locker(fImage->GetTeam());
-       ImageInfo imageInfo(fImage->Info());
-       locker.Unlock();
-
-       // create the debug info
-       ImageDebugInfo* debugInfo;
-       status_t error = fImage->GetTeam()->DebugInfo()->LoadImageDebugInfo(
-               imageInfo, fImage->ImageFile(), debugInfo);
-
-       // set the result
-       locker.Lock();
-       if (error == B_OK) {
-               error = fImage->SetImageDebugInfo(debugInfo, 
IMAGE_DEBUG_INFO_LOADED);
-               debugInfo->ReleaseReference();
-       } else
-               fImage->SetImageDebugInfo(NULL, IMAGE_DEBUG_INFO_UNAVAILABLE);
-
-       return error;
-}
-
-
-/*static*/ status_t
-LoadImageDebugInfoJob::ScheduleIfNecessary(Worker* worker, Image* image,
-       ImageDebugInfo** _imageDebugInfo)
-{
-       AutoLocker<Team> teamLocker(image->GetTeam());
-
-       // If already loaded, we're done.
-       if (image->GetImageDebugInfo() != NULL) {
-               if (_imageDebugInfo != NULL) {
-                       *_imageDebugInfo = image->GetImageDebugInfo();
-                       (*_imageDebugInfo)->AcquireReference();
-               }
-               return B_OK;
-       }
-
-       // If already loading, the caller has to wait, if desired.
-       if (image->ImageDebugInfoState() == IMAGE_DEBUG_INFO_LOADING) {
-               if (_imageDebugInfo != NULL)
-                       *_imageDebugInfo = NULL;
-               return B_OK;
-       }
-
-       // If an earlier load attempt failed, bail out.
-       if (image->ImageDebugInfoState() != IMAGE_DEBUG_INFO_NOT_LOADED)
-               return B_ERROR;
-
-       // schedule a job
-       LoadImageDebugInfoJob* job = new(std::nothrow) 
LoadImageDebugInfoJob(image);
-       if (job == NULL)
-               return B_NO_MEMORY;
-
-       status_t error = worker->ScheduleJob(job);
-       if (error != B_OK) {
-               image->SetImageDebugInfo(NULL, IMAGE_DEBUG_INFO_UNAVAILABLE);
-               return error;
-       }
-
-       image->SetImageDebugInfo(NULL, IMAGE_DEBUG_INFO_LOADING);
-
-       if (_imageDebugInfo != NULL)
-               *_imageDebugInfo = NULL;
-       return B_OK;
-}
-
-
-// #pragma mark - LoadSourceCodeJob
-
-
-LoadSourceCodeJob::LoadSourceCodeJob(
-       DebuggerInterface* debuggerInterface, Architecture* architecture,
-       Team* team, FunctionInstance* functionInstance, bool loadForFunction)
-       :
-       fKey(functionInstance, JOB_TYPE_LOAD_SOURCE_CODE),
-       fDebuggerInterface(debuggerInterface),
-       fArchitecture(architecture),
-       fTeam(team),
-       fFunctionInstance(functionInstance),
-       fLoadForFunction(loadForFunction)
-{
-       fFunctionInstance->AcquireReference();
-}
-
-
-LoadSourceCodeJob::~LoadSourceCodeJob()
-{
-       fFunctionInstance->ReleaseReference();
-}
-
-
-const JobKey&
-LoadSourceCodeJob::Key() const
-{
-       return fKey;
-}
-
-
-status_t
-LoadSourceCodeJob::Do()
-{
-       // if requested, try loading the source code for the function
-       Function* function = fFunctionInstance->GetFunction();
-       if (fLoadForFunction) {
-               FileSourceCode* sourceCode;
-               status_t error = fTeam->DebugInfo()->LoadSourceCode(
-                       function->SourceFile(), sourceCode);
-
-               AutoLocker<Team> locker(fTeam);
-
-               if (error == B_OK) {
-                       function->SetSourceCode(sourceCode, 
FUNCTION_SOURCE_LOADED);
-                       sourceCode->ReleaseReference();
-                       return B_OK;
-               }
-
-               function->SetSourceCode(NULL, FUNCTION_SOURCE_UNAVAILABLE);
-       }
-
-       // Only try to load the function instance code, if it's not overridden 
yet.
-       AutoLocker<Team> locker(fTeam);
-       if (fFunctionInstance->SourceCodeState() != FUNCTION_SOURCE_LOADING)
-               return B_OK;
-       locker.Unlock();
-
-       // disassemble the function
-       DisassembledCode* sourceCode = NULL;
-       status_t error = 
fTeam->DebugInfo()->DisassembleFunction(fFunctionInstance,
-               sourceCode);
-
-       // set the result
-       locker.Lock();
-       if (error == B_OK) {
-               if (fFunctionInstance->SourceCodeState() == 
FUNCTION_SOURCE_LOADING) {
-                       fFunctionInstance->SetSourceCode(sourceCode,
-                               FUNCTION_SOURCE_LOADED);
-                       sourceCode->ReleaseReference();
-               }
-       } else
-               fFunctionInstance->SetSourceCode(NULL, 
FUNCTION_SOURCE_UNAVAILABLE);
-
-       return error;
-}
-
-
-// #pragma mark - ResolveValueNodeValueJob
-
-
-ResolveValueNodeValueJob::ResolveValueNodeValueJob(
-       DebuggerInterface* debuggerInterface, Architecture* architecture,
-       CpuState* cpuState, TeamTypeInformation* typeInformation,
-       ValueNodeContainer* container, ValueNode* valueNode)
-       :
-       fKey(valueNode, JOB_TYPE_RESOLVE_VALUE_NODE_VALUE),
-       fDebuggerInterface(debuggerInterface),
-       fArchitecture(architecture),
-       fCpuState(cpuState),
-       fTypeInformation(typeInformation),
-       fContainer(container),
-       fValueNode(valueNode)
-{
-       if (fCpuState != NULL)
-               fCpuState->AcquireReference();
-       fContainer->AcquireReference();
-       fValueNode->AcquireReference();
-}
-
-
-ResolveValueNodeValueJob::~ResolveValueNodeValueJob()
-{
-       if (fCpuState != NULL)
-               fCpuState->ReleaseReference();
-       fContainer->ReleaseReference();
-       fValueNode->ReleaseReference();
-}
-
-
-const JobKey&
-ResolveValueNodeValueJob::Key() const
-{
-       return fKey;
-}
-
-
-status_t
-ResolveValueNodeValueJob::Do()
-{
-       // check whether the node still belongs to the container
-       AutoLocker<ValueNodeContainer> containerLocker(fContainer);
-       if (fValueNode->Container() != fContainer)
-               return B_BAD_VALUE;
-
-       // if already resolved, we're done
-       status_t nodeResolutionState
-               = fValueNode->LocationAndValueResolutionState();
-       if (nodeResolutionState != VALUE_NODE_UNRESOLVED)
-               return nodeResolutionState;
-
-       containerLocker.Unlock();
-
-       // resolve
-       status_t error = _ResolveNodeValue();
-       if (error != B_OK) {
-               nodeResolutionState = 
fValueNode->LocationAndValueResolutionState();
-               if (nodeResolutionState != VALUE_NODE_UNRESOLVED)
-                       return nodeResolutionState;
-
-               containerLocker.Lock();
-               fValueNode->SetLocationAndValue(NULL, NULL, error);
-               containerLocker.Unlock();
-       }
-
-       return error;
-}
-
-
-status_t
-ResolveValueNodeValueJob::_ResolveNodeValue()
-{
-       // get the node child and parent node
-       AutoLocker<ValueNodeContainer> containerLocker(fContainer);
-       ValueNodeChild* nodeChild = fValueNode->NodeChild();
-       BReference<ValueNodeChild> nodeChildReference(nodeChild);
-
-       ValueNode* parentNode = nodeChild->Parent();
-       BReference<ValueNode> parentNodeReference(parentNode);
-
-       // Check whether the node child location has been resolved already
-       // (successfully).
-       status_t nodeChildResolutionState = 
nodeChild->LocationResolutionState();
-       bool nodeChildDone = nodeChildResolutionState != VALUE_NODE_UNRESOLVED;
-       if (nodeChildDone && nodeChildResolutionState != B_OK)
-               return nodeChildResolutionState;
-
-       // If the child node location has not been resolved yet, check whether 
the
-       // parent node location and value have been resolved already 
(successfully).
-       bool parentDone = true;
-       if (!nodeChildDone && parentNode != NULL) {
-               status_t parentResolutionState
-                       = parentNode->LocationAndValueResolutionState();
-               parentDone = parentResolutionState != VALUE_NODE_UNRESOLVED;
-               if (parentDone && parentResolutionState != B_OK)
-                       return parentResolutionState;
-       }
-
-       containerLocker.Unlock();
-
-       // resolve the parent node location and value, if necessary
-       if (!parentDone) {
-               status_t error = _ResolveParentNodeValue(parentNode);
-               if (error != B_OK) {
-                       
TRACE_LOCALS("ResolveValueNodeValueJob::_ResolveNodeValue(): value "
-                               "node: %p (\"%s\"): _ResolveParentNodeValue(%p) 
failed\n",
-                               fValueNode, fValueNode->Name().String(), 
parentNode);
-                       return error;
-               }
-
-               if (State() == JOB_STATE_WAITING)
-                       return B_OK;
-       }
-
-       // resolve the node child location, if necessary
-       if (!nodeChildDone) {
-               status_t error = _ResolveNodeChildLocation(nodeChild);
-               if (error != B_OK) {
-                       
TRACE_LOCALS("ResolveValueNodeValueJob::_ResolveNodeValue(): value "
-                               "node: %p (\"%s\"): 
_ResolveNodeChildLocation(%p) failed\n",
-                               fValueNode, fValueNode->Name().String(), 
nodeChild);
-                       return error;
-               }
-       }
-
-       // resolve the node location and value
-       ValueLoader valueLoader(fArchitecture, fDebuggerInterface,
-               fTypeInformation, fCpuState);
-       ValueLocation* location;
-       Value* value;
-       status_t error = fValueNode->ResolvedLocationAndValue(&valueLoader,
-               location, value);
-       if (error != B_OK) {
-               TRACE_LOCALS("ResolveValueNodeValueJob::_ResolveNodeValue(): 
value "
-                       "node: %p (\"%s\"): 
fValueNode->ResolvedLocationAndValue() "
-                       "failed\n", fValueNode, fValueNode->Name().String());
-               return error;
-       }
-       BReference<ValueLocation> locationReference(location, true);
-       BReference<Value> valueReference(value, true);
-
-       // set location and value on the node
-       containerLocker.Lock();
-       status_t nodeResolutionState
-               = fValueNode->LocationAndValueResolutionState();
-       if (nodeResolutionState != VALUE_NODE_UNRESOLVED)
-               return nodeResolutionState;
-       fValueNode->SetLocationAndValue(location, value, B_OK);
-       containerLocker.Unlock();
-
-       return B_OK;
-}
-
-
-status_t
-ResolveValueNodeValueJob::_ResolveNodeChildLocation(ValueNodeChild* nodeChild)
-{
-       // resolve the location
-       ValueLoader valueLoader(fArchitecture, fDebuggerInterface,
-               fTypeInformation, fCpuState);
-       ValueLocation* location = NULL;
-       status_t error = nodeChild->ResolveLocation(&valueLoader, location);
-       BReference<ValueLocation> locationReference(location, true);
-
-       // set the location on the node child
-       AutoLocker<ValueNodeContainer> containerLocker(fContainer);
-       status_t nodeChildResolutionState = 
nodeChild->LocationResolutionState();
-       if (nodeChildResolutionState == VALUE_NODE_UNRESOLVED)
-               nodeChild->SetLocation(location, error);
-       else
-               error = nodeChildResolutionState;
-
-       return error;
-}
-
-
-status_t
-ResolveValueNodeValueJob::_ResolveParentNodeValue(ValueNode* parentNode)
-{
-       AutoLocker<ValueNodeContainer> containerLocker(fContainer);
-
-       if (parentNode->Container() != fContainer)
-               return B_BAD_VALUE;
-
-       // if the parent node already has a value, we're done
-       status_t nodeResolutionState
-               = parentNode->LocationAndValueResolutionState();
-       if (nodeResolutionState != VALUE_NODE_UNRESOLVED)
-               return nodeResolutionState;
-
-       // check whether a job is already in progress
-       AutoLocker<Worker> workerLocker(GetWorker());
-       SimpleJobKey jobKey(parentNode, JOB_TYPE_RESOLVE_VALUE_NODE_VALUE);
-       if (GetWorker()->GetJob(jobKey) == NULL) {
-               workerLocker.Unlock();
-
-               // schedule the job
-               status_t error = GetWorker()->ScheduleJob(
-                       new(std::nothrow) 
ResolveValueNodeValueJob(fDebuggerInterface,
-                               fArchitecture, fCpuState, fTypeInformation, 
fContainer,
-                               parentNode));
-               if (error != B_OK) {
-                       // scheduling failed -- set the value to invalid
-                       parentNode->SetLocationAndValue(NULL, NULL, error);
-                       return error;
-               }
-       }
-
-       // wait for the job to finish
-       workerLocker.Unlock();
-       containerLocker.Unlock();
-
-       switch (WaitFor(jobKey)) {
-               case JOB_DEPENDENCY_SUCCEEDED:
-               case JOB_DEPENDENCY_NOT_FOUND:
-                       // "Not found" can happen due to a race condition 
between
-                       // unlocking the worker and starting to wait.
-                       break;
-               case JOB_DEPENDENCY_ACTIVE:
-                       return B_OK;
-               case JOB_DEPENDENCY_FAILED:
-               case JOB_DEPENDENCY_ABORTED:
-               default:
-                       return B_ERROR;
-       }
-
-       containerLocker.Lock();
-
-       // now there should be a value for the node
-       nodeResolutionState = parentNode->LocationAndValueResolutionState();
-       return nodeResolutionState != VALUE_NODE_UNRESOLVED
-               ? nodeResolutionState : B_ERROR;
-}
-
-
-RetrieveMemoryBlockJob::RetrieveMemoryBlockJob(Team* team,
-       TeamMemory* teamMemory, TeamMemoryBlock* memoryBlock)
-       :
-       fKey(memoryBlock, JOB_TYPE_GET_MEMORY_BLOCK),
-       fTeam(team),
-       fTeamMemory(teamMemory),
-       fMemoryBlock(memoryBlock)
-{
-       fTeamMemory->AcquireReference();
-       fMemoryBlock->AcquireReference();
-}
-
-
-RetrieveMemoryBlockJob::~RetrieveMemoryBlockJob()
-{
-       fTeamMemory->ReleaseReference();
-       fMemoryBlock->ReleaseReference();
-}
-
-
-const JobKey&
-RetrieveMemoryBlockJob::Key() const
-{
-       return fKey;
-}
-
-
-status_t
-RetrieveMemoryBlockJob::Do()
-{
-       ssize_t result = fTeamMemory->ReadMemory(fMemoryBlock->BaseAddress(),
-               fMemoryBlock->Data(), fMemoryBlock->Size());
-       if (result < 0)
-               return result;
-
-       uint32 protection = 0;
-       uint32 locking = 0;
-       status_t error = get_memory_properties(fTeam->ID(),
-               (const void *)fMemoryBlock->BaseAddress(), &protection, 
&locking);
-       if (error != B_OK)
-               return error;
-
-       fMemoryBlock->SetWritable((protection & B_WRITE_AREA) != 0);
-       fMemoryBlock->MarkValid();
-       return B_OK;
-}
diff --git a/src/apps/debugger/TeamDebugger.cpp 
b/src/apps/debugger/controllers/TeamDebugger.cpp
similarity index 100%
rename from src/apps/debugger/TeamDebugger.cpp
rename to src/apps/debugger/controllers/TeamDebugger.cpp
diff --git a/src/apps/debugger/TeamDebugger.h 
b/src/apps/debugger/controllers/TeamDebugger.h
similarity index 100%
rename from src/apps/debugger/TeamDebugger.h
rename to src/apps/debugger/controllers/TeamDebugger.h
diff --git a/src/apps/debugger/ThreadHandler.cpp 
b/src/apps/debugger/controllers/ThreadHandler.cpp
similarity index 100%
rename from src/apps/debugger/ThreadHandler.cpp
rename to src/apps/debugger/controllers/ThreadHandler.cpp
diff --git a/src/apps/debugger/ThreadHandler.h 
b/src/apps/debugger/controllers/ThreadHandler.h
similarity index 100%
rename from src/apps/debugger/ThreadHandler.h
rename to src/apps/debugger/controllers/ThreadHandler.h
diff --git a/src/apps/debugger/BreakpointManager.cpp 
b/src/apps/debugger/debug_managers/BreakpointManager.cpp
similarity index 100%
rename from src/apps/debugger/BreakpointManager.cpp
rename to src/apps/debugger/debug_managers/BreakpointManager.cpp
diff --git a/src/apps/debugger/BreakpointManager.h 
b/src/apps/debugger/debug_managers/BreakpointManager.h
similarity index 100%
rename from src/apps/debugger/BreakpointManager.h
rename to src/apps/debugger/debug_managers/BreakpointManager.h
diff --git a/src/apps/debugger/TeamMemoryBlockManager.cpp 
b/src/apps/debugger/debug_managers/TeamMemoryBlockManager.cpp
similarity index 100%
rename from src/apps/debugger/TeamMemoryBlockManager.cpp
rename to src/apps/debugger/debug_managers/TeamMemoryBlockManager.cpp
diff --git a/src/apps/debugger/TeamMemoryBlockManager.h 
b/src/apps/debugger/debug_managers/TeamMemoryBlockManager.h
similarity index 100%
rename from src/apps/debugger/TeamMemoryBlockManager.h
rename to src/apps/debugger/debug_managers/TeamMemoryBlockManager.h
diff --git a/src/apps/debugger/WatchpointManager.cpp 
b/src/apps/debugger/debug_managers/WatchpointManager.cpp
similarity index 100%
rename from src/apps/debugger/WatchpointManager.cpp
rename to src/apps/debugger/debug_managers/WatchpointManager.cpp
diff --git a/src/apps/debugger/WatchpointManager.h 
b/src/apps/debugger/debug_managers/WatchpointManager.h
similarity index 100%
rename from src/apps/debugger/WatchpointManager.h
rename to src/apps/debugger/debug_managers/WatchpointManager.h
diff --git a/src/apps/debugger/jobs/GetCPUStateJob.cpp 
b/src/apps/debugger/jobs/GetCPUStateJob.cpp
new file mode 100644
index 0000000..2d28c4c
--- /dev/null
+++ b/src/apps/debugger/jobs/GetCPUStateJob.cpp
@@ -0,0 +1,56 @@
+/*
+ * Copyright 2012, Rene Gollent, rene@xxxxxxxxxxxx
+ * Copyright 2009, Ingo Weinhold, ingo_weinhold@xxxxxxx
+ * Distributed under the terms of the MIT License.
+ */
+
+#include "Jobs.h"
+
+#include <AutoLocker.h>
+
+#include "CpuState.h"
+#include "DebuggerInterface.h"
+#include "Team.h"
+#include "Thread.h"
+
+
+GetCpuStateJob::GetCpuStateJob(DebuggerInterface* debuggerInterface,
+       Thread* thread)
+       :
+       fKey(thread, JOB_TYPE_GET_CPU_STATE),
+       fDebuggerInterface(debuggerInterface),
+       fThread(thread)
+{
+       fThread->AcquireReference();
+}
+
+
+GetCpuStateJob::~GetCpuStateJob()
+{
+       fThread->ReleaseReference();
+}
+
+
+const JobKey&
+GetCpuStateJob::Key() const
+{
+       return fKey;
+}
+
+
+status_t
+GetCpuStateJob::Do()
+{
+       CpuState* state;
+       status_t error = fDebuggerInterface->GetCpuState(fThread->ID(), state);
+       if (error != B_OK)
+               return error;
+       BReference<CpuState> reference(state, true);
+
+       AutoLocker<Team> locker(fThread->GetTeam());
+
+       if (fThread->State() == THREAD_STATE_STOPPED)
+               fThread->SetCpuState(state);
+
+       return B_OK;
+}
diff --git a/src/apps/debugger/jobs/GetStackTraceJob.cpp 
b/src/apps/debugger/jobs/GetStackTraceJob.cpp
new file mode 100644
index 0000000..61a1c72
--- /dev/null
+++ b/src/apps/debugger/jobs/GetStackTraceJob.cpp
@@ -0,0 +1,116 @@
+/*
+ * Copyright 2012, Rene Gollent, rene@xxxxxxxxxxxx
+ * Copyright 2009, Ingo Weinhold, ingo_weinhold@xxxxxxx
+ * Distributed under the terms of the MIT License.
+ */
+
+#include "Jobs.h"
+
+#include <AutoLocker.h>
+
+#include "Architecture.h"
+#include "CpuState.h"
+#include "DebuggerInterface.h"
+#include "ImageDebugInfo.h"
+#include "StackTrace.h"
+#include "Thread.h"
+#include "Team.h"
+
+
+GetStackTraceJob::GetStackTraceJob(DebuggerInterface* debuggerInterface,
+       Architecture* architecture, Thread* thread)
+       :
+       fKey(thread, JOB_TYPE_GET_STACK_TRACE),
+       fDebuggerInterface(debuggerInterface),
+       fArchitecture(architecture),
+       fThread(thread)
+{
+       fThread->AcquireReference();
+
+       fCpuState = fThread->GetCpuState();
+       if (fCpuState != NULL)
+               fCpuState->AcquireReference();
+}
+
+
+GetStackTraceJob::~GetStackTraceJob()
+{
+       if (fCpuState != NULL)
+               fCpuState->ReleaseReference();
+
+       fThread->ReleaseReference();
+}
+
+
+const JobKey&
+GetStackTraceJob::Key() const
+{
+       return fKey;
+}
+
+
+status_t
+GetStackTraceJob::Do()
+{
+       if (fCpuState == NULL)
+               return B_BAD_VALUE;
+
+       // get the stack trace
+       StackTrace* stackTrace;
+       status_t error = fArchitecture->CreateStackTrace(fThread->GetTeam(), 
this,
+               fCpuState, stackTrace);
+       if (error != B_OK)
+               return error;
+       BReference<StackTrace> stackTraceReference(stackTrace, true);
+
+       // set the stack trace, unless something has changed
+       AutoLocker<Team> locker(fThread->GetTeam());
+
+       if (fThread->GetCpuState() == fCpuState)
+               fThread->SetStackTrace(stackTrace);
+
+       return B_OK;
+}
+
+
+status_t
+GetStackTraceJob::GetImageDebugInfo(Image* image, ImageDebugInfo*& _info)
+{
+       AutoLocker<Team> teamLocker(fThread->GetTeam());
+
+       while (image->GetImageDebugInfo() == NULL) {
+               // schedule a job, if not loaded
+               ImageDebugInfo* info;
+               status_t error = 
LoadImageDebugInfoJob::ScheduleIfNecessary(GetWorker(),
+                       image, &info);
+               if (error != B_OK)
+                       return error;
+
+               if (info != NULL) {
+                       _info = info;
+                       return B_OK;
+               }
+
+               teamLocker.Unlock();
+
+               // wait for the job to finish
+               switch (WaitFor(SimpleJobKey(image, 
JOB_TYPE_LOAD_IMAGE_DEBUG_INFO))) {
+                       case JOB_DEPENDENCY_SUCCEEDED:
+                       case JOB_DEPENDENCY_NOT_FOUND:
+                               // "Not found" can happen due to a race 
condition between
+                               // unlocking the worker and starting to wait.
+                               break;
+                       case JOB_DEPENDENCY_FAILED:
+                       case JOB_DEPENDENCY_ABORTED:
+                       default:
+                               return B_ERROR;
+               }
+
+               teamLocker.Lock();
+       }
+
+       _info = image->GetImageDebugInfo();
+       _info->AcquireReference();
+
+       return B_OK;
+}
diff --git a/src/apps/debugger/jobs/GetThreadStateJob.cpp 
b/src/apps/debugger/jobs/GetThreadStateJob.cpp
new file mode 100644
index 0000000..61ae3dd
--- /dev/null
+++ b/src/apps/debugger/jobs/GetThreadStateJob.cpp
@@ -0,0 +1,62 @@
+/*
+ * Copyright 2012, Rene Gollent, rene@xxxxxxxxxxxx
+ * Copyright 2009, Ingo Weinhold, ingo_weinhold@xxxxxxx
+ * Distributed under the terms of the MIT License.
+ */
+
+#include "Jobs.h"
+
+#include <AutoLocker.h>
+
+#include "CpuState.h"
+#include "DebuggerInterface.h"
+#include "Team.h"
+#include "Thread.h"
+
+
+GetThreadStateJob::GetThreadStateJob(DebuggerInterface* debuggerInterface,
+       Thread* thread)
+       :
+       fKey(thread, JOB_TYPE_GET_THREAD_STATE),
+       fDebuggerInterface(debuggerInterface),
+       fThread(thread)
+{
+       fThread->AcquireReference();
+}
+
+
+GetThreadStateJob::~GetThreadStateJob()
+{
+       fThread->ReleaseReference();
+}
+
+
+const JobKey&
+GetThreadStateJob::Key() const
+{
+       return fKey;
+}
+
+
+status_t
+GetThreadStateJob::Do()
+{
+       CpuState* state = NULL;
+       status_t error = fDebuggerInterface->GetCpuState(fThread->ID(), state);
+       BReference<CpuState> reference(state, true);
+
+       AutoLocker<Team> locker(fThread->GetTeam());
+
+       if (fThread->State() != THREAD_STATE_UNKNOWN)
+               return B_OK;
+
+       if (error == B_OK) {
+               fThread->SetState(THREAD_STATE_STOPPED);
+               fThread->SetCpuState(state);
+       } else if (error == B_BAD_THREAD_STATE) {
+               fThread->SetState(THREAD_STATE_RUNNING);
+       } else
+               return error;
+
+       return B_OK;
+}
diff --git a/src/apps/debugger/Jobs.h b/src/apps/debugger/jobs/Jobs.h
similarity index 100%
rename from src/apps/debugger/Jobs.h
rename to src/apps/debugger/jobs/Jobs.h
diff --git a/src/apps/debugger/jobs/LoadImageDebugInfoJob.cpp 
b/src/apps/debugger/jobs/LoadImageDebugInfoJob.cpp
new file mode 100644
index 0000000..dc1706c
--- /dev/null
+++ b/src/apps/debugger/jobs/LoadImageDebugInfoJob.cpp
@@ -0,0 +1,106 @@
+/*
+ * Copyright 2012, Rene Gollent, rene@xxxxxxxxxxxx
+ * Copyright 2009, Ingo Weinhold, ingo_weinhold@xxxxxxx
+ * Distributed under the terms of the MIT License.
+ */
+
+#include "Jobs.h"
+
+#include <AutoLocker.h>
+
+#include "Image.h"
+#include "ImageDebugInfo.h"
+#include "TeamDebugInfo.h"
+#include "Team.h"
+
+
+LoadImageDebugInfoJob::LoadImageDebugInfoJob(Image* image)
+       :
+       fKey(image, JOB_TYPE_LOAD_IMAGE_DEBUG_INFO),
+       fImage(image)
+{
+       fImage->AcquireReference();
+}
+
+
+LoadImageDebugInfoJob::~LoadImageDebugInfoJob()
+{
+       fImage->ReleaseReference();
+}
+
+
+const JobKey&
+LoadImageDebugInfoJob::Key() const
+{
+       return fKey;
+}
+
+
+status_t
+LoadImageDebugInfoJob::Do()
+{
+       // get an image info for the image
+       AutoLocker<Team> locker(fImage->GetTeam());
+       ImageInfo imageInfo(fImage->Info());
+       locker.Unlock();
+
+       // create the debug info
+       ImageDebugInfo* debugInfo;
+       status_t error = fImage->GetTeam()->DebugInfo()->LoadImageDebugInfo(
+               imageInfo, fImage->ImageFile(), debugInfo);
+
+       // set the result
+       locker.Lock();
+       if (error == B_OK) {
+               error = fImage->SetImageDebugInfo(debugInfo, 
IMAGE_DEBUG_INFO_LOADED);
+               debugInfo->ReleaseReference();
+       } else
+               fImage->SetImageDebugInfo(NULL, IMAGE_DEBUG_INFO_UNAVAILABLE);
+
+       return error;
+}
+
+
+/*static*/ status_t
+LoadImageDebugInfoJob::ScheduleIfNecessary(Worker* worker, Image* image,
+       ImageDebugInfo** _imageDebugInfo)
+{
+       AutoLocker<Team> teamLocker(image->GetTeam());
+
+       // If already loaded, we're done.
+       if (image->GetImageDebugInfo() != NULL) {
+               if (_imageDebugInfo != NULL) {
+                       *_imageDebugInfo = image->GetImageDebugInfo();
+                       (*_imageDebugInfo)->AcquireReference();
+               }
+               return B_OK;
+       }
+
+       // If already loading, the caller has to wait, if desired.
+       if (image->ImageDebugInfoState() == IMAGE_DEBUG_INFO_LOADING) {
+               if (_imageDebugInfo != NULL)
+                       *_imageDebugInfo = NULL;
+               return B_OK;
+       }
+
+       // If an earlier load attempt failed, bail out.
+       if (image->ImageDebugInfoState() != IMAGE_DEBUG_INFO_NOT_LOADED)
+               return B_ERROR;
+
+       // schedule a job
+       LoadImageDebugInfoJob* job = new(std::nothrow) 
LoadImageDebugInfoJob(image);
+       if (job == NULL)
+               return B_NO_MEMORY;
+
+       status_t error = worker->ScheduleJob(job);
+       if (error != B_OK) {
+               image->SetImageDebugInfo(NULL, IMAGE_DEBUG_INFO_UNAVAILABLE);
+               return error;
+       }
+
+       image->SetImageDebugInfo(NULL, IMAGE_DEBUG_INFO_LOADING);
+
+       if (_imageDebugInfo != NULL)
+               *_imageDebugInfo = NULL;
+       return B_OK;
+}
diff --git a/src/apps/debugger/jobs/LoadSourceCodeJob.cpp 
b/src/apps/debugger/jobs/LoadSourceCodeJob.cpp
new file mode 100644
index 0000000..4cb60a0
--- /dev/null
+++ b/src/apps/debugger/jobs/LoadSourceCodeJob.cpp
@@ -0,0 +1,93 @@
+/*
+ * Copyright 2012, Rene Gollent, rene@xxxxxxxxxxxx
+ * Copyright 2009, Ingo Weinhold, ingo_weinhold@xxxxxxx
+ * Distributed under the terms of the MIT License.
+ */
+
+#include "Jobs.h"
+
+#include <AutoLocker.h>
+
+#include "Architecture.h"
+#include "DebuggerInterface.h"
+#include "DisassembledCode.h"
+#include "Function.h"
+#include "FunctionInstance.h"
+#include "FileSourceCode.h"
+#include "Team.h"
+#include "TeamDebugInfo.h"
+
+
+LoadSourceCodeJob::LoadSourceCodeJob(
+       DebuggerInterface* debuggerInterface, Architecture* architecture,
+       Team* team, FunctionInstance* functionInstance, bool loadForFunction)
+       :
+       fKey(functionInstance, JOB_TYPE_LOAD_SOURCE_CODE),
+       fDebuggerInterface(debuggerInterface),
+       fArchitecture(architecture),
+       fTeam(team),
+       fFunctionInstance(functionInstance),
+       fLoadForFunction(loadForFunction)
+{
+       fFunctionInstance->AcquireReference();
+}
+
+
+LoadSourceCodeJob::~LoadSourceCodeJob()
+{
+       fFunctionInstance->ReleaseReference();
+}
+
+
+const JobKey&
+LoadSourceCodeJob::Key() const
+{
+       return fKey;
+}
+
+
+status_t
+LoadSourceCodeJob::Do()
+{
+       // if requested, try loading the source code for the function
+       Function* function = fFunctionInstance->GetFunction();
+       if (fLoadForFunction) {
+               FileSourceCode* sourceCode;
+               status_t error = fTeam->DebugInfo()->LoadSourceCode(
+                       function->SourceFile(), sourceCode);
+
+               AutoLocker<Team> locker(fTeam);
+
+               if (error == B_OK) {
+                       function->SetSourceCode(sourceCode, 
FUNCTION_SOURCE_LOADED);
+                       sourceCode->ReleaseReference();
+                       return B_OK;
+               }
+
+               function->SetSourceCode(NULL, FUNCTION_SOURCE_UNAVAILABLE);
+       }
+
+       // Only try to load the function instance code, if it's not overridden 
yet.
+       AutoLocker<Team> locker(fTeam);
+       if (fFunctionInstance->SourceCodeState() != FUNCTION_SOURCE_LOADING)
+               return B_OK;
+       locker.Unlock();
+
+       // disassemble the function
+       DisassembledCode* sourceCode = NULL;
+       status_t error = 
fTeam->DebugInfo()->DisassembleFunction(fFunctionInstance,
+               sourceCode);
+
+       // set the result
+       locker.Lock();
+       if (error == B_OK) {
+               if (fFunctionInstance->SourceCodeState() == 
FUNCTION_SOURCE_LOADING) {
+                       fFunctionInstance->SetSourceCode(sourceCode,
+                               FUNCTION_SOURCE_LOADED);
+                       sourceCode->ReleaseReference();
+               }
+       } else
+               fFunctionInstance->SetSourceCode(NULL, 
FUNCTION_SOURCE_UNAVAILABLE);
+
+       return error;
+}
diff --git a/src/apps/debugger/jobs/ResolveValueNodeJob.cpp 
b/src/apps/debugger/jobs/ResolveValueNodeJob.cpp
new file mode 100644
index 0000000..c810ad5
--- /dev/null
+++ b/src/apps/debugger/jobs/ResolveValueNodeJob.cpp
@@ -0,0 +1,254 @@
+/*
+ * Copyright 2012, Rene Gollent, rene@xxxxxxxxxxxx
+ * Copyright 2009, Ingo Weinhold, ingo_weinhold@xxxxxxx
+ * Distributed under the terms of the MIT License.
+ */
+
+#include "Jobs.h"
+
+#include <AutoLocker.h>
+
+#include "Architecture.h"
+#include "CpuState.h"
+#include "DebuggerInterface.h"
+#include "TeamTypeInformation.h"
+#include "Tracing.h"
+#include "Value.h"
+#include "ValueLoader.h"
+#include "ValueLocation.h"
+#include "ValueNode.h"
+#include "ValueNodeContainer.h"
+
+
+ResolveValueNodeValueJob::ResolveValueNodeValueJob(
+       DebuggerInterface* debuggerInterface, Architecture* architecture,
+       CpuState* cpuState, TeamTypeInformation* typeInformation,
+       ValueNodeContainer* container, ValueNode* valueNode)
+       :
+       fKey(valueNode, JOB_TYPE_RESOLVE_VALUE_NODE_VALUE),
+       fDebuggerInterface(debuggerInterface),
+       fArchitecture(architecture),
+       fCpuState(cpuState),
+       fTypeInformation(typeInformation),
+       fContainer(container),
+       fValueNode(valueNode)
+{
+       if (fCpuState != NULL)
+               fCpuState->AcquireReference();
+       fContainer->AcquireReference();
+       fValueNode->AcquireReference();
+}
+
+
+ResolveValueNodeValueJob::~ResolveValueNodeValueJob()
+{
+       if (fCpuState != NULL)
+               fCpuState->ReleaseReference();
+       fContainer->ReleaseReference();
+       fValueNode->ReleaseReference();
+}
+
+
+const JobKey&
+ResolveValueNodeValueJob::Key() const
+{
+       return fKey;
+}
+
+
+status_t
+ResolveValueNodeValueJob::Do()
+{
+       // check whether the node still belongs to the container
+       AutoLocker<ValueNodeContainer> containerLocker(fContainer);
+       if (fValueNode->Container() != fContainer)
+               return B_BAD_VALUE;
+
+       // if already resolved, we're done
+       status_t nodeResolutionState
+               = fValueNode->LocationAndValueResolutionState();
+       if (nodeResolutionState != VALUE_NODE_UNRESOLVED)
+               return nodeResolutionState;
+
+       containerLocker.Unlock();
+
+       // resolve
+       status_t error = _ResolveNodeValue();
+       if (error != B_OK) {
+               nodeResolutionState = 
fValueNode->LocationAndValueResolutionState();
+               if (nodeResolutionState != VALUE_NODE_UNRESOLVED)
+                       return nodeResolutionState;
+
+               containerLocker.Lock();
+               fValueNode->SetLocationAndValue(NULL, NULL, error);
+               containerLocker.Unlock();
+       }
+
+       return error;
+}
+
+
+status_t
+ResolveValueNodeValueJob::_ResolveNodeValue()
+{
+       // get the node child and parent node
+       AutoLocker<ValueNodeContainer> containerLocker(fContainer);
+       ValueNodeChild* nodeChild = fValueNode->NodeChild();
+       BReference<ValueNodeChild> nodeChildReference(nodeChild);
+
+       ValueNode* parentNode = nodeChild->Parent();
+       BReference<ValueNode> parentNodeReference(parentNode);
+
+       // Check whether the node child location has been resolved already
+       // (successfully).
+       status_t nodeChildResolutionState = 
nodeChild->LocationResolutionState();
+       bool nodeChildDone = nodeChildResolutionState != VALUE_NODE_UNRESOLVED;
+       if (nodeChildDone && nodeChildResolutionState != B_OK)
+               return nodeChildResolutionState;
+
+       // If the child node location has not been resolved yet, check whether 
the
+       // parent node location and value have been resolved already 
(successfully).
+       bool parentDone = true;
+       if (!nodeChildDone && parentNode != NULL) {
+               status_t parentResolutionState
+                       = parentNode->LocationAndValueResolutionState();
+               parentDone = parentResolutionState != VALUE_NODE_UNRESOLVED;
+               if (parentDone && parentResolutionState != B_OK)
+                       return parentResolutionState;
+       }
+
+       containerLocker.Unlock();
+
+       // resolve the parent node location and value, if necessary
+       if (!parentDone) {
+               status_t error = _ResolveParentNodeValue(parentNode);
+               if (error != B_OK) {
+                       
TRACE_LOCALS("ResolveValueNodeValueJob::_ResolveNodeValue(): value "
+                               "node: %p (\"%s\"): _ResolveParentNodeValue(%p) 
failed\n",
+                               fValueNode, fValueNode->Name().String(), 
parentNode);
+                       return error;
+               }
+
+               if (State() == JOB_STATE_WAITING)
+                       return B_OK;
+       }
+
+       // resolve the node child location, if necessary
+       if (!nodeChildDone) {
+               status_t error = _ResolveNodeChildLocation(nodeChild);
+               if (error != B_OK) {
+                       
TRACE_LOCALS("ResolveValueNodeValueJob::_ResolveNodeValue(): value "
+                               "node: %p (\"%s\"): 
_ResolveNodeChildLocation(%p) failed\n",
+                               fValueNode, fValueNode->Name().String(), 
nodeChild);
+                       return error;
+               }
+       }
+
+       // resolve the node location and value
+       ValueLoader valueLoader(fArchitecture, fDebuggerInterface,
+               fTypeInformation, fCpuState);
+       ValueLocation* location;
+       Value* value;
+       status_t error = fValueNode->ResolvedLocationAndValue(&valueLoader,
+               location, value);
+       if (error != B_OK) {
+               TRACE_LOCALS("ResolveValueNodeValueJob::_ResolveNodeValue(): 
value "
+                       "node: %p (\"%s\"): 
fValueNode->ResolvedLocationAndValue() "
+                       "failed\n", fValueNode, fValueNode->Name().String());
+               return error;
+       }
+       BReference<ValueLocation> locationReference(location, true);
+       BReference<Value> valueReference(value, true);
+
+       // set location and value on the node
+       containerLocker.Lock();
+       status_t nodeResolutionState
+               = fValueNode->LocationAndValueResolutionState();
+       if (nodeResolutionState != VALUE_NODE_UNRESOLVED)
+               return nodeResolutionState;
+       fValueNode->SetLocationAndValue(location, value, B_OK);
+       containerLocker.Unlock();
+
+       return B_OK;
+}
+
+
+status_t
+ResolveValueNodeValueJob::_ResolveNodeChildLocation(ValueNodeChild* nodeChild)
+{
+       // resolve the location
+       ValueLoader valueLoader(fArchitecture, fDebuggerInterface,
+               fTypeInformation, fCpuState);
+       ValueLocation* location = NULL;
+       status_t error = nodeChild->ResolveLocation(&valueLoader, location);
+       BReference<ValueLocation> locationReference(location, true);
+
+       // set the location on the node child
+       AutoLocker<ValueNodeContainer> containerLocker(fContainer);
+       status_t nodeChildResolutionState = 
nodeChild->LocationResolutionState();
+       if (nodeChildResolutionState == VALUE_NODE_UNRESOLVED)
+               nodeChild->SetLocation(location, error);
+       else
+               error = nodeChildResolutionState;
+
+       return error;
+}
+
+
+status_t
+ResolveValueNodeValueJob::_ResolveParentNodeValue(ValueNode* parentNode)
+{
+       AutoLocker<ValueNodeContainer> containerLocker(fContainer);
+
+       if (parentNode->Container() != fContainer)
+               return B_BAD_VALUE;
+
+       // if the parent node already has a value, we're done
+       status_t nodeResolutionState
+               = parentNode->LocationAndValueResolutionState();
+       if (nodeResolutionState != VALUE_NODE_UNRESOLVED)
+               return nodeResolutionState;
+
+       // check whether a job is already in progress
+       AutoLocker<Worker> workerLocker(GetWorker());
+       SimpleJobKey jobKey(parentNode, JOB_TYPE_RESOLVE_VALUE_NODE_VALUE);
+       if (GetWorker()->GetJob(jobKey) == NULL) {
+               workerLocker.Unlock();
+
+               // schedule the job
+               status_t error = GetWorker()->ScheduleJob(
+                       new(std::nothrow) 
ResolveValueNodeValueJob(fDebuggerInterface,
+                               fArchitecture, fCpuState, fTypeInformation, 
fContainer,
+                               parentNode));
+               if (error != B_OK) {
+                       // scheduling failed -- set the value to invalid
+                       parentNode->SetLocationAndValue(NULL, NULL, error);
+                       return error;
+               }
+       }
+
+       // wait for the job to finish
+       workerLocker.Unlock();
+       containerLocker.Unlock();
+
+       switch (WaitFor(jobKey)) {
+               case JOB_DEPENDENCY_SUCCEEDED:
+               case JOB_DEPENDENCY_NOT_FOUND:
+                       // "Not found" can happen due to a race condition 
between
+                       // unlocking the worker and starting to wait.
+                       break;
+               case JOB_DEPENDENCY_ACTIVE:
+                       return B_OK;
+               case JOB_DEPENDENCY_FAILED:
+               case JOB_DEPENDENCY_ABORTED:
+               default:
+                       return B_ERROR;
+       }
+
+       containerLocker.Lock();
+
+       // now there should be a value for the node
+       nodeResolutionState = parentNode->LocationAndValueResolutionState();
+       return nodeResolutionState != VALUE_NODE_UNRESOLVED
+               ? nodeResolutionState : B_ERROR;
+}
diff --git a/src/apps/debugger/jobs/RetrieveMemoryBlockJob.cpp 
b/src/apps/debugger/jobs/RetrieveMemoryBlockJob.cpp
new file mode 100644
index 0000000..888bfa4
--- /dev/null
+++ b/src/apps/debugger/jobs/RetrieveMemoryBlockJob.cpp
@@ -0,0 +1,62 @@
+/*
+ * Copyright 2012, Rene Gollent, rene@xxxxxxxxxxxx
+ * Copyright 2009, Ingo Weinhold, ingo_weinhold@xxxxxxx
+ * Distributed under the terms of the MIT License.
+ */
+
+#include "Jobs.h"
+
+#include <AutoLocker.h>
+#include <memory_private.h>
+
+#include "Team.h"
+#include "TeamMemory.h"
+#include "TeamMemoryBlock.h"
+
+
+RetrieveMemoryBlockJob::RetrieveMemoryBlockJob(Team* team,
+       TeamMemory* teamMemory, TeamMemoryBlock* memoryBlock)
+       :
+       fKey(memoryBlock, JOB_TYPE_GET_MEMORY_BLOCK),
+       fTeam(team),
+       fTeamMemory(teamMemory),
+       fMemoryBlock(memoryBlock)
+{
+       fTeamMemory->AcquireReference();
+       fMemoryBlock->AcquireReference();
+}
+
+
+RetrieveMemoryBlockJob::~RetrieveMemoryBlockJob()
+{
+       fTeamMemory->ReleaseReference();
+       fMemoryBlock->ReleaseReference();
+}
+
+
+const JobKey&
+RetrieveMemoryBlockJob::Key() const
+{
+       return fKey;
+}
+
+
+status_t
+RetrieveMemoryBlockJob::Do()
+{
+       ssize_t result = fTeamMemory->ReadMemory(fMemoryBlock->BaseAddress(),
+               fMemoryBlock->Data(), fMemoryBlock->Size());
+       if (result < 0)
+               return result;
+
+       uint32 protection = 0;
+       uint32 locking = 0;
+       status_t error = get_memory_properties(fTeam->ID(),
+               (const void *)fMemoryBlock->BaseAddress(), &protection, 
&locking);
+       if (error != B_OK)
+               return error;
+
+       fMemoryBlock->SetWritable((protection & B_WRITE_AREA) != 0);
+       fMemoryBlock->MarkValid();
+       return B_OK;
+}
diff --git a/src/apps/debugger/Worker.cpp b/src/apps/debugger/util/Worker.cpp
similarity index 100%
rename from src/apps/debugger/Worker.cpp
rename to src/apps/debugger/util/Worker.cpp
diff --git a/src/apps/debugger/Worker.h b/src/apps/debugger/util/Worker.h
similarity index 100%
rename from src/apps/debugger/Worker.h
rename to src/apps/debugger/util/Worker.h


Other related posts:

  • » [haiku-commits] haiku: hrev44804 - in src/apps/debugger: . controllers debug_managers jobs util - anevilyak