1
0
Fork 0
mirror of https://github.com/eclipse-cdt/cdt synced 2025-07-28 11:25:35 +02:00

Bug 323552: [registers] Register View content is not stack frame

specific

Change-Id: Ib7922f8487d10e3b9cb5b6dcb255590cc31d2a97
Signed-off-by: Alvaro Sanchez-Leon <alvsan09@gmail.com>
Reviewed-on: https://git.eclipse.org/r/16566
Reviewed-by: Marc Khouzam <marc.khouzam@ericsson.com>
IP-Clean: Marc Khouzam <marc.khouzam@ericsson.com>
Tested-by: Marc Khouzam <marc.khouzam@ericsson.com>
This commit is contained in:
Alvaro Sanchez-Leon 2013-09-18 09:09:16 -04:00 committed by Marc Khouzam
parent c92d135f6d
commit 6c85c85a06
6 changed files with 303 additions and 83 deletions

View file

@ -9,6 +9,7 @@
* Wind River Systems - initial API and implementation
* Ericsson - Modified for additional features in DSF Reference Implementation
* Roland Grunberg (RedHat) - Refresh all registers once one is changed (Bug 400840)
* Alvaro Sanchez-Leon (Ericsson) - Make Registers View specific to a frame (Bug 323552)
*******************************************************************************/
package org.eclipse.cdt.dsf.mi.service;
@ -17,6 +18,7 @@ import java.util.Hashtable;
import java.util.List;
import org.eclipse.cdt.dsf.concurrent.DataRequestMonitor;
import org.eclipse.cdt.dsf.concurrent.ImmediateDataRequestMonitor;
import org.eclipse.cdt.dsf.concurrent.ImmediateRequestMonitor;
import org.eclipse.cdt.dsf.concurrent.RequestMonitor;
import org.eclipse.cdt.dsf.datamodel.AbstractDMContext;
@ -29,6 +31,8 @@ import org.eclipse.cdt.dsf.debug.service.IRegisters;
import org.eclipse.cdt.dsf.debug.service.IRunControl;
import org.eclipse.cdt.dsf.debug.service.IRunControl.IContainerDMContext;
import org.eclipse.cdt.dsf.debug.service.IRunControl.StateChangeReason;
import org.eclipse.cdt.dsf.debug.service.IStack;
import org.eclipse.cdt.dsf.debug.service.IStack.IFrameDMContext;
import org.eclipse.cdt.dsf.debug.service.command.BufferedCommandControl;
import org.eclipse.cdt.dsf.debug.service.command.CommandCache;
import org.eclipse.cdt.dsf.debug.service.command.ICommandControlService;
@ -97,6 +101,11 @@ public class MIRegisters extends AbstractDsfService implements IRegisters, ICach
private int fRegNo;
private String fRegName;
/**
* An MIRegiserDMC created with no frame context will not be able to resolve the associated register value.
* However these instances are useful to provide the register name i.e. needed from the selection of a process,
* or a running thread where it is not possible to associate registers to frames and therefore values.
*/
public MIRegisterDMC(MIRegisters service, MIRegisterGroupDMC group, int regNo, String regName) {
super(service.getSession().getId(),
new IDMContext[] { group });
@ -104,9 +113,26 @@ public class MIRegisters extends AbstractDsfService implements IRegisters, ICach
fRegName = regName;
}
@Deprecated
public MIRegisterDMC(MIRegisters service, MIRegisterGroupDMC group, IMIExecutionDMContext execDmc, int regNo, String regName) {
super(service.getSession().getId(),
new IDMContext[] { execDmc, group });
new IDMContext[] { execDmc, group });
fRegNo = regNo;
fRegName = regName;
}
/**
* This Register context is associated to two parent contexts. A stack frame context (IFrameDMContext), and a register group
* context (MIRegisterGroupDMC). When the scenario requires to build a register contexts from the selection of a thread, then the top
* frame shall be resolved and be provided in this constructor.
*
* The frame context is necessary to resolve the register's data e.g. value
*
* @since 4.3
*/
public MIRegisterDMC(MIRegisters service, MIRegisterGroupDMC group, IFrameDMContext frameDmc, int regNo, String regName) {
super(service.getSession().getId(),
new IDMContext[] { frameDmc, group });
fRegNo = regNo;
fRegName = regName;
}
@ -265,17 +291,17 @@ public class MIRegisters extends AbstractDsfService implements IRegisters, ICach
public void getRegisterData(IRegisterDMContext regDmc , final DataRequestMonitor<IRegisterDMData> rm) {
if (regDmc instanceof MIRegisterDMC) {
final MIRegisterDMC miRegDmc = (MIRegisterDMC)regDmc;
IMIExecutionDMContext execDmc = DMContexts.getAncestorOfType(regDmc, IMIExecutionDMContext.class);
// Create register DMC with name if execution DMC is not present.
if(execDmc == null){
rm.setData(new RegisterData(miRegDmc.getName(), BLANK_STRING, false));
final IFrameDMContext frameDmc = DMContexts.getAncestorOfType(regDmc, IFrameDMContext.class);
// Create register data with name only e.g. not editable.
if(frameDmc == null){
rm.setData(new RegisterData(null, miRegDmc.getName(), BLANK_STRING, false));
rm.done();
return;
}
int[] regnos = {miRegDmc.getRegNo()};
fRegisterValueCache.execute(
fCommandFactory.createMIDataListRegisterValues(execDmc, MIFormat.HEXADECIMAL, regnos),
fCommandFactory.createMIDataListRegisterValues(frameDmc, MIFormat.HEXADECIMAL, regnos),
new DataRequestMonitor<MIDataListRegisterValuesInfo>(getExecutor(), rm) {
@Override
protected void handleSuccess() {
@ -301,9 +327,9 @@ public class MIRegisters extends AbstractDsfService implements IRegisters, ICach
if ( reg.getValue().contains("float")) { //$NON-NLS-1$
isFloat = true;
}
// Return the new register attributes.
rm.setData(new RegisterData(miRegDmc.getName(), BLANK_STRING, isFloat));
rm.setData(new RegisterData(frameDmc, miRegDmc.getName(), BLANK_STRING, isFloat));
rm.done();
}
});
@ -314,9 +340,9 @@ public class MIRegisters extends AbstractDsfService implements IRegisters, ICach
}
private void getRegisterDataValue( final MIRegisterDMC regDmc, final String formatId, final DataRequestMonitor<FormattedValueDMData> rm) {
IMIExecutionDMContext miExecDmc = DMContexts.getAncestorOfType(regDmc, IMIExecutionDMContext.class);
if(miExecDmc == null){
// Set value to blank if execution dmc is not present
IFrameDMContext frameDmc = DMContexts.getAncestorOfType(regDmc, IFrameDMContext.class);
if(frameDmc == null){
// Set value to blank if frame dmc is not present
rm.setData( new FormattedValueDMData( BLANK_STRING ) );
rm.done();
return;
@ -333,7 +359,7 @@ public class MIRegisters extends AbstractDsfService implements IRegisters, ICach
int[] regnos = {regDmc.getRegNo()};
fRegisterValueCache.execute(
fCommandFactory.createMIDataListRegisterValues(miExecDmc, NumberFormat, regnos),
fCommandFactory.createMIDataListRegisterValues(frameDmc, NumberFormat, regnos),
new DataRequestMonitor<MIDataListRegisterValuesInfo>(getExecutor(), rm) {
@Override
protected void handleSuccess() {
@ -362,12 +388,14 @@ public class MIRegisters extends AbstractDsfService implements IRegisters, ICach
final private String fRegName;
final private String fRegDesc;
final private boolean fIsFloat;
final private IFrameDMContext fContext;
public RegisterData(String regName, String regDesc, boolean isFloat ) {
public RegisterData(IFrameDMContext context, String regName, String regDesc, boolean isFloat ) {
fRegName = regName;
fRegDesc = regDesc;
fIsFloat = isFloat;
fContext = context;
}
@Override
@ -375,7 +403,12 @@ public class MIRegisters extends AbstractDsfService implements IRegisters, ICach
@Override
public boolean isReadOnce() { return false; }
@Override
public boolean isWriteable() { return true; }
public boolean isWriteable() {
//The absence of the frame context is likely the result of a selection not specific to a stack frame
//e.g. the selection of a running thread, or the selection of a process.
//So, an instance with no stack frame is not writable
return (fContext != null);
}
@Override
public boolean isWriteOnce() { return false; }
@Override
@ -397,13 +430,13 @@ public class MIRegisters extends AbstractDsfService implements IRegisters, ICach
}
// Wraps a list of registers in DMContexts.
private MIRegisterDMC[] makeRegisterDMCs(MIRegisterGroupDMC groupDmc, IMIExecutionDMContext execDmc, String[] regNames) {
private MIRegisterDMC[] makeRegisterDMCs(MIRegisterGroupDMC groupDmc, IFrameDMContext frameDmc, String[] regNames) {
List<MIRegisterDMC> regDmcList = new ArrayList<MIRegisters.MIRegisterDMC>( regNames.length );
int regNo = 0;
for (String regName : regNames) {
if(regName != null && regName.length() > 0) {
if(execDmc != null)
regDmcList.add(new MIRegisterDMC(this, groupDmc, execDmc, regNo, regName));
if(frameDmc != null)
regDmcList.add(new MIRegisterDMC(this, groupDmc, frameDmc, regNo, regName));
else
regDmcList.add(new MIRegisterDMC(this, groupDmc, regNo, regName));
}
@ -494,57 +527,96 @@ public class MIRegisters extends AbstractDsfService implements IRegisters, ICach
rm.done() ;
}
/*
* (non-Javadoc)
* @see org.eclipse.cdt.dsf.debug.service.IRegisters#getRegisters(org.eclipse.cdt.dsf.debug.service.IRegisters.IRegisterGroupDMContext, org.eclipse.cdt.dsf.concurrent.DataRequestMonitor)
*/
@Override
public void getRegisters(final IDMContext dmc, final DataRequestMonitor<IRegisterDMContext[]> rm) {
final MIRegisterGroupDMC groupDmc = DMContexts.getAncestorOfType(dmc, MIRegisterGroupDMC.class);
if ( groupDmc == null ) {
rm.setStatus( new Status( IStatus.ERROR , GdbPlugin.PLUGIN_ID , INVALID_HANDLE , "RegisterGroup context not found", null ) ) ; //$NON-NLS-1$
rm.done();
return;
}
public void getRegisters(final IDMContext dmc, final DataRequestMonitor<IRegisterDMContext[]> rm) {
final MIRegisterGroupDMC groupDmc = DMContexts.getAncestorOfType(dmc, MIRegisterGroupDMC.class);
if (groupDmc == null) {
rm.setStatus(new Status(IStatus.ERROR, GdbPlugin.PLUGIN_ID, INVALID_HANDLE,
"RegisterGroup context not found", null)); //$NON-NLS-1$
rm.done();
return;
}
final IContainerDMContext containerDmc = DMContexts.getAncestorOfType(dmc, IContainerDMContext.class);
if ( containerDmc == null ) {
rm.setStatus( new Status( IStatus.ERROR , GdbPlugin.PLUGIN_ID , INVALID_HANDLE , "Container context not found" , null ) ) ; //$NON-NLS-1$
rm.done();
return;
}
final IContainerDMContext containerDmc = DMContexts.getAncestorOfType(dmc, IContainerDMContext.class);
if (containerDmc == null) {
rm.setStatus(new Status(IStatus.ERROR, GdbPlugin.PLUGIN_ID, INVALID_HANDLE,
"Container context not found", null)); //$NON-NLS-1$
rm.done();
return;
}
// There is only one group and its number must be 0.
if ( groupDmc.getGroupNo() == 0 ) {
final IMIExecutionDMContext executionDmc = DMContexts.getAncestorOfType(dmc, IMIExecutionDMContext.class);
fRegisterNameCache.execute(
fCommandFactory.createMIDataListRegisterNames(containerDmc),
new DataRequestMonitor<MIDataListRegisterNamesInfo>(getExecutor(), rm) {
@Override
protected void handleSuccess() {
// Retrieve the register names.
String[] regNames = getData().getRegisterNames() ;
// If the list is empty just return empty handed.
if ( regNames.length == 0 ) {
rm.done();
return;
}
// Create DMContexts for each of the register names.
if(executionDmc == null)
rm.setData(makeRegisterDMCs(groupDmc, regNames));
else
rm.setData(makeRegisterDMCs(groupDmc, executionDmc, regNames));
rm.done();
}
});
} else {
rm.setStatus(new Status(IStatus.ERROR , GdbPlugin.PLUGIN_ID , INTERNAL_ERROR , "Invalid group = " + groupDmc , null)); //$NON-NLS-1$
rm.done();
}
}
// There is only one group and its number must be 0.
if (groupDmc.getGroupNo() == 0) {
final IFrameDMContext frameDmc = DMContexts.getAncestorOfType(dmc, IFrameDMContext.class);
if (frameDmc == null) {
// The selection does not provide a specific frame, then resolve the top frame on the current thread
IMIExecutionDMContext execDmc = DMContexts.getAncestorOfType(dmc, IMIExecutionDMContext.class);
if (execDmc != null) {
IStack stackService = getServicesTracker().getService(IStack.class);
if (stackService != null) {
stackService.getTopFrame(execDmc, new ImmediateDataRequestMonitor<IStack.IFrameDMContext>(rm) {
@Override
protected void handleSuccess() {
getRegisters(getData(), groupDmc, containerDmc, rm);
}
@Override
protected void handleFailure() {
//Unable to resolve top frame on current thread.
//The thread could e.g. be in running state,
//we return register instances with no associated execution context
//i.e. unable to resolve its associated value.
getRegisters(null, groupDmc, containerDmc, rm);
}
});
return;
}
}
}
getRegisters(frameDmc, groupDmc, containerDmc, rm);
} else {
rm.setStatus(new Status(IStatus.ERROR, GdbPlugin.PLUGIN_ID, INTERNAL_ERROR,
"Invalid group = " + groupDmc, null)); //$NON-NLS-1$
rm.done();
}
}
private void getRegisters(final IFrameDMContext frameDmc, final MIRegisterGroupDMC groupDmc,
IContainerDMContext containerDmc, final DataRequestMonitor<IRegisterDMContext[]> rm) {
fRegisterNameCache.execute(fCommandFactory.createMIDataListRegisterNames(containerDmc),
new ImmediateDataRequestMonitor<MIDataListRegisterNamesInfo>(rm) {
@Override
protected void handleSuccess() {
// Retrieve the register names.
String[] regNames = getData().getRegisterNames();
// If the list is empty just return empty handed.
if (regNames.length == 0) {
rm.done();
return;
}
if (frameDmc == null)
// The selection does not provide a frame or thread context,
// This can happen e.g. if a container /process is selected
// Lets provide the list of register names applicable to the selected process
// i.e. instances with only name information which can not resolve a value
rm.setData(makeRegisterDMCs(groupDmc, regNames));
else
rm.setData(makeRegisterDMCs(groupDmc, frameDmc, regNames));
rm.done();
}
});
}
/*
* (non-Javadoc)
* @see org.eclipse.cdt.dsf.debug.service.IRegisters#getBitFields(org.eclipse.cdt.dsf.debug.service.IRegisters.IRegisterDMContext, org.eclipse.cdt.dsf.concurrent.DataRequestMonitor)

View file

@ -20,6 +20,7 @@
* Anton Gorenkov - A preference to use RTTI for variable types determination (Bug 377536)
* Vladimir Prus (Mentor Graphics) - Support for -info-os (Bug 360314)
* John Dallaway - Support for -data-write-memory-bytes (Bug 387793)
* Alvaro Sanchez-Leon (Ericsson) - Make Registers View specific to a frame (Bug (323552)
*******************************************************************************/
package org.eclipse.cdt.dsf.mi.service.command;
@ -429,13 +430,29 @@ public class CommandFactory {
return new MIDataListRegisterNames(ctx, regnos);
}
@Deprecated
public ICommand<MIDataListRegisterValuesInfo> createMIDataListRegisterValues(IMIExecutionDMContext ctx, int fmt) {
return new MIDataListRegisterValues(ctx, fmt);
}
@Deprecated
public ICommand<MIDataListRegisterValuesInfo> createMIDataListRegisterValues(IMIExecutionDMContext ctx, int fmt, int [] regnos) {
return new MIDataListRegisterValues(ctx, fmt, regnos);
}
/**
* @since 4.3
*/
public ICommand<MIDataListRegisterValuesInfo> createMIDataListRegisterValues(IFrameDMContext ctx, int fmt) {
return new MIDataListRegisterValues(ctx, fmt);
}
/**
* @since 4.3
*/
public ICommand<MIDataListRegisterValuesInfo> createMIDataListRegisterValues(IFrameDMContext ctx, int fmt, int [] regnos) {
return new MIDataListRegisterValues(ctx, fmt, regnos);
}
public ICommand<MIDataReadMemoryInfo> createMIDataReadMemory(IDMContext ctx, long offset, String address,
int word_format, int word_size, int rows, int cols,

View file

@ -8,10 +8,13 @@
* Contributors:
* QNX Software Systems - Initial API and implementation
* Wind River Systems - Modified for new DSF Reference Implementation
* Alvaro Sanchez-Leon (Ericsson) - Make Registers View specific to a frame (Bug 323552)
*******************************************************************************/
package org.eclipse.cdt.dsf.mi.service.command.commands;
import org.eclipse.cdt.dsf.datamodel.IDMContext;
import org.eclipse.cdt.dsf.debug.service.IStack.IFrameDMContext;
import org.eclipse.cdt.dsf.debug.service.command.ICommand;
import org.eclipse.cdt.dsf.debug.service.command.ICommandResult;
import org.eclipse.cdt.dsf.mi.service.IMIExecutionDMContext;
@ -35,12 +38,34 @@ public class MIDataListRegisterValues extends MICommand<MIDataListRegisterValues
int[] regnums;
int fFmt;
public MIDataListRegisterValues(IMIExecutionDMContext ctx, int fmt) {
/**
* @since 4.3
*/
public MIDataListRegisterValues(IFrameDMContext ctx, int fmt) {
this(ctx, fmt, null);
}
/**
* @since 4.3
*/
public MIDataListRegisterValues(IFrameDMContext ctx, int fmt, int [] regnos) {
super(ctx, "-data-list-register-values"); //$NON-NLS-1$
init(fmt, regnos);
}
@Deprecated
public MIDataListRegisterValues(IMIExecutionDMContext ctx, int fmt) {
this(ctx, fmt, null);
}
@Deprecated
public MIDataListRegisterValues(IMIExecutionDMContext ctx, int fmt, int [] regnos) {
super(ctx, "-data-list-register-values"); //$NON-NLS-1$
init(fmt, regnos);
}
private void init(int fmt, int [] regnos) {
regnums = regnos;
String format = "x"; //$NON-NLS-1$
@ -86,7 +111,16 @@ public class MIDataListRegisterValues extends MICommand<MIDataListRegisterValues
/*
* Can coalesce only with other DsfMIDataListRegisterValues commands.
*/
if (! (command instanceof MIDataListRegisterValues) ) return null;
if (! (command instanceof MIDataListRegisterValues) ) return null;
IDMContext context = getContext();
/*
* Make sure we are coalescing over the same context
*/
if (!command.getContext().equals(context)) {
return null;
}
MIDataListRegisterValues cmd = (MIDataListRegisterValues) command;
@ -145,6 +179,14 @@ public class MIDataListRegisterValues extends MICommand<MIDataListRegisterValues
/*
* Now construct a new one. The format we will use is this command.
*/
return( new MIDataListRegisterValues((IMIExecutionDMContext)getContext(), fFmt, finalregnums));
MIDataListRegisterValues dataValues;
if (context instanceof IFrameDMContext) {
dataValues = new MIDataListRegisterValues((IFrameDMContext)context, fFmt, finalregnums);
} else {
//Keeping for compatibility with potential users
dataValues = new MIDataListRegisterValues((IMIExecutionDMContext)context, fFmt, finalregnums);
}
return(dataValues);
}
}

View file

@ -7,15 +7,19 @@
*
* Contributors:
* Ericsson - initial API and implementation
* Alvaro Sanchez-Leon (Ericsson) - Make Registers View specific to a frame (Bug 323552)
*******************************************************************************/
package org.eclipse.cdt.tests.dsf.gdb.tests;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;
import java.util.LinkedList;
import java.util.List;
import java.util.concurrent.ExecutionException;
import org.eclipse.cdt.debug.core.ICDTLaunchConfigurationConstants;
import org.eclipse.cdt.dsf.concurrent.CountingRequestMonitor;
@ -46,6 +50,7 @@ import org.eclipse.cdt.dsf.mi.service.IMICommandControl;
import org.eclipse.cdt.dsf.mi.service.IMIExecutionDMContext;
import org.eclipse.cdt.dsf.mi.service.IMIProcesses;
import org.eclipse.cdt.dsf.mi.service.MIProcesses;
import org.eclipse.cdt.dsf.mi.service.MIRegisters.MIRegisterDMC;
import org.eclipse.cdt.dsf.mi.service.command.events.MIStoppedEvent;
import org.eclipse.cdt.dsf.mi.service.command.output.MIDataListRegisterNamesInfo;
import org.eclipse.cdt.dsf.service.DsfServicesTracker;
@ -279,7 +284,17 @@ public class MIRegistersTest extends BaseTestCase {
IFrameDMContext frameDmc = SyncUtil.getStackFrame(stoppedEvent.getDMContext(), 0);
final IRegisterDMContext[] regDMCs = getRegisters(frameDmc);
List<String> regNames = get_X86_REGS();
IRegisterDMData[] datas = getRegistersData(regDMCs);
for(IRegisterDMData data: datas){
String regName = data.getName();
Assert.assertFalse("GDB does not support register name: " + regName, !regNames.contains(regName));
}
}
private IRegisterDMData[] getRegistersData(final IRegisterDMContext[] regDMCs) throws InterruptedException, ExecutionException {
Query<IRegisterDMData[]> query = new Query<IRegisterDMData[]>() {
@Override
protected void execute(DataRequestMonitor<IRegisterDMData[]> rm) {
@ -305,15 +320,10 @@ public class MIRegistersTest extends BaseTestCase {
fSession.getExecutor().execute(query);
IRegisterDMData[] datas = query.get();
for(IRegisterDMData data: datas){
String regName = data.getName();
Assert.assertFalse("GDB does not support register name: " + regName, !regNames.contains(regName));
}
}
private String getModelDataForRegisterDataValue(IFrameDMContext frameDmc, String format, int regNo) throws Throwable {
return query.get();
}
private String getModelDataForRegisterDataValue(IFrameDMContext frameDmc, String format, int regNo) throws Throwable {
final AsyncCompletionWaitor wait = new AsyncCompletionWaitor();
final IRegisterDMContext[] regDMCs = getRegisters(frameDmc);
@ -548,4 +558,75 @@ public class MIRegistersTest extends BaseTestCase {
assertTrue("Failed writing register. New value should have been " + regValue + "instead of " + val, regValue.equals(val));
}
/**
* This test validates retrieval of different values for the same register used on different frames
*/
@Test
public void frameSpecificValues() throws Throwable {
// Step to a multi-level stack level to be able to test different stack frames
SyncUtil.runToLocation("PrintHello");
MIStoppedEvent stoppedEvent = SyncUtil.step(StepType.STEP_OVER);
int depth = SyncUtil.getStackDepth(stoppedEvent.getDMContext());
// validate expected stack depth
assertEquals(4, depth);
// Resolve the register name of the stack pointer
String sp_name = resolveStackPointerName();
assertNotNull(sp_name);
// Get the stack pointer value for frame0
IFrameDMContext frame0 = SyncUtil.getStackFrame(stoppedEvent.getDMContext(), 0);
IRegisterDMContext[] registers_f0 = getRegisters(frame0);
MIRegisterDMC sp_reg_f0 = (MIRegisterDMC) findStackPointerRegister(sp_name, registers_f0);
assertNotNull(sp_reg_f0);
String sp_f0_str = getModelDataForRegisterDataValue(frame0, IFormattedValues.HEX_FORMAT, sp_reg_f0.getRegNo());
// Get the stack pointer value for frame1
IFrameDMContext frame1 = SyncUtil.getStackFrame(stoppedEvent.getDMContext(), 1);
IRegisterDMContext[] registers_f1 = getRegisters(frame1);
MIRegisterDMC sp_reg_f1 = (MIRegisterDMC) findStackPointerRegister(sp_name, registers_f1);
assertNotNull(sp_reg_f1);
String sp_f1_str = getModelDataForRegisterDataValue(frame1, IFormattedValues.HEX_FORMAT, sp_reg_f1.getRegNo());
//The stack pointer's are not expected to be the same among frames
assertNotEquals("Stack pointers shall be different among frames", sp_f0_str, sp_f1_str);
}
private IRegisterDMContext findStackPointerRegister(String sp_name, IRegisterDMContext[] registerDMCs) throws InterruptedException, ExecutionException {
IRegisterDMData[] registersData = getRegistersData(registerDMCs);
for (int i = 0; i < registersData.length; i++) {
IRegisterDMData registerData = registersData[i];
if (registerData.getName().equals(sp_name)) {
return registerDMCs[i];
}
}
return null;
}
private String resolveStackPointerName() throws Throwable {
List<String> regNames = get_X86_REGS();
// for 64 bits
String sp_name = "rsp";
if (regNames.contains(sp_name)) {
return sp_name;
}
// for 32 bits
sp_name = "esp";
if (regNames.contains(sp_name)) {
return sp_name;
}
// for 16 bits
sp_name = "sp";
if (regNames.contains(sp_name)) {
return sp_name;
}
return null;
}
}

View file

@ -7,6 +7,7 @@
*
* Contributors:
* Wind River Systems - initial API and implementation
* Alvaro Sanchez-Leon (Ericsson) - Make Registers View specific to a frame (Bug 323552)
*******************************************************************************/
package org.eclipse.cdt.dsf.debug.ui.viewmodel.register;
@ -29,6 +30,7 @@ import org.eclipse.cdt.dsf.debug.service.IRegisters.IRegisterDMContext;
import org.eclipse.cdt.dsf.debug.service.IRegisters.IRegisterDMData;
import org.eclipse.cdt.dsf.debug.service.IRegisters.IRegisterGroupDMData;
import org.eclipse.cdt.dsf.debug.service.IRegisters.IRegistersChangedDMEvent;
import org.eclipse.cdt.dsf.debug.service.IRunControl.IResumedDMEvent;
import org.eclipse.cdt.dsf.debug.service.IRunControl.ISuspendedDMEvent;
import org.eclipse.cdt.dsf.debug.ui.viewmodel.ErrorLabelForeground;
import org.eclipse.cdt.dsf.debug.ui.viewmodel.ErrorLabelText;
@ -672,6 +674,7 @@ public class RegisterVMNode extends AbstractExpressionVMNode
@Override
public int getDeltaFlags(Object e) {
if ( e instanceof ISuspendedDMEvent ||
e instanceof IResumedDMEvent ||
e instanceof IMemoryChangedEvent ||
e instanceof IRegistersChangedDMEvent ||
(e instanceof PropertyChangeEvent &&
@ -697,6 +700,7 @@ public class RegisterVMNode extends AbstractExpressionVMNode
// The following events can affect any register's values,
// refresh the contents of the parent element (i.e. all the registers).
if ( e instanceof ISuspendedDMEvent ||
e instanceof IResumedDMEvent ||
e instanceof IMemoryChangedEvent ||
e instanceof IRegistersChangedDMEvent ||
(e instanceof PropertyChangeEvent &&

View file

@ -7,6 +7,7 @@
*
* Contributors:
* Wind River Systems - initial API and implementation
* Alvaro Sanchez-Leon (Ericsson) - Make Registers View specific to a frame (Bug 323552)
*******************************************************************************/
package org.eclipse.cdt.dsf.debug.ui.viewmodel.register;
@ -19,6 +20,7 @@ import org.eclipse.cdt.dsf.debug.service.ICachingService;
import org.eclipse.cdt.dsf.debug.service.IRegisters;
import org.eclipse.cdt.dsf.debug.service.IRunControl.IExecutionDMContext;
import org.eclipse.cdt.dsf.debug.service.IRunControl.ISuspendedDMEvent;
import org.eclipse.cdt.dsf.debug.service.IStack.IFrameDMContext;
import org.eclipse.cdt.dsf.debug.ui.DsfDebugUITools;
import org.eclipse.cdt.dsf.debug.ui.IDsfDebugUIConstants;
import org.eclipse.cdt.dsf.debug.ui.viewmodel.update.BreakpointHitUpdatePolicy;
@ -168,24 +170,26 @@ public class RegisterVMProvider extends AbstractDMVMProvider
*/
@Override
public void update(IViewerInputUpdate update) {
/*
* Use the execution context in the current selection as the input provider.
* This insures that the REGISTER VIEW will not collapse and expand on stepping or on
* re-selection in the DEBUG VIEW. Currently the register content is not stack frame
* specific. If it were to become so then we would need to modify this policy.
*/
/*
* Using the frame context as first alternative to display register values per stack frame
* if not available e.g. user selected a thread, the execution context is used instead
*/
Object element = update.getElement();
if (element instanceof IDMVMContext) {
IDMContext ctx = ((IDMVMContext) element).getDMContext();
IExecutionDMContext execDmc = DMContexts.getAncestorOfType(ctx, IExecutionDMContext.class);
if ( execDmc != null ) {
IDMContext selDmc = DMContexts.getAncestorOfType(ctx, IFrameDMContext.class);
if (selDmc == null) {
selDmc = DMContexts.getAncestorOfType(ctx, IExecutionDMContext.class);
}
if ( selDmc != null ) {
/*
* This tells the Flexible Hierarchy that element driving this view has not changed
* and there is no need to redraw the view. Since this is a somewhat fake VMContext
* we provide our Root Layout node as the representative VM node.
*/
update.setInputElement(new ViewInputElement(RegisterVMProvider.this.getRootVMNode(), execDmc));
update.setInputElement(new ViewInputElement(RegisterVMProvider.this.getRootVMNode(), selDmc));
update.done();
return;
}