mirror of
https://github.com/eclipse-cdt/cdt
synced 2025-04-22 06:02:11 +02:00
Bug 489513 - Show registers in the traditional memory render
Change-Id: I9ddbbeb9c8345f006004d9d2982a778d28c6d68c
This commit is contained in:
parent
6bdca5f4a2
commit
b2db3a489c
2 changed files with 241 additions and 1 deletions
|
@ -24,6 +24,7 @@ import org.eclipse.cdt.dsf.debug.service.IExpressions.IExpressionChangedDMEvent;
|
||||||
import org.eclipse.cdt.dsf.debug.service.IRegisters.IRegisterChangedDMEvent;
|
import org.eclipse.cdt.dsf.debug.service.IRegisters.IRegisterChangedDMEvent;
|
||||||
import org.eclipse.cdt.dsf.debug.service.IRunControl.IContainerDMContext;
|
import org.eclipse.cdt.dsf.debug.service.IRunControl.IContainerDMContext;
|
||||||
import org.eclipse.cdt.dsf.debug.service.IStack.IFrameDMContext;
|
import org.eclipse.cdt.dsf.debug.service.IStack.IFrameDMContext;
|
||||||
|
import org.eclipse.cdt.dsf.gdb.internal.memory.GdbMemoryAddressInfoRegistersRetrieval;
|
||||||
import org.eclipse.cdt.dsf.gdb.internal.memory.GdbMemoryAddressInfoVariablesRetrieval;
|
import org.eclipse.cdt.dsf.gdb.internal.memory.GdbMemoryAddressInfoVariablesRetrieval;
|
||||||
import org.eclipse.cdt.dsf.gdb.memory.IGdbMemoryAddressInfoTypeRetrieval;
|
import org.eclipse.cdt.dsf.gdb.memory.IGdbMemoryAddressInfoTypeRetrieval;
|
||||||
import org.eclipse.cdt.dsf.service.DsfServiceEventHandler;
|
import org.eclipse.cdt.dsf.service.DsfServiceEventHandler;
|
||||||
|
@ -47,7 +48,7 @@ public class GdbMemoryBlockAddressInfoRetrieval implements IMemoryBlockAddressIn
|
||||||
}
|
}
|
||||||
|
|
||||||
protected IGdbMemoryAddressInfoTypeRetrieval[] resolveMemoryAddressInfoProviders() {
|
protected IGdbMemoryAddressInfoTypeRetrieval[] resolveMemoryAddressInfoProviders() {
|
||||||
return new IGdbMemoryAddressInfoTypeRetrieval[] {new GdbMemoryAddressInfoVariablesRetrieval(fSession)};
|
return new IGdbMemoryAddressInfoTypeRetrieval[] {new GdbMemoryAddressInfoVariablesRetrieval(fSession), new GdbMemoryAddressInfoRegistersRetrieval(fSession)};
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -0,0 +1,239 @@
|
||||||
|
/*******************************************************************************
|
||||||
|
* Copyright (c) 2016 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:
|
||||||
|
* Ericsson - initial API and implementation
|
||||||
|
*******************************************************************************/
|
||||||
|
package org.eclipse.cdt.dsf.gdb.internal.memory;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import org.eclipse.cdt.debug.core.model.IMemoryBlockAddressInfoRetrieval.IMemoryBlockAddressInfoItem;
|
||||||
|
import org.eclipse.cdt.dsf.concurrent.CountingRequestMonitor;
|
||||||
|
import org.eclipse.cdt.dsf.concurrent.DataRequestMonitor;
|
||||||
|
import org.eclipse.cdt.dsf.concurrent.DsfExecutor;
|
||||||
|
import org.eclipse.cdt.dsf.datamodel.DMContexts;
|
||||||
|
import org.eclipse.cdt.dsf.datamodel.IDMContext;
|
||||||
|
import org.eclipse.cdt.dsf.debug.service.IFormattedValues;
|
||||||
|
import org.eclipse.cdt.dsf.debug.service.IFormattedValues.FormattedValueDMContext;
|
||||||
|
import org.eclipse.cdt.dsf.debug.service.IFormattedValues.FormattedValueDMData;
|
||||||
|
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.IRegisters2;
|
||||||
|
import org.eclipse.cdt.dsf.debug.service.IStack.IFrameDMContext;
|
||||||
|
import org.eclipse.cdt.dsf.gdb.internal.GdbPlugin;
|
||||||
|
import org.eclipse.cdt.dsf.gdb.memory.IGdbMemoryAddressInfoTypeRetrieval;
|
||||||
|
import org.eclipse.cdt.dsf.service.DsfServicesTracker;
|
||||||
|
import org.eclipse.cdt.dsf.service.DsfSession;
|
||||||
|
import org.eclipse.core.runtime.IStatus;
|
||||||
|
import org.eclipse.core.runtime.Status;
|
||||||
|
import org.eclipse.debug.core.model.IMemoryBlock;
|
||||||
|
|
||||||
|
public class GdbMemoryAddressInfoRegistersRetrieval implements IGdbMemoryAddressInfoTypeRetrieval {
|
||||||
|
|
||||||
|
private final static String REGISTERS_INFO_TYPE = "Registers"; //$NON-NLS-1$
|
||||||
|
private final DsfSession fSession;
|
||||||
|
|
||||||
|
public GdbMemoryAddressInfoRegistersRetrieval(DsfSession session) {
|
||||||
|
fSession = session;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void itemsRequest(final IDMContext context, final IMemoryBlock memBlock, final DataRequestMonitor<IMemoryBlockAddressInfoItem[]> rm) {
|
||||||
|
if (fSession == null || fSession.getExecutor() == null) {
|
||||||
|
rm.done(new Status(IStatus.ERROR, GdbPlugin.PLUGIN_ID, "Initialization problem, invalid session")); //$NON-NLS-1$
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
final DsfExecutor executor = fSession.getExecutor();
|
||||||
|
IFrameDMContext frameCtx = DMContexts.getAncestorOfType(context, IFrameDMContext.class);
|
||||||
|
final IRegisters2 service = resolveService(IRegisters2.class);
|
||||||
|
|
||||||
|
if (frameCtx != null && service != null) {
|
||||||
|
// Getting all available register contexts
|
||||||
|
service.getRegisters(frameCtx, new DataRequestMonitor<IRegisterDMContext[]>(executor, rm) {
|
||||||
|
@Override
|
||||||
|
protected void handleSuccess() {
|
||||||
|
final IRegisterDMContext[] registers = getData();
|
||||||
|
if (registers != null && registers.length != 0) {
|
||||||
|
// Resolve register data
|
||||||
|
getRegistersData(service, registers,
|
||||||
|
new DataRequestMonitor<IRegisterDMData[]>(fSession.getExecutor(), rm) {
|
||||||
|
@Override
|
||||||
|
protected void handleSuccess() {
|
||||||
|
final IRegisterDMData[] regBaseData = getData();
|
||||||
|
// Resolve register values
|
||||||
|
getRegisterValues(service, registers,
|
||||||
|
new DataRequestMonitor<FormattedValueDMData[]>(fSession.getExecutor(),
|
||||||
|
rm) {
|
||||||
|
@Override
|
||||||
|
protected void handleSuccess() {
|
||||||
|
// Extract the register information needed to build the requested data items
|
||||||
|
FormattedValueDMData[] regFormattedData = getData();
|
||||||
|
String[] regNames = extractRegNames(regBaseData);
|
||||||
|
String[] regValues = extractValues(regFormattedData);
|
||||||
|
|
||||||
|
// Consolidate the Register information in a container class
|
||||||
|
IMemoryBlockAddressInfoItem[] regDataContainers = createRegisterDataContainers(
|
||||||
|
registers, regNames, regValues);
|
||||||
|
|
||||||
|
// Filter or arrange data as needed
|
||||||
|
regDataContainers = normalizeRegisterData(regDataContainers, memBlock);
|
||||||
|
|
||||||
|
rm.setData(regDataContainers);
|
||||||
|
rm.done();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
};
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
// no valid registers
|
||||||
|
rm.done(new Status(IStatus.ERROR, GdbPlugin.PLUGIN_ID,
|
||||||
|
"Successful request of register contexts but no registers received")); //$NON-NLS-1$
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
rm.done(new Status(IStatus.INFO, GdbPlugin.PLUGIN_ID,
|
||||||
|
"Unable to resolve registers for the currently selected context")); //$NON-NLS-1$
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected IMemoryBlockAddressInfoItem[] normalizeRegisterData(IMemoryBlockAddressInfoItem[] regDataContainers, IMemoryBlock memBlock) {
|
||||||
|
// // The information provided may be applicable per memory space
|
||||||
|
// String memSpaceId = ""; //$NON-NLS-1$
|
||||||
|
// if (memBlock instanceof IMemorySpaceAwareMemoryBlock) {
|
||||||
|
// memSpaceId = ((IMemorySpaceAwareMemoryBlock) memBlock).getMemorySpaceID();
|
||||||
|
// }
|
||||||
|
|
||||||
|
List<IMemoryBlockAddressInfoItem> items = new ArrayList<IMemoryBlockAddressInfoItem>();
|
||||||
|
// Remove all items with value zero
|
||||||
|
for (IMemoryBlockAddressInfoItem item : regDataContainers) {
|
||||||
|
if (item.getAddress().intValue() != 0) {
|
||||||
|
items.add(item);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Add any other filter, value adjustments etc.
|
||||||
|
|
||||||
|
return items.toArray(new IMemoryBlockAddressInfoItem[items.size()]);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getInfoType() {
|
||||||
|
return REGISTERS_INFO_TYPE;
|
||||||
|
}
|
||||||
|
|
||||||
|
private class MemoryBlockAddressRegisterItem extends MemoryBlockAddressInfoItem {
|
||||||
|
public MemoryBlockAddressRegisterItem(String name, String value) {
|
||||||
|
super(name, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getInfoType() {
|
||||||
|
return REGISTERS_INFO_TYPE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private IMemoryBlockAddressInfoItem[] createRegisterDataContainers(IRegisterDMContext[] regContext, String[] names,
|
||||||
|
String[] values) {
|
||||||
|
// Expecting the three building arrays to be of the same length
|
||||||
|
assert (regContext.length > 0 && regContext.length == names.length && regContext.length == values.length);
|
||||||
|
IMemoryBlockAddressInfoItem[] regContainers = new IMemoryBlockAddressInfoItem[regContext.length];
|
||||||
|
for (int i = 0; i < regContext.length; i++) {
|
||||||
|
regContainers[i] = new MemoryBlockAddressRegisterItem(names[i], values[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
return regContainers;
|
||||||
|
}
|
||||||
|
|
||||||
|
private String[] extractRegNames(IRegisterDMData[] regData) {
|
||||||
|
String[] names = new String[regData.length];
|
||||||
|
for (int i = 0; i < regData.length; i++) {
|
||||||
|
names[i] = regData[i].getName();
|
||||||
|
}
|
||||||
|
return names;
|
||||||
|
}
|
||||||
|
|
||||||
|
private String[] extractValues(FormattedValueDMData[] regValues) {
|
||||||
|
String[] values = new String[regValues.length];
|
||||||
|
for (int i = 0; i < regValues.length; i++) {
|
||||||
|
values[i] = regValues[i].getEditableValue();
|
||||||
|
}
|
||||||
|
return values;
|
||||||
|
}
|
||||||
|
|
||||||
|
private <V> V resolveService(Class<V> type) {
|
||||||
|
V service = null;
|
||||||
|
if (fSession != null) {
|
||||||
|
DsfServicesTracker tracker = new DsfServicesTracker(GdbPlugin.getDefault().getBundle().getBundleContext(),
|
||||||
|
fSession.getId());
|
||||||
|
service = tracker.getService(type);
|
||||||
|
tracker.dispose();
|
||||||
|
}
|
||||||
|
return service;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void getRegistersData(final IRegisters2 service, final IRegisterDMContext[] regDMCs,
|
||||||
|
final DataRequestMonitor<IRegisterDMData[]> rm) {
|
||||||
|
final IRegisterDMData[] datas = new IRegisterDMData[regDMCs.length];
|
||||||
|
rm.setData(datas);
|
||||||
|
final CountingRequestMonitor countingRm = new CountingRequestMonitor(fSession.getExecutor(), rm);
|
||||||
|
for (int i = 0; i < regDMCs.length; i++) {
|
||||||
|
final int index = i;
|
||||||
|
service.getRegisterData(regDMCs[index],
|
||||||
|
new DataRequestMonitor<IRegisterDMData>(fSession.getExecutor(), countingRm) {
|
||||||
|
@Override
|
||||||
|
protected void handleCompleted() {
|
||||||
|
datas[index] = getData();
|
||||||
|
if (!isSuccess()) {
|
||||||
|
countingRm.setStatus(getStatus());
|
||||||
|
}
|
||||||
|
countingRm.done();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
countingRm.setDoneCount(regDMCs.length);
|
||||||
|
}
|
||||||
|
|
||||||
|
private FormattedValueDMContext[] getFormatContexts(IRegisters2 service, IRegisterDMContext[] regDMCs) {
|
||||||
|
FormattedValueDMContext[] datas = new FormattedValueDMContext[regDMCs.length];
|
||||||
|
for (int i = 0; i < regDMCs.length; i++) {
|
||||||
|
datas[i] = service.getFormattedValueContext(regDMCs[i], IFormattedValues.HEX_FORMAT);
|
||||||
|
}
|
||||||
|
|
||||||
|
return datas;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void getRegisterValues(final IRegisters2 service, final IRegisterDMContext[] regDMCs,
|
||||||
|
final DataRequestMonitor<FormattedValueDMData[]> rm) {
|
||||||
|
FormattedValueDMContext[] fmtContexts = getFormatContexts(service, regDMCs);
|
||||||
|
|
||||||
|
final FormattedValueDMData[] datas = new FormattedValueDMData[regDMCs.length];
|
||||||
|
rm.setData(datas);
|
||||||
|
final CountingRequestMonitor countingRm = new CountingRequestMonitor(fSession.getExecutor(), rm);
|
||||||
|
for (int i = 0; i < regDMCs.length; i++) {
|
||||||
|
final int index = i;
|
||||||
|
service.getFormattedExpressionValue(fmtContexts[index],
|
||||||
|
new DataRequestMonitor<FormattedValueDMData>(fSession.getExecutor(), countingRm) {
|
||||||
|
@Override
|
||||||
|
protected void handleCompleted() {
|
||||||
|
datas[index] = getData();
|
||||||
|
if (!isSuccess()) {
|
||||||
|
countingRm.setStatus(getStatus());
|
||||||
|
}
|
||||||
|
countingRm.done();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
countingRm.setDoneCount(regDMCs.length);
|
||||||
|
}
|
||||||
|
}
|
Loading…
Add table
Reference in a new issue