diff options
author | Bruno Medeiros | 2017-01-19 17:14:24 +0000 |
---|---|---|
committer | Alvaro Sanchez-Leon | 2017-02-28 20:41:10 +0000 |
commit | 5a71bf21d82d2563b0d37d73a99977d5617c2788 (patch) | |
tree | 4b2c65d3e204a04a42cf5b97827e84d709f8832b /dsf-gdb | |
parent | 064ce187b6de00e343b26a614a98846ef46213d7 (diff) | |
download | org.eclipse.cdt-5a71bf21d82d2563b0d37d73a99977d5617c2788.tar.gz org.eclipse.cdt-5a71bf21d82d2563b0d37d73a99977d5617c2788.tar.xz org.eclipse.cdt-5a71bf21d82d2563b0d37d73a99977d5617c2788.zip |
Bug 449104: Enhance Register Grouping for multi processes
This patch adds support to GDBRegisters for persisting the register
group configuration on a per-process/per-core basis. The default
behavior of GDBRegisters is not modified. Instead, subclasses must
override getPersistenceIdForRegisterGroupContainer(IContainerDMContext)
to enable the new behavior, and provide a persistence id that is stable
across launches.
Update: fixed bug in RegisterGroupDescriptor.getContainerId()
Change-Id: I284df3ee215d9a4a9f72f3dca9aba5c16ca4b850
Signed-off-by: Bruno Medeiros <bruno.do.medeiros@gmail.com>
Diffstat (limited to 'dsf-gdb')
6 files changed, 398 insertions, 23 deletions
diff --git a/dsf-gdb/org.eclipse.cdt.dsf.gdb.tests/.settings/org.eclipse.jdt.core.prefs b/dsf-gdb/org.eclipse.cdt.dsf.gdb.tests/.settings/org.eclipse.jdt.core.prefs index ce1f6109477..87965802f37 100644 --- a/dsf-gdb/org.eclipse.cdt.dsf.gdb.tests/.settings/org.eclipse.jdt.core.prefs +++ b/dsf-gdb/org.eclipse.cdt.dsf.gdb.tests/.settings/org.eclipse.jdt.core.prefs @@ -60,7 +60,7 @@ org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionWhenOverridin org.eclipse.jdt.core.compiler.problem.unusedImport=error org.eclipse.jdt.core.compiler.problem.unusedLabel=warning org.eclipse.jdt.core.compiler.problem.unusedLocal=warning -org.eclipse.jdt.core.compiler.problem.unusedParameter=ignore +org.eclipse.jdt.core.compiler.problem.unusedParameter=warning org.eclipse.jdt.core.compiler.problem.unusedParameterIncludeDocCommentReference=enabled org.eclipse.jdt.core.compiler.problem.unusedParameterWhenImplementingAbstract=disabled org.eclipse.jdt.core.compiler.problem.unusedParameterWhenOverridingConcrete=disabled diff --git a/dsf-gdb/org.eclipse.cdt.dsf.gdb.tests/src/org/eclipse/cdt/dsf/gdb/service/CommonDsfTest.java b/dsf-gdb/org.eclipse.cdt.dsf.gdb.tests/src/org/eclipse/cdt/dsf/gdb/service/CommonDsfTest.java new file mode 100644 index 00000000000..094bcb18f75 --- /dev/null +++ b/dsf-gdb/org.eclipse.cdt.dsf.gdb.tests/src/org/eclipse/cdt/dsf/gdb/service/CommonDsfTest.java @@ -0,0 +1,109 @@ +/*******************************************************************************
+ * Copyright (c) 2017 Renesas Electronics 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:
+ * Bruno Medeiros (Renesas) - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.cdt.dsf.gdb.service;
+
+import static org.junit.Assert.fail;
+
+import org.eclipse.cdt.debug.core.ICDTLaunchConfigurationConstants;
+import org.eclipse.cdt.dsf.concurrent.DataRequestMonitor;
+import org.eclipse.cdt.dsf.concurrent.DefaultDsfExecutor;
+import org.eclipse.cdt.dsf.concurrent.RequestMonitor;
+import org.eclipse.cdt.dsf.debug.model.DsfLaunch;
+import org.eclipse.cdt.dsf.gdb.internal.GdbPlugin;
+import org.eclipse.cdt.dsf.service.DsfSession;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.debug.core.DebugPlugin;
+import org.eclipse.debug.core.ILaunch;
+import org.eclipse.debug.core.ILaunchConfigurationType;
+import org.eclipse.debug.core.ILaunchConfigurationWorkingCopy;
+import org.eclipse.debug.core.ILaunchManager;
+import org.eclipse.debug.core.model.ISourceLocator;
+import org.junit.AfterClass;
+import org.junit.Before;
+import org.junit.BeforeClass;
+
+/**
+ * Helper base class for running DSF related tests
+ */
+public class CommonDsfTest extends CommonTest {
+
+ protected static DsfSession fSession = null;
+
+ /**
+ * Setup the test.
+ * The session is typically configured once per class load, but we allow subclasses to override this,
+ * and sometimes re-setup during a test (or interactive debugging).
+ * Therefore {@link Before} is used, not {@link BeforeClass}.
+ */
+ @Before
+ public void setup() {
+ if(fSession != null) {
+ return; // Already set-up
+ }
+
+ doSetupSession();
+ }
+
+ protected void doSetupSession() {
+ fSession = DsfSession.startSession(new DefaultDsfExecutor(GdbPlugin.PLUGIN_ID), GdbPlugin.PLUGIN_ID);
+
+ registerLaunch();
+ }
+
+ @AfterClass
+ public static void tearDown() {
+ if(fSession != null) {
+ DsfSession.endSession(fSession);
+ fSession = null;
+ }
+ }
+
+ protected ILaunchConfigurationType getCLaunchConfigType() {
+ return getLaunchManager().getLaunchConfigurationType(ICDTLaunchConfigurationConstants.ID_LAUNCH_C_APP);
+ }
+
+ protected ILaunchManager getLaunchManager() {
+ return DebugPlugin.getDefault().getLaunchManager();
+ }
+
+ protected void registerLaunch() {
+ ILaunchConfigurationWorkingCopy lc;
+ try {
+ lc = getCLaunchConfigType().newInstance(null, "TestLaunch");
+ } catch(CoreException e) {
+ fail(e.getMessage());
+ return;
+ }
+ ISourceLocator sourceLocator = null;
+ DsfLaunch dsfLaunch = new DsfLaunch(lc, ILaunchManager.DEBUG_MODE, sourceLocator);
+ fSession.registerModelAdapter(ILaunch.class, dsfLaunch);
+ }
+
+ protected RequestMonitor newRequestMonitor() {
+ return new RequestMonitor(fSession.getExecutor(), null);
+ }
+
+ protected <T> DataRequestMonitor<T> newDataRequestMonitor() {
+ return new DataRequestMonitor<>(fSession.getExecutor(), null);
+ }
+}
+
+/**
+ * Misc test utilities.
+ */
+class CommonTest {
+ /* ----------------- ----------------- */
+
+ @SafeVarargs
+ public static <T> T[] array(T... elems) {
+ return elems;
+ }
+}
\ No newline at end of file diff --git a/dsf-gdb/org.eclipse.cdt.dsf.gdb.tests/src/org/eclipse/cdt/dsf/gdb/service/GDBRegisterTest.java b/dsf-gdb/org.eclipse.cdt.dsf.gdb.tests/src/org/eclipse/cdt/dsf/gdb/service/GDBRegisterTest.java new file mode 100644 index 00000000000..eb22e775d3d --- /dev/null +++ b/dsf-gdb/org.eclipse.cdt.dsf.gdb.tests/src/org/eclipse/cdt/dsf/gdb/service/GDBRegisterTest.java @@ -0,0 +1,199 @@ +/******************************************************************************* + * Copyright (c) 2017 Renesas Electronics 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: + * Bruno Medeiros (Renesas) - initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.dsf.gdb.service; + +import static org.junit.Assert.assertTrue; + +import java.util.Arrays; + +import org.eclipse.cdt.debug.internal.core.model.IRegisterGroupDescriptor; +import org.eclipse.cdt.dsf.datamodel.DMContexts; +import org.eclipse.cdt.dsf.debug.service.IProcesses.IProcessDMContext; +import org.eclipse.cdt.dsf.debug.service.IRunControl.IContainerDMContext; +import org.eclipse.cdt.dsf.mi.service.IMIContainerDMContext; +import org.eclipse.cdt.dsf.mi.service.MIProcesses; +import org.eclipse.cdt.dsf.mi.service.MIRegisters.MIRegisterDMC; +import org.eclipse.cdt.dsf.mi.service.MIRegisters.MIRegisterGroupDMC; +import org.eclipse.cdt.dsf.mi.service.command.MIControlDMContext; +import org.eclipse.core.runtime.Assert; +import org.junit.Test; + + +public class GDBRegisterTest extends CommonDsfTest { + + public static final String PROCESS_A = "processA"; + public static final String PROCESS_B = "processB"; + + protected MIProcesses miProcesses; + protected GDBRegisters gdbRegisters; + + @Override + protected void doSetupSession() { + super.doSetupSession(); + + miProcesses = new MIProcesses(fSession); + gdbRegisters = createGdbRegisters(); + } + + protected GDBRegisters createGdbRegisters() { + return new GDBRegisters(fSession) { + @Override + protected boolean useProcessIdAsRegisterGroupPersistanceId() { + return true; + } + }; + } + + @Test + public void testRegisterPersistence() throws Exception { testRegisterPersistence$(); } + public void testRegisterPersistence$() throws Exception { + + MIControlDMContext controlDmc = new MIControlDMContext(fSession.getId(), "TestControl"); + + IProcessDMContext processDmcA = miProcesses.createProcessContext(controlDmc, PROCESS_A); + IProcessDMContext processDmcB = miProcesses.createProcessContext(controlDmc, PROCESS_B); + IMIContainerDMContext containerA = miProcesses.createContainerContext(processDmcA, "containerA"); + IMIContainerDMContext containerB = miProcesses.createContainerContext(processDmcB, "containerB"); + + + MIRegisterGroupDMC[] initialRegisterGroups = gdbRegisters.readGroupsFromMemento(containerA); + Assert.isTrue(initialRegisterGroups.length == 0); + + MIRegisterGroupDMC registerGroupA = addRegisterGroup(containerA, "RegGroupA", "register_foo"); + // check build descriptors + IRegisterGroupDescriptor[] buildDescriptors = gdbRegisters.buildDescriptors(); + org.junit.Assert.assertEquals(buildDescriptors[0].getContainerId(), gdbRegisters.getPersistenceIdForRegisterGroupContainer(containerA)); + + // Save then check persistence + gdbRegisters.save(); + checkAfterAdding_GroupA(containerA, containerB, registerGroupA); + + // Now add a second register group to a different process context + MIRegisterGroupDMC registerGroupB = addRegisterGroup(containerB, "RegGroupB", "register_bar"); + gdbRegisters.save(); + checkAfterAdding_GroupB(containerA, containerB, registerGroupA, registerGroupB); + } + + protected void checkAfterAdding_GroupA( + IMIContainerDMContext containerA, IMIContainerDMContext containerB, MIRegisterGroupDMC registerGroupA + ) { + checkRegisterGroupMemento(containerA, registerGroupA); + checkRegisterGroupsMemento(containerB, array()); + } + + protected void checkAfterAdding_GroupB( + IMIContainerDMContext containerA, IMIContainerDMContext containerB, + MIRegisterGroupDMC registerGroupA, MIRegisterGroupDMC registerGroupB + ) { + checkRegisterGroupMemento(containerA, registerGroupA); + checkRegisterGroupMemento(containerB, registerGroupB); + } + + protected MIRegisterGroupDMC addRegisterGroup(IMIContainerDMContext container, String groupName, String registerName) { + MIRegisterGroupDMC registerGroup = new MIRegisterGroupDMC(gdbRegisters, container, 1, groupName); + MIRegisterDMC rgFoo = new MIRegisterDMC(gdbRegisters, registerGroup, 1, registerName); + + gdbRegisters.addRegisterGroup(container, registerGroup.getName(), array(rgFoo), newRequestMonitor()); + return registerGroup; + } + + protected void checkRegisterGroupMemento(IMIContainerDMContext container, MIRegisterGroupDMC registerGroup) { + checkRegisterGroupsMemento(container, array(registerGroup)); + } + + protected void checkRegisterGroupsMemento(IMIContainerDMContext container, MIRegisterGroupDMC[] expectedRegisterGroups) { + MIRegisterGroupDMC[] savedRegisterGroups = gdbRegisters.readGroupsFromMemento(container); + if(expectedRegisterGroups == null) { + assertTrue(savedRegisterGroups == null); + return; + } + + assertTrue(expectedRegisterGroups.length == savedRegisterGroups.length); + + for (int ix = 0; ix < expectedRegisterGroups.length; ix++) { + MIRegisterGroupDMC expectedRG = expectedRegisterGroups[ix]; + int groupNo = savedRegisterGroups[ix].getGroupNo(); // Don't check group number, so set expected to obtained value + expectedRegisterGroups[ix] = new MIRegisterGroupDMC(gdbRegisters, container, groupNo, expectedRG.getName()); + } + + assertTrue(Arrays.equals(expectedRegisterGroups, savedRegisterGroups)); + } + + /* ----------------- ----------------- */ + + /** + * Variant of {@link GDBRegisterTest} where register groups are saved without a container id. + * This is the default behavior for register group persistence. + */ + public static class GDBRegisterTest_NoContainerTest extends GDBRegisterTest { + + @Override + protected GDBRegisters createGdbRegisters() { + return new GDBRegisters(fSession) { + @Override + protected boolean useProcessIdAsRegisterGroupPersistanceId() { + return false; + } + }; + } + + @Override + protected void checkAfterAdding_GroupA( + IMIContainerDMContext containerA, IMIContainerDMContext containerB, MIRegisterGroupDMC registerGroupA + ) { + checkRegisterGroupMemento(containerA, registerGroupA); + checkRegisterGroupMemento(containerB, registerGroupA); + } + + @Override + protected void checkAfterAdding_GroupB( + IMIContainerDMContext containerA, IMIContainerDMContext containerB, + MIRegisterGroupDMC registerGroupA, MIRegisterGroupDMC registerGroupB + ) { + checkRegisterGroupsMemento(containerA, array(registerGroupA, registerGroupB)); + checkRegisterGroupsMemento(containerB, array(registerGroupA, registerGroupB)); + } + } + + public static class GDBRegisterTest_WithAlternativeProcessIdTest extends GDBRegisterTest { + + @Override + protected GDBRegisters createGdbRegisters() { + return new GDBRegisters(fSession) { + @Override + protected boolean useProcessIdAsRegisterGroupPersistanceId() { + return true; + } + @Override + protected String getPersistenceIdForRegisterGroupContainer(IContainerDMContext contDmc) { + return super.getPersistenceIdForRegisterGroupContainer(contDmc) + "XXX"; + } + }; + } + + } + + + public static class GDBRegisterTest_WithContainerDMContextTest extends GDBRegisterTest { + + @Override + protected GDBRegisters createGdbRegisters() { + return new GDBRegisters(fSession) { + @Override + protected String getPersistenceIdForRegisterGroupContainer(IContainerDMContext contDmc) { + IMIContainerDMContext contextDmc = DMContexts.getAncestorOfType(contDmc, IMIContainerDMContext.class); + return contextDmc.getGroupId(); + } + }; + } + + } +}
\ No newline at end of file diff --git a/dsf-gdb/org.eclipse.cdt.dsf.gdb.tests/src/org/eclipse/cdt/dsf/gdb/tests/AutomatedIntegrationSuite.java b/dsf-gdb/org.eclipse.cdt.dsf.gdb.tests/src/org/eclipse/cdt/dsf/gdb/tests/AutomatedIntegrationSuite.java index 37eb0477a83..2ab2a2e0c41 100644 --- a/dsf-gdb/org.eclipse.cdt.dsf.gdb.tests/src/org/eclipse/cdt/dsf/gdb/tests/AutomatedIntegrationSuite.java +++ b/dsf-gdb/org.eclipse.cdt.dsf.gdb.tests/src/org/eclipse/cdt/dsf/gdb/tests/AutomatedIntegrationSuite.java @@ -10,6 +10,10 @@ *******************************************************************************/ package org.eclipse.cdt.dsf.gdb.tests; +import org.eclipse.cdt.dsf.gdb.service.GDBRegisterTest; +import org.eclipse.cdt.dsf.gdb.service.GDBRegisterTest.GDBRegisterTest_NoContainerTest; +import org.eclipse.cdt.dsf.gdb.service.GDBRegisterTest.GDBRegisterTest_WithAlternativeProcessIdTest; +import org.eclipse.cdt.dsf.gdb.service.GDBRegisterTest.GDBRegisterTest_WithContainerDMContextTest; import org.eclipse.cdt.dsf.mi.service.command.commands.TestMIBreakInsertCommand; import org.eclipse.cdt.dsf.mi.service.command.commands.TestMICommandConstructCommand; import org.eclipse.cdt.dsf.mi.service.command.commands.TestMIGDBSetSysroot; @@ -30,6 +34,10 @@ import org.junit.runners.Suite.SuiteClasses; MIStringHandlerTests.class, ProcStatParserTest.class, FilePartsTest.class, + GDBRegisterTest.class, + GDBRegisterTest_NoContainerTest.class, + GDBRegisterTest_WithAlternativeProcessIdTest.class, + GDBRegisterTest_WithContainerDMContextTest.class, }) public class AutomatedIntegrationSuite { // Often overriding BeforeClass method here diff --git a/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/gdb/service/GDBRegisters.java b/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/gdb/service/GDBRegisters.java index d9bda88cb36..537fdbb23d3 100644 --- a/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/gdb/service/GDBRegisters.java +++ b/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/gdb/service/GDBRegisters.java @@ -7,6 +7,7 @@ * * Contributors: * Alvaro Sanchez-Leon (Ericsson) - First Implementation and API (Bug 235747) + * Bruno Medeiros (Renesas) - Persistence of register groups per process (449104) *******************************************************************************/ package org.eclipse.cdt.dsf.gdb.service; @@ -15,7 +16,6 @@ import java.util.Arrays; import java.util.HashMap; import java.util.HashSet; import java.util.Hashtable; -import java.util.Iterator; import java.util.List; import java.util.Map; import java.util.Map.Entry; @@ -40,6 +40,7 @@ import org.eclipse.cdt.dsf.debug.service.IStack; import org.eclipse.cdt.dsf.debug.service.IStack.IFrameDMContext; import org.eclipse.cdt.dsf.gdb.internal.GdbPlugin; import org.eclipse.cdt.dsf.mi.service.IMIExecutionDMContext; +import org.eclipse.cdt.dsf.mi.service.IMIProcessDMContext; import org.eclipse.cdt.dsf.mi.service.MIRegisters; import org.eclipse.cdt.dsf.service.DsfSession; import org.eclipse.core.runtime.CoreException; @@ -52,7 +53,9 @@ import org.eclipse.osgi.util.NLS; /** * <p>An extension of MIRegisters to support management of Register Groups as per the IRegisters2 interface.</p> * <p>The managed registered groups are user-defined subsets of the complete list of Registers reported by GDB for a specific Target</p> - * <p>This class also triggers the read/write (persistence) of the user-defined Register Groups during the start/shutdown process of a session respectively</p> + * <p>This class also triggers the read/write (persistence) of the user-defined Register Groups during the start/shutdown process of a session respectively. + * It optionally supports persistence of user-defined Register Groups per container/process, + * see {@link #getPersistenceIdForRegisterGroupContainer(IContainerDMContext)}.</p> * @since 4.6 */ public class GDBRegisters extends MIRegisters implements IRegisters2 { @@ -239,6 +242,12 @@ public class GDBRegisters extends MIRegisters implements IRegisters2 { public boolean isEnabled() { return fEnabled; } + + @Override + public String getContainerId() { + IContainerDMContext parent = fgroup.getContainerParent(); + return getPersistenceIdForRegisterGroupContainer(parent); + } @Override public IRegisterDescriptor[] getChildren() throws CoreException { @@ -520,9 +529,6 @@ public class GDBRegisters extends MIRegisters implements IRegisters2 { } } - // must be a child of an existing container, at least the root group must be present - assert (fContextToGroupsMap.containsKey(contDmc)); - // Make sure the name is not currently in use if (fContextToGroupsMap.getGroupNameMap(contDmc).get(groupName) != null) { rm.setStatus(new Status(IStatus.ERROR, GdbPlugin.PLUGIN_ID, NOT_SUPPORTED, NLS.bind( @@ -727,17 +733,21 @@ public class GDBRegisters extends MIRegisters implements IRegisters2 { super.shutdown(rm); } + /** + * Save the register group settings into the underlying launch configuration. + */ public void save() { - IRegisterGroupDescriptor[] groups = buildDescriptors(); - ILaunchConfiguration launchConfig = getLaunchConfig(); - if (launchConfig != null) { - RegisterGroupsPersistance serializer = new RegisterGroupsPersistance(launchConfig); - try { - serializer.saveGroups(groups); - } catch (CoreException e1) { - e1.printStackTrace(); - } - } + IRegisterGroupDescriptor[] groups = buildDescriptors(); + ILaunchConfiguration launchConfig = getLaunchConfig(); + if (launchConfig != null) { + RegisterGroupsPersistance serializer = new RegisterGroupsPersistance(launchConfig); + try { + serializer.saveGroups(groups); + } catch (CoreException e) { + GdbPlugin.log(e); + } + } + } /** @@ -855,7 +865,7 @@ public class GDBRegisters extends MIRegisters implements IRegisters2 { return config; } - private IRegisterGroupDescriptor[] buildDescriptors() { + IRegisterGroupDescriptor[] buildDescriptors() { // use a tree map to sort the entries by group number TreeMap<Integer, MIRegisterGroupDMC> sortedGroups = new TreeMap<Integer, MIRegisterGroupDMC>(); @@ -872,9 +882,8 @@ public class GDBRegisters extends MIRegisters implements IRegisters2 { // load group descriptors sorted in ascending order to their group // number into the result array int i = 0; - for (Iterator<Entry<Integer, MIRegisterGroupDMC>> iterator = groupSet.iterator(); iterator.hasNext();) { - Entry<Integer, MIRegisterGroupDMC> entry = iterator.next(); - descriptors[i] = new RegisterGroupDescriptor(entry.getValue(), true); + for (Entry<Integer, MIRegisterGroupDMC> groupEntry : groupSet) { + descriptors[i] = new RegisterGroupDescriptor(groupEntry.getValue(), true); i++; } @@ -895,9 +904,16 @@ public class GDBRegisters extends MIRegisters implements IRegisters2 { return newArr; } - private MIRegisterGroupDMC[] readGroupsFromMemento(final IContainerDMContext contDmc) { + MIRegisterGroupDMC[] readGroupsFromMemento(final IContainerDMContext contDmc) { + String containerId = getPersistenceIdForRegisterGroupContainer(contDmc); + RegisterGroupsPersistance deserializer = new RegisterGroupsPersistance(getLaunchConfig()); - IRegisterGroupDescriptor[] groupDescriptions = deserializer.parseGroups(); + IRegisterGroupDescriptor[] groupDescriptions; + try { + groupDescriptions = deserializer.parseGroups(containerId); + } catch(CoreException e) { + return new MIRegisterGroupDMC[0]; + } List<MIRegisterGroupDMC> groups = new ArrayList<MIRegisterGroupDMC>(); for (IRegisterGroupDescriptor group : groupDescriptions) { @@ -908,6 +924,39 @@ public class GDBRegisters extends MIRegisters implements IRegisters2 { return groups.toArray(new MIRegisterGroupDMC[groups.size()]); } + + /** + * @return the persistence id for the register group in the given contDmc container context, + * or null to associate the Register Groups in the given container to the launch itself (this is the default behavior). + * + * Subclasses may override. Alternatively simply use override {@link #useProcessIdAsRegisterGroupPersistanceId()} to return true to have + * the process id be used as the persistence id. + * + * Note that for this to work correctly the id returned for a given container must be same across launch sessions, + * otherwise persistence info will be lost. (Hence why null is the default behavior) + * + * @since 5.3 + */ + protected String getPersistenceIdForRegisterGroupContainer(final IContainerDMContext contDmc) { + if(useProcessIdAsRegisterGroupPersistanceId()) { + IMIProcessDMContext processDmc = DMContexts.getAncestorOfType(contDmc, IMIProcessDMContext.class); + return processDmc == null ? null : processDmc.getProcId(); + } else { + return null; + } + } + + /** + * @return whether the process id should be used as a container id for the persistence + * of the register groups. Subclasses may override. + * + * @see #getPersistenceIdForRegisterGroupContainer(IContainerDMContext) + * + * @since 5.3 + */ + protected boolean useProcessIdAsRegisterGroupPersistanceId() { + return false; + } private void getUserGroupRegisters(IDMContext ctx, final DataRequestMonitor<IRegisterDMContext[]> rm) { final MIRegisterGroupDMC groupDmc = DMContexts.getAncestorOfType(ctx, MIRegisterGroupDMC.class); diff --git a/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/mi/service/MIRegisters.java b/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/mi/service/MIRegisters.java index 94b9b865bf3..27154be2e66 100644 --- a/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/mi/service/MIRegisters.java +++ b/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/mi/service/MIRegisters.java @@ -85,17 +85,27 @@ public class MIRegisters extends AbstractDsfService implements IRegisters, ICach */ public static class MIRegisterGroupDMC extends AbstractDMContext implements IRegisterGroupDMContext { - private int fGroupNo; + private final int fGroupNo; + private final IContainerDMContext parent; private String fGroupName; public MIRegisterGroupDMC(MIRegisters service, IContainerDMContext contDmc, int groupNo, String groupName) { super(service.getSession().getId(), new IDMContext[] { contDmc }); + this.parent = contDmc; fGroupNo = groupNo; fGroupName = groupName; } public int getGroupNo() { return fGroupNo; } public String getName() { return fGroupName; } + + /** + * @since 5.3 + */ + public IContainerDMContext getContainerParent() { + return parent; + } + /** * @since 4.6 */ |