1
0
Fork 0
mirror of https://github.com/eclipse-cdt/cdt synced 2025-07-23 08:55:25 +02:00

Bug 237798

Added a ServiceFactory to allow for different implementation of the same services, depending on the backend .
This commit is contained in:
Marc Khouzam 2008-06-24 18:41:39 +00:00
parent 0bc7b6f932
commit 6fc511904f
8 changed files with 269 additions and 35 deletions

View file

@ -0,0 +1,52 @@
/*******************************************************************************
* 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.dsf.debug.service;
import org.eclipse.dd.dsf.service.DsfSession;
public abstract class AbstractDsfDebugServicesFactory implements IDsfDebugServicesFactory {
@SuppressWarnings("unchecked")
public <V> V createService(DsfSession session, Class<V> clazz) {
if (IDisassembly.class.isAssignableFrom(clazz)) {
return (V)createDisassemblyService(session);
} else if (IRegisters.class.isAssignableFrom(clazz)) {
return (V)createRegistersService(session);
} else if (IBreakpoints.class.isAssignableFrom(clazz)) {
return (V)createBreakpointService(session);
} else if (ISourceLookup.class.isAssignableFrom(clazz)) {
return (V)createSourceLookupService(session);
} else if (IExpressions.class.isAssignableFrom(clazz)) {
return (V)createExpressionService(session);
} else if (IStack.class.isAssignableFrom(clazz)) {
return (V)createStackService(session);
} else if (IModules.class.isAssignableFrom(clazz)) {
return (V)createModulesService(session);
} else if (IMemory.class.isAssignableFrom(clazz)) {
return (V)createMemoryService(session);
} else if (IRunControl.class.isAssignableFrom(clazz)) {
return (V)createRunControlService(session);
}
return null;
}
protected abstract IDisassembly createDisassemblyService(DsfSession session);
protected abstract IRegisters createRegistersService(DsfSession session);
protected abstract IBreakpoints createBreakpointService(DsfSession session);
protected abstract ISourceLookup createSourceLookupService(DsfSession session);
protected abstract IExpressions createExpressionService(DsfSession session);
protected abstract IStack createStackService(DsfSession session);
protected abstract IModules createModulesService(DsfSession session);
protected abstract IMemory createMemoryService(DsfSession session);
protected abstract IRunControl createRunControlService(DsfSession session);
}

View file

@ -0,0 +1,21 @@
/*******************************************************************************
* 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.dsf.debug.service;
import org.eclipse.dd.dsf.service.DsfSession;
/*
* A factory to create DSF services. Using this interface allows
* to easily have different service implementation for different backends.
*/
public interface IDsfDebugServicesFactory {
public <V> V createService(DsfSession session, Class<V> clazz);
}

View file

@ -30,6 +30,7 @@ import org.eclipse.dd.dsf.concurrent.Sequence;
import org.eclipse.dd.dsf.concurrent.ThreadSafe;
import org.eclipse.dd.dsf.concurrent.ThreadSafeAndProhibitedFromDsfExecutor;
import org.eclipse.dd.dsf.debug.model.DsfMemoryBlockRetrieval;
import org.eclipse.dd.dsf.debug.service.IDsfDebugServicesFactory;
import org.eclipse.dd.dsf.debug.service.IMemory.IMemoryDMContext;
import org.eclipse.dd.dsf.service.DsfServiceEventHandler;
import org.eclipse.dd.dsf.service.DsfServicesTracker;
@ -60,6 +61,7 @@ public class GdbLaunch extends Launch
private boolean fShutDown = false;
private DsfMemoryBlockRetrieval fMemRetrieval;
private IDsfDebugServicesFactory fServiceFactory;
public GdbLaunch(ILaunchConfiguration launchConfiguration, String mode, ISourceLocator locator) {
super(launchConfiguration, mode, locator);
@ -73,6 +75,7 @@ public class GdbLaunch extends Launch
}
public DsfExecutor getDsfExecutor() { return fExecutor; }
public IDsfDebugServicesFactory getServiceFactory() { return fServiceFactory; }
public void initialize()
{
@ -174,6 +177,10 @@ public class GdbLaunch extends Launch
}
}
public void setServiceFactory(IDsfDebugServicesFactory factory) {
fServiceFactory = factory;
}
///////////////////////////////////////////////////////////////////////////
// IServiceEventListener
@DsfServiceEventHandler public void eventDispatched(GDBControl.GDBExitedEvent event) {

View file

@ -31,10 +31,12 @@ import org.eclipse.core.runtime.Status;
import org.eclipse.dd.dsf.concurrent.DsfExecutor;
import org.eclipse.dd.dsf.concurrent.Sequence;
import org.eclipse.dd.dsf.concurrent.ThreadSafe;
import org.eclipse.dd.dsf.debug.service.IDsfDebugServicesFactory;
import org.eclipse.dd.dsf.debug.sourcelookup.DsfSourceLookupDirector;
import org.eclipse.dd.dsf.service.DsfSession;
import org.eclipse.dd.gdb.internal.GdbPlugin;
import org.eclipse.dd.gdb.internal.provisional.IGDBLaunchConfigurationConstants;
import org.eclipse.dd.gdb.internal.provisional.service.GdbDebugServicesFactory;
import org.eclipse.dd.gdb.internal.provisional.service.command.GDBControl.SessionType;
import org.eclipse.debug.core.DebugException;
import org.eclipse.debug.core.ILaunch;
@ -102,6 +104,8 @@ public class GdbLaunchDelegate extends LaunchConfigurationDelegate
monitor.worked( 1 );
launch.setServiceFactory(newServiceFactory(LaunchUtils.getGDBVersion(config)));
// Create and invoke the launch sequence to create the debug control and services
final ServicesLaunchSequence servicesLaunchSequence =
new ServicesLaunchSequence(launch.getSession(), launch, exePath, sessionType, attach);
@ -308,5 +312,14 @@ public class GdbLaunchDelegate extends LaunchConfigurationDelegate
}
return false;
}
private IDsfDebugServicesFactory newServiceFactory(String version) {
if (version.startsWith("6.6") || //$NON-NLS-1$
version.startsWith("6.7") || //$NON-NLS-1$
version.startsWith("6.8")) { //$NON-NLS-1$
return new GdbDebugServicesFactory(version);
}
return new GdbDebugServicesFactory(version);
}
}

View file

@ -10,8 +10,14 @@
*******************************************************************************/
package org.eclipse.dd.gdb.internal.provisional.launching;
import java.io.BufferedReader;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.Reader;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import org.eclipse.cdt.core.CCorePlugin;
import org.eclipse.cdt.core.IBinaryParser;
@ -19,6 +25,7 @@ import org.eclipse.cdt.core.ICExtensionReference;
import org.eclipse.cdt.core.IBinaryParser.IBinaryObject;
import org.eclipse.cdt.core.model.ICProject;
import org.eclipse.cdt.debug.core.ICDTLaunchConfigurationConstants;
import org.eclipse.cdt.utils.spawner.ProcessFactory;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.ResourcesPlugin;
@ -29,6 +36,8 @@ import org.eclipse.core.runtime.MultiStatus;
import org.eclipse.core.runtime.Path;
import org.eclipse.core.runtime.Status;
import org.eclipse.dd.gdb.internal.GdbPlugin;
import org.eclipse.dd.gdb.internal.provisional.IGDBLaunchConfigurationConstants;
import org.eclipse.debug.core.DebugException;
import org.eclipse.debug.core.ILaunchConfiguration;
public class LaunchUtils {
@ -177,5 +186,46 @@ public class LaunchUtils {
private static String getProjectName(ILaunchConfiguration configuration) throws CoreException {
return configuration.getAttribute(ICDTLaunchConfigurationConstants.ATTR_PROJECT_NAME, (String)null);
}
public static IPath getGDBPath(ILaunchConfiguration configuration) {
IPath retVal = new Path(IGDBLaunchConfigurationConstants.DEBUGGER_DEBUG_NAME_DEFAULT);
try {
retVal = new Path(configuration.getAttribute(IGDBLaunchConfigurationConstants.ATTR_DEBUG_NAME,
IGDBLaunchConfigurationConstants.DEBUGGER_DEBUG_NAME_DEFAULT));
} catch (CoreException e) {
}
return retVal;
}
public static String getGDBVersion(final ILaunchConfiguration configuration) throws CoreException {
String line, version = "";//$NON-NLS-1$
Process process = null;
String cmd = getGDBPath(configuration).toOSString() + " --version"; //$NON-NLS-1$
try {
process = ProcessFactory.getFactory().exec(cmd);
} catch(IOException e) {
throw new DebugException(new Status(IStatus.ERROR, GdbPlugin.PLUGIN_ID, DebugException.REQUEST_FAILED,
"Error while launching command: " + cmd, e.getCause()));//$NON-NLS-1$
}
try {
InputStream stream = process.getInputStream();
Reader r = new InputStreamReader(stream);
BufferedReader reader = new BufferedReader(r);
Pattern pattern = Pattern.compile(" gdb (\\d*(\\.\\d*)*)", Pattern.MULTILINE); //$NON-NLS-1$
while ((line = reader.readLine()) != null) {
Matcher matcher = pattern.matcher(line);
if (matcher.find()) {
version = matcher.group(1);
}
}
} catch (IOException e) {
throw new DebugException(new Status(IStatus.ERROR, GdbPlugin.PLUGIN_ID, DebugException.REQUEST_FAILED,
"Error reading GDB STDOUT after sending: " + cmd, e.getCause()));//$NON-NLS-1$
}
return version;
}
}

View file

@ -10,28 +10,25 @@
*******************************************************************************/
package org.eclipse.dd.gdb.internal.provisional.launching;
import org.eclipse.cdt.debug.core.CDebugCorePlugin;
import org.eclipse.cdt.debug.internal.core.sourcelookup.CSourceLookupDirector;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.Path;
import org.eclipse.dd.dsf.concurrent.RequestMonitor;
import org.eclipse.dd.dsf.concurrent.Sequence;
import org.eclipse.dd.dsf.debug.service.IBreakpoints;
import org.eclipse.dd.dsf.debug.service.IDisassembly;
import org.eclipse.dd.dsf.debug.service.IExpressions;
import org.eclipse.dd.dsf.debug.service.IMemory;
import org.eclipse.dd.dsf.debug.service.IModules;
import org.eclipse.dd.dsf.debug.service.IRegisters;
import org.eclipse.dd.dsf.debug.service.IRunControl;
import org.eclipse.dd.dsf.debug.service.ISourceLookup;
import org.eclipse.dd.dsf.debug.service.IStack;
import org.eclipse.dd.dsf.debug.service.StepQueueManager;
import org.eclipse.dd.dsf.service.DsfSession;
import org.eclipse.dd.gdb.internal.provisional.IGDBLaunchConfigurationConstants;
import org.eclipse.dd.gdb.internal.provisional.service.GDBRunControl;
import org.eclipse.dd.gdb.internal.provisional.service.command.GDBControl;
import org.eclipse.dd.gdb.internal.provisional.service.command.GDBControl.SessionType;
import org.eclipse.dd.mi.service.CSourceLookup;
import org.eclipse.dd.mi.service.ExpressionService;
import org.eclipse.dd.mi.service.MIBreakpoints;
import org.eclipse.dd.mi.service.MIBreakpointsManager;
import org.eclipse.dd.mi.service.MIDisassembly;
import org.eclipse.dd.mi.service.MIMemory;
import org.eclipse.dd.mi.service.MIModules;
import org.eclipse.dd.mi.service.MIRegisters;
import org.eclipse.dd.mi.service.MIStack;
public class ServicesLaunchSequence extends Sequence {
@ -43,13 +40,14 @@ public class ServicesLaunchSequence extends Sequence {
//
// Create the connection.
//
fCommandControl = new GDBControl(fSession, getGDBPath(), fExecPath, fSessionType, fAttach, 30);
fCommandControl = new GDBControl(fSession, LaunchUtils.getGDBPath(fLaunch.getLaunchConfiguration()),
fExecPath, fSessionType, fAttach, 30);
fCommandControl.initialize(requestMonitor);
}
},
new Step() { @Override
public void execute(RequestMonitor requestMonitor) {
new GDBRunControl(fSession).initialize(requestMonitor);
fLaunch.getServiceFactory().createService(fSession, IRunControl.class).initialize(requestMonitor);
}},
new Step() { @Override
public void execute(RequestMonitor requestMonitor) {
@ -57,23 +55,23 @@ public class ServicesLaunchSequence extends Sequence {
}},
new Step() { @Override
public void execute(RequestMonitor requestMonitor) {
new MIMemory(fSession).initialize(requestMonitor);
fLaunch.getServiceFactory().createService(fSession, IMemory.class).initialize(requestMonitor);
}},
new Step() { @Override
public void execute(RequestMonitor requestMonitor) {
new MIModules(fSession).initialize(requestMonitor);
fLaunch.getServiceFactory().createService(fSession, IModules.class).initialize(requestMonitor);
}},
new Step() { @Override
public void execute(RequestMonitor requestMonitor) {
new MIStack(fSession).initialize(requestMonitor);
fLaunch.getServiceFactory().createService(fSession, IStack.class).initialize(requestMonitor);
}},
new Step() { @Override
public void execute(RequestMonitor requestMonitor) {
new ExpressionService(fSession).initialize(requestMonitor);
fLaunch.getServiceFactory().createService(fSession, IExpressions.class).initialize(requestMonitor);
}},
new Step() { @Override
public void execute(RequestMonitor requestMonitor) {
fSourceLookup = new CSourceLookup(fSession);
fSourceLookup = (CSourceLookup)fLaunch.getServiceFactory().createService(fSession, ISourceLookup.class);
fSourceLookup.initialize(requestMonitor);
}},
new Step() { @Override
@ -84,23 +82,21 @@ public class ServicesLaunchSequence extends Sequence {
new Step() { @Override
public void execute(final RequestMonitor requestMonitor) {
// Create the low-level breakpoint service
final MIBreakpoints bpService = new MIBreakpoints(fSession);
bpService.initialize(new RequestMonitor(getExecutor(), requestMonitor));
fLaunch.getServiceFactory().createService(fSession, IBreakpoints.class).initialize(new RequestMonitor(getExecutor(), requestMonitor));
}},
new Step() { @Override
public void execute(final RequestMonitor requestMonitor) {
// Create high-level breakpoint service and install breakpoints
// for the GDB debug context.
fBpmService = new MIBreakpointsManager(fSession, CDebugCorePlugin.PLUGIN_ID);
fBpmService.initialize(new RequestMonitor(getExecutor(), requestMonitor));
fLaunch.getServiceFactory().createService(fSession, MIBreakpointsManager.class).initialize(new RequestMonitor(getExecutor(), requestMonitor));
}},
new Step() { @Override
public void execute(RequestMonitor requestMonitor) {
new MIRegisters(fSession).initialize(requestMonitor);
fLaunch.getServiceFactory().createService(fSession, IRegisters.class).initialize(requestMonitor);
}},
new Step() { @Override
public void execute(RequestMonitor requestMonitor) {
new MIDisassembly(fSession).initialize(requestMonitor);
fLaunch.getServiceFactory().createService(fSession, IDisassembly.class).initialize(requestMonitor);
}},
};
@ -113,7 +109,6 @@ public class ServicesLaunchSequence extends Sequence {
GDBControl fCommandControl;
CSourceLookup fSourceLookup;
MIBreakpointsManager fBpmService;
public ServicesLaunchSequence(DsfSession session, GdbLaunch launch, IPath execPath, SessionType sessionType, boolean attach) {
super(session.getExecutor());
@ -129,14 +124,6 @@ public class ServicesLaunchSequence extends Sequence {
return fSteps;
}
private IPath getGDBPath() {
IPath retVal = new Path(IGDBLaunchConfigurationConstants.DEBUGGER_DEBUG_NAME_DEFAULT);
try {
retVal = new Path(fLaunch.getLaunchConfiguration().getAttribute(IGDBLaunchConfigurationConstants.ATTR_DEBUG_NAME,
IGDBLaunchConfigurationConstants.DEBUGGER_DEBUG_NAME_DEFAULT));
} catch (CoreException e) {
}
return retVal;
}
}

View file

@ -0,0 +1,100 @@
/*******************************************************************************
* 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.cdt.debug.core.CDebugCorePlugin;
import org.eclipse.dd.dsf.debug.service.AbstractDsfDebugServicesFactory;
import org.eclipse.dd.dsf.debug.service.IBreakpoints;
import org.eclipse.dd.dsf.debug.service.IDisassembly;
import org.eclipse.dd.dsf.debug.service.IExpressions;
import org.eclipse.dd.dsf.debug.service.IMemory;
import org.eclipse.dd.dsf.debug.service.IModules;
import org.eclipse.dd.dsf.debug.service.IRegisters;
import org.eclipse.dd.dsf.debug.service.IRunControl;
import org.eclipse.dd.dsf.debug.service.ISourceLookup;
import org.eclipse.dd.dsf.debug.service.IStack;
import org.eclipse.dd.dsf.service.DsfSession;
import org.eclipse.dd.mi.service.CSourceLookup;
import org.eclipse.dd.mi.service.ExpressionService;
import org.eclipse.dd.mi.service.MIBreakpoints;
import org.eclipse.dd.mi.service.MIBreakpointsManager;
import org.eclipse.dd.mi.service.MIDisassembly;
import org.eclipse.dd.mi.service.MIMemory;
import org.eclipse.dd.mi.service.MIModules;
import org.eclipse.dd.mi.service.MIRegisters;
import org.eclipse.dd.mi.service.MIStack;
public class GdbDebugServicesFactory extends AbstractDsfDebugServicesFactory {
public GdbDebugServicesFactory(String version) {
}
@Override
@SuppressWarnings("unchecked")
public <V> V createService(DsfSession session, Class<V> clazz) {
if (MIBreakpointsManager.class.isAssignableFrom(clazz)) {
return (V)createBreakpointManagerService(session);
}
return super.createService(session, clazz);
}
@Override
protected IDisassembly createDisassemblyService(DsfSession session) {
return new MIDisassembly(session);
}
@Override
protected IRegisters createRegistersService(DsfSession session) {
return new MIRegisters(session);
}
@Override
protected IBreakpoints createBreakpointService(DsfSession session) {
return new MIBreakpoints(session);
}
@Override
protected ISourceLookup createSourceLookupService(DsfSession session) {
return new CSourceLookup(session);
}
@Override
protected IExpressions createExpressionService(DsfSession session) {
return new ExpressionService(session);
}
@Override
protected IStack createStackService(DsfSession session) {
return new MIStack(session);
}
@Override
protected IModules createModulesService(DsfSession session) {
return new MIModules(session);
}
@Override
protected IMemory createMemoryService(DsfSession session) {
return new MIMemory(session);
}
@Override
protected IRunControl createRunControlService(DsfSession session) {
return new GDBRunControl(session);
}
protected MIBreakpointsManager createBreakpointManagerService(DsfSession session) {
return new MIBreakpointsManager(session, CDebugCorePlugin.PLUGIN_ID);
}
}

View file

@ -25,7 +25,9 @@ import org.eclipse.core.runtime.Status;
import org.eclipse.dd.dsf.concurrent.ThreadSafe;
import org.eclipse.dd.gdb.internal.provisional.launching.FinalLaunchSequence;
import org.eclipse.dd.gdb.internal.provisional.launching.GdbLaunch;
import org.eclipse.dd.gdb.internal.provisional.launching.LaunchUtils;
import org.eclipse.dd.gdb.internal.provisional.launching.ServicesLaunchSequence;
import org.eclipse.dd.gdb.internal.provisional.service.GdbDebugServicesFactory;
import org.eclipse.dd.gdb.internal.provisional.service.command.GDBControl.SessionType;
import org.eclipse.debug.core.DebugException;
import org.eclipse.debug.core.ILaunch;
@ -80,6 +82,8 @@ public class TestLaunchDelegate extends LaunchConfigurationDelegate
monitor.worked( 1 );
launch.setServiceFactory(new GdbDebugServicesFactory(LaunchUtils.getGDBVersion(config)));
final ServicesLaunchSequence servicesLaunchSequence =
new ServicesLaunchSequence(launch.getSession(), launch, exePath, SessionType.LOCAL, false);
launch.getSession().getExecutor().execute(servicesLaunchSequence);