diff options
author | Alvaro Sanchez-Leon | 2013-12-05 20:20:44 +0000 |
---|---|---|
committer | Marc Khouzam | 2014-01-15 14:06:21 +0000 |
commit | f1639f8a859821bd2767f1ca7decc8eff3fa3d18 (patch) | |
tree | 695eefa3dff60bdeeebc2444e93a7bdadfdac723 | |
parent | 54a0b2dd06a48c470bd210a5b98296240218b888 (diff) | |
download | org.eclipse.cdt-f1639f8a859821bd2767f1ca7decc8eff3fa3d18.tar.gz org.eclipse.cdt-f1639f8a859821bd2767f1ca7decc8eff3fa3d18.tar.xz org.eclipse.cdt-f1639f8a859821bd2767f1ca7decc8eff3fa3d18.zip |
Bug 250323 - Each memory context needs a different memory retrieval
Change-Id: I7874d84e5831aeb36be508a5b6b83c1623fcc5ab
Signed-off-by: Alvaro Sanchez-Leon <alvsan09@gmail.com>
Reviewed-on: https://git.eclipse.org/r/19453
Reviewed-by: Mikhail Khodjaiants <mikhailkhod@googlemail.com>
IP-Clean: Mikhail Khodjaiants <mikhailkhod@googlemail.com>
Tested-by: Mikhail Khodjaiants <mikhailkhod@googlemail.com>
Tested-by: Hudson CI
Reviewed-by: Marc Khouzam <marc.khouzam@ericsson.com>
IP-Clean: Marc Khouzam <marc.khouzam@ericsson.com>
Tested-by: Marc Khouzam <marc.khouzam@ericsson.com>
8 files changed, 317 insertions, 67 deletions
diff --git a/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/gdb/internal/GdbPlugin.java b/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/gdb/internal/GdbPlugin.java index f58229748eb..32b3a8f4540 100644 --- a/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/gdb/internal/GdbPlugin.java +++ b/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/gdb/internal/GdbPlugin.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2006, 2012 Wind River Systems and others. + * Copyright (c) 2006, 2013 Wind River Systems 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 @@ -9,6 +9,7 @@ * Wind River Systems - initial API and implementation * Abeer Bagul (Tensilica) - Updated error message (Bug 339048) * Jason Litton (Sage Electronic Engineering, LLC) - Added support for dynamic tracing option (Bug 379169) + * Alvaro Sanchez-Leon (Ericsson AB) - Each memory context needs a different MemoryRetrieval (Bug 250323) *******************************************************************************/ package org.eclipse.cdt.dsf.gdb.internal; @@ -17,8 +18,12 @@ import java.util.concurrent.RejectedExecutionException; import org.eclipse.cdt.dsf.concurrent.DataRequestMonitor; import org.eclipse.cdt.dsf.concurrent.Query; +import org.eclipse.cdt.dsf.datamodel.IDMContext; +import org.eclipse.cdt.dsf.debug.internal.provisional.model.MemoryBlockRetrievalFactory; import org.eclipse.cdt.dsf.gdb.launching.GdbLaunch; +import org.eclipse.core.runtime.IAdapterFactory; import org.eclipse.core.runtime.IStatus; +import org.eclipse.core.runtime.Platform; import org.eclipse.core.runtime.Plugin; import org.eclipse.core.runtime.Status; import org.eclipse.debug.core.DebugPlugin; @@ -38,6 +43,8 @@ public class GdbPlugin extends Plugin { private static BundleContext fgBundleContext; + private IAdapterFactory fMemoryRetrievalFactory = null; + /** * The constructor */ @@ -55,6 +62,9 @@ public class GdbPlugin extends Plugin { plugin = this; new GdbDebugOptions(context); + + fMemoryRetrievalFactory = new MemoryBlockRetrievalFactory(); + Platform.getAdapterManager().registerAdapters(fMemoryRetrievalFactory, IDMContext.class); } /* @@ -65,6 +75,11 @@ public class GdbPlugin extends Plugin { public void stop(BundleContext context) throws Exception { shutdownActiveLaunches(); plugin = null; + + if (fMemoryRetrievalFactory != null) { + Platform.getAdapterManager().unregisterAdapters(fMemoryRetrievalFactory, IDMContext.class); + } + super.stop(context); fgBundleContext = null; } diff --git a/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/gdb/internal/memory/GdbMemoryBlockRetrieval.java b/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/gdb/internal/memory/GdbMemoryBlockRetrieval.java index 551923c5954..8fa44d5a422 100644 --- a/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/gdb/internal/memory/GdbMemoryBlockRetrieval.java +++ b/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/gdb/internal/memory/GdbMemoryBlockRetrieval.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2010, Texas Instruments, Freescale Semiconductor and others. + * Copyright (c) 2010, 2013 Texas Instruments, Freescale Semiconductor 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 @@ -7,6 +7,7 @@ * * Contributors: * Texas Instruments, Freescale Semiconductor - initial API and implementation + * Alvaro Sanchez-Leon (Ericsson AB) - Each memory context needs a different MemoryRetrieval (Bug 250323) *******************************************************************************/ package org.eclipse.cdt.dsf.gdb.internal.memory; @@ -24,23 +25,16 @@ import org.eclipse.cdt.dsf.debug.model.DsfMemoryBlock; import org.eclipse.cdt.dsf.debug.model.DsfMemoryBlockRetrieval; import org.eclipse.cdt.dsf.debug.service.IMemory.IMemoryDMContext; import org.eclipse.cdt.dsf.debug.service.IMemorySpaces; -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.service.DsfServiceEventHandler; import org.eclipse.cdt.dsf.service.DsfServices; import org.eclipse.cdt.dsf.service.DsfSession; import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.IAdaptable; -import org.eclipse.core.runtime.IProgressMonitor; import org.eclipse.core.runtime.IStatus; import org.eclipse.core.runtime.Status; -import org.eclipse.core.runtime.jobs.Job; import org.eclipse.debug.core.DebugException; import org.eclipse.debug.core.DebugPlugin; import org.eclipse.debug.core.ILaunchConfiguration; -import org.eclipse.debug.core.IMemoryBlockManager; import org.eclipse.debug.core.model.IMemoryBlock; import org.eclipse.debug.core.model.IMemoryBlockExtension; import org.osgi.framework.BundleContext; @@ -95,6 +89,7 @@ public class GdbMemoryBlockRetrieval extends DsfMemoryBlockRetrieval implements GdbPlugin.PLUGIN_ID, DebugException.INTERNAL_ERROR, "Error creating service filter.", e)); //$NON-NLS-1$ } + fMemorySpaceServiceTracker.open(); } @@ -388,35 +383,4 @@ public class GdbMemoryBlockRetrieval extends DsfMemoryBlockRetrieval implements } return false; } - - @DsfServiceEventHandler - public void eventDispatched(IStartedDMEvent event) { - if (event.getDMContext() instanceof IContainerDMContext) { - IMemoryDMContext memoryDmc = DMContexts.getAncestorOfType(event.getDMContext(), IMemoryDMContext.class); - if (memoryDmc != null) { - initialize(memoryDmc); - } - } - } - - @DsfServiceEventHandler - public void eventDispatched(IExitedDMEvent event) { - if (event.getDMContext() instanceof IContainerDMContext) { - IMemoryDMContext memoryDmc = DMContexts.getAncestorOfType(event.getDMContext(), IMemoryDMContext.class); - if (memoryDmc != null) { - saveMemoryBlocks(); - Job removeJob = new Job("Removing memory blocks") { //$NON-NLS-1$ - - @Override - protected IStatus run( IProgressMonitor monitor ) { - IMemoryBlockManager mbm = DebugPlugin.getDefault().getMemoryBlockManager(); - IMemoryBlock[] deletedMemoryBlocks = mbm.getMemoryBlocks(GdbMemoryBlockRetrieval.this); - mbm.removeMemoryBlocks(deletedMemoryBlocks); - return Status.OK_STATUS; - } - }; - removeJob.schedule(); - } - } - } } diff --git a/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/gdb/internal/memory/GdbMemoryBlockRetrievalManager.java b/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/gdb/internal/memory/GdbMemoryBlockRetrievalManager.java new file mode 100644 index 00000000000..be5860366f8 --- /dev/null +++ b/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/gdb/internal/memory/GdbMemoryBlockRetrievalManager.java @@ -0,0 +1,43 @@ +/******************************************************************************* + * Copyright (c) 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 + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Alvaro Sanchez-Leon (Ericsson AB) - Each memory context needs a different MemoryRetrieval (Bug 250323) + *******************************************************************************/ +package org.eclipse.cdt.dsf.gdb.internal.memory; + +import org.eclipse.cdt.dsf.debug.internal.provisional.model.MemoryBlockRetrievalManager; +import org.eclipse.cdt.dsf.debug.model.DsfMemoryBlockRetrieval; +import org.eclipse.cdt.dsf.gdb.internal.GdbPlugin; +import org.eclipse.cdt.dsf.service.DsfSession; +import org.eclipse.debug.core.DebugException; +import org.eclipse.debug.core.ILaunchConfiguration; +import org.eclipse.debug.core.model.IMemoryBlockRetrieval; + +public class GdbMemoryBlockRetrievalManager extends MemoryBlockRetrievalManager { + + public GdbMemoryBlockRetrievalManager(String modelId, ILaunchConfiguration config, DsfSession session) { + super(modelId, config, session); + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.dsf.debug.internal.provisional.model.MemoryBlockRetrievalManager#createMemoryBlockRetrieval(java.lang.String, org.eclipse.debug.core.ILaunchConfiguration, org.eclipse.cdt.dsf.service.DsfSession) + */ + @Override + protected IMemoryBlockRetrieval createMemoryBlockRetrieval(String model, ILaunchConfiguration config, DsfSession session) { + DsfMemoryBlockRetrieval memRetrieval = null; + + try { + memRetrieval = new GdbMemoryBlockRetrieval(model, config, session); + } catch (DebugException e) { + GdbPlugin.getDefault().getLog().log(e.getStatus()); + } + + return memRetrieval; + } + +} diff --git a/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/gdb/launching/GdbLaunch.java b/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/gdb/launching/GdbLaunch.java index 175d36cfd94..d64778f1150 100644 --- a/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/gdb/launching/GdbLaunch.java +++ b/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/gdb/launching/GdbLaunch.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2006, 2012 Wind River Systems and others. + * Copyright (c) 2006, 2013 Wind River Systems 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 @@ -9,6 +9,7 @@ * Wind River Systems - initial API and implementation * Marc Khouzam (Ericsson) - Fix NPE for partial launches (Bug 368597) * Marc Khouzam (Ericsson) - Create the gdb process through the process factory (Bug 210366) + * Alvaro Sanchez-Leon (Ericsson AB) - Each memory context needs a different MemoryRetrieval (Bug 250323) *******************************************************************************/ package org.eclipse.cdt.dsf.gdb.launching; @@ -32,13 +33,13 @@ import org.eclipse.cdt.dsf.concurrent.Sequence; import org.eclipse.cdt.dsf.concurrent.Sequence.Step; import org.eclipse.cdt.dsf.concurrent.ThreadSafe; import org.eclipse.cdt.dsf.concurrent.ThreadSafeAndProhibitedFromDsfExecutor; +import org.eclipse.cdt.dsf.debug.internal.provisional.model.IMemoryBlockRetrievalManager; import org.eclipse.cdt.dsf.debug.model.DsfLaunch; -import org.eclipse.cdt.dsf.debug.model.DsfMemoryBlockRetrieval; import org.eclipse.cdt.dsf.debug.service.IDsfDebugServicesFactory; import org.eclipse.cdt.dsf.debug.service.command.ICommandControlService.ICommandControlShutdownDMEvent; import org.eclipse.cdt.dsf.gdb.IGdbDebugConstants; import org.eclipse.cdt.dsf.gdb.internal.GdbPlugin; -import org.eclipse.cdt.dsf.gdb.internal.memory.GdbMemoryBlockRetrieval; +import org.eclipse.cdt.dsf.gdb.internal.memory.GdbMemoryBlockRetrievalManager; import org.eclipse.cdt.dsf.gdb.service.command.IGDBControl; import org.eclipse.cdt.dsf.mi.service.command.AbstractCLIProcess; import org.eclipse.cdt.dsf.service.DsfServiceEventHandler; @@ -49,14 +50,12 @@ import org.eclipse.core.runtime.IStatus; import org.eclipse.core.runtime.MultiStatus; import org.eclipse.core.runtime.Platform; import org.eclipse.core.runtime.Status; -import org.eclipse.debug.core.DebugEvent; import org.eclipse.debug.core.DebugException; import org.eclipse.debug.core.DebugPlugin; import org.eclipse.debug.core.ILaunch; import org.eclipse.debug.core.ILaunchConfiguration; import org.eclipse.debug.core.commands.ITerminateHandler; import org.eclipse.debug.core.model.IDisconnect; -import org.eclipse.debug.core.model.IMemoryBlockRetrieval; import org.eclipse.debug.core.model.ISourceLocator; import org.eclipse.debug.core.model.ITerminate; @@ -72,8 +71,7 @@ public class GdbLaunch extends DsfLaunch private DsfServicesTracker fTracker; private boolean fInitialized = false; private boolean fShutDown = false; - - private DsfMemoryBlockRetrieval fMemRetrieval; + private IMemoryBlockRetrievalManager fMemRetrievalManager; private IDsfDebugServicesFactory fServiceFactory; public GdbLaunch(ILaunchConfiguration launchConfiguration, String mode, ISourceLocator locator) { @@ -125,15 +123,15 @@ public class GdbLaunch extends DsfLaunch public void initializeControl() throws CoreException { - // Create a memory retrieval and register it with the session + // Create a memory retrieval manager and register it with the session + // To maintain a mapping of memory contexts to the corresponding memory retrieval in this session try { fExecutor.submit( new Callable<Object>() { @Override public Object call() throws CoreException { - fMemRetrieval = new GdbMemoryBlockRetrieval( - GdbLaunchDelegate.GDB_DEBUG_MODEL_ID, getLaunchConfiguration(), fSession); - fSession.registerModelAdapter(IMemoryBlockRetrieval.class, fMemRetrieval); - fSession.addServiceEventListener(fMemRetrieval, null); + fMemRetrievalManager = new GdbMemoryBlockRetrievalManager(GdbLaunchDelegate.GDB_DEBUG_MODEL_ID, getLaunchConfiguration(), fSession); + fSession.registerModelAdapter(IMemoryBlockRetrievalManager.class, fMemRetrievalManager); + fSession.addServiceEventListener(fMemRetrievalManager, null); return null; } }).get(); @@ -244,8 +242,10 @@ public class GdbLaunch extends DsfLaunch new RequestMonitor(fSession.getExecutor(), rm) { @Override public void handleCompleted() { - if (fMemRetrieval != null) - fSession.removeServiceEventListener(fMemRetrieval); + if (fMemRetrievalManager != null) { + fSession.removeServiceEventListener(fMemRetrievalManager); + fMemRetrievalManager.dispose(); + } fSession.removeServiceEventListener(GdbLaunch.this); if (!isSuccess()) { @@ -256,18 +256,6 @@ public class GdbLaunch extends DsfLaunch fTracker.dispose(); fTracker = null; DsfSession.endSession(fSession); - - // The memory retrieval can be null if the launch was aborted - // in the middle. We saw this when doing an automatic remote - // launch with an invalid gdbserver - // Bug 368597 - if (fMemRetrieval != null) { - - // Fire a terminate event for the memory retrieval object so - // that the hosting memory views can clean up. See 255120 and - // 283586 - DebugPlugin.getDefault().fireDebugEventSet( new DebugEvent[] { new DebugEvent(fMemRetrieval, DebugEvent.TERMINATE) }); - } // 'fireTerminate()' removes this launch from the list of 'DebugEvent' // listeners. The launch may not be terminated at this point: the inferior diff --git a/dsf/org.eclipse.cdt.dsf/META-INF/MANIFEST.MF b/dsf/org.eclipse.cdt.dsf/META-INF/MANIFEST.MF index 62acb0a310a..5016ab01357 100644 --- a/dsf/org.eclipse.cdt.dsf/META-INF/MANIFEST.MF +++ b/dsf/org.eclipse.cdt.dsf/META-INF/MANIFEST.MF @@ -14,7 +14,7 @@ Require-Bundle: org.eclipse.core.runtime, Bundle-ActivationPolicy: lazy Export-Package: org.eclipse.cdt.dsf.concurrent, org.eclipse.cdt.dsf.datamodel, - org.eclipse.cdt.dsf.debug.internal.provisional.model;x-friends:="org.eclipse.cdt.dsf.ui", + org.eclipse.cdt.dsf.debug.internal.provisional.model;x-friends:="org.eclipse.cdt.dsf.ui, org.eclipse.cdt.dsf.gdb", org.eclipse.cdt.dsf.debug.internal.provisional.service;x-internal:=true, org.eclipse.cdt.dsf.debug.model, org.eclipse.cdt.dsf.debug.service, diff --git a/dsf/org.eclipse.cdt.dsf/src/org/eclipse/cdt/dsf/debug/internal/provisional/model/IMemoryBlockRetrievalManager.java b/dsf/org.eclipse.cdt.dsf/src/org/eclipse/cdt/dsf/debug/internal/provisional/model/IMemoryBlockRetrievalManager.java new file mode 100644 index 00000000000..97d911b5abd --- /dev/null +++ b/dsf/org.eclipse.cdt.dsf/src/org/eclipse/cdt/dsf/debug/internal/provisional/model/IMemoryBlockRetrievalManager.java @@ -0,0 +1,44 @@ +/******************************************************************************* + * Copyright (c) 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 + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Alvaro Sanchez-Leon (Ericsson AB) - Each memory context needs a different MemoryRetrieval (Bug 250323) + *******************************************************************************/ +package org.eclipse.cdt.dsf.debug.internal.provisional.model; + +import org.eclipse.cdt.dsf.datamodel.IDMContext; +import org.eclipse.debug.core.model.IMemoryBlockRetrieval; + +/** + * <p>It's expected to have one IMemoryBlockRetrievalManager per session which instantiates and keeps the mapping between IMemoryDMContext and its + * corresponding IMemoryBlockRetrieval. </p> + * + * <p>One IMemoryDMContext represents a hierarchy of elements that share the same memory e.g A process, thread and frame in Linux, + * One session is capable of having multiple IMemoryContext e.g. Debugging multiple programs under the same session</p> + * + * <p>An IMemoryBlockRetrieval helps to retrieve memory blocks from the same memory and therefore it is expected to have a one to one + * relationship with an IMemoryDMContext</p> + * + * <p>Functionality detecting changes to different memory context elements can resolve the corresponding IMemoryBlockRetrieval via this API.</p> + * + */ +public interface IMemoryBlockRetrievalManager { + /** + * A method to resolve the specific IMemoryBlockRetrieval associated to the IMemoryDMContext of the given IDMContext + * + * @param dmc - A context which either itself or one of its parents is an IMemoryDMContext + * @return - The IMemoryBlockRetrieval associated to the IMemoryDMContext resolved from the given dmc + */ + public IMemoryBlockRetrieval getMemoryBlockRetrieval(IDMContext dmc); + + /** + * Shall be called when this manager is no longer needed + * Any required clean up needs to be performed so this class can be + * garbage collected. + */ + public void dispose(); +} diff --git a/dsf/org.eclipse.cdt.dsf/src/org/eclipse/cdt/dsf/debug/internal/provisional/model/MemoryBlockRetrievalFactory.java b/dsf/org.eclipse.cdt.dsf/src/org/eclipse/cdt/dsf/debug/internal/provisional/model/MemoryBlockRetrievalFactory.java new file mode 100644 index 00000000000..d4c51de1e3f --- /dev/null +++ b/dsf/org.eclipse.cdt.dsf/src/org/eclipse/cdt/dsf/debug/internal/provisional/model/MemoryBlockRetrievalFactory.java @@ -0,0 +1,55 @@ +/******************************************************************************* + * Copyright (c) 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 + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Alvaro Sanchez-Leon (Ericsson AB) - Each memory context needs a different MemoryRetrieval (Bug 250323) + *******************************************************************************/ +package org.eclipse.cdt.dsf.debug.internal.provisional.model; + +import org.eclipse.cdt.dsf.datamodel.IDMContext; +import org.eclipse.core.runtime.IAdaptable; +import org.eclipse.core.runtime.IAdapterFactory; +import org.eclipse.debug.core.model.IMemoryBlockRetrieval; + +/** + * A common MemoryBlockRetrievalFactory across debug sessions + * which resolves (adapts) an element context to its corresponding + * IMemoryBlockRetrieval via the session's IMemoryBlockRetrievalManager + * + * (non-Javadoc) + * @see org.eclipse.cdt.dsf.debug.internal.provisional.model.IMemoryBlockRetrievalManager + * + */ +public class MemoryBlockRetrievalFactory implements IAdapterFactory { + + @SuppressWarnings("rawtypes") + @Override + public Object getAdapter(Object adaptableObject, Class adapterType) { + IMemoryBlockRetrieval memRetrieval = null; + + if (adaptableObject instanceof IDMContext) { + if (adapterType.equals(IMemoryBlockRetrieval.class)) { + IAdaptable adaptable = (IAdaptable) adaptableObject; + //Retrieve the session's Memory Block Retrieval Manager + IMemoryBlockRetrievalManager retrievalManager = ((IMemoryBlockRetrievalManager) adaptable + .getAdapter(IMemoryBlockRetrievalManager.class)); + if (retrievalManager != null) { + //resolve the specific Memory Block Retrieval associated to the memory context of adaptableObject + memRetrieval = retrievalManager.getMemoryBlockRetrieval((IDMContext) adaptableObject); + } + } + } + + return memRetrieval; + } + + @SuppressWarnings("rawtypes") + @Override + public Class[] getAdapterList() { + return new Class[] { IMemoryBlockRetrieval.class }; + } +} diff --git a/dsf/org.eclipse.cdt.dsf/src/org/eclipse/cdt/dsf/debug/internal/provisional/model/MemoryBlockRetrievalManager.java b/dsf/org.eclipse.cdt.dsf/src/org/eclipse/cdt/dsf/debug/internal/provisional/model/MemoryBlockRetrievalManager.java new file mode 100644 index 00000000000..2a3e60b26fb --- /dev/null +++ b/dsf/org.eclipse.cdt.dsf/src/org/eclipse/cdt/dsf/debug/internal/provisional/model/MemoryBlockRetrievalManager.java @@ -0,0 +1,141 @@ +/******************************************************************************* + * Copyright (c) 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 + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Alvaro Sanchez-Leon (Ericsson AB) - Each memory context needs a different MemoryRetrieval (Bug 250323) + *******************************************************************************/ +package org.eclipse.cdt.dsf.debug.internal.provisional.model; + +import java.util.HashMap; +import java.util.Map; + +import org.eclipse.cdt.dsf.datamodel.DMContexts; +import org.eclipse.cdt.dsf.datamodel.IDMContext; +import org.eclipse.cdt.dsf.debug.model.DsfMemoryBlockRetrieval; +import org.eclipse.cdt.dsf.debug.service.IMemory.IMemoryDMContext; +import org.eclipse.cdt.dsf.debug.service.IRunControl.IExitedDMEvent; +import org.eclipse.cdt.dsf.debug.service.IRunControl.IStartedDMEvent; +import org.eclipse.cdt.dsf.internal.DsfPlugin; +import org.eclipse.cdt.dsf.service.DsfServiceEventHandler; +import org.eclipse.cdt.dsf.service.DsfSession; +import org.eclipse.core.runtime.IProgressMonitor; +import org.eclipse.core.runtime.IStatus; +import org.eclipse.core.runtime.Status; +import org.eclipse.core.runtime.jobs.Job; +import org.eclipse.debug.core.DebugEvent; +import org.eclipse.debug.core.DebugException; +import org.eclipse.debug.core.DebugPlugin; +import org.eclipse.debug.core.ILaunchConfiguration; +import org.eclipse.debug.core.IMemoryBlockManager; +import org.eclipse.debug.core.model.IMemoryBlock; +import org.eclipse.debug.core.model.IMemoryBlockRetrieval; + +/* (non-Javadoc) + * @see org.eclipse.cdt.dsf.debug.internal.provisional.model.IMemoryBlockRetrievalManager + */ +public class MemoryBlockRetrievalManager implements IMemoryBlockRetrievalManager { + + private final String fModelId; + private final DsfSession fSession; + private final ILaunchConfiguration fLaunchConfig; + private final Map<IMemoryDMContext, IMemoryBlockRetrieval> fMapMemDMCToBlockRetrieval = new HashMap<IMemoryDMContext, IMemoryBlockRetrieval>(); + + /** + * Constructor + */ + public MemoryBlockRetrievalManager(String modelId, ILaunchConfiguration config, DsfSession session) { + fModelId = modelId; + fSession = session; + fLaunchConfig = config; + } + + @DsfServiceEventHandler + public void eventDispatched(IStartedDMEvent event) { + // If a new memory context is starting, create its memory retrieval instance + if (event.getDMContext() instanceof IMemoryDMContext) { + IMemoryDMContext memDmc = (IMemoryDMContext) event.getDMContext(); + if (!fMapMemDMCToBlockRetrieval.containsKey(memDmc)) { + // We need a new memory retrieval for this new memory context + IMemoryBlockRetrieval memRetrieval = null; + try { + memRetrieval = createMemoryBlockRetrieval(fModelId, fLaunchConfig, fSession); + } catch (DebugException e) { + DsfPlugin.getDefault().getLog().log(e.getStatus()); + return; + } + + if (memRetrieval != null) { + if (memRetrieval instanceof DsfMemoryBlockRetrieval) { + ((DsfMemoryBlockRetrieval) memRetrieval).initialize(memDmc); + } + + fMapMemDMCToBlockRetrieval.put(memDmc, memRetrieval); + } + } + } + } + + @DsfServiceEventHandler + public void eventDispatched(IExitedDMEvent event) { + // If a memory context is exiting, save expressions and clean its used resources + if (event.getDMContext() instanceof IMemoryDMContext) { + IMemoryDMContext memDmc = (IMemoryDMContext) event.getDMContext(); + // Remove entry if it exists + final IMemoryBlockRetrieval retrieval = fMapMemDMCToBlockRetrieval.remove(memDmc); + if (retrieval != null) { + if (retrieval instanceof DsfMemoryBlockRetrieval) { + ((DsfMemoryBlockRetrieval) retrieval).saveMemoryBlocks(); + } + // Fire a terminate event for the memory retrieval object so + // that the hosting memory views can clean up. See 255120 and + // 283586 + DebugPlugin.getDefault().fireDebugEventSet( + new DebugEvent[] { new DebugEvent(retrieval, DebugEvent.TERMINATE) }); + + Job removeJob = new Job("Removing memory blocks") { //$NON-NLS-1$ + + @Override + protected IStatus run(IProgressMonitor monitor) { + IMemoryBlockManager mbm = DebugPlugin.getDefault().getMemoryBlockManager(); + IMemoryBlock[] deletedMemoryBlocks = mbm.getMemoryBlocks(retrieval); + mbm.removeMemoryBlocks(deletedMemoryBlocks); + return Status.OK_STATUS; + } + }; + removeJob.schedule(); + } + } + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.dsf.debug.internal.provisional.model.IMemoryBlockRetrievalManager#getMemoryBlockRetrieval(org.eclipse.cdt.dsf.datamodel.IDMContext) + */ + @Override + public IMemoryBlockRetrieval getMemoryBlockRetrieval(IDMContext dmc) { + IMemoryBlockRetrieval memRetrieval = null; + IMemoryDMContext memDmc = DMContexts.getAncestorOfType(dmc, IMemoryDMContext.class); + if (memDmc != null) { + memRetrieval = fMapMemDMCToBlockRetrieval.get(memDmc); + } + + return memRetrieval; + } + + protected IMemoryBlockRetrieval createMemoryBlockRetrieval(String model, ILaunchConfiguration config, + DsfSession session) throws DebugException { + return new DsfMemoryBlockRetrieval(model, config, session); + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.dsf.debug.internal.provisional.model.IMemoryBlockRetrievalManager#dispose() + */ + @Override + public void dispose() { + // release resources / references + fMapMemDMCToBlockRetrieval.clear(); + } +} |