[haiku-commits] haiku: hrev43504 - in src/apps/debugger: . arch

  • From: anevilyak@xxxxxxxxx
  • To: haiku-commits@xxxxxxxxxxxxx
  • Date: Thu, 15 Dec 2011 04:32:24 +0100 (CET)

hrev43504 adds 2 changesets to branch 'master'
old head: d3e31951126b42f65cb57ac59eebeba003b34973
new head: 118ddee0fdddd28bb953d559713a8da1bcd0d06e

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

16875b8: Make CreateStackTrace() more flexible.
  
  CreateStackTrace() can now optionally be asked to limit the maximum
  number of frames it tries to unwind. In conjunction, it can also be
  passed an already existing partial stack trace, and be asked to
  unwind more frames from it.

118ddee: Adjust ThreadHandler's usage of CreateStackTrace().
  
  - Limit invocations of CreateStackTrace() in ThreadHandler to
    only unwind the topmost frame since that's all it actually
    cares about anyways. Also adjust Step Over to use this
    functionality in order to work with the correct frame addresses,
    since the CPU frame pointer register isn't entirely what we want
    here.

                                      [ Rene Gollent <anevilyak@xxxxxxxxx> ]

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

3 files changed, 57 insertions(+), 22 deletions(-)
src/apps/debugger/ThreadHandler.cpp     |   42 ++++++++++++++++++--------
src/apps/debugger/arch/Architecture.cpp |   33 ++++++++++++++++-----
src/apps/debugger/arch/Architecture.h   |    4 ++-

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

Commit:      16875b8c58c43e778fdf41b99134285052e5a5bb
URL:         http://cgit.haiku-os.org/haiku/commit/?id=16875b8
Author:      Rene Gollent <anevilyak@xxxxxxxxx>
Date:        Thu Dec 15 03:00:17 2011 UTC

Make CreateStackTrace() more flexible.

CreateStackTrace() can now optionally be asked to limit the maximum
number of frames it tries to unwind. In conjunction, it can also be
passed an already existing partial stack trace, and be asked to
unwind more frames from it.

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

diff --git a/src/apps/debugger/arch/Architecture.cpp 
b/src/apps/debugger/arch/Architecture.cpp
index 33e5460..084b8ee 100644
--- a/src/apps/debugger/arch/Architecture.cpp
+++ b/src/apps/debugger/arch/Architecture.cpp
@@ -94,18 +94,31 @@ Architecture::InitRegisterRules(CfaContext& context) const
 status_t
 Architecture::CreateStackTrace(Team* team,
        ImageDebugInfoProvider* imageInfoProvider, CpuState* cpuState,
-       StackTrace*& _stackTrace)
+       StackTrace*& _stackTrace, int32 maxStackDepth, bool useExistingTrace)
 {
        BReference<CpuState> cpuStateReference(cpuState);
 
-       // create the object
-       StackTrace* stackTrace = new(std::nothrow) StackTrace;
-       if (stackTrace == NULL)
-               return B_NO_MEMORY;
-       ObjectDeleter<StackTrace> stackTraceDeleter(stackTrace);
-
+       StackTrace* stackTrace = NULL;
+       ObjectDeleter<StackTrace> stackTraceDeleter;
        StackFrame* frame = NULL;
 
+       if (useExistingTrace)
+               stackTrace = _stackTrace;
+       else {
+               // create the object
+               stackTrace = new(std::nothrow) StackTrace;
+               if (stackTrace == NULL)
+                       return B_NO_MEMORY;
+               stackTraceDeleter.SetTo(stackTrace);
+       }
+
+       // if we're passed an already existing partial stack trace,
+       // attempt to continue building it from where it left off.
+       if (stackTrace->CountFrames() > 0) {
+               frame = stackTrace->FrameAt(stackTrace->CountFrames() - 1);
+               cpuState = frame->GetCpuState();
+       }
+
        while (cpuState != NULL) {
                // get the instruction pointer
                target_addr_t instructionPointer = 
cpuState->InstructionPointer();
@@ -169,11 +182,15 @@ Architecture::CreateStackTrace(Team* team,
                previousFrame->SetImage(image);
                previousFrame->SetFunction(function);
 
-               if (!stackTrace->AddFrame(previousFrame))
+               if (!stackTrace->AddFrame(previousFrame)) {
+                       delete previousFrame;
                        return B_NO_MEMORY;
+               }
 
                frame = previousFrame;
                cpuState = previousCpuState;
+               if (--maxStackDepth == 0)
+                       break;
        }
 
        stackTraceDeleter.Detach();
diff --git a/src/apps/debugger/arch/Architecture.h 
b/src/apps/debugger/arch/Architecture.h
index d74d652..1f0d40b 100644
--- a/src/apps/debugger/arch/Architecture.h
+++ b/src/apps/debugger/arch/Architecture.h
@@ -100,7 +100,9 @@ public:
                        status_t                        CreateStackTrace(Team* 
team,
                                                                        
ImageDebugInfoProvider* imageInfoProvider,
                                                                        
CpuState* cpuState,
-                                                                       
StackTrace*& _stackTrace);
+                                                                       
StackTrace*& _stackTrace,
+                                                                       int32 
maxStackDepth = -1,
+                                                                       bool 
useExistingTrace = false);
                                                                                
// team is not locked
 
 protected:

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

Revision:    hrev43504
Commit:      118ddee0fdddd28bb953d559713a8da1bcd0d06e
URL:         http://cgit.haiku-os.org/haiku/commit/?id=118ddee
Author:      Rene Gollent <anevilyak@xxxxxxxxx>
Date:        Thu Dec 15 03:27:38 2011 UTC

Adjust ThreadHandler's usage of CreateStackTrace().

- Limit invocations of CreateStackTrace() in ThreadHandler to
  only unwind the topmost frame since that's all it actually
  cares about anyways. Also adjust Step Over to use this
  functionality in order to work with the correct frame addresses,
  since the CPU frame pointer register isn't entirely what we want
  here.

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

diff --git a/src/apps/debugger/ThreadHandler.cpp 
b/src/apps/debugger/ThreadHandler.cpp
index 19450f9..c1932f2 100644
--- a/src/apps/debugger/ThreadHandler.cpp
+++ b/src/apps/debugger/ThreadHandler.cpp
@@ -253,7 +253,7 @@ ThreadHandler::HandleThreadAction(uint32 action)
 
        if (stackTrace == NULL && cpuState != NULL) {
                if (fDebuggerInterface->GetArchitecture()->CreateStackTrace(
-                               fThread->GetTeam(), this, cpuState, stackTrace) 
== B_OK) {
+                               fThread->GetTeam(), this, cpuState, stackTrace, 
1) == B_OK) {
                        stackTraceReference.SetTo(stackTrace, true);
                }
        }
@@ -324,7 +324,7 @@ ThreadHandler::HandleThreadAction(uint32 action)
                fStepMode = STEP_INTO;
                _SingleStepThread(frame->GetCpuState()->InstructionPointer());
        } else {
-               fPreviousFrameAddress = cpuState->StackFramePointer();
+               fPreviousFrameAddress = frame->FrameAddress();
                // step over
                fStepMode = STEP_OVER;
                if (!_DoStepOver(frame->GetCpuState()))
@@ -559,17 +559,32 @@ ThreadHandler::_HandleBreakpointHitStep(CpuState* 
cpuState)
        switch (fStepMode) {
                case STEP_OVER:
                {
-                       // If we're not in the same frame we started in, keep 
executing.
-                       if (cpuState->StackFramePointer() != 
fPreviousFrameAddress)
-                       {
-                               status_t error = _InstallTemporaryBreakpoint(
-                                       cpuState->InstructionPointer());
-                               if (error != B_OK)
-                                       _StepFallback();
-                               else
-                                       
_RunThread(cpuState->InstructionPointer());
-                               return true;
+                       StackTrace* stackTrace = fThread->GetStackTrace();
+                       BReference<StackTrace> stackTraceReference(stackTrace);
+
+                       if (stackTrace == NULL && cpuState != NULL) {
+                               if 
(fDebuggerInterface->GetArchitecture()->CreateStackTrace(
+                                               fThread->GetTeam(), this, 
cpuState, stackTrace, 1)
+                                               == B_OK) {
+                                       stackTraceReference.SetTo(stackTrace, 
true);
+                               }
+                       }
+                       if (stackTrace != NULL) {
+                               StackFrame* frame = stackTrace->FrameAt(0);
+                               // If we're not in the same frame we started in,
+                               // keep executing.
+                               if (frame != NULL && fPreviousFrameAddress
+                                               != 
stackTrace->FrameAt(0)->FrameAddress()) {
+                                       status_t error = 
_InstallTemporaryBreakpoint(
+                                               cpuState->InstructionPointer());
+                                       if (error != B_OK)
+                                               _StepFallback();
+                                       else
+                                               
_RunThread(cpuState->InstructionPointer());
+                                       return true;
+                               }
                        }
+
                        // If we're still in the statement, we continue 
single-stepping,
                        // otherwise we're done.
                        if (fStepStatement->ContainsAddress(
@@ -635,7 +650,8 @@ ThreadHandler::_HandleSingleStepStep(CpuState* cpuState)
 
                        if (stackTrace == NULL && cpuState != NULL) {
                                if 
(fDebuggerInterface->GetArchitecture()->CreateStackTrace(
-                                               fThread->GetTeam(), this, 
cpuState, stackTrace) == B_OK) {
+                                               fThread->GetTeam(), this, 
cpuState, stackTrace, 1)
+                                               == B_OK) {
                                        stackTraceReference.SetTo(stackTrace, 
true);
                                }
                        }


Other related posts: