Skip to main content

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [List Home]
[cdt-patch] Display limited number of stack frames if the backtrace is too deep.

If the backtrace is very deep the debugger is unable to parse MI output. The limited number of stack frames will be displayed.

Index: ChangeLog
===================================================================
RCS file: /home/tools/org.eclipse.cdt.debug.core/ChangeLog,v
retrieving revision 1.52
diff -u -r1.52 ChangeLog
--- ChangeLog 14 Nov 2002 21:09:54 -0000 1.52
+++ ChangeLog 16 Nov 2002 00:47:47 -0000
@@ -1,3 +1,11 @@
+2002-11-15 Mikhail Khodjaiants
+ If the backtrace is very deep the debugger is unable to parse MI output.
+ The limited number of stack frames will be displayed.
+ * IDummyStackFrame.java
+ * CDummyStackFrame.java
+ * CStackFrame.java
+ * CThread.java
+
 2002-11-14 Alain Magloire
 
  This is needed in post-mortem, application doing a
Index: src/org/eclipse/cdt/debug/core/IDummyStackFrame.java
===================================================================
RCS file: src/org/eclipse/cdt/debug/core/IDummyStackFrame.java
diff -N src/org/eclipse/cdt/debug/core/IDummyStackFrame.java
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ src/org/eclipse/cdt/debug/core/IDummyStackFrame.java 16 Nov 2002 00:47:47 -0000
@@ -0,0 +1,15 @@
+/*
+ *(c) Copyright QNX Software Systems Ltd. 2002.
+ * All Rights Reserved.
+ *
+ */
+package org.eclipse.cdt.debug.core;
+
+/**
+ * Enter type comment.
+ *
+ * @since: Nov 13, 2002
+ */
+public interface IDummyStackFrame
+{
+}
Index: src/org/eclipse/cdt/debug/internal/core/model/CDummyStackFrame.java
===================================================================
RCS file: src/org/eclipse/cdt/debug/internal/core/model/CDummyStackFrame.java
diff -N src/org/eclipse/cdt/debug/internal/core/model/CDummyStackFrame.java
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ src/org/eclipse/cdt/debug/internal/core/model/CDummyStackFrame.java 16 Nov 2002 00:47:47 -0000
@@ -0,0 +1,244 @@
+/*
+ *(c) Copyright QNX Software Systems Ltd. 2002.
+ * All Rights Reserved.
+ *
+ */
+package org.eclipse.cdt.debug.internal.core.model;
+
+import org.eclipse.cdt.debug.core.IDummyStackFrame;
+import org.eclipse.debug.core.DebugException;
+import org.eclipse.debug.core.model.IRegisterGroup;
+import org.eclipse.debug.core.model.IStackFrame;
+import org.eclipse.debug.core.model.IThread;
+import org.eclipse.debug.core.model.IVariable;
+
+/**
+ * Enter type comment.
+ *
+ * @since: Nov 13, 2002
+ */
+public class CDummyStackFrame extends CDebugElement implements IStackFrame, IDummyStackFrame
+{
+ /**
+  * Containing thread.
+  */
+ private CThread fThread;
+
+ /**
+  * Constructor for CDummyStackFrame.
+  * @param target
+  */
+ public CDummyStackFrame( CThread thread )
+ {
+  super( (CDebugTarget)thread.getDebugTarget() );
+  setThread( thread );
+ }
+
+ /* (non-Javadoc)
+  * @see org.eclipse.debug.core.model.IStackFrame#getThread()
+  */
+ public IThread getThread()
+ {
+  return fThread;
+ }
+
+ /* (non-Javadoc)
+  * @see org.eclipse.debug.core.model.IStackFrame#getVariables()
+  */
+ public IVariable[] getVariables() throws DebugException
+ {
+  return new IVariable[0];
+ }
+
+ /* (non-Javadoc)
+  * @see org.eclipse.debug.core.model.IStackFrame#hasVariables()
+  */
+ public boolean hasVariables() throws DebugException
+ {
+  return false;
+ }
+
+ /* (non-Javadoc)
+  * @see org.eclipse.debug.core.model.IStackFrame#getLineNumber()
+  */
+ public int getLineNumber() throws DebugException
+ {
+  return 0;
+ }
+
+ /* (non-Javadoc)
+  * @see org.eclipse.debug.core.model.IStackFrame#getCharStart()
+  */
+ public int getCharStart() throws DebugException
+ {
+  return 0;
+ }
+
+ /* (non-Javadoc)
+  * @see org.eclipse.debug.core.model.IStackFrame#getCharEnd()
+  */
+ public int getCharEnd() throws DebugException
+ {
+  return 0;
+ }
+
+ /* (non-Javadoc)
+  * @see org.eclipse.debug.core.model.IStackFrame#getName()
+  */
+ public String getName() throws DebugException
+ {
+  return "...";
+ }
+
+ /* (non-Javadoc)
+  * @see org.eclipse.debug.core.model.IStackFrame#getRegisterGroups()
+  */
+ public IRegisterGroup[] getRegisterGroups() throws DebugException
+ {
+  return ((CDebugTarget)getDebugTarget()).getRegisterGroups();
+ }
+
+ /* (non-Javadoc)
+  * @see org.eclipse.debug.core.model.IStackFrame#hasRegisterGroups()
+  */
+ public boolean hasRegisterGroups() throws DebugException
+ {
+  return ((CDebugTarget)getDebugTarget()).getRegisterGroups().length > 0;
+ }
+
+ /* (non-Javadoc)
+  * @see org.eclipse.debug.core.model.IStep#canStepInto()
+  */
+ public boolean canStepInto()
+ {
+  return false;
+ }
+
+ /* (non-Javadoc)
+  * @see org.eclipse.debug.core.model.IStep#canStepOver()
+  */
+ public boolean canStepOver()
+ {
+  return false;
+ }
+
+ /* (non-Javadoc)
+  * @see org.eclipse.debug.core.model.IStep#canStepReturn()
+  */
+ public boolean canStepReturn()
+ {
+  return false;
+ }
+
+ /* (non-Javadoc)
+  * @see org.eclipse.debug.core.model.IStep#isStepping()
+  */
+ public boolean isStepping()
+ {
+  return false;
+ }
+
+ /* (non-Javadoc)
+  * @see org.eclipse.debug.core.model.IStep#stepInto()
+  */
+ public void stepInto() throws DebugException
+ {
+ }
+
+ /* (non-Javadoc)
+  * @see org.eclipse.debug.core.model.IStep#stepOver()
+  */
+ public void stepOver() throws DebugException
+ {
+ }
+
+ /* (non-Javadoc)
+  * @see org.eclipse.debug.core.model.IStep#stepReturn()
+  */
+ public void stepReturn() throws DebugException
+ {
+ }
+
+ /* (non-Javadoc)
+  * @see org.eclipse.debug.core.model.ISuspendResume#canResume()
+  */
+ public boolean canResume()
+ {
+  return false;
+ }
+
+ /* (non-Javadoc)
+  * @see org.eclipse.debug.core.model.ISuspendResume#canSuspend()
+  */
+ public boolean canSuspend()
+ {
+  return false;
+ }
+
+ /* (non-Javadoc)
+  * @see org.eclipse.debug.core.model.ISuspendResume#isSuspended()
+  */
+ public boolean isSuspended()
+ {
+  return false;
+ }
+
+ /* (non-Javadoc)
+  * @see org.eclipse.debug.core.model.ISuspendResume#resume()
+  */
+ public void resume() throws DebugException
+ {
+ }
+
+ /* (non-Javadoc)
+  * @see org.eclipse.debug.core.model.ISuspendResume#suspend()
+  */
+ public void suspend() throws DebugException
+ {
+ }
+
+ /* (non-Javadoc)
+  * @see org.eclipse.debug.core.model.ITerminate#canTerminate()
+  */
+ public boolean canTerminate()
+ {
+  return false;
+ }
+
+ /* (non-Javadoc)
+  * @see org.eclipse.debug.core.model.ITerminate#isTerminated()
+  */
+ public boolean isTerminated()
+ {
+  return false;
+ }
+
+ /* (non-Javadoc)
+  * @see org.eclipse.debug.core.model.ITerminate#terminate()
+  */
+ public void terminate() throws DebugException
+ {
+ }
+
+ /**
+  * Sets the containing thread.
+  *
+  * @param thread the containing thread
+  */
+ protected void setThread( CThread thread )
+ {
+  fThread = thread;
+ }
+
+ /* (non-Javadoc)
+  * @see org.eclipse.core.runtime.IAdaptable#getAdapter(Class)
+  */
+ public Object getAdapter( Class adapter )
+ {
+  if ( adapter.equals( IDummyStackFrame.class ) )
+   return this;
+  if ( adapter.equals( IStackFrame.class ) )
+   return this;
+  return super.getAdapter(adapter);
+ }
+}
Index: src/org/eclipse/cdt/debug/internal/core/model/CStackFrame.java
===================================================================
RCS file: /home/tools/org.eclipse.cdt.debug.core/src/org/eclipse/cdt/debug/internal/core/model/CStackFrame.java,v
retrieving revision 1.10
diff -u -r1.10 CStackFrame.java
--- src/org/eclipse/cdt/debug/internal/core/model/CStackFrame.java 13 Nov 2002 21:01:51 -0000 1.10
+++ src/org/eclipse/cdt/debug/internal/core/model/CStackFrame.java 16 Nov 2002 00:47:48 -0000
@@ -538,6 +538,10 @@
   */
  public Object getAdapter( Class adapter )
  {
+  if ( adapter == CStackFrame.class )
+  {
+   return this;
+  }
   if ( adapter == IStackFrame.class )
   {
    return this;
Index: src/org/eclipse/cdt/debug/internal/core/model/CThread.java
===================================================================
RCS file: /home/tools/org.eclipse.cdt.debug.core/src/org/eclipse/cdt/debug/internal/core/model/CThread.java,v
retrieving revision 1.17
diff -u -r1.17 CThread.java
--- src/org/eclipse/cdt/debug/internal/core/model/CThread.java 15 Oct 2002 17:06:57 -0000 1.17
+++ src/org/eclipse/cdt/debug/internal/core/model/CThread.java 16 Nov 2002 00:47:48 -0000
@@ -7,10 +7,10 @@
 package org.eclipse.cdt.debug.internal.core.model;
 
 import java.util.ArrayList;
-import java.util.Collections;
 import java.util.Iterator;
 import java.util.List;
 
+import org.eclipse.cdt.debug.core.IDummyStackFrame;
 import org.eclipse.cdt.debug.core.IInstructionStep;
 import org.eclipse.cdt.debug.core.IRestart;
 import org.eclipse.cdt.debug.core.IState;
@@ -33,6 +33,7 @@
 import org.eclipse.cdt.debug.core.cdi.model.ICDITarget;
 import org.eclipse.cdt.debug.core.cdi.model.ICDIThread;
 import org.eclipse.cdt.debug.core.sourcelookup.ISourceMode;
+import org.eclipse.core.runtime.IAdaptable;
 import org.eclipse.debug.core.DebugEvent;
 import org.eclipse.debug.core.DebugException;
 import org.eclipse.debug.core.model.IBreakpoint;
@@ -53,6 +54,8 @@
          ISwitchToFrame,
          ICDIEventListener
 {
+ private final static int MAX_STACK_DEPTH = 100;
+
  /**
   * Underlying CDI thread.
   */
@@ -61,7 +64,7 @@
  /**
   * Collection of stack frames
   */
- private List fStackFrames;
+ private ArrayList fStackFrames;
 
  /**
   * Whether running.
@@ -96,6 +99,8 @@
  private boolean fIsCurrent = false;
  
  private CStackFrame fLastStackFrame = null; 

+ private int fLastStackDepth = 0;
 
  /**
   * Constructor for CThread.
@@ -119,7 +124,7 @@
   */
  protected void initialize()
  {
-  fStackFrames = Collections.EMPTY_LIST;
+  fStackFrames = new ArrayList();
   setRunning( false );
 //  setRunning( !getCDIThread().isSuspended() );
  }
@@ -162,70 +167,67 @@
   {
    if ( isTerminated() )
    {
-    fStackFrames = Collections.EMPTY_LIST;
+    fStackFrames = new ArrayList();
    }
    else if ( refreshChildren )
    {
-    if ( fStackFrames.isEmpty() )
+    if ( fStackFrames.size() > 0 )
     {
-     fStackFrames = createAllStackFrames();
-     setRefreshChildren( false );
-     return fStackFrames;
-    }
-    ICDIStackFrame[] frames = getCDIStackFrames();
-    // compute new or removed stack frames
-    int offset = 0, length = frames.length;
-    if ( length > fStackFrames.size() )
-    {
-     // compute new frames
-     offset = length - fStackFrames.size();
-     for ( int i = offset - 1; i >= 0; i-- )
+     Object frame = fStackFrames.get( fStackFrames.size() - 1 );
+     if ( frame instanceof IDummyStackFrame )
      {
-      fStackFrames.add( 0, new CStackFrame( this, frames[i] ) );
+      fStackFrames.remove( frame );
      }
-     length = fStackFrames.size() - offset;
     }
-    else if ( length < fStackFrames.size() )
+    int depth = getStackDepth();
+    ICDIStackFrame[] frames = ( depth != 0 ) ?
+         getCDIStackFrames( 0, ( depth > getMaxStackDepth() ) ? getMaxStackDepth() - 1 : depth - 1 ) :
+         new ICDIStackFrame[0];
+    if ( fStackFrames.isEmpty() )
     {
-     // compute removed children
-     int removed = fStackFrames.size() - length;
-     for ( int i = 0; i < removed; i++ )
-     {
-      ((CStackFrame)fStackFrames.get( 0 )).dispose();
-      fStackFrames.remove( 0 );
-     }
+     addStackFrames( frames, 0, frames.length );
     }
-    else
+    else if ( depth < getLastStackDepth() )
     {
-     if ( frames.length == 0 )
+     disposeStackFrames( 0, getLastStackDepth() - depth );
+     updateStackFrames( frames, 0, fStackFrames, fStackFrames.size() );
+     if ( fStackFrames.size() < frames.length )
      {
-      fStackFrames = Collections.EMPTY_LIST;
+      addStackFrames( frames, fStackFrames.size(), frames.length - fStackFrames.size() );
      }
-     else
+    }
+    else if ( depth > getLastStackDepth() )
+    {
+     disposeStackFrames( frames.length - depth + getLastStackDepth(), depth - getLastStackDepth() );
+     addStackFrames( frames, 0, depth - getLastStackDepth() );
+     updateStackFrames( frames, depth - getLastStackDepth(), fStackFrames, frames.length - depth + getLastStackDepth() );
+    }
+    else // depth == getLastStackDepth()
+    {
+     if ( depth != 0 )
      {
       // same number of frames - if top frames are in different
       // method, replace all frames
-      ICDIStackFrame newTop = frames[0];
-      ICDIStackFrame oldTop = ((CStackFrame)fStackFrames.get( 0 ) ).getLastCDIStackFrame();
-      if ( !CStackFrame.equalFrame( newTop, oldTop ) )
+      ICDIStackFrame newTopFrame = frames[0];
+      ICDIStackFrame oldTopFrame = ((CStackFrame)fStackFrames.get( 0 ) ).getLastCDIStackFrame();
+      if ( !CStackFrame.equalFrame( newTopFrame, oldTopFrame ) )
+      {
+       disposeStackFrames( 0, fStackFrames.size() );
+       addStackFrames( frames, 0, frames.length );
+      }
+      else // we are in the same frame
       {
-       disposeStackFrames();
-       fStackFrames = new ArrayList( frames.length );
-       for ( int i = 0; i < frames.length; ++i )
-       {
-        fStackFrames.add( new CStackFrame( this, frames[i] ) );
-       }
-       offset = fStackFrames.size();
+       updateStackFrames( frames, 0, fStackFrames, frames.length );
       }
      }
     }
-    // update preserved frames
-    if ( offset < fStackFrames.size() )
+    if ( depth > getMaxStackDepth() )
     {
-     updateStackFrames( frames, offset, fStackFrames, length );
+     fStackFrames.add( new CDummyStackFrame( this ) );
     }
+    setLastStackDepth( depth );
+    setRefreshChildren( false );
    }
-   setRefreshChildren( false );
   }
   return fStackFrames;
  }
@@ -240,9 +242,23 @@
   */
  protected ICDIStackFrame[] getCDIStackFrames() throws DebugException
  {
+  return new ICDIStackFrame[0];
+ }
+
+ /**
+  * Retrieves and returns underlying stack frames between <code>lowFrame<code/>
+  * and <code>highFrame<code/>.
+  *
+  * @return list of <code>StackFrame</code>
+  * @exception DebugException if this method fails.  Reasons include:
+  * <ul>
+  * </ul>
+  */
+ protected ICDIStackFrame[] getCDIStackFrames( int lowFrame, int highFrame ) throws DebugException
+ {
   try
   {
-   return getCDIThread().getStackFrames();
+   return getCDIThread().getStackFrames( lowFrame, highFrame );
   }
   catch( CDIException e )
   {
@@ -277,6 +293,19 @@
   }
  }
 
+ protected void addStackFrames( ICDIStackFrame[] newFrames,
+           int startIndex,
+           int length )
+ {
+  if ( newFrames.length >= startIndex + length )
+  {
+   for ( int i = 0; i < length; ++i )
+   {
+    fStackFrames.add( i, new CStackFrame( this, newFrames[startIndex + i] ) );
+   }
+  }
+ }
+
  /**
   * Returns this thread's current stack frames as a list, computing
   * them if required. Returns an empty collection if this thread is
@@ -326,20 +355,18 @@
   * underlying stack frames.
   *
   * @exception DebugException if this method fails.  Reasons include:
-  * <ul>
-  * <li>Failure communicating with the VM.  The DebugException's
-  * status code contains the underlying exception responsible for
-  * the failure.</li>
-  * </ul>
   */
- protected List createAllStackFrames() throws DebugException
+ protected List createAllStackFrames( int depth, ICDIStackFrame[] frames ) throws DebugException
  {
-  ICDIStackFrame[] frames = getCDIStackFrames();
   List list= new ArrayList( frames.length );
   for ( int i = 0; i < frames.length; ++i )
   {
    list.add( new CStackFrame( this, frames[i] ) );
   }
+  if ( depth > frames.length )
+  {
+   list.add( new CDummyStackFrame( this ) );
+  }
   return list;
  }
 
@@ -672,7 +699,11 @@
   Iterator it = fStackFrames.iterator();
   while( it.hasNext() )
   {
-   ((CStackFrame)it.next()).preserve();
+   CStackFrame frame = (CStackFrame)(((IAdaptable)it.next()).getAdapter( CStackFrame.class ));
+   if ( frame != null )
+   {
+    frame.preserve();
+   }
   }
   setRefreshChildren( true );
  }
@@ -689,12 +720,35 @@
   Iterator it = fStackFrames.iterator();
   while( it.hasNext() )
   {
-   ((CStackFrame)it.next()).dispose();
+   CStackFrame frame = (CStackFrame)(((IAdaptable)it.next()).getAdapter( CStackFrame.class ));
+   if ( frame != null )
+   {
+    ((CStackFrame)frame).dispose();
+   }
   }
   fStackFrames.clear();
+  setLastStackDepth( 0 );
   setRefreshChildren( true );
  }
 
+ protected void disposeStackFrames( int index, int length )
+ {
+  List removeList = new ArrayList( length );
+  Iterator it = fStackFrames.iterator();
+  int counter = 0;
+  while( it.hasNext() )
+  {
+   CStackFrame frame = (CStackFrame)(((IAdaptable)it.next()).getAdapter( CStackFrame.class ));
+   if ( frame != null && counter >= index && counter < index + length )
+   {
+    frame.dispose();
+    removeList.add( frame );
+   }
+   ++counter;
+  }
+  fStackFrames.removeAll( removeList );
+ }
+
  /**
   * Notification this thread has terminated - update state
   * and fire a terminate event.
@@ -1003,5 +1057,34 @@
  private CStackFrame getLastStackFrame()
  {
   return fLastStackFrame;
+ }

+ protected int getStackDepth() throws DebugException
+ {
+  int depth = 0;
+  try
+  {
+   depth = getCDIThread().getStackFrameCount();
+  }
+  catch( CDIException e )
+  {
+//   targetRequestFailed( e.getMessage(), null );
+  }
+  return depth;
+ }

+ protected int getMaxStackDepth()
+ {
+  return MAX_STACK_DEPTH;
+ }

+ private void setLastStackDepth( int depth )
+ {
+  fLastStackDepth = depth;
+ }

+ private int getLastStackDepth()
+ {
+  return fLastStackDepth;
  }
 }


Back to the top