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:
parent
23097b55e8
commit
b44541d2d1
5 changed files with 410 additions and 56 deletions
|
@ -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
|
||||
|
|
|
@ -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
|
||||
{
|
||||
}
|
|
@ -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);
|
||||
}
|
||||
}
|
|
@ -538,6 +538,10 @@ public class CStackFrame extends CDebugElement
|
|||
*/
|
||||
public Object getAdapter( Class adapter )
|
||||
{
|
||||
if ( adapter == CStackFrame.class )
|
||||
{
|
||||
return this;
|
||||
}
|
||||
if ( adapter == IStackFrame.class )
|
||||
{
|
||||
return this;
|
||||
|
|
|
@ -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.ICDIStackFrame;
|
|||
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 @@ public class CThread extends CDebugElement
|
|||
ISwitchToFrame,
|
||||
ICDIEventListener
|
||||
{
|
||||
private final static int MAX_STACK_DEPTH = 100;
|
||||
|
||||
/**
|
||||
* Underlying CDI thread.
|
||||
*/
|
||||
|
@ -61,7 +64,7 @@ public class CThread extends CDebugElement
|
|||
/**
|
||||
* Collection of stack frames
|
||||
*/
|
||||
private List fStackFrames;
|
||||
private ArrayList fStackFrames;
|
||||
|
||||
/**
|
||||
* Whether running.
|
||||
|
@ -97,6 +100,8 @@ public class CThread extends CDebugElement
|
|||
|
||||
private CStackFrame fLastStackFrame = null;
|
||||
|
||||
private int fLastStackDepth = 0;
|
||||
|
||||
/**
|
||||
* Constructor for CThread.
|
||||
* @param target
|
||||
|
@ -119,7 +124,7 @@ public class CThread extends CDebugElement
|
|||
*/
|
||||
protected void initialize()
|
||||
{
|
||||
fStackFrames = Collections.EMPTY_LIST;
|
||||
fStackFrames = new ArrayList();
|
||||
setRunning( false );
|
||||
// setRunning( !getCDIThread().isSuspended() );
|
||||
}
|
||||
|
@ -162,71 +167,68 @@ public class CThread extends CDebugElement
|
|||
{
|
||||
if ( isTerminated() )
|
||||
{
|
||||
fStackFrames = Collections.EMPTY_LIST;
|
||||
fStackFrames = new ArrayList();
|
||||
}
|
||||
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() )
|
||||
{
|
||||
fStackFrames = createAllStackFrames();
|
||||
setRefreshChildren( false );
|
||||
return fStackFrames;
|
||||
addStackFrames( frames, 0, frames.length );
|
||||
}
|
||||
ICDIStackFrame[] frames = getCDIStackFrames();
|
||||
// compute new or removed stack frames
|
||||
int offset = 0, length = frames.length;
|
||||
if ( length > fStackFrames.size() )
|
||||
else if ( depth < getLastStackDepth() )
|
||||
{
|
||||
// compute new frames
|
||||
offset = length - fStackFrames.size();
|
||||
for ( int i = offset - 1; i >= 0; i-- )
|
||||
disposeStackFrames( 0, getLastStackDepth() - depth );
|
||||
updateStackFrames( frames, 0, fStackFrames, fStackFrames.size() );
|
||||
if ( fStackFrames.size() < frames.length )
|
||||
{
|
||||
fStackFrames.add( 0, new CStackFrame( this, frames[i] ) );
|
||||
}
|
||||
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 );
|
||||
addStackFrames( frames, fStackFrames.size(), frames.length - fStackFrames.size() );
|
||||
}
|
||||
}
|
||||
else
|
||||
else if ( depth > getLastStackDepth() )
|
||||
{
|
||||
if ( frames.length == 0 )
|
||||
{
|
||||
fStackFrames = Collections.EMPTY_LIST;
|
||||
disposeStackFrames( frames.length - depth + getLastStackDepth(), depth - getLastStackDepth() );
|
||||
addStackFrames( frames, 0, depth - getLastStackDepth() );
|
||||
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
|
||||
// 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();
|
||||
fStackFrames = new ArrayList( frames.length );
|
||||
for ( int i = 0; i < frames.length; ++i )
|
||||
disposeStackFrames( 0, fStackFrames.size() );
|
||||
addStackFrames( frames, 0, frames.length );
|
||||
}
|
||||
else // we are in the same frame
|
||||
{
|
||||
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 );
|
||||
}
|
||||
}
|
||||
return fStackFrames;
|
||||
}
|
||||
|
||||
|
@ -239,10 +241,24 @@ public class CThread extends CDebugElement
|
|||
* </ul>
|
||||
*/
|
||||
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 @@ 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
|
||||
* them if required. Returns an empty collection if this thread is
|
||||
|
@ -326,20 +355,18 @@ public class CThread extends CDebugElement
|
|||
* 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 @@ public class CThread extends CDebugElement
|
|||
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 @@ public class CThread extends CDebugElement
|
|||
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.
|
||||
|
@ -1004,4 +1058,33 @@ public class CThread extends CDebugElement
|
|||
{
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue