From 255b92bfbd131a066d75fd1d592f0898579c5a0d Mon Sep 17 00:00:00 2001 From: Marc Khouzam Date: Wed, 16 Jul 2008 19:46:15 +0000 Subject: [PATCH] Bug 240556 If no frame context is provided in an expression, but an execution (thread) is present, then we define the expression to belong to the top-most frame of that thread. --- .../dd/mi/service/ExpressionService.java | 11 +++++++- .../dd/tests/gdb/ExpressionServiceTest.java | 27 ++++++++++++++++++- 2 files changed, 36 insertions(+), 2 deletions(-) diff --git a/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/ExpressionService.java b/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/ExpressionService.java index a0b717b442b..a02e3ad8579 100644 --- a/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/ExpressionService.java +++ b/plugins/org.eclipse.dd.mi/src/org/eclipse/dd/mi/service/ExpressionService.java @@ -501,7 +501,16 @@ public class ExpressionService extends AbstractDsfService implements IExpression IMIExecutionDMContext execCtx = DMContexts.getAncestorOfType(ctx, IMIExecutionDMContext.class); if (execCtx != null) { - return new MIExpressionDMC(getSession().getId(), expression, relExpr, execCtx); + // If we have a thread context but not a frame context, we give the user + // the expression as per the top-most frame of the specified thread. + // To do this, we create our own frame context. + MIStack stackService = getServicesTracker().getService(MIStack.class); + if (stackService != null) { + frameDmc = stackService.createFrameDMContext(execCtx, 0); + return new MIExpressionDMC(getSession().getId(), expression, relExpr, frameDmc); + } + + return new InvalidContextExpressionDMC(getSession().getId(), expression, execCtx); } IMemoryDMContext memoryCtx = DMContexts.getAncestorOfType(ctx, IMemoryDMContext.class); diff --git a/plugins/org.eclipse.dd.tests.gdb/src/org/eclipse/dd/tests/gdb/ExpressionServiceTest.java b/plugins/org.eclipse.dd.tests.gdb/src/org/eclipse/dd/tests/gdb/ExpressionServiceTest.java index df5f8a509fb..a54ec26992e 100644 --- a/plugins/org.eclipse.dd.tests.gdb/src/org/eclipse/dd/tests/gdb/ExpressionServiceTest.java +++ b/plugins/org.eclipse.dd.tests.gdb/src/org/eclipse/dd/tests/gdb/ExpressionServiceTest.java @@ -1161,7 +1161,7 @@ public class ExpressionServiceTest extends BaseTestCase { * * @return void */ - // @Test + @Test public void testGlobalVariables() throws Throwable { // Step to a stack level of 2 to be able to test differen stack frames @@ -1259,6 +1259,31 @@ public class ExpressionServiceTest extends BaseTestCase { executeExpressionSubTests(tests, frameDmc); } + /** + * This test makes sure that if a request for expression values are made with + * a thread selected, the top-most stack frame is used for evaluation + */ + @Test + public void testThreadContext() throws Throwable { + + // Step to a stack level of 2 to be able to test differen stack frames + SyncUtil.SyncRunToLocation("locals2"); + MIStoppedEvent stoppedEvent = SyncUtil.SyncStep(StepType.STEP_OVER); + + // Create a map of expressions to expected values. + Map tests = new HashMap(); + + // First make sure we have a different value on the other stack frame and that we select + // a frame that is not the top frame + tests.put("lIntVar", new String[] { "0x3039", "030071", "11000000111001", "12345", "12345" }); + executeExpressionSubTests(tests, SyncUtil.SyncGetStackFrame(stoppedEvent.getDMContext(), 1)); + + // Now check that we get the same values as the top stack when selecting the thread only + tests = new HashMap(); + tests.put("lIntVar", new String[] { "0x1a85", "015205", "1101010000101", "6789", "6789" }); + executeExpressionSubTests(tests, stoppedEvent.getDMContext()); + } + /** * This test verifies that the ExpressionService can handle having a * child variable with the same name in two methods that also have the same name