1
0
Fork 0
mirror of https://github.com/eclipse-cdt/cdt synced 2025-04-29 19:45:01 +02:00

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

This commit is contained in:
Mikhail Khodjaiants 2002-11-16 00:48:31 +00:00
parent 23097b55e8
commit b44541d2d1
5 changed files with 410 additions and 56 deletions

View file

@ -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 2002-11-14 Alain Magloire
This is needed in post-mortem, application doing a This is needed in post-mortem, application doing a

View file

@ -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
{
}

View file

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

View file

@ -538,6 +538,10 @@ public class CStackFrame extends CDebugElement
*/ */
public Object getAdapter( Class adapter ) public Object getAdapter( Class adapter )
{ {
if ( adapter == CStackFrame.class )
{
return this;
}
if ( adapter == IStackFrame.class ) if ( adapter == IStackFrame.class )
{ {
return this; return this;

View file

@ -7,10 +7,10 @@
package org.eclipse.cdt.debug.internal.core.model; package org.eclipse.cdt.debug.internal.core.model;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collections;
import java.util.Iterator; import java.util.Iterator;
import java.util.List; import java.util.List;
import org.eclipse.cdt.debug.core.IDummyStackFrame;
import org.eclipse.cdt.debug.core.IInstructionStep; import org.eclipse.cdt.debug.core.IInstructionStep;
import org.eclipse.cdt.debug.core.IRestart; import org.eclipse.cdt.debug.core.IRestart;
import org.eclipse.cdt.debug.core.IState; import org.eclipse.cdt.debug.core.IState;
@ -33,6 +33,7 @@ import org.eclipse.cdt.debug.core.cdi.model.ICDIStackFrame;
import org.eclipse.cdt.debug.core.cdi.model.ICDITarget; import org.eclipse.cdt.debug.core.cdi.model.ICDITarget;
import org.eclipse.cdt.debug.core.cdi.model.ICDIThread; import org.eclipse.cdt.debug.core.cdi.model.ICDIThread;
import org.eclipse.cdt.debug.core.sourcelookup.ISourceMode; 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.DebugEvent;
import org.eclipse.debug.core.DebugException; import org.eclipse.debug.core.DebugException;
import org.eclipse.debug.core.model.IBreakpoint; import org.eclipse.debug.core.model.IBreakpoint;
@ -53,6 +54,8 @@ public class CThread extends CDebugElement
ISwitchToFrame, ISwitchToFrame,
ICDIEventListener ICDIEventListener
{ {
private final static int MAX_STACK_DEPTH = 100;
/** /**
* Underlying CDI thread. * Underlying CDI thread.
*/ */
@ -61,7 +64,7 @@ public class CThread extends CDebugElement
/** /**
* Collection of stack frames * Collection of stack frames
*/ */
private List fStackFrames; private ArrayList fStackFrames;
/** /**
* Whether running. * Whether running.
@ -97,6 +100,8 @@ public class CThread extends CDebugElement
private CStackFrame fLastStackFrame = null; private CStackFrame fLastStackFrame = null;
private int fLastStackDepth = 0;
/** /**
* Constructor for CThread. * Constructor for CThread.
* @param target * @param target
@ -119,7 +124,7 @@ public class CThread extends CDebugElement
*/ */
protected void initialize() protected void initialize()
{ {
fStackFrames = Collections.EMPTY_LIST; fStackFrames = new ArrayList();
setRunning( false ); setRunning( false );
// setRunning( !getCDIThread().isSuspended() ); // setRunning( !getCDIThread().isSuspended() );
} }
@ -162,71 +167,68 @@ public class CThread extends CDebugElement
{ {
if ( isTerminated() ) if ( isTerminated() )
{ {
fStackFrames = Collections.EMPTY_LIST; fStackFrames = new ArrayList();
} }
else if ( refreshChildren ) else if ( refreshChildren )
{ {
if ( fStackFrames.size() > 0 )
{
Object frame = fStackFrames.get( fStackFrames.size() - 1 );
if ( frame instanceof IDummyStackFrame )
{
fStackFrames.remove( frame );
}
}
int depth = getStackDepth();
ICDIStackFrame[] frames = ( depth != 0 ) ?
getCDIStackFrames( 0, ( depth > getMaxStackDepth() ) ? getMaxStackDepth() - 1 : depth - 1 ) :
new ICDIStackFrame[0];
if ( fStackFrames.isEmpty() ) if ( fStackFrames.isEmpty() )
{ {
fStackFrames = createAllStackFrames(); addStackFrames( frames, 0, frames.length );
setRefreshChildren( false );
return fStackFrames;
} }
ICDIStackFrame[] frames = getCDIStackFrames(); else if ( depth < getLastStackDepth() )
// compute new or removed stack frames
int offset = 0, length = frames.length;
if ( length > fStackFrames.size() )
{ {
// compute new frames disposeStackFrames( 0, getLastStackDepth() - depth );
offset = length - fStackFrames.size(); updateStackFrames( frames, 0, fStackFrames, fStackFrames.size() );
for ( int i = offset - 1; i >= 0; i-- ) if ( fStackFrames.size() < frames.length )
{ {
fStackFrames.add( 0, new CStackFrame( this, frames[i] ) ); addStackFrames( frames, fStackFrames.size(), frames.length - fStackFrames.size() );
}
length = fStackFrames.size() - offset;
}
else if ( length < fStackFrames.size() )
{
// compute removed children
int removed = fStackFrames.size() - length;
for ( int i = 0; i < removed; i++ )
{
((CStackFrame)fStackFrames.get( 0 )).dispose();
fStackFrames.remove( 0 );
} }
} }
else else if ( depth > getLastStackDepth() )
{ {
if ( frames.length == 0 ) disposeStackFrames( frames.length - depth + getLastStackDepth(), depth - getLastStackDepth() );
{ addStackFrames( frames, 0, depth - getLastStackDepth() );
fStackFrames = Collections.EMPTY_LIST; updateStackFrames( frames, depth - getLastStackDepth(), fStackFrames, frames.length - depth + getLastStackDepth() );
} }
else else // depth == getLastStackDepth()
{
if ( depth != 0 )
{ {
// same number of frames - if top frames are in different // same number of frames - if top frames are in different
// method, replace all frames // method, replace all frames
ICDIStackFrame newTop = frames[0]; ICDIStackFrame newTopFrame = frames[0];
ICDIStackFrame oldTop = ((CStackFrame)fStackFrames.get( 0 ) ).getLastCDIStackFrame(); ICDIStackFrame oldTopFrame = ((CStackFrame)fStackFrames.get( 0 ) ).getLastCDIStackFrame();
if ( !CStackFrame.equalFrame( newTop, oldTop ) ) if ( !CStackFrame.equalFrame( newTopFrame, oldTopFrame ) )
{ {
disposeStackFrames(); disposeStackFrames( 0, fStackFrames.size() );
fStackFrames = new ArrayList( frames.length ); addStackFrames( frames, 0, frames.length );
for ( int i = 0; i < frames.length; ++i ) }
else // we are in the same frame
{ {
fStackFrames.add( new CStackFrame( this, frames[i] ) ); updateStackFrames( frames, 0, fStackFrames, frames.length );
}
offset = fStackFrames.size();
} }
} }
} }
// update preserved frames if ( depth > getMaxStackDepth() )
if ( offset < fStackFrames.size() )
{ {
updateStackFrames( frames, offset, fStackFrames, length ); fStackFrames.add( new CDummyStackFrame( this ) );
}
} }
setLastStackDepth( depth );
setRefreshChildren( false ); setRefreshChildren( false );
} }
}
return fStackFrames; return fStackFrames;
} }
@ -239,10 +241,24 @@ public class CThread extends CDebugElement
* </ul> * </ul>
*/ */
protected ICDIStackFrame[] getCDIStackFrames() throws DebugException 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 try
{ {
return getCDIThread().getStackFrames(); return getCDIThread().getStackFrames( lowFrame, highFrame );
} }
catch( CDIException e ) catch( CDIException e )
{ {
@ -277,6 +293,19 @@ public class CThread extends CDebugElement
} }
} }
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 * Returns this thread's current stack frames as a list, computing
* them if required. Returns an empty collection if this thread is * them if required. Returns an empty collection if this thread is
@ -326,20 +355,18 @@ public class CThread extends CDebugElement
* underlying stack frames. * underlying stack frames.
* *
* @exception DebugException if this method fails. Reasons include: * @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 ); List list= new ArrayList( frames.length );
for ( int i = 0; i < frames.length; ++i ) for ( int i = 0; i < frames.length; ++i )
{ {
list.add( new CStackFrame( this, frames[i] ) ); list.add( new CStackFrame( this, frames[i] ) );
} }
if ( depth > frames.length )
{
list.add( new CDummyStackFrame( this ) );
}
return list; return list;
} }
@ -672,7 +699,11 @@ public class CThread extends CDebugElement
Iterator it = fStackFrames.iterator(); Iterator it = fStackFrames.iterator();
while( it.hasNext() ) while( it.hasNext() )
{ {
((CStackFrame)it.next()).preserve(); CStackFrame frame = (CStackFrame)(((IAdaptable)it.next()).getAdapter( CStackFrame.class ));
if ( frame != null )
{
frame.preserve();
}
} }
setRefreshChildren( true ); setRefreshChildren( true );
} }
@ -689,12 +720,35 @@ public class CThread extends CDebugElement
Iterator it = fStackFrames.iterator(); Iterator it = fStackFrames.iterator();
while( it.hasNext() ) while( it.hasNext() )
{ {
((CStackFrame)it.next()).dispose(); CStackFrame frame = (CStackFrame)(((IAdaptable)it.next()).getAdapter( CStackFrame.class ));
if ( frame != null )
{
((CStackFrame)frame).dispose();
}
} }
fStackFrames.clear(); fStackFrames.clear();
setLastStackDepth( 0 );
setRefreshChildren( true ); 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 * Notification this thread has terminated - update state
* and fire a terminate event. * and fire a terminate event.
@ -1004,4 +1058,33 @@ public class CThread extends CDebugElement
{ {
return fLastStackFrame; 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;
}
} }