diff --git a/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/gdb/service/DebugNewProcessSequence.java b/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/gdb/service/DebugNewProcessSequence.java index acd2c10c2cc..0d06a83ebc5 100644 --- a/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/gdb/service/DebugNewProcessSequence.java +++ b/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/gdb/service/DebugNewProcessSequence.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2011, 2012 Ericsson and others. + * Copyright (c) 2011, 2013 Ericsson and others. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at @@ -28,6 +28,7 @@ import org.eclipse.cdt.dsf.concurrent.RequestMonitor; import org.eclipse.cdt.dsf.datamodel.DMContexts; import org.eclipse.cdt.dsf.datamodel.IDMContext; import org.eclipse.cdt.dsf.debug.service.IBreakpoints.IBreakpointsTargetDMContext; +import org.eclipse.cdt.dsf.debug.service.IMemory.IMemoryDMContext; import org.eclipse.cdt.dsf.debug.service.IRunControl.IContainerDMContext; import org.eclipse.cdt.dsf.gdb.IGDBLaunchConfigurationConstants; import org.eclipse.cdt.dsf.gdb.internal.GdbPlugin; @@ -106,6 +107,7 @@ public class DebugNewProcessSequence extends ReflectionSequence { // For post-mortem launch only "stepSpecifyCoreFile", //$NON-NLS-1$ + "stepInitializeMemory", //$NON-NLS-1$ "stepStartTrackingBreakpoints", //$NON-NLS-1$ "stepStartExecution", //$NON-NLS-1$ "stepCleanupBaseSequence", //$NON-NLS-1$ @@ -443,6 +445,21 @@ public class DebugNewProcessSequence extends ReflectionSequence { } } + /** + * Initialize the memory service with the data for given process. + * @since 4.2 + */ + @Execute + public void stepInitializeMemory(final RequestMonitor rm) { + IGDBMemory memory = fTracker.getService(IGDBMemory.class); + IMemoryDMContext memContext = DMContexts.getAncestorOfType(getContainerContext(), IMemoryDMContext.class); + if (memory == null || memContext == null) { + rm.done(); + return; + } + memory.initializeMemoryData(memContext, rm); + } + /** * Start executing the program. */ diff --git a/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/gdb/service/GDBMemory.java b/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/gdb/service/GDBMemory.java index ecb4b3276d0..9795f8553d7 100644 --- a/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/gdb/service/GDBMemory.java +++ b/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/gdb/service/GDBMemory.java @@ -21,6 +21,7 @@ import org.eclipse.cdt.dsf.concurrent.DataRequestMonitor; import org.eclipse.cdt.dsf.concurrent.ImmediateExecutor; import org.eclipse.cdt.dsf.concurrent.ImmediateRequestMonitor; import org.eclipse.cdt.dsf.concurrent.RequestMonitor; +import org.eclipse.cdt.dsf.concurrent.Sequence; import org.eclipse.cdt.dsf.datamodel.DMContexts; import org.eclipse.cdt.dsf.datamodel.IDMContext; import org.eclipse.cdt.dsf.debug.service.IExpressions; @@ -28,7 +29,6 @@ import org.eclipse.cdt.dsf.debug.service.IExpressions.IExpressionDMContext; import org.eclipse.cdt.dsf.debug.service.IMemory; import org.eclipse.cdt.dsf.debug.service.IRunControl.IContainerDMContext; import org.eclipse.cdt.dsf.debug.service.IRunControl.IExitedDMEvent; -import org.eclipse.cdt.dsf.debug.service.IRunControl.IStartedDMEvent; import org.eclipse.cdt.dsf.gdb.internal.GdbPlugin; import org.eclipse.cdt.dsf.gdb.service.command.IGDBControl; import org.eclipse.cdt.dsf.mi.service.MIMemory; @@ -56,7 +56,7 @@ public class GDBMemory extends MIMemory implements IGDBMemory { /** * We assume the endianness is the same for all processes because GDB supports only one target. */ - private boolean fIsBigEndian = false; + private Boolean fIsBigEndian; public GDBMemory(DsfSession session) { super(session); @@ -121,15 +121,59 @@ public class GDBMemory extends MIMemory implements IGDBMemory { }); } - @DsfServiceEventHandler - public void eventDispatched(IStartedDMEvent event) { - if (event.getDMContext() instanceof IContainerDMContext) { - IMemoryDMContext memContext = DMContexts.getAncestorOfType(event.getDMContext(), IMemoryDMContext.class); - if (memContext != null) { - readAddressSize(memContext); - readEndianness(memContext); + @Override + public void initializeMemoryData(final IMemoryDMContext memContext, RequestMonitor rm) { + ImmediateExecutor.getInstance().execute(new Sequence(getExecutor(), rm) { + + private Step[] fSteps = new Step[] { + new Step() { + @Override + public void execute(final RequestMonitor requestMonitor) { + Integer addrSize = fAddressSizes.get(memContext); + if (addrSize != null) { + requestMonitor.done(); + return; + } + readAddressSize( + memContext, + new DataRequestMonitor(ImmediateExecutor.getInstance(), requestMonitor) { + @Override + @ConfinedToDsfExecutor("fExecutor") + protected void handleSuccess() { + fAddressSizes.put(memContext, getData()); + requestMonitor.done(); + } + }); + } + }, + + new Step() { + @Override + public void execute(final RequestMonitor requestMonitor) { + if ( fIsBigEndian != null) { + requestMonitor.done(); + return; + } + readEndianness( + memContext, + new DataRequestMonitor(ImmediateExecutor.getInstance(), requestMonitor) { + @Override + @ConfinedToDsfExecutor("fExecutor") + protected void handleSuccess() { + fIsBigEndian = getData(); + requestMonitor.done(); + } + }); + } + }, + + }; + + @Override + public Step[] getSteps() { + return fSteps; } - } + }); } @DsfServiceEventHandler @@ -153,40 +197,7 @@ public class GDBMemory extends MIMemory implements IGDBMemory { return fIsBigEndian; } - /** - * Retrieves the address size for given memory and execution contexts. - */ - private void readAddressSize(final IMemoryDMContext memContext) { - Integer addrSize = fAddressSizes.get(memContext); - if (addrSize == null) { - doReadAddressSize( - memContext, - new DataRequestMonitor(ImmediateExecutor.getInstance(), null) { - @Override - @ConfinedToDsfExecutor("fExecutor") - protected void handleSuccess() { - fAddressSizes.put(memContext, getData()); - } - }); - } - } - - /** - * Retrieves the endianness for given memory and execution contexts. - */ - private void readEndianness(IMemoryDMContext memContext) { - doReadEndianness( - memContext, - new DataRequestMonitor(ImmediateExecutor.getInstance(), null) { - @Override - @ConfinedToDsfExecutor("fExecutor") - protected void handleSuccess() { - fIsBigEndian = getData(); - } - }); - } - - protected void doReadAddressSize(IMemoryDMContext memContext, final DataRequestMonitor drm) { + protected void readAddressSize(IMemoryDMContext memContext, final DataRequestMonitor drm) { IExpressions exprService = getServicesTracker().getService(IExpressions.class); IExpressionDMContext exprContext = exprService.createExpression(memContext, "sizeof (void*)"); //$NON-NLS-1$ CommandFactory commandFactory = fCommandControl.getCommandFactory(); @@ -207,7 +218,7 @@ public class GDBMemory extends MIMemory implements IGDBMemory { }); } - protected void doReadEndianness(IMemoryDMContext memContext, final DataRequestMonitor drm) { + protected void readEndianness(IMemoryDMContext memContext, final DataRequestMonitor drm) { CommandFactory commandFactory = fCommandControl.getCommandFactory(); fCommandControl.queueCommand( commandFactory.createCLIShowEndian(memContext), diff --git a/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/gdb/service/GDBProcesses.java b/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/gdb/service/GDBProcesses.java index 923a7af4b7c..da76d7b4528 100644 --- a/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/gdb/service/GDBProcesses.java +++ b/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/gdb/service/GDBProcesses.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2008, 2012 Ericsson and others. + * Copyright (c) 2008, 2013 Ericsson and others. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at @@ -245,13 +245,43 @@ public class GDBProcesses extends MIProcesses implements IGDBProcesses { protected void handleSuccess() { // For an attach, we actually know the pid, so let's remember it fProcId = ((IMIProcessDMContext)procCtx).getProcId(); - IDMContext containerDmc = getData(); - rm.setData(containerDmc); + final IDMContext ctx = getData(); + rm.setData(ctx); - // Start tracking breakpoints. - MIBreakpointsManager bpmService = getServicesTracker().getService(MIBreakpointsManager.class); - IBreakpointsTargetDMContext bpTargetDmc = DMContexts.getAncestorOfType(containerDmc, IBreakpointsTargetDMContext.class); - bpmService.startTrackingBreakpoints(bpTargetDmc, rm); + ImmediateExecutor.getInstance().execute( + new Sequence(getExecutor(), rm) { + + private Step[] fSteps = new Step[] { + // Initialize memory data for this process + new Step() { + @Override + public void execute(RequestMonitor memoryDataRm) { + IGDBMemory memory = getServicesTracker().getService(IGDBMemory.class); + IMemoryDMContext memContext = DMContexts.getAncestorOfType(ctx, IMemoryDMContext.class); + if (memory == null || memContext == null) { + memoryDataRm.done(); + return; + } + memory.initializeMemoryData(memContext, memoryDataRm); + }; + }, + + // Start tracking breakpoints. + new Step() { + @Override + public void execute(RequestMonitor trackBpRm) { + MIBreakpointsManager bpmService = getServicesTracker().getService(MIBreakpointsManager.class); + IBreakpointsTargetDMContext bpTargetDmc = DMContexts.getAncestorOfType(ctx, IBreakpointsTargetDMContext.class); + bpmService.startTrackingBreakpoints(bpTargetDmc, trackBpRm); + }; + } + }; + @Override + public Step[] getSteps() { + return fSteps; + } + + }); } }); } diff --git a/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/gdb/service/GDBProcesses_7_0.java b/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/gdb/service/GDBProcesses_7_0.java index 8eaf847bc40..1793892e9dd 100644 --- a/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/gdb/service/GDBProcesses_7_0.java +++ b/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/gdb/service/GDBProcesses_7_0.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2008, 2012 Ericsson and others. + * Copyright (c) 2008, 2013 Ericsson and others. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at @@ -911,6 +911,19 @@ public class GDBProcesses_7_0 extends AbstractDsfService // Store the fully formed container context so it can be returned to the caller. dataRm.setData(fContainerDmc); + // Initialize memory data for this process. + IGDBMemory memory = getServicesTracker().getService(IGDBMemory.class); + IMemoryDMContext memContext = DMContexts.getAncestorOfType(fContainerDmc, IMemoryDMContext.class); + if (memory == null || memContext == null) { + rm.done(); + return; + } + memory.initializeMemoryData(memContext, rm); + } + }, + new Step() { + @Override + public void execute(RequestMonitor rm) { // Start tracking breakpoints. MIBreakpointsManager bpmService = getServicesTracker().getService(MIBreakpointsManager.class); IBreakpointsTargetDMContext bpTargetDmc = DMContexts.getAncestorOfType(fContainerDmc, IBreakpointsTargetDMContext.class); diff --git a/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/gdb/service/GDBProcesses_7_2.java b/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/gdb/service/GDBProcesses_7_2.java index 4a313fc1d95..3a10e94e4b9 100644 --- a/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/gdb/service/GDBProcesses_7_2.java +++ b/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/gdb/service/GDBProcesses_7_2.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2010, 2011 TUBITAK BILGEM-ITI and others. + * Copyright (c) 2010, 2013 TUBITAK BILGEM-ITI and others. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at @@ -26,6 +26,7 @@ import org.eclipse.cdt.dsf.concurrent.Sequence; import org.eclipse.cdt.dsf.datamodel.DMContexts; import org.eclipse.cdt.dsf.datamodel.IDMContext; import org.eclipse.cdt.dsf.debug.service.IBreakpoints.IBreakpointsTargetDMContext; +import org.eclipse.cdt.dsf.debug.service.IMemory.IMemoryDMContext; import org.eclipse.cdt.dsf.debug.service.IRunControl.IContainerDMContext; import org.eclipse.cdt.dsf.debug.service.IRunControl.IExitedDMEvent; import org.eclipse.cdt.dsf.debug.service.command.ICommandControlService.ICommandControlDMContext; @@ -311,6 +312,19 @@ public class GDBProcesses_7_2 extends GDBProcesses_7_1 { new ImmediateDataRequestMonitor(rm)); } }, + // Initialize memory data for this process. + new Step() { + @Override + public void execute(RequestMonitor rm) { + IGDBMemory memory = getServicesTracker().getService(IGDBMemory.class); + IMemoryDMContext memContext = DMContexts.getAncestorOfType(fContainerDmc, IMemoryDMContext.class); + if (memory == null || memContext == null) { + rm.done(); + return; + } + memory.initializeMemoryData(memContext, rm); + } + }, // Start tracking this process' breakpoints. new Step() { @Override diff --git a/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/gdb/service/IGDBMemory.java b/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/gdb/service/IGDBMemory.java index 97c146c14e5..e28107beed1 100644 --- a/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/gdb/service/IGDBMemory.java +++ b/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/gdb/service/IGDBMemory.java @@ -10,13 +10,22 @@ *******************************************************************************/ package org.eclipse.cdt.dsf.gdb.service; +import org.eclipse.cdt.dsf.concurrent.RequestMonitor; import org.eclipse.cdt.dsf.debug.service.IMemory; /** + * Provides access to memory related data such as address size and endianness. + * * @since 4.2 */ public interface IGDBMemory extends IMemory { + /** + * This method is required to retrieve data from GDB asynchronously. The Platform's + * memory related API is not asynchronous, so the data can not be acquired on demand. + */ + public void initializeMemoryData(IMemoryDMContext ctx, RequestMonitor rm); + /** * Returns the address size (in bytes) of the memory specified by the given context. */