mirror of
https://github.com/eclipse-cdt/cdt
synced 2025-04-21 21:52:10 +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.IRunControl.IContainerDMContext;
|
||||
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.memory.IGdbMemoryAddressInfoTypeRetrieval;
|
||||
import org.eclipse.cdt.dsf.service.DsfServiceEventHandler;
|
||||
|
@ -47,7 +48,7 @@ public class GdbMemoryBlockAddressInfoRetrieval implements IMemoryBlockAddressIn
|
|||
}
|
||||
|
||||
protected IGdbMemoryAddressInfoTypeRetrieval[] resolveMemoryAddressInfoProviders() {
|
||||
return new IGdbMemoryAddressInfoTypeRetrieval[] {new GdbMemoryAddressInfoVariablesRetrieval(fSession)};
|
||||
return new IGdbMemoryAddressInfoTypeRetrieval[] {new GdbMemoryAddressInfoVariablesRetrieval(fSession), new GdbMemoryAddressInfoRegistersRetrieval(fSession)};
|
||||
}
|
||||
|
||||
@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