mirror of
https://github.com/eclipse-cdt/cdt
synced 2025-07-31 12:55:40 +02:00
fixed for bug# 151253 -Single steping a mult-thread program to fast results in unexpected behavior
This commit is contained in:
parent
f8b90d3d95
commit
06016b3405
7 changed files with 228 additions and 109 deletions
|
@ -184,9 +184,10 @@ public class ExpressionManager extends Manager {
|
|||
Target target = (Target)frame.getTarget();
|
||||
Thread currentThread = (Thread)target.getCurrentThread();
|
||||
StackFrame currentFrame = currentThread.getCurrentStackFrame();
|
||||
target.lockTarget();
|
||||
try {
|
||||
target.setCurrentThread(frame.getThread(), false);
|
||||
((Thread)frame.getThread()).setCurrentStackFrame(frame, false);
|
||||
try {
|
||||
MISession mi = target.getMISession();
|
||||
CommandFactory factory = mi.getCommandFactory();
|
||||
MIVarCreate var = factory.createMIVarCreate(code);
|
||||
|
@ -204,6 +205,7 @@ public class ExpressionManager extends Manager {
|
|||
} finally {
|
||||
target.setCurrentThread(currentThread, false);
|
||||
currentThread.setCurrentStackFrame(currentFrame, false);
|
||||
target.releaseTarget();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -254,9 +254,10 @@ public class RegisterManager extends Manager {
|
|||
Target target = (Target)frame.getTarget();
|
||||
Thread currentThread = (Thread)target.getCurrentThread();
|
||||
StackFrame currentFrame = currentThread.getCurrentStackFrame();
|
||||
target.lockTarget();
|
||||
try {
|
||||
target.setCurrentThread(frame.getThread(), false);
|
||||
((Thread)frame.getThread()).setCurrentStackFrame(frame, false);
|
||||
try {
|
||||
MISession mi = target.getMISession();
|
||||
CommandFactory factory = mi.getCommandFactory();
|
||||
MIVarCreate var = factory.createMIVarCreate(regName);
|
||||
|
@ -269,8 +270,12 @@ public class RegisterManager extends Manager {
|
|||
} catch (MIException e) {
|
||||
throw new MI2CDIException(e);
|
||||
} finally {
|
||||
try {
|
||||
target.setCurrentThread(currentThread, false);
|
||||
currentThread.setCurrentStackFrame(currentFrame, false);
|
||||
} finally {
|
||||
target.releaseTarget();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -424,13 +424,15 @@ public class SourceManager extends Manager {
|
|||
Target target = (Target)frame.getTarget();
|
||||
Thread currentThread = (Thread)target.getCurrentThread();
|
||||
StackFrame currentFrame = currentThread.getCurrentStackFrame();
|
||||
target.lockTarget();
|
||||
try {
|
||||
target.setCurrentThread(frame.getThread(), false);
|
||||
((Thread)frame.getThread()).setCurrentStackFrame(frame, false);
|
||||
try {
|
||||
return getDetailTypeName(target, variable);
|
||||
} finally {
|
||||
target.setCurrentThread(currentThread, false);
|
||||
currentThread.setCurrentStackFrame(currentFrame, false);
|
||||
target.releaseTarget();
|
||||
}
|
||||
}
|
||||
public String getDetailTypeName(Target target, String typename) throws CDIException {
|
||||
|
@ -460,13 +462,15 @@ public class SourceManager extends Manager {
|
|||
Target target = (Target)frame.getTarget();
|
||||
Thread currentThread = (Thread)target.getCurrentThread();
|
||||
StackFrame currentFrame = currentThread.getCurrentStackFrame();
|
||||
target.lockTarget();
|
||||
try {
|
||||
target.setCurrentThread(frame.getThread(), false);
|
||||
((Thread)frame.getThread()).setCurrentStackFrame(frame, false);
|
||||
try {
|
||||
return getTypeName(target, variable);
|
||||
} finally {
|
||||
target.setCurrentThread(currentThread, false);
|
||||
currentThread.setCurrentStackFrame(currentFrame, false);
|
||||
target.releaseTarget();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -175,9 +175,10 @@ public class VariableManager extends Manager {
|
|||
Target target = (Target)frame.getTarget();
|
||||
Thread currentThread = (Thread)target.getCurrentThread();
|
||||
StackFrame currentFrame = currentThread.getCurrentStackFrame();
|
||||
target.lockTarget();
|
||||
try {
|
||||
target.setCurrentThread(frame.getThread(), false);
|
||||
((Thread)frame.getThread()).setCurrentStackFrame(frame, false);
|
||||
try {
|
||||
MISession miSession = target.getMISession();
|
||||
RxThread rxThread = miSession.getRxThread();
|
||||
rxThread.setEnableConsole(false);
|
||||
|
@ -196,6 +197,7 @@ public class VariableManager extends Manager {
|
|||
rxThread.setEnableConsole(true);
|
||||
target.setCurrentThread(currentThread, false);
|
||||
currentThread.setCurrentStackFrame(currentFrame, false);
|
||||
target.releaseTarget();
|
||||
}
|
||||
} else {
|
||||
throw new CDIException(CdiResources.getString("cdi.VariableManager.Unknown_type")); //$NON-NLS-1$
|
||||
|
@ -367,9 +369,10 @@ public class VariableManager extends Manager {
|
|||
Target target = (Target)argDesc.getTarget();
|
||||
Thread currentThread = (Thread)target.getCurrentThread();
|
||||
StackFrame currentFrame = currentThread.getCurrentStackFrame();
|
||||
target.lockTarget();
|
||||
try {
|
||||
target.setCurrentThread(stack.getThread(), false);
|
||||
((Thread)stack.getThread()).setCurrentStackFrame(stack, false);
|
||||
try {
|
||||
MISession mi = target.getMISession();
|
||||
CommandFactory factory = mi.getCommandFactory();
|
||||
MIVarCreate var = factory.createMIVarCreate(name);
|
||||
|
@ -388,6 +391,7 @@ public class VariableManager extends Manager {
|
|||
} finally {
|
||||
target.setCurrentThread(currentThread, false);
|
||||
currentThread.setCurrentStackFrame(currentFrame, false);
|
||||
target.releaseTarget();
|
||||
}
|
||||
}
|
||||
return argument;
|
||||
|
@ -398,9 +402,10 @@ public class VariableManager extends Manager {
|
|||
Target target = (Target)frame.getTarget();
|
||||
Thread currentThread = (Thread)target.getCurrentThread();
|
||||
StackFrame currentFrame = currentThread.getCurrentStackFrame();
|
||||
target.lockTarget();
|
||||
try {
|
||||
target.setCurrentThread(frame.getThread(), false);
|
||||
((Thread)frame.getThread()).setCurrentStackFrame(frame, false);
|
||||
try {
|
||||
MISession mi = target.getMISession();
|
||||
CommandFactory factory = mi.getCommandFactory();
|
||||
int depth = frame.getThread().getStackFrameCount();
|
||||
|
@ -429,6 +434,7 @@ public class VariableManager extends Manager {
|
|||
} finally {
|
||||
target.setCurrentThread(currentThread, false);
|
||||
currentThread.setCurrentStackFrame(currentFrame, false);
|
||||
target.releaseTarget();
|
||||
}
|
||||
return (ICDIArgumentDescriptor[]) argObjects.toArray(new ICDIArgumentDescriptor[0]);
|
||||
}
|
||||
|
@ -489,9 +495,10 @@ public class VariableManager extends Manager {
|
|||
Target target = (Target)frame.getTarget();
|
||||
Thread currentThread = (Thread)target.getCurrentThread();
|
||||
StackFrame currentFrame = currentThread.getCurrentStackFrame();
|
||||
target.lockTarget();
|
||||
try {
|
||||
target.setCurrentThread(frame.getThread(), false);
|
||||
((Thread)frame.getThread()).setCurrentStackFrame(frame, false);
|
||||
try {
|
||||
MISession mi = target.getMISession();
|
||||
CommandFactory factory = mi.getCommandFactory();
|
||||
int level = frame.getLevel();
|
||||
|
@ -514,6 +521,7 @@ public class VariableManager extends Manager {
|
|||
} finally {
|
||||
target.setCurrentThread(currentThread, false);
|
||||
currentThread.setCurrentStackFrame(currentFrame, false);
|
||||
target.releaseTarget();
|
||||
}
|
||||
return (ICDILocalVariableDescriptor[]) varObjects.toArray(new ICDILocalVariableDescriptor[0]);
|
||||
}
|
||||
|
@ -530,9 +538,10 @@ public class VariableManager extends Manager {
|
|||
Target target = (Target)varDesc.getTarget();
|
||||
Thread currentThread = (Thread)target.getCurrentThread();
|
||||
StackFrame currentFrame = currentThread.getCurrentStackFrame();
|
||||
target.lockTarget();
|
||||
try {
|
||||
target.setCurrentThread(stack.getThread(), false);
|
||||
((Thread)stack.getThread()).setCurrentStackFrame(stack, false);
|
||||
try {
|
||||
MISession mi = target.getMISession();
|
||||
CommandFactory factory = mi.getCommandFactory();
|
||||
MIVarCreate var = factory.createMIVarCreate(name);
|
||||
|
@ -551,6 +560,7 @@ public class VariableManager extends Manager {
|
|||
} finally {
|
||||
target.setCurrentThread(currentThread, false);
|
||||
currentThread.setCurrentStackFrame(currentFrame, false);
|
||||
target.releaseTarget();
|
||||
}
|
||||
}
|
||||
return local;
|
||||
|
|
|
@ -13,6 +13,7 @@ package org.eclipse.cdt.debug.mi.core.cdi.model;
|
|||
import java.math.BigInteger;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import org.eclipse.cdt.debug.core.cdi.CDIException;
|
||||
import org.eclipse.cdt.debug.core.cdi.ICDIAddressLocation;
|
||||
import org.eclipse.cdt.debug.core.cdi.ICDICondition;
|
||||
|
@ -87,6 +88,45 @@ import org.eclipse.cdt.debug.mi.core.output.MIThreadSelectInfo;
|
|||
*/
|
||||
public class Target extends SessionObject implements ICDITarget {
|
||||
|
||||
public class Lock {
|
||||
|
||||
java.lang.Thread heldBy;
|
||||
int count;
|
||||
|
||||
public Lock() {
|
||||
|
||||
}
|
||||
|
||||
public synchronized void aquire() {
|
||||
if (heldBy == null || heldBy == java.lang.Thread.currentThread()) {
|
||||
heldBy = java.lang.Thread.currentThread();
|
||||
count++;
|
||||
} else {
|
||||
while (true) {
|
||||
try {
|
||||
wait();
|
||||
} catch (InterruptedException e) {
|
||||
}
|
||||
if (heldBy == null) {
|
||||
heldBy = java.lang.Thread.currentThread();
|
||||
count++;
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public synchronized void release() {
|
||||
if (heldBy == null || heldBy != java.lang.Thread.currentThread()) {
|
||||
throw new IllegalStateException("Thread does not own lock");
|
||||
}
|
||||
if(--count == 0) {
|
||||
heldBy = null;
|
||||
notifyAll();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
MISession miSession;
|
||||
ICDITargetConfiguration fConfiguration;
|
||||
Thread[] noThreads = new Thread[0];
|
||||
|
@ -95,6 +135,7 @@ public class Target extends SessionObject implements ICDITarget {
|
|||
String fEndian = null;
|
||||
boolean suspended = true;
|
||||
boolean deferBreakpoints = true;
|
||||
Lock lock = new Lock();
|
||||
|
||||
public Target(Session s, MISession mi) {
|
||||
super(s);
|
||||
|
@ -102,6 +143,14 @@ public class Target extends SessionObject implements ICDITarget {
|
|||
currentThreads = noThreads;
|
||||
}
|
||||
|
||||
public void lockTarget() {
|
||||
lock.aquire();
|
||||
}
|
||||
|
||||
public void releaseTarget() {
|
||||
lock.release();
|
||||
}
|
||||
|
||||
public MISession getMISession() {
|
||||
return miSession;
|
||||
}
|
||||
|
@ -419,7 +468,6 @@ public class Target extends SessionObject implements ICDITarget {
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @see org.eclipse.cdt.debug.core.cdi.model.ICDITarget#stepIntoInstruction()
|
||||
*/
|
||||
|
|
|
@ -109,8 +109,9 @@ public class Thread extends CObject implements ICDIThread {
|
|||
currentFrames = new ArrayList();
|
||||
Target target = (Target)getTarget();
|
||||
ICDIThread currentThread = target.getCurrentThread();
|
||||
target.setCurrentThread(this, false);
|
||||
target.lockTarget();
|
||||
try {
|
||||
target.setCurrentThread(this, false);
|
||||
MISession mi = target.getMISession();
|
||||
CommandFactory factory = mi.getCommandFactory();
|
||||
MIStackListFrames frames = factory.createMIStackListFrames();
|
||||
|
@ -131,6 +132,7 @@ public class Thread extends CObject implements ICDIThread {
|
|||
//System.out.println(e);
|
||||
} finally {
|
||||
target.setCurrentThread(currentThread, false);
|
||||
target.releaseTarget();
|
||||
}
|
||||
// assign the currentFrame if it was not done yet.
|
||||
if (currentFrame == null) {
|
||||
|
@ -152,8 +154,9 @@ public class Thread extends CObject implements ICDIThread {
|
|||
if (stackdepth == 0) {
|
||||
Target target = (Target)getTarget();
|
||||
ICDIThread currentThread = target.getCurrentThread();
|
||||
target.setCurrentThread(this, false);
|
||||
target.lockTarget();
|
||||
try {
|
||||
target.setCurrentThread(this, false);
|
||||
MISession mi = target.getMISession();
|
||||
CommandFactory factory = mi.getCommandFactory();
|
||||
MIStackInfoDepth depth = factory.createMIStackInfoDepth();
|
||||
|
@ -184,6 +187,7 @@ public class Thread extends CObject implements ICDIThread {
|
|||
throw new MI2CDIException(e);
|
||||
} finally {
|
||||
target.setCurrentThread(currentThread, false);
|
||||
target.releaseTarget();
|
||||
}
|
||||
}
|
||||
return stackdepth;
|
||||
|
@ -197,8 +201,9 @@ public class Thread extends CObject implements ICDIThread {
|
|||
currentFrames = new ArrayList();
|
||||
Target target = (Target) getTarget();
|
||||
ICDIThread currentThread = target.getCurrentThread();
|
||||
target.setCurrentThread(this, false);
|
||||
target.lockTarget();
|
||||
try {
|
||||
target.setCurrentThread(this, false);
|
||||
int depth = getStackFrameCount();
|
||||
int upperBound;
|
||||
// try to get the largest subset.
|
||||
|
@ -230,6 +235,7 @@ public class Thread extends CObject implements ICDIThread {
|
|||
//System.out.println(e);
|
||||
} finally {
|
||||
target.setCurrentThread(currentThread, false);
|
||||
target.releaseTarget();
|
||||
}
|
||||
// take time to assign the currentFrame, if it is in the set
|
||||
if (currentFrame == null) {
|
||||
|
@ -268,7 +274,6 @@ public class Thread extends CObject implements ICDIThread {
|
|||
}
|
||||
}
|
||||
|
||||
try {
|
||||
Target target = (Target)getTarget();
|
||||
MISession mi = target.getMISession();
|
||||
CommandFactory factory = mi.getCommandFactory();
|
||||
|
@ -277,6 +282,8 @@ public class Thread extends CObject implements ICDIThread {
|
|||
int miLevel = getStackFrameCount() - frameLevel;
|
||||
MIStackSelectFrame frame = factory.createMIStackSelectFrame(miLevel);
|
||||
// Set ourself as the current thread first.
|
||||
target.lockTarget();
|
||||
try {
|
||||
target.setCurrentThread(this, doUpdate);
|
||||
mi.postCommand(frame);
|
||||
MIInfo info = frame.getMIInfo();
|
||||
|
@ -300,6 +307,8 @@ public class Thread extends CObject implements ICDIThread {
|
|||
}
|
||||
} catch (MIException e) {
|
||||
throw new MI2CDIException(e);
|
||||
} finally {
|
||||
target.releaseTarget();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -314,8 +323,13 @@ public class Thread extends CObject implements ICDIThread {
|
|||
* @see org.eclipse.cdt.debug.core.cdi.model.ICDIExecuteStep#stepInto(int)
|
||||
*/
|
||||
public void stepInto(int count) throws CDIException {
|
||||
((Target)getTarget()).lockTarget();
|
||||
try {
|
||||
((Target)getTarget()).setCurrentThread(this);
|
||||
getTarget().stepInto(count);
|
||||
} finally {
|
||||
((Target)getTarget()).releaseTarget();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -329,8 +343,13 @@ public class Thread extends CObject implements ICDIThread {
|
|||
* @see org.eclipse.cdt.debug.core.cdi.model.ICDIExecuteStep#stepIntoInstruction(int)
|
||||
*/
|
||||
public void stepIntoInstruction(int count) throws CDIException {
|
||||
((Target)getTarget()).lockTarget();
|
||||
try {
|
||||
((Target)getTarget()).setCurrentThread(this);
|
||||
getTarget().stepIntoInstruction(count);
|
||||
} finally {
|
||||
((Target)getTarget()).releaseTarget();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -344,9 +363,13 @@ public class Thread extends CObject implements ICDIThread {
|
|||
* @see org.eclipse.cdt.debug.core.cdi.model.ICDIExecuteStep#stepOver(int)
|
||||
*/
|
||||
public void stepOver(int count) throws CDIException {
|
||||
((Target)getTarget()).lockTarget();
|
||||
try {
|
||||
((Target)getTarget()).setCurrentThread(this);
|
||||
getTarget().stepOver(count);
|
||||
|
||||
} finally {
|
||||
((Target)getTarget()).releaseTarget();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -360,8 +383,13 @@ public class Thread extends CObject implements ICDIThread {
|
|||
* @see org.eclipse.cdt.debug.core.cdi.model.ICDIExecuteStep#stepOverInstruction(int)
|
||||
*/
|
||||
public void stepOverInstruction(int count) throws CDIException {
|
||||
((Target)getTarget()).lockTarget();
|
||||
try {
|
||||
((Target)getTarget()).setCurrentThread(this);
|
||||
getTarget().stepOverInstruction(count);
|
||||
} finally {
|
||||
((Target)getTarget()).releaseTarget();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -382,8 +410,13 @@ public class Thread extends CObject implements ICDIThread {
|
|||
* @see org.eclipse.cdt.debug.core.cdi.model.ICDIExecuteStep#stepUntil(org.eclipse.cdt.debug.core.cdi.ICDILocation)
|
||||
*/
|
||||
public void stepUntil(ICDILocation location) throws CDIException {
|
||||
((Target)getTarget()).lockTarget();
|
||||
try {
|
||||
((Target)getTarget()).setCurrentThread(this);
|
||||
getTarget().stepUntil(location);
|
||||
} finally {
|
||||
((Target)getTarget()).releaseTarget();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -412,26 +445,38 @@ public class Thread extends CObject implements ICDIThread {
|
|||
*/
|
||||
|
||||
public void resume(boolean passSignal) throws CDIException {
|
||||
((Target)getTarget()).lockTarget();
|
||||
try {
|
||||
((Target)getTarget()).setCurrentThread(this);
|
||||
getTarget().resume(passSignal);
|
||||
} finally {
|
||||
((Target)getTarget()).releaseTarget();
|
||||
}
|
||||
}
|
||||
/* (non-Javadoc)
|
||||
* @see org.eclipse.cdt.debug.core.cdi.model.ICDIExecuteResume#resume(org.eclipse.cdt.debug.core.cdi.ICDILocation)
|
||||
*/
|
||||
public void resume(ICDILocation location) throws CDIException {
|
||||
// TODO Auto-generated method stub
|
||||
((Target)getTarget()).lockTarget();
|
||||
try {
|
||||
((Target)getTarget()).setCurrentThread(this);
|
||||
getTarget().resume(location);
|
||||
|
||||
} finally {
|
||||
((Target)getTarget()).releaseTarget();
|
||||
}
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.eclipse.cdt.debug.core.cdi.model.ICDIExecuteResume#resume(org.eclipse.cdt.debug.core.cdi.model.ICDISignal)
|
||||
*/
|
||||
public void resume(ICDISignal signal) throws CDIException {
|
||||
((Target)getTarget()).lockTarget();
|
||||
try {
|
||||
((Target)getTarget()).setCurrentThread(this);
|
||||
getTarget().resume(signal);
|
||||
|
||||
} finally {
|
||||
((Target)getTarget()).releaseTarget();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -240,6 +240,8 @@ public abstract class VariableDescriptor extends CObject implements ICDIVariable
|
|||
StackFrame currentFrame = currentThread.getCurrentStackFrame();
|
||||
StackFrame frame = (StackFrame)getStackFrame();
|
||||
Thread thread = (Thread)getThread();
|
||||
target.lockTarget();
|
||||
try {
|
||||
if (frame != null) {
|
||||
target.setCurrentThread(frame.getThread(), false);
|
||||
((Thread)frame.getThread()).setCurrentStackFrame(frame, false);
|
||||
|
@ -250,7 +252,6 @@ public abstract class VariableDescriptor extends CObject implements ICDIVariable
|
|||
CommandFactory factory = mi.getCommandFactory();
|
||||
String exp = "sizeof(" + getTypeName() + ")"; //$NON-NLS-1$ //$NON-NLS-2$
|
||||
MIDataEvaluateExpression evaluate = factory.createMIDataEvaluateExpression(exp);
|
||||
try {
|
||||
mi.postCommand(evaluate);
|
||||
MIDataEvaluateExpressionInfo info = evaluate.getMIDataEvaluateExpressionInfo();
|
||||
if (info == null) {
|
||||
|
@ -260,12 +261,16 @@ public abstract class VariableDescriptor extends CObject implements ICDIVariable
|
|||
} catch (MIException e) {
|
||||
throw new MI2CDIException(e);
|
||||
} finally {
|
||||
try {
|
||||
if (frame != null) {
|
||||
target.setCurrentThread(currentThread, false);
|
||||
currentThread.setCurrentStackFrame(currentFrame, false);
|
||||
} else if (thread != null) {
|
||||
target.setCurrentThread(currentThread, false);
|
||||
}
|
||||
} finally {
|
||||
target.releaseTarget();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue