mirror of
https://github.com/eclipse-cdt/cdt
synced 2025-08-09 17:25:38 +02:00
[248636] Adding --thread option to the MI memory commands for GDB 7.0. This change was done in provisional classes to allow for changes, but required the use of a GDBMemory service.
This commit is contained in:
parent
6e0e76e459
commit
4edaf1587b
5 changed files with 176 additions and 7 deletions
|
@ -0,0 +1,103 @@
|
|||
package org.eclipse.dd.gdb.internal.provisional.service;
|
||||
|
||||
import java.util.Hashtable;
|
||||
|
||||
import org.eclipse.cdt.core.IAddress;
|
||||
import org.eclipse.dd.dsf.concurrent.DataRequestMonitor;
|
||||
import org.eclipse.dd.dsf.concurrent.RequestMonitor;
|
||||
import org.eclipse.dd.dsf.datamodel.DMContexts;
|
||||
import org.eclipse.dd.dsf.datamodel.IDMContext;
|
||||
import org.eclipse.dd.dsf.debug.service.IMemory;
|
||||
import org.eclipse.dd.dsf.service.DsfSession;
|
||||
import org.eclipse.dd.mi.service.IMIContainerDMContext;
|
||||
import org.eclipse.dd.mi.service.IMIExecutionDMContext;
|
||||
import org.eclipse.dd.mi.service.MIMemory;
|
||||
import org.eclipse.debug.core.model.MemoryByte;
|
||||
|
||||
public class GDBMemory_7_0 extends MIMemory {
|
||||
|
||||
public GDBMemory_7_0(DsfSession session) {
|
||||
super(session);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void initialize(final RequestMonitor requestMonitor) {
|
||||
super.initialize(
|
||||
new RequestMonitor(getExecutor(), requestMonitor) {
|
||||
@Override
|
||||
public void handleSuccess() {
|
||||
doInitialize(requestMonitor);
|
||||
}});
|
||||
}
|
||||
|
||||
private void doInitialize(final RequestMonitor requestMonitor) {
|
||||
register(new String[] { MIMemory.class.getName(), IMemory.class.getName(), GDBMemory_7_0.class.getName()},
|
||||
new Hashtable<String, String>());
|
||||
|
||||
setMemoryCache(new GDBMemoryCache());
|
||||
|
||||
requestMonitor.done();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void shutdown(final RequestMonitor requestMonitor) {
|
||||
unregister();
|
||||
super.shutdown(requestMonitor);
|
||||
}
|
||||
|
||||
protected class GDBMemoryCache extends MIMemoryCache {
|
||||
@Override
|
||||
protected void readMemoryBlock(IDMContext dmc, IAddress address, final long offset,
|
||||
final int word_size, final int count, final DataRequestMonitor<MemoryByte[]> drm)
|
||||
{
|
||||
IDMContext threadOrMemoryDmc = dmc;
|
||||
|
||||
IMIContainerDMContext containerCtx = DMContexts.getAncestorOfType(dmc, IMIContainerDMContext.class);
|
||||
if(containerCtx != null) {
|
||||
IGDBProcesses procService = getServicesTracker().getService(IGDBProcesses.class);
|
||||
|
||||
if (procService != null) {
|
||||
IMIExecutionDMContext[] execCtxs = procService.getExecutionContexts(containerCtx);
|
||||
// Return any thread... let's take the first one.
|
||||
if (execCtxs != null && execCtxs.length > 0) {
|
||||
threadOrMemoryDmc = execCtxs[0];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
super.readMemoryBlock(threadOrMemoryDmc, address, offset, word_size, count, drm);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param memoryDMC
|
||||
* @param address
|
||||
* @param offset
|
||||
* @param word_size
|
||||
* @param count
|
||||
* @param buffer
|
||||
* @param rm
|
||||
*/
|
||||
@Override
|
||||
protected void writeMemoryBlock(final IDMContext dmc, final IAddress address, final long offset,
|
||||
final int word_size, final int count, final byte[] buffer, final RequestMonitor rm)
|
||||
{
|
||||
IDMContext threadOrMemoryDmc = dmc;
|
||||
|
||||
IMIContainerDMContext containerCtx = DMContexts.getAncestorOfType(dmc, IMIContainerDMContext.class);
|
||||
if(containerCtx != null) {
|
||||
IGDBProcesses procService = getServicesTracker().getService(IGDBProcesses.class);
|
||||
|
||||
if (procService != null) {
|
||||
IMIExecutionDMContext[] execCtxs = procService.getExecutionContexts(containerCtx);
|
||||
// Return any thread... let's take the first one.
|
||||
if (execCtxs != null && execCtxs.length > 0) {
|
||||
threadOrMemoryDmc = execCtxs[0];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
super.writeMemoryBlock(threadOrMemoryDmc, address, offset, word_size, count, buffer, rm);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -10,9 +10,11 @@
|
|||
*******************************************************************************/
|
||||
package org.eclipse.dd.gdb.internal.provisional.service;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.Hashtable;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import org.eclipse.core.runtime.IStatus;
|
||||
|
@ -75,7 +77,7 @@ import org.osgi.framework.BundleContext;
|
|||
*
|
||||
*/
|
||||
public class GDBProcesses_7_0 extends AbstractDsfService
|
||||
implements IMIProcesses, ICachingService, IEventListener {
|
||||
implements IGDBProcesses, ICachingService, IEventListener {
|
||||
|
||||
// Below is the context hierarchy that is implemented between the
|
||||
// MIProcesses service and the MIRunControl service for the MI
|
||||
|
@ -393,6 +395,7 @@ public class GDBProcesses_7_0 extends AbstractDsfService
|
|||
// Register this service.
|
||||
register(new String[] { IProcesses.class.getName(),
|
||||
IMIProcesses.class.getName(),
|
||||
IGDBProcesses.class.getName(),
|
||||
GDBProcesses_7_0.class.getName() },
|
||||
new Hashtable<String, String>());
|
||||
|
||||
|
@ -448,6 +451,24 @@ public class GDBProcesses_7_0 extends AbstractDsfService
|
|||
return createContainerContext(processDmc, groupId);
|
||||
}
|
||||
|
||||
public IMIExecutionDMContext[] getExecutionContexts(IMIContainerDMContext containerDmc) {
|
||||
String groupId = containerDmc.getGroupId();
|
||||
List<IMIExecutionDMContext> execDmcList = new ArrayList<IMIExecutionDMContext>();
|
||||
Iterator<Map.Entry<String, String>> iterator = fThreadToGroupMap.entrySet().iterator();
|
||||
while (iterator.hasNext()){
|
||||
Map.Entry<String, String> entry = iterator.next();
|
||||
if (entry.getValue().equals(groupId)) {
|
||||
String threadId = entry.getKey();
|
||||
IProcessDMContext procDmc = DMContexts.getAncestorOfType(containerDmc, IProcessDMContext.class);
|
||||
IMIExecutionDMContext execDmc = createExecutionContext(containerDmc,
|
||||
createThreadContext(procDmc, threadId),
|
||||
threadId);
|
||||
execDmcList.add(execDmc);
|
||||
}
|
||||
}
|
||||
return execDmcList.toArray(new IMIExecutionDMContext[0]);
|
||||
}
|
||||
|
||||
/**
|
||||
* This method obtains the model data for a given IThreadDMContext object
|
||||
* which can represent a thread or a process.
|
||||
|
|
|
@ -92,6 +92,10 @@ public class GdbDebugServicesFactory extends AbstractDsfDebugServicesFactory {
|
|||
|
||||
@Override
|
||||
protected IMemory createMemoryService(DsfSession session) {
|
||||
if ("6.8".compareTo(fVersion) < 0) { //$NON-NLS-1$
|
||||
return new GDBMemory_7_0(session);
|
||||
}
|
||||
|
||||
return new MIMemory(session);
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,27 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (c) 2008 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.dd.gdb.internal.provisional.service;
|
||||
|
||||
import org.eclipse.dd.mi.service.IMIContainerDMContext;
|
||||
import org.eclipse.dd.mi.service.IMIExecutionDMContext;
|
||||
import org.eclipse.dd.mi.service.IMIProcesses;
|
||||
|
||||
public interface IGDBProcesses extends IMIProcesses {
|
||||
/**
|
||||
* Get a list of all execution contexts belonging to a container. This call is synchronous,
|
||||
* unlike the call to getProcessesBeingDebugged(). However, some services may not be able
|
||||
* to fulfill this request synchronously and will have to rely on getProcessesBeingDebugged().
|
||||
*
|
||||
* @param containerDmc The container for which we want to get the execution contexts
|
||||
*/
|
||||
IMIExecutionDMContext[] getExecutionContexts(IMIContainerDMContext containerDmc);
|
||||
|
||||
}
|
|
@ -116,7 +116,7 @@ public class MIMemory extends AbstractDsfService implements IMemory, ICachingSer
|
|||
register(new String[] { MIMemory.class.getName(), IMemory.class.getName() }, new Hashtable<String, String>());
|
||||
|
||||
// Create the memory requests cache
|
||||
fMemoryCache = new MIMemoryCache();
|
||||
setMemoryCache(new MIMemoryCache());
|
||||
|
||||
// Register as service event listener
|
||||
getSession().addServiceEventListener(this, null);
|
||||
|
@ -149,6 +149,15 @@ public class MIMemory extends AbstractDsfService implements IMemory, ICachingSer
|
|||
return MIPlugin.getBundleContext();
|
||||
}
|
||||
|
||||
/**
|
||||
* This method resets the memory cache. It allows an overriding class to provide
|
||||
* its own overridden memory cache class.
|
||||
*
|
||||
* @since 1.1
|
||||
*/
|
||||
protected void setMemoryCache(MIMemoryCache cache) { fMemoryCache = cache; }
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// IMemory
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
|
@ -440,7 +449,12 @@ public class MIMemory extends AbstractDsfService implements IMemory, ICachingSer
|
|||
// MIMemoryCache
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
|
||||
private class MIMemoryCache {
|
||||
/**
|
||||
* This class can now be overridden.
|
||||
*
|
||||
* @since 1.1
|
||||
*/
|
||||
protected class MIMemoryCache {
|
||||
|
||||
// Back-end commands cache
|
||||
private CommandCache fCommandCache;
|
||||
|
@ -848,7 +862,7 @@ public class MIMemory extends AbstractDsfService implements IMemory, ICachingSer
|
|||
* @param count
|
||||
* @param drm
|
||||
*/
|
||||
private void readMemoryBlock(IMemoryDMContext memoryDMC, IAddress address, final long offset,
|
||||
protected void readMemoryBlock(IDMContext dmc, IAddress address, final long offset,
|
||||
final int word_size, final int count, final DataRequestMonitor<MemoryByte[]> drm)
|
||||
{
|
||||
/* To simplify the parsing of the MI result, we request the output to
|
||||
|
@ -860,7 +874,7 @@ public class MIMemory extends AbstractDsfService implements IMemory, ICachingSer
|
|||
Character asChar = null;
|
||||
|
||||
fCommandCache.execute(
|
||||
new MIDataReadMemory(memoryDMC, offset, address.toString(), mode, word_size, nb_rows, nb_cols, asChar),
|
||||
new MIDataReadMemory(dmc, offset, address.toString(), mode, word_size, nb_rows, nb_cols, asChar),
|
||||
new DataRequestMonitor<MIDataReadMemoryInfo>(getExecutor(), drm) {
|
||||
@Override
|
||||
protected void handleSuccess() {
|
||||
|
@ -890,7 +904,7 @@ public class MIMemory extends AbstractDsfService implements IMemory, ICachingSer
|
|||
* @param buffer
|
||||
* @param rm
|
||||
*/
|
||||
private void writeMemoryBlock(final IMemoryDMContext memoryDMC, final IAddress address, final long offset,
|
||||
protected void writeMemoryBlock(final IDMContext dmc, final IAddress address, final long offset,
|
||||
final int word_size, final int count, final byte[] buffer, final RequestMonitor rm)
|
||||
{
|
||||
// Each byte is written individually (GDB power...)
|
||||
|
@ -906,7 +920,7 @@ public class MIMemory extends AbstractDsfService implements IMemory, ICachingSer
|
|||
for (int i = 0; i < count; i++) {
|
||||
String value = new Byte(buffer[i]).toString();
|
||||
fCommandCache.execute(
|
||||
new MIDataWriteMemory(memoryDMC, offset + i, baseAddress, format, word_size, value),
|
||||
new MIDataWriteMemory(dmc, offset + i, baseAddress, format, word_size, value),
|
||||
new DataRequestMonitor<MIDataWriteMemoryInfo>(getExecutor(), countingRM)
|
||||
);
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue