mirror of
https://github.com/eclipse-cdt/cdt
synced 2025-04-29 19:45:01 +02:00
New org.eclipse.dd.gdb.launch plugin to separate the launch logic
This commit is contained in:
parent
ca2922f0bb
commit
ec69c08687
14 changed files with 1423 additions and 0 deletions
7
plugins/org.eclipse.dd.gdb.launch/.classpath
Normal file
7
plugins/org.eclipse.dd.gdb.launch/.classpath
Normal file
|
@ -0,0 +1,7 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<classpath>
|
||||||
|
<classpathentry kind="src" path="src"/>
|
||||||
|
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/J2SE-1.5"/>
|
||||||
|
<classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/>
|
||||||
|
<classpathentry kind="output" path="bin"/>
|
||||||
|
</classpath>
|
28
plugins/org.eclipse.dd.gdb.launch/.project
Normal file
28
plugins/org.eclipse.dd.gdb.launch/.project
Normal file
|
@ -0,0 +1,28 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<projectDescription>
|
||||||
|
<name>org.eclipse.dd.gdb.launch</name>
|
||||||
|
<comment></comment>
|
||||||
|
<projects>
|
||||||
|
</projects>
|
||||||
|
<buildSpec>
|
||||||
|
<buildCommand>
|
||||||
|
<name>org.eclipse.jdt.core.javabuilder</name>
|
||||||
|
<arguments>
|
||||||
|
</arguments>
|
||||||
|
</buildCommand>
|
||||||
|
<buildCommand>
|
||||||
|
<name>org.eclipse.pde.ManifestBuilder</name>
|
||||||
|
<arguments>
|
||||||
|
</arguments>
|
||||||
|
</buildCommand>
|
||||||
|
<buildCommand>
|
||||||
|
<name>org.eclipse.pde.SchemaBuilder</name>
|
||||||
|
<arguments>
|
||||||
|
</arguments>
|
||||||
|
</buildCommand>
|
||||||
|
</buildSpec>
|
||||||
|
<natures>
|
||||||
|
<nature>org.eclipse.pde.PluginNature</nature>
|
||||||
|
<nature>org.eclipse.jdt.core.javanature</nature>
|
||||||
|
</natures>
|
||||||
|
</projectDescription>
|
|
@ -0,0 +1,7 @@
|
||||||
|
#Mon Mar 03 11:58:56 EST 2008
|
||||||
|
eclipse.preferences.version=1
|
||||||
|
org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.5
|
||||||
|
org.eclipse.jdt.core.compiler.compliance=1.5
|
||||||
|
org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
|
||||||
|
org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
|
||||||
|
org.eclipse.jdt.core.compiler.source=1.5
|
20
plugins/org.eclipse.dd.gdb.launch/META-INF/MANIFEST.MF
Normal file
20
plugins/org.eclipse.dd.gdb.launch/META-INF/MANIFEST.MF
Normal file
|
@ -0,0 +1,20 @@
|
||||||
|
Manifest-Version: 1.0
|
||||||
|
Bundle-ManifestVersion: 2
|
||||||
|
Bundle-Name: Debug Services Framework GDB Launch Plug-in
|
||||||
|
Bundle-Vendor: Eclipse.org
|
||||||
|
Bundle-SymbolicName: org.eclipse.dd.gdb.launch; singleton:=true
|
||||||
|
Bundle-Version: 1.0.0
|
||||||
|
Bundle-Activator: org.eclipse.dd.gdb.launch.internal.GdbLaunchPlugin
|
||||||
|
Require-Bundle: org.eclipse.core.runtime,
|
||||||
|
org.eclipse.dd.dsf,
|
||||||
|
org.eclipse.dd.dsf.debug,
|
||||||
|
org.eclipse.dd.mi,
|
||||||
|
org.eclipse.dd.gdb,
|
||||||
|
org.eclipse.debug.core,
|
||||||
|
org.eclipse.cdt.core,
|
||||||
|
org.eclipse.cdt.launch,
|
||||||
|
org.eclipse.cdt.debug.core,
|
||||||
|
org.eclipse.cdt.debug.mi.core
|
||||||
|
Bundle-ActivationPolicy: lazy
|
||||||
|
Bundle-RequiredExecutionEnvironment: J2SE-1.5
|
||||||
|
Export-Package: org.eclipse.dd.gdb.launch.launching
|
24
plugins/org.eclipse.dd.gdb.launch/about.html
Normal file
24
plugins/org.eclipse.dd.gdb.launch/about.html
Normal file
|
@ -0,0 +1,24 @@
|
||||||
|
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
|
||||||
|
<html xmlns="http://www.w3.org/1999/xhtml"><head>
|
||||||
|
|
||||||
|
|
||||||
|
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1"><title>About</title></head><body lang="EN-US">
|
||||||
|
<h2>About This Content</h2>
|
||||||
|
|
||||||
|
<p>June 5, 2007</p>
|
||||||
|
<h3>License</h3>
|
||||||
|
|
||||||
|
<p>The Eclipse Foundation makes available all content in this plug-in ("Content"). Unless otherwise
|
||||||
|
indicated below, the Content is provided to you under the terms and conditions of the
|
||||||
|
Eclipse Public License Version 1.0 ("EPL"). A copy of the EPL is available
|
||||||
|
at <a href="http://www.eclipse.org/legal/epl-v10.html">http://www.eclipse.org/legal/epl-v10.html</a>.
|
||||||
|
For purposes of the EPL, "Program" will mean the Content.</p>
|
||||||
|
|
||||||
|
<p>If you did not receive this Content directly from the Eclipse Foundation, the Content is
|
||||||
|
being redistributed by another party ("Redistributor") and different terms and conditions may
|
||||||
|
apply to your use of any object code in the Content. Check the Redistributor's license that was
|
||||||
|
provided with the Content. If no such license exists, contact the Redistributor. Unless otherwise
|
||||||
|
indicated below, the terms and conditions of the EPL still apply to any source code in the Content
|
||||||
|
and such source code may be obtained at <a href="http://www.eclipse.org/">http://www.eclipse.org</a>.</p>
|
||||||
|
|
||||||
|
</body></html>
|
7
plugins/org.eclipse.dd.gdb.launch/build.properties
Normal file
7
plugins/org.eclipse.dd.gdb.launch/build.properties
Normal file
|
@ -0,0 +1,7 @@
|
||||||
|
source.. = src/
|
||||||
|
output.. = bin/
|
||||||
|
bin.includes = plugin.xml,\
|
||||||
|
META-INF/,\
|
||||||
|
.,\
|
||||||
|
icons/,\
|
||||||
|
about.html
|
24
plugins/org.eclipse.dd.gdb.launch/plugin.xml
Normal file
24
plugins/org.eclipse.dd.gdb.launch/plugin.xml
Normal file
|
@ -0,0 +1,24 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<?eclipse version="3.2"?>
|
||||||
|
<plugin>
|
||||||
|
<extension point="org.eclipse.debug.core.launchConfigurationTypes">
|
||||||
|
<launchConfigurationType
|
||||||
|
sourceLocatorId="org.eclipse.cdt.debug.core.sourceLocator"
|
||||||
|
delegate="org.eclipse.dd.gdb.launch.launching.GdbLocalLaunchDelegate"
|
||||||
|
public="true"
|
||||||
|
sourcePathComputerId="org.eclipse.cdt.debug.core.sourcePathComputer"
|
||||||
|
name="Local C/C++ Application (Experimental - DSF)"
|
||||||
|
id="org.eclipse.dd.gdb.launch.localCLaunch"
|
||||||
|
modes="debug">
|
||||||
|
</launchConfigurationType>
|
||||||
|
<launchConfigurationType
|
||||||
|
delegate="org.eclipse.dd.gdb.launch.launching.GdbLocalLaunchDelegate"
|
||||||
|
id="org.eclipse.dd.gdb.launch.remoteCLaunch"
|
||||||
|
modes="debug"
|
||||||
|
name="Remote C/C++ Application (Experimental - DSF)"
|
||||||
|
public="true"
|
||||||
|
sourceLocatorId="org.eclipse.cdt.debug.core.sourceLocator"
|
||||||
|
sourcePathComputerId="org.eclipse.cdt.debug.core.sourcePathComputer">
|
||||||
|
</launchConfigurationType>
|
||||||
|
</extension>
|
||||||
|
</plugin>
|
|
@ -0,0 +1,120 @@
|
||||||
|
/*******************************************************************************
|
||||||
|
* 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.launch.internal;
|
||||||
|
|
||||||
|
import java.util.concurrent.ExecutionException;
|
||||||
|
import java.util.concurrent.RejectedExecutionException;
|
||||||
|
|
||||||
|
import org.eclipse.core.runtime.IStatus;
|
||||||
|
import org.eclipse.core.runtime.Plugin;
|
||||||
|
import org.eclipse.core.runtime.Status;
|
||||||
|
import org.eclipse.dd.dsf.concurrent.DataRequestMonitor;
|
||||||
|
import org.eclipse.dd.dsf.concurrent.Query;
|
||||||
|
import org.eclipse.dd.gdb.launch.launching.GdbLaunch;
|
||||||
|
import org.eclipse.debug.core.DebugPlugin;
|
||||||
|
import org.eclipse.debug.core.ILaunch;
|
||||||
|
import org.osgi.framework.BundleContext;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The activator class controls the plug-in life cycle
|
||||||
|
*/
|
||||||
|
public class GdbLaunchPlugin extends Plugin {
|
||||||
|
|
||||||
|
// The plug-in ID
|
||||||
|
public static final String PLUGIN_ID = "org.eclipse.dd.gdb"; //$NON-NLS-1$
|
||||||
|
|
||||||
|
// The shared instance
|
||||||
|
private static GdbLaunchPlugin plugin;
|
||||||
|
|
||||||
|
private static BundleContext fgBundleContext;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The constructor
|
||||||
|
*/
|
||||||
|
public GdbLaunchPlugin() {
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* (non-Javadoc)
|
||||||
|
* @see org.eclipse.core.runtime.Plugins#start(org.osgi.framework.BundleContext)
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public void start(BundleContext context) throws Exception {
|
||||||
|
fgBundleContext = context;
|
||||||
|
super.start(context);
|
||||||
|
plugin = this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* (non-Javadoc)
|
||||||
|
* @see org.eclipse.core.runtime.Plugin#stop(org.osgi.framework.BundleContext)
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public void stop(BundleContext context) throws Exception {
|
||||||
|
shutdownActiveLaunches();
|
||||||
|
plugin = null;
|
||||||
|
super.stop(context);
|
||||||
|
fgBundleContext = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the shared instance
|
||||||
|
*
|
||||||
|
* @return the shared instance
|
||||||
|
*/
|
||||||
|
public static GdbLaunchPlugin getDefault() {
|
||||||
|
return plugin;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static BundleContext getBundleContext() {
|
||||||
|
return fgBundleContext;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Shuts down any active launches. We must shutdown any active sessions
|
||||||
|
* and services associated with this plugin before this plugin is stopped.
|
||||||
|
* Any attempts to use the plugins {@link BundleContext} after the plugin
|
||||||
|
* is shut down will result in exceptions.
|
||||||
|
*/
|
||||||
|
private void shutdownActiveLaunches() {
|
||||||
|
for (ILaunch launch : DebugPlugin.getDefault().getLaunchManager().getLaunches()) {
|
||||||
|
if (launch instanceof GdbLaunch && ((GdbLaunch)launch).getSession().isActive()) {
|
||||||
|
final GdbLaunch gdbLaunch = (GdbLaunch)launch;
|
||||||
|
|
||||||
|
Query<Object> launchShutdownQuery = new Query<Object>() {
|
||||||
|
@Override
|
||||||
|
protected void execute(DataRequestMonitor<Object> rm) {
|
||||||
|
gdbLaunch.shutdownSession(rm);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
try {
|
||||||
|
gdbLaunch.getSession().getExecutor().execute(launchShutdownQuery);
|
||||||
|
} catch (RejectedExecutionException e) {
|
||||||
|
// We can get this exception if the session is shutdown concurrently
|
||||||
|
// to this method running.
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
// The Query.get() method is a synchronous call which blocks until the
|
||||||
|
// query completes.
|
||||||
|
try {
|
||||||
|
launchShutdownQuery.get();
|
||||||
|
} catch (InterruptedException e) {
|
||||||
|
getLog().log(new Status(IStatus.ERROR, PLUGIN_ID, "InterruptedException while shutting down PDA debugger launch " + gdbLaunch, e.getCause())); //$NON-NLS-1$
|
||||||
|
} catch (ExecutionException e) {
|
||||||
|
getLog().log(new Status(IStatus.ERROR, PLUGIN_ID, "Exception while shutting down PDA debugger launch " + gdbLaunch, e.getCause())); //$NON-NLS-1$
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,175 @@
|
||||||
|
/*******************************************************************************
|
||||||
|
* Copyright (c) 2006 Wind River Systems 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:
|
||||||
|
* Wind River Systems - initial API and implementation
|
||||||
|
*******************************************************************************/
|
||||||
|
package org.eclipse.dd.gdb.launch.launching;
|
||||||
|
|
||||||
|
import java.util.concurrent.ExecutionException;
|
||||||
|
|
||||||
|
import org.eclipse.core.runtime.CoreException;
|
||||||
|
import org.eclipse.core.runtime.IStatus;
|
||||||
|
import org.eclipse.core.runtime.MultiStatus;
|
||||||
|
import org.eclipse.core.runtime.Platform;
|
||||||
|
import org.eclipse.core.runtime.Status;
|
||||||
|
import org.eclipse.dd.dsf.concurrent.ConfinedToDsfExecutor;
|
||||||
|
import org.eclipse.dd.dsf.concurrent.DefaultDsfExecutor;
|
||||||
|
import org.eclipse.dd.dsf.concurrent.DsfExecutor;
|
||||||
|
import org.eclipse.dd.dsf.concurrent.DsfRunnable;
|
||||||
|
import org.eclipse.dd.dsf.concurrent.ImmediateExecutor;
|
||||||
|
import org.eclipse.dd.dsf.concurrent.RequestMonitor;
|
||||||
|
import org.eclipse.dd.dsf.concurrent.Sequence;
|
||||||
|
import org.eclipse.dd.dsf.concurrent.ThreadSafe;
|
||||||
|
import org.eclipse.dd.dsf.service.DsfServiceEventHandler;
|
||||||
|
import org.eclipse.dd.dsf.service.DsfServicesTracker;
|
||||||
|
import org.eclipse.dd.dsf.service.DsfSession;
|
||||||
|
import org.eclipse.dd.dsf.service.IDsfService;
|
||||||
|
import org.eclipse.dd.gdb.launch.internal.GdbLaunchPlugin;
|
||||||
|
import org.eclipse.dd.gdb.service.command.GDBControl;
|
||||||
|
import org.eclipse.debug.core.DebugException;
|
||||||
|
import org.eclipse.debug.core.ILaunchConfiguration;
|
||||||
|
import org.eclipse.debug.core.Launch;
|
||||||
|
import org.eclipse.debug.core.model.ISourceLocator;
|
||||||
|
import org.eclipse.debug.core.model.ITerminate;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The only object in the model that implements the traditional interfaces.
|
||||||
|
*/
|
||||||
|
@ThreadSafe
|
||||||
|
public class GdbLaunch extends Launch
|
||||||
|
implements ITerminate
|
||||||
|
{
|
||||||
|
private DefaultDsfExecutor fExecutor;
|
||||||
|
private DsfSession fSession;
|
||||||
|
private DsfServicesTracker fTracker;
|
||||||
|
private boolean fInitialized = false;
|
||||||
|
private boolean fShutDown = false;
|
||||||
|
|
||||||
|
|
||||||
|
public GdbLaunch(ILaunchConfiguration launchConfiguration, String mode, ISourceLocator locator) {
|
||||||
|
super(launchConfiguration, mode, locator);
|
||||||
|
|
||||||
|
// Create the dispatch queue to be used by debugger control and services
|
||||||
|
// that belong to this launch
|
||||||
|
final DefaultDsfExecutor dsfExecutor = new DefaultDsfExecutor(GdbLocalLaunchDelegate.GDB_DEBUG_MODEL_ID);
|
||||||
|
dsfExecutor.prestartCoreThread();
|
||||||
|
fExecutor = dsfExecutor;
|
||||||
|
fSession = DsfSession.startSession(fExecutor, GdbLocalLaunchDelegate.GDB_DEBUG_MODEL_ID);
|
||||||
|
}
|
||||||
|
|
||||||
|
public DsfExecutor getDsfExecutor() { return fExecutor; }
|
||||||
|
|
||||||
|
@ConfinedToDsfExecutor("getExecutor")
|
||||||
|
public void initializeControl()
|
||||||
|
throws CoreException
|
||||||
|
{
|
||||||
|
|
||||||
|
Runnable initRunnable = new DsfRunnable() {
|
||||||
|
public void run() {
|
||||||
|
fTracker = new DsfServicesTracker(GdbLaunchPlugin.getBundleContext(), fSession.getId());
|
||||||
|
fSession.addServiceEventListener(GdbLaunch.this, null);
|
||||||
|
|
||||||
|
fInitialized = true;
|
||||||
|
fireChanged();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// Invoke the execution code and block waiting for the result.
|
||||||
|
try {
|
||||||
|
fExecutor.submit(initRunnable).get();
|
||||||
|
} catch (InterruptedException e) {
|
||||||
|
new Status(IStatus.ERROR, GdbLaunchPlugin.PLUGIN_ID, IDsfService.INTERNAL_ERROR, "Error initializing launch", e); //$NON-NLS-1$
|
||||||
|
} catch (ExecutionException e) {
|
||||||
|
new Status(IStatus.ERROR, GdbLaunchPlugin.PLUGIN_ID, IDsfService.INTERNAL_ERROR, "Error initializing launch", e); //$NON-NLS-1$
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public DsfSession getSession() { return fSession; }
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////
|
||||||
|
// IServiceEventListener
|
||||||
|
@DsfServiceEventHandler public void eventDispatched(GDBControl.ExitedEvent event) {
|
||||||
|
shutdownSession(new RequestMonitor(ImmediateExecutor.getInstance(), null));
|
||||||
|
}
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////
|
||||||
|
// ITerminate
|
||||||
|
@Override
|
||||||
|
public boolean canTerminate() {
|
||||||
|
return super.canTerminate() && fInitialized && !fShutDown;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isTerminated() {
|
||||||
|
return super.isTerminated() || fShutDown;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void terminate() throws DebugException {
|
||||||
|
if (fShutDown) return;
|
||||||
|
super.terminate();
|
||||||
|
}
|
||||||
|
// ITerminate
|
||||||
|
///////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Shuts down the services, the session and the executor associated with
|
||||||
|
* this launch.
|
||||||
|
* <p>
|
||||||
|
* Note: The argument request monitor to this method should NOT use the
|
||||||
|
* executor that belongs to this launch. By the time the shutdown is
|
||||||
|
* complete, this executor will not be dispatching anymore and the
|
||||||
|
* request monitor will never be invoked. Instead callers should use
|
||||||
|
* the {@link ImmediateExecutor}.
|
||||||
|
* </p>
|
||||||
|
* @param rm The request monitor invoked when the shutdown is complete.
|
||||||
|
*/
|
||||||
|
@ConfinedToDsfExecutor("getSession().getExecutor()")
|
||||||
|
public void shutdownSession(final RequestMonitor rm) {
|
||||||
|
if (fShutDown) {
|
||||||
|
rm.done();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
fShutDown = true;
|
||||||
|
|
||||||
|
Sequence shutdownSeq = new ShutdownSequence(
|
||||||
|
getDsfExecutor(), fSession.getId(),
|
||||||
|
new RequestMonitor(fSession.getExecutor(), rm) {
|
||||||
|
@Override
|
||||||
|
public void handleCompleted() {
|
||||||
|
fSession.removeServiceEventListener(GdbLaunch.this);
|
||||||
|
if (!getStatus().isOK()) {
|
||||||
|
GdbLaunchPlugin.getDefault().getLog().log(new MultiStatus(
|
||||||
|
GdbLaunchPlugin.PLUGIN_ID, -1, new IStatus[]{getStatus()}, "Session shutdown failed", null)); //$NON-NLS-1$
|
||||||
|
}
|
||||||
|
// Last order of business, shutdown the dispatch queue.
|
||||||
|
fTracker.dispose();
|
||||||
|
fTracker = null;
|
||||||
|
DsfSession.endSession(fSession);
|
||||||
|
// endSession takes a full dispatch to distribute the
|
||||||
|
// session-ended event, finish step only after the dispatch.
|
||||||
|
fExecutor.shutdown();
|
||||||
|
fExecutor = null;
|
||||||
|
fireTerminate();
|
||||||
|
|
||||||
|
rm.setStatus(getStatus());
|
||||||
|
rm.done();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
fExecutor.execute(shutdownSeq);
|
||||||
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
@Override
|
||||||
|
public Object getAdapter(Class adapter) {
|
||||||
|
// Must force adapters to be loaded.
|
||||||
|
Platform.getAdapterManager().loadAdapter(this, adapter.getName());
|
||||||
|
return super.getAdapter(adapter);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,291 @@
|
||||||
|
/*******************************************************************************
|
||||||
|
* Copyright (c) 2004, 2006 QNX Software Systems 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:
|
||||||
|
* QNX Software Systems - Initial API and implementation
|
||||||
|
*******************************************************************************/
|
||||||
|
package org.eclipse.dd.gdb.launch.launching;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.util.concurrent.Callable;
|
||||||
|
import java.util.concurrent.ExecutionException;
|
||||||
|
import java.util.concurrent.RejectedExecutionException;
|
||||||
|
import java.util.concurrent.atomic.AtomicReference;
|
||||||
|
|
||||||
|
import org.eclipse.cdt.core.model.ICProject;
|
||||||
|
import org.eclipse.cdt.debug.core.ICDTLaunchConfigurationConstants;
|
||||||
|
import org.eclipse.cdt.launch.AbstractCLaunchDelegate;
|
||||||
|
import org.eclipse.cdt.launch.internal.ui.LaunchMessages;
|
||||||
|
import org.eclipse.cdt.launch.internal.ui.LaunchUIPlugin;
|
||||||
|
import org.eclipse.cdt.utils.pty.PTY;
|
||||||
|
import org.eclipse.cdt.utils.spawner.ProcessFactory;
|
||||||
|
import org.eclipse.core.runtime.CoreException;
|
||||||
|
import org.eclipse.core.runtime.IPath;
|
||||||
|
import org.eclipse.core.runtime.IProgressMonitor;
|
||||||
|
import org.eclipse.core.runtime.IStatus;
|
||||||
|
import org.eclipse.core.runtime.NullProgressMonitor;
|
||||||
|
import org.eclipse.core.runtime.Status;
|
||||||
|
import org.eclipse.dd.dsf.concurrent.ThreadSafe;
|
||||||
|
import org.eclipse.dd.dsf.debug.model.DsfMemoryBlockRetrieval;
|
||||||
|
import org.eclipse.dd.dsf.debug.service.IMemory.IMemoryDMContext;
|
||||||
|
import org.eclipse.dd.dsf.service.DsfServicesTracker;
|
||||||
|
import org.eclipse.dd.gdb.launch.internal.GdbLaunchPlugin;
|
||||||
|
import org.eclipse.dd.gdb.service.command.GDBControl;
|
||||||
|
import org.eclipse.dd.mi.service.command.AbstractCLIProcess;
|
||||||
|
import org.eclipse.dd.mi.service.command.MIInferiorProcess;
|
||||||
|
import org.eclipse.debug.core.DebugException;
|
||||||
|
import org.eclipse.debug.core.DebugPlugin;
|
||||||
|
import org.eclipse.debug.core.ILaunch;
|
||||||
|
import org.eclipse.debug.core.ILaunchConfiguration;
|
||||||
|
import org.eclipse.debug.core.ILaunchManager;
|
||||||
|
import org.eclipse.debug.core.IStatusHandler;
|
||||||
|
import org.eclipse.debug.core.model.ILaunchConfigurationDelegate2;
|
||||||
|
import org.eclipse.debug.core.model.IMemoryBlockRetrieval;
|
||||||
|
import org.eclipse.debug.core.model.IPersistableSourceLocator;
|
||||||
|
import org.eclipse.debug.core.model.ISourceLocator;
|
||||||
|
import org.eclipse.debug.core.sourcelookup.IPersistableSourceLocator2;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The launch configuration delegate for the CDI debugger session types.
|
||||||
|
*/
|
||||||
|
@ThreadSafe
|
||||||
|
public class GdbLocalLaunchDelegate extends AbstractCLaunchDelegate
|
||||||
|
implements ILaunchConfigurationDelegate2
|
||||||
|
{
|
||||||
|
public final static String GDB_DEBUG_MODEL_ID = "org.eclipse.dd.gdb"; //$NON-NLS-1$
|
||||||
|
|
||||||
|
/* (non-Javadoc)
|
||||||
|
* @see org.eclipse.cdt.launch.AbstractCLaunchDelegate#launch(org.eclipse.debug.core.ILaunchConfiguration, java.lang.String, org.eclipse.debug.core.ILaunch, org.eclipse.core.runtime.IProgressMonitor)
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public void launch( ILaunchConfiguration config, String mode, ILaunch launch, IProgressMonitor monitor ) throws CoreException {
|
||||||
|
if ( monitor == null ) {
|
||||||
|
monitor = new NullProgressMonitor();
|
||||||
|
}
|
||||||
|
if ( mode.equals( ILaunchManager.DEBUG_MODE ) ) {
|
||||||
|
launchDebugger( config, launch, monitor );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void launchDebugger( ILaunchConfiguration config, ILaunch launch, IProgressMonitor monitor ) throws CoreException {
|
||||||
|
monitor.beginTask("Launching debugger session", 10); //$NON-NLS-1$
|
||||||
|
if ( monitor.isCanceled() ) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
String debugMode = config.getAttribute( ICDTLaunchConfigurationConstants.ATTR_DEBUGGER_START_MODE, ICDTLaunchConfigurationConstants.DEBUGGER_MODE_RUN );
|
||||||
|
if ( debugMode.equals( ICDTLaunchConfigurationConstants.DEBUGGER_MODE_RUN ) ) {
|
||||||
|
launchLocalDebugSession( config, launch, monitor );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
finally {
|
||||||
|
monitor.done();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void launchLocalDebugSession( final ILaunchConfiguration config, ILaunch l, IProgressMonitor monitor ) throws CoreException {
|
||||||
|
if ( monitor.isCanceled() ) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
final GdbLaunch launch = (GdbLaunch)l;
|
||||||
|
|
||||||
|
monitor.subTask( "Debugging local C/C++ application" ); //$NON-NLS-1$
|
||||||
|
IPath exePath = verifyProgramPath( config );
|
||||||
|
ICProject project = verifyCProject( config );
|
||||||
|
if ( exePath != null ) {
|
||||||
|
verifyBinary( project, exePath );
|
||||||
|
}
|
||||||
|
|
||||||
|
setDefaultSourceLocator(launch, config);
|
||||||
|
|
||||||
|
monitor.worked( 1 );
|
||||||
|
|
||||||
|
|
||||||
|
// Create and invoke the launch sequence to create the debug control and services
|
||||||
|
final LaunchSequence launchSequence =
|
||||||
|
new LaunchSequence(launch.getSession(), launch, exePath);
|
||||||
|
launch.getSession().getExecutor().execute(launchSequence);
|
||||||
|
try {
|
||||||
|
launchSequence.get();
|
||||||
|
} catch (InterruptedException e1) {
|
||||||
|
throw new DebugException(new Status(IStatus.ERROR, GdbLaunchPlugin.PLUGIN_ID, DebugException.INTERNAL_ERROR, "Interrupted Exception in dispatch thread", e1)); //$NON-NLS-1$
|
||||||
|
} catch (ExecutionException e1) {
|
||||||
|
throw new DebugException(new Status(IStatus.ERROR, GdbLaunchPlugin.PLUGIN_ID, DebugException.REQUEST_FAILED, "Error in launch sequence", e1.getCause())); //$NON-NLS-1$
|
||||||
|
}
|
||||||
|
|
||||||
|
launch.initializeControl();
|
||||||
|
|
||||||
|
// Add the CLI and "inferior" process objects to the launch.
|
||||||
|
final AtomicReference<AbstractCLIProcess> cliProcessRef = new AtomicReference<AbstractCLIProcess>();
|
||||||
|
final AtomicReference<MIInferiorProcess> inferiorProcessRef = new AtomicReference<MIInferiorProcess>();
|
||||||
|
try {
|
||||||
|
launch.getDsfExecutor().submit( new Callable<Object>() {
|
||||||
|
public Object call() throws CoreException {
|
||||||
|
DsfServicesTracker tracker = new DsfServicesTracker(GdbLaunchPlugin.getBundleContext(), launch.getSession().getId());
|
||||||
|
GDBControl gdb = tracker.getService(GDBControl.class);
|
||||||
|
if (gdb != null) {
|
||||||
|
cliProcessRef.set(gdb.getCLIProcess());
|
||||||
|
inferiorProcessRef.set(gdb.getInferiorProcess());
|
||||||
|
}
|
||||||
|
tracker.dispose();
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}).get();
|
||||||
|
launch.addProcess(DebugPlugin.newProcess(launch, cliProcessRef.get(), "gdb")); //$NON-NLS-1$
|
||||||
|
launch.addProcess(DebugPlugin.newProcess(launch, inferiorProcessRef.get(), exePath.lastSegment()));
|
||||||
|
} catch (InterruptedException e) {
|
||||||
|
throw new CoreException(new Status(IStatus.ERROR, GdbLaunchPlugin.PLUGIN_ID, 0, "Interrupted while waiting for get process callable.", e)); //$NON-NLS-1$
|
||||||
|
} catch (ExecutionException e) {
|
||||||
|
throw (CoreException)e.getCause();
|
||||||
|
} catch (RejectedExecutionException e) {
|
||||||
|
throw new CoreException(new Status(IStatus.ERROR, GdbLaunchPlugin.PLUGIN_ID, 0, "Debugger shut down before launch was completed.", e)); //$NON-NLS-1$
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create a memory retrieval and register it with session
|
||||||
|
try {
|
||||||
|
launch.getDsfExecutor().submit( new Callable<Object>() {
|
||||||
|
public Object call() throws CoreException {
|
||||||
|
DsfServicesTracker tracker = new DsfServicesTracker(GdbLaunchPlugin.getBundleContext(), launch.getSession().getId());
|
||||||
|
GDBControl gdbControl = tracker.getService(GDBControl.class);
|
||||||
|
if (gdbControl != null) {
|
||||||
|
IMemoryBlockRetrieval memRetrieval = new DsfMemoryBlockRetrieval(
|
||||||
|
GDB_DEBUG_MODEL_ID, config, (IMemoryDMContext)gdbControl.getControlDMContext());
|
||||||
|
launch.getSession().registerModelAdapter(IMemoryBlockRetrieval.class, memRetrieval);
|
||||||
|
((DsfMemoryBlockRetrieval) memRetrieval).initialize();
|
||||||
|
}
|
||||||
|
tracker.dispose();
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}).get();
|
||||||
|
} catch (InterruptedException e) {
|
||||||
|
throw new CoreException(new Status(IStatus.ERROR, GdbLaunchPlugin.PLUGIN_ID, 0, "Interrupted while waiting for get process callable.", e)); //$NON-NLS-1$
|
||||||
|
} catch (ExecutionException e) {
|
||||||
|
throw (CoreException)e.getCause();
|
||||||
|
} catch (RejectedExecutionException e) {
|
||||||
|
throw new CoreException(new Status(IStatus.ERROR, GdbLaunchPlugin.PLUGIN_ID, 0, "Debugger shut down before launch was completed.", e)); //$NON-NLS-1$
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* (non-Javadoc)
|
||||||
|
* @see org.eclipse.cdt.launch.AbstractCLaunchDelegate#getPluginID()
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
protected String getPluginID() {
|
||||||
|
return LaunchUIPlugin.getUniqueIdentifier();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Performs a runtime exec on the given command line in the context of the
|
||||||
|
* specified working directory, and returns the resulting process. If the
|
||||||
|
* current runtime does not support the specification of a working
|
||||||
|
* directory, the status handler for error code
|
||||||
|
* <code>ERR_WORKING_DIRECTORY_NOT_SUPPORTED</code> is queried to see if
|
||||||
|
* the exec should be re-executed without specifying a working directory.
|
||||||
|
*
|
||||||
|
* @param cmdLine
|
||||||
|
* the command line
|
||||||
|
* @param workingDirectory
|
||||||
|
* the working directory, or <code>null</code>
|
||||||
|
* @return the resulting process or <code>null</code> if the exec is
|
||||||
|
* cancelled
|
||||||
|
* @see Runtime
|
||||||
|
*/
|
||||||
|
protected Process exec( String[] cmdLine, String[] environ, File workingDirectory, boolean usePty ) throws CoreException {
|
||||||
|
Process p = null;
|
||||||
|
try {
|
||||||
|
if ( workingDirectory == null ) {
|
||||||
|
p = ProcessFactory.getFactory().exec( cmdLine, environ );
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
if ( usePty && PTY.isSupported() ) {
|
||||||
|
p = ProcessFactory.getFactory().exec( cmdLine, environ, workingDirectory, new PTY() );
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
p = ProcessFactory.getFactory().exec( cmdLine, environ, workingDirectory );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch( IOException e ) {
|
||||||
|
if ( p != null ) {
|
||||||
|
p.destroy();
|
||||||
|
}
|
||||||
|
abort( "Error starting process.", e, ICDTLaunchConfigurationConstants.ERR_INTERNAL_ERROR ); //$NON-NLS-1$
|
||||||
|
}
|
||||||
|
catch( NoSuchMethodError e ) {
|
||||||
|
// attempting launches on 1.2.* - no ability to set working
|
||||||
|
// directory
|
||||||
|
IStatus status = new Status( IStatus.ERROR, LaunchUIPlugin.getUniqueIdentifier(), ICDTLaunchConfigurationConstants.ERR_WORKING_DIRECTORY_NOT_SUPPORTED, LaunchMessages.getString( "LocalDsfLaunchDelegate.9" ), e ); //$NON-NLS-1$
|
||||||
|
IStatusHandler handler = DebugPlugin.getDefault().getStatusHandler( status );
|
||||||
|
if ( handler != null ) {
|
||||||
|
Object result = handler.handleStatus( status, this );
|
||||||
|
if ( result instanceof Boolean && ((Boolean)result).booleanValue() ) {
|
||||||
|
p = exec( cmdLine, environ, null, usePty );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return p;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* (non-Javadoc)
|
||||||
|
* @see org.eclipse.cdt.launch.AbstractCLaunchDelegate#preLaunchCheck(org.eclipse.debug.core.ILaunchConfiguration, java.lang.String, org.eclipse.core.runtime.IProgressMonitor)
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public boolean preLaunchCheck( ILaunchConfiguration config, String mode, IProgressMonitor monitor ) throws CoreException {
|
||||||
|
// no pre launch check for core file
|
||||||
|
if ( mode.equals( ILaunchManager.DEBUG_MODE ) ) {
|
||||||
|
if ( ICDTLaunchConfigurationConstants.DEBUGGER_MODE_CORE.equals( config.getAttribute( ICDTLaunchConfigurationConstants.ATTR_DEBUGGER_START_MODE, ICDTLaunchConfigurationConstants.DEBUGGER_MODE_RUN ) ) )
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return super.preLaunchCheck( config, mode, monitor );
|
||||||
|
}
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////
|
||||||
|
// ILaunchConfigurationDelegate2
|
||||||
|
@Override
|
||||||
|
public boolean buildForLaunch(ILaunchConfiguration configuration, String mode, IProgressMonitor monitor) throws CoreException {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean finalLaunchCheck(ILaunchConfiguration configuration, String mode, IProgressMonitor monitor) throws CoreException {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ILaunch getLaunch(ILaunchConfiguration configuration, String mode) throws CoreException {
|
||||||
|
// Need to configure the source locator before creating the launch
|
||||||
|
// because once the launch is created and added to launch manager,
|
||||||
|
// the adapters will be created for the whole session, including
|
||||||
|
// the source lookup adapter.
|
||||||
|
ISourceLocator locator = getSourceLocator(configuration);
|
||||||
|
|
||||||
|
return new GdbLaunch(configuration, mode, locator);
|
||||||
|
}
|
||||||
|
|
||||||
|
private ISourceLocator getSourceLocator(ILaunchConfiguration configuration) throws CoreException {
|
||||||
|
String type = configuration.getAttribute(ILaunchConfiguration.ATTR_SOURCE_LOCATOR_ID, (String)null);
|
||||||
|
if (type == null) {
|
||||||
|
type = configuration.getType().getSourceLocatorId();
|
||||||
|
}
|
||||||
|
if (type != null) {
|
||||||
|
IPersistableSourceLocator locator = DebugPlugin.getDefault().getLaunchManager().newSourceLocator(type);
|
||||||
|
String memento = configuration.getAttribute(ILaunchConfiguration.ATTR_SOURCE_LOCATOR_MEMENTO, (String)null);
|
||||||
|
if (memento == null) {
|
||||||
|
locator.initializeDefaults(configuration);
|
||||||
|
} else {
|
||||||
|
if(locator instanceof IPersistableSourceLocator2)
|
||||||
|
((IPersistableSourceLocator2)locator).initializeFromMemento(memento, configuration);
|
||||||
|
else
|
||||||
|
locator.initializeFromMemento(memento);
|
||||||
|
}
|
||||||
|
return locator;
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,301 @@
|
||||||
|
/*******************************************************************************
|
||||||
|
* 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.launch.launching;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.util.concurrent.Callable;
|
||||||
|
import java.util.concurrent.ExecutionException;
|
||||||
|
import java.util.concurrent.RejectedExecutionException;
|
||||||
|
import java.util.concurrent.atomic.AtomicReference;
|
||||||
|
|
||||||
|
import org.eclipse.cdt.core.model.ICProject;
|
||||||
|
import org.eclipse.cdt.debug.core.ICDTLaunchConfigurationConstants;
|
||||||
|
import org.eclipse.cdt.launch.AbstractCLaunchDelegate;
|
||||||
|
import org.eclipse.cdt.launch.internal.ui.LaunchMessages;
|
||||||
|
import org.eclipse.cdt.launch.internal.ui.LaunchUIPlugin;
|
||||||
|
import org.eclipse.cdt.utils.pty.PTY;
|
||||||
|
import org.eclipse.cdt.utils.spawner.ProcessFactory;
|
||||||
|
import org.eclipse.core.runtime.CoreException;
|
||||||
|
import org.eclipse.core.runtime.IPath;
|
||||||
|
import org.eclipse.core.runtime.IProgressMonitor;
|
||||||
|
import org.eclipse.core.runtime.IStatus;
|
||||||
|
import org.eclipse.core.runtime.NullProgressMonitor;
|
||||||
|
import org.eclipse.core.runtime.Status;
|
||||||
|
import org.eclipse.dd.dsf.concurrent.ThreadSafe;
|
||||||
|
import org.eclipse.dd.dsf.debug.model.DsfMemoryBlockRetrieval;
|
||||||
|
import org.eclipse.dd.dsf.debug.service.IMemory.IMemoryDMContext;
|
||||||
|
import org.eclipse.dd.dsf.service.DsfServicesTracker;
|
||||||
|
import org.eclipse.dd.gdb.launch.internal.GdbLaunchPlugin;
|
||||||
|
import org.eclipse.dd.gdb.service.command.GDBControl;
|
||||||
|
import org.eclipse.dd.mi.service.command.AbstractCLIProcess;
|
||||||
|
import org.eclipse.dd.mi.service.command.MIInferiorProcess;
|
||||||
|
import org.eclipse.debug.core.DebugException;
|
||||||
|
import org.eclipse.debug.core.DebugPlugin;
|
||||||
|
import org.eclipse.debug.core.ILaunch;
|
||||||
|
import org.eclipse.debug.core.ILaunchConfiguration;
|
||||||
|
import org.eclipse.debug.core.ILaunchConfigurationWorkingCopy;
|
||||||
|
import org.eclipse.debug.core.ILaunchManager;
|
||||||
|
import org.eclipse.debug.core.IStatusHandler;
|
||||||
|
import org.eclipse.debug.core.model.ILaunchConfigurationDelegate2;
|
||||||
|
import org.eclipse.debug.core.model.IMemoryBlockRetrieval;
|
||||||
|
import org.eclipse.debug.core.model.IPersistableSourceLocator;
|
||||||
|
import org.eclipse.debug.core.model.ISourceLocator;
|
||||||
|
import org.eclipse.debug.core.sourcelookup.IPersistableSourceLocator2;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The launch configuration delegate for the CDI debugger session types.
|
||||||
|
*/
|
||||||
|
@ThreadSafe
|
||||||
|
public class GdbRemoteLaunchDelegate extends AbstractCLaunchDelegate
|
||||||
|
implements ILaunchConfigurationDelegate2
|
||||||
|
{
|
||||||
|
public final static String GDB_DEBUG_MODEL_ID = "org.eclipse.dd.gdb"; //$NON-NLS-1$
|
||||||
|
|
||||||
|
/* (non-Javadoc)
|
||||||
|
* @see org.eclipse.cdt.launch.AbstractCLaunchDelegate#launch(org.eclipse.debug.core.ILaunchConfiguration, java.lang.String, org.eclipse.debug.core.ILaunch, org.eclipse.core.runtime.IProgressMonitor)
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public void launch( ILaunchConfiguration config, String mode, ILaunch launch, IProgressMonitor monitor ) throws CoreException {
|
||||||
|
if ( monitor == null ) {
|
||||||
|
monitor = new NullProgressMonitor();
|
||||||
|
}
|
||||||
|
if ( mode.equals( ILaunchManager.DEBUG_MODE ) ) {
|
||||||
|
launchDebugger( config, launch, monitor );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void launchDebugger( ILaunchConfiguration config, ILaunch launch, IProgressMonitor monitor ) throws CoreException {
|
||||||
|
monitor.beginTask("Launching debugger session", 10); //$NON-NLS-1$
|
||||||
|
if ( monitor.isCanceled() ) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
// Hack until we fix the tabs
|
||||||
|
try {
|
||||||
|
ILaunchConfigurationWorkingCopy wc = config.getWorkingCopy();
|
||||||
|
wc.setAttribute( ICDTLaunchConfigurationConstants.ATTR_DEBUGGER_START_MODE, IGDBLaunchConfigurationConstants.DEBUGGER_MODE_REMOTE );
|
||||||
|
wc.doSave();
|
||||||
|
}
|
||||||
|
catch( CoreException e ) {
|
||||||
|
}
|
||||||
|
// END HACK
|
||||||
|
String debugMode = config.getAttribute( ICDTLaunchConfigurationConstants.ATTR_DEBUGGER_START_MODE, IGDBLaunchConfigurationConstants.DEBUGGER_MODE_REMOTE );
|
||||||
|
if ( debugMode.equals( IGDBLaunchConfigurationConstants.DEBUGGER_MODE_REMOTE ) ) {
|
||||||
|
launchRemoteDebugSession( config, launch, monitor );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
finally {
|
||||||
|
monitor.done();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void launchRemoteDebugSession( final ILaunchConfiguration config, ILaunch l, IProgressMonitor monitor ) throws CoreException {
|
||||||
|
if ( monitor.isCanceled() ) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
final GdbLaunch launch = (GdbLaunch)l;
|
||||||
|
|
||||||
|
monitor.subTask( "Debugging remote C/C++ application" ); //$NON-NLS-1$
|
||||||
|
IPath exePath = verifyProgramPath( config );
|
||||||
|
ICProject project = verifyCProject( config );
|
||||||
|
if ( exePath != null ) {
|
||||||
|
verifyBinary( project, exePath );
|
||||||
|
}
|
||||||
|
|
||||||
|
setDefaultSourceLocator(launch, config);
|
||||||
|
|
||||||
|
monitor.worked( 1 );
|
||||||
|
|
||||||
|
|
||||||
|
// Create and invoke the launch sequence to create the debug control and services
|
||||||
|
final LaunchSequence launchSequence =
|
||||||
|
new LaunchSequence(launch.getSession(), launch, exePath);
|
||||||
|
launch.getSession().getExecutor().execute(launchSequence);
|
||||||
|
try {
|
||||||
|
launchSequence.get();
|
||||||
|
} catch (InterruptedException e1) {
|
||||||
|
throw new DebugException(new Status(IStatus.ERROR, GdbLaunchPlugin.PLUGIN_ID, DebugException.INTERNAL_ERROR, "Interrupted Exception in dispatch thread", e1)); //$NON-NLS-1$
|
||||||
|
} catch (ExecutionException e1) {
|
||||||
|
throw new DebugException(new Status(IStatus.ERROR, GdbLaunchPlugin.PLUGIN_ID, DebugException.REQUEST_FAILED, "Error in launch sequence", e1.getCause())); //$NON-NLS-1$
|
||||||
|
}
|
||||||
|
|
||||||
|
launch.initializeControl();
|
||||||
|
|
||||||
|
// Add the CLI and "inferior" process objects to the launch.
|
||||||
|
final AtomicReference<AbstractCLIProcess> cliProcessRef = new AtomicReference<AbstractCLIProcess>();
|
||||||
|
final AtomicReference<MIInferiorProcess> inferiorProcessRef = new AtomicReference<MIInferiorProcess>();
|
||||||
|
try {
|
||||||
|
launch.getDsfExecutor().submit( new Callable<Object>() {
|
||||||
|
public Object call() throws CoreException {
|
||||||
|
DsfServicesTracker tracker = new DsfServicesTracker(GdbLaunchPlugin.getBundleContext(), launch.getSession().getId());
|
||||||
|
GDBControl gdb = tracker.getService(GDBControl.class);
|
||||||
|
if (gdb != null) {
|
||||||
|
cliProcessRef.set(gdb.getCLIProcess());
|
||||||
|
inferiorProcessRef.set(gdb.getInferiorProcess());
|
||||||
|
}
|
||||||
|
tracker.dispose();
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}).get();
|
||||||
|
launch.addProcess(DebugPlugin.newProcess(launch, cliProcessRef.get(), "gdb")); //$NON-NLS-1$
|
||||||
|
launch.addProcess(DebugPlugin.newProcess(launch, inferiorProcessRef.get(), exePath.lastSegment()));
|
||||||
|
} catch (InterruptedException e) {
|
||||||
|
throw new CoreException(new Status(IStatus.ERROR, GdbLaunchPlugin.PLUGIN_ID, 0, "Interrupted while waiting for get process callable.", e)); //$NON-NLS-1$
|
||||||
|
} catch (ExecutionException e) {
|
||||||
|
throw (CoreException)e.getCause();
|
||||||
|
} catch (RejectedExecutionException e) {
|
||||||
|
throw new CoreException(new Status(IStatus.ERROR, GdbLaunchPlugin.PLUGIN_ID, 0, "Debugger shut down before launch was completed.", e)); //$NON-NLS-1$
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create a memory retrieval and register it with session
|
||||||
|
try {
|
||||||
|
launch.getDsfExecutor().submit( new Callable<Object>() {
|
||||||
|
public Object call() throws CoreException {
|
||||||
|
DsfServicesTracker tracker = new DsfServicesTracker(GdbLaunchPlugin.getBundleContext(), launch.getSession().getId());
|
||||||
|
GDBControl gdbControl = tracker.getService(GDBControl.class);
|
||||||
|
if (gdbControl != null) {
|
||||||
|
IMemoryBlockRetrieval memRetrieval = new DsfMemoryBlockRetrieval(
|
||||||
|
GDB_DEBUG_MODEL_ID, config, (IMemoryDMContext)gdbControl.getControlDMContext());
|
||||||
|
launch.getSession().registerModelAdapter(IMemoryBlockRetrieval.class, memRetrieval);
|
||||||
|
((DsfMemoryBlockRetrieval) memRetrieval).initialize();
|
||||||
|
}
|
||||||
|
tracker.dispose();
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}).get();
|
||||||
|
} catch (InterruptedException e) {
|
||||||
|
throw new CoreException(new Status(IStatus.ERROR, GdbLaunchPlugin.PLUGIN_ID, 0, "Interrupted while waiting for get process callable.", e)); //$NON-NLS-1$
|
||||||
|
} catch (ExecutionException e) {
|
||||||
|
throw (CoreException)e.getCause();
|
||||||
|
} catch (RejectedExecutionException e) {
|
||||||
|
throw new CoreException(new Status(IStatus.ERROR, GdbLaunchPlugin.PLUGIN_ID, 0, "Debugger shut down before launch was completed.", e)); //$NON-NLS-1$
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* (non-Javadoc)
|
||||||
|
* @see org.eclipse.cdt.launch.AbstractCLaunchDelegate#getPluginID()
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
protected String getPluginID() {
|
||||||
|
return LaunchUIPlugin.getUniqueIdentifier();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Performs a runtime exec on the given command line in the context of the
|
||||||
|
* specified working directory, and returns the resulting process. If the
|
||||||
|
* current runtime does not support the specification of a working
|
||||||
|
* directory, the status handler for error code
|
||||||
|
* <code>ERR_WORKING_DIRECTORY_NOT_SUPPORTED</code> is queried to see if
|
||||||
|
* the exec should be re-executed without specifying a working directory.
|
||||||
|
*
|
||||||
|
* @param cmdLine
|
||||||
|
* the command line
|
||||||
|
* @param workingDirectory
|
||||||
|
* the working directory, or <code>null</code>
|
||||||
|
* @return the resulting process or <code>null</code> if the exec is
|
||||||
|
* cancelled
|
||||||
|
* @see Runtime
|
||||||
|
*/
|
||||||
|
protected Process exec( String[] cmdLine, String[] environ, File workingDirectory, boolean usePty ) throws CoreException {
|
||||||
|
Process p = null;
|
||||||
|
try {
|
||||||
|
if ( workingDirectory == null ) {
|
||||||
|
p = ProcessFactory.getFactory().exec( cmdLine, environ );
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
if ( usePty && PTY.isSupported() ) {
|
||||||
|
p = ProcessFactory.getFactory().exec( cmdLine, environ, workingDirectory, new PTY() );
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
p = ProcessFactory.getFactory().exec( cmdLine, environ, workingDirectory );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch( IOException e ) {
|
||||||
|
if ( p != null ) {
|
||||||
|
p.destroy();
|
||||||
|
}
|
||||||
|
abort( "Error starting process.", e, ICDTLaunchConfigurationConstants.ERR_INTERNAL_ERROR ); //$NON-NLS-1$
|
||||||
|
}
|
||||||
|
catch( NoSuchMethodError e ) {
|
||||||
|
// attempting launches on 1.2.* - no ability to set working
|
||||||
|
// directory
|
||||||
|
IStatus status = new Status( IStatus.ERROR, LaunchUIPlugin.getUniqueIdentifier(), ICDTLaunchConfigurationConstants.ERR_WORKING_DIRECTORY_NOT_SUPPORTED, LaunchMessages.getString( "LocalDsfLaunchDelegate.9" ), e ); //$NON-NLS-1$
|
||||||
|
IStatusHandler handler = DebugPlugin.getDefault().getStatusHandler( status );
|
||||||
|
if ( handler != null ) {
|
||||||
|
Object result = handler.handleStatus( status, this );
|
||||||
|
if ( result instanceof Boolean && ((Boolean)result).booleanValue() ) {
|
||||||
|
p = exec( cmdLine, environ, null, usePty );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return p;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* (non-Javadoc)
|
||||||
|
* @see org.eclipse.cdt.launch.AbstractCLaunchDelegate#preLaunchCheck(org.eclipse.debug.core.ILaunchConfiguration, java.lang.String, org.eclipse.core.runtime.IProgressMonitor)
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public boolean preLaunchCheck( ILaunchConfiguration config, String mode, IProgressMonitor monitor ) throws CoreException {
|
||||||
|
// no pre launch check for core file
|
||||||
|
if ( mode.equals( ILaunchManager.DEBUG_MODE ) ) {
|
||||||
|
if ( ICDTLaunchConfigurationConstants.DEBUGGER_MODE_CORE.equals( config.getAttribute( ICDTLaunchConfigurationConstants.ATTR_DEBUGGER_START_MODE, ICDTLaunchConfigurationConstants.DEBUGGER_MODE_RUN ) ) )
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return super.preLaunchCheck( config, mode, monitor );
|
||||||
|
}
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////
|
||||||
|
// ILaunchConfigurationDelegate2
|
||||||
|
@Override
|
||||||
|
public boolean buildForLaunch(ILaunchConfiguration configuration, String mode, IProgressMonitor monitor) throws CoreException {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean finalLaunchCheck(ILaunchConfiguration configuration, String mode, IProgressMonitor monitor) throws CoreException {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ILaunch getLaunch(ILaunchConfiguration configuration, String mode) throws CoreException {
|
||||||
|
// Need to configure the source locator before creating the launch
|
||||||
|
// because once the launch is created and added to launch manager,
|
||||||
|
// the adapters will be created for the whole session, including
|
||||||
|
// the source lookup adapter.
|
||||||
|
ISourceLocator locator = getSourceLocator(configuration);
|
||||||
|
|
||||||
|
return new GdbLaunch(configuration, mode, locator);
|
||||||
|
}
|
||||||
|
|
||||||
|
private ISourceLocator getSourceLocator(ILaunchConfiguration configuration) throws CoreException {
|
||||||
|
String type = configuration.getAttribute(ILaunchConfiguration.ATTR_SOURCE_LOCATOR_ID, (String)null);
|
||||||
|
if (type == null) {
|
||||||
|
type = configuration.getType().getSourceLocatorId();
|
||||||
|
}
|
||||||
|
if (type != null) {
|
||||||
|
IPersistableSourceLocator locator = DebugPlugin.getDefault().getLaunchManager().newSourceLocator(type);
|
||||||
|
String memento = configuration.getAttribute(ILaunchConfiguration.ATTR_SOURCE_LOCATOR_MEMENTO, (String)null);
|
||||||
|
if (memento == null) {
|
||||||
|
locator.initializeDefaults(configuration);
|
||||||
|
} else {
|
||||||
|
if(locator instanceof IPersistableSourceLocator2)
|
||||||
|
((IPersistableSourceLocator2)locator).initializeFromMemento(memento, configuration);
|
||||||
|
else
|
||||||
|
locator.initializeFromMemento(memento);
|
||||||
|
}
|
||||||
|
return locator;
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,7 @@
|
||||||
|
package org.eclipse.dd.gdb.launch.launching;
|
||||||
|
|
||||||
|
public class IGDBLaunchConfigurationConstants {
|
||||||
|
|
||||||
|
public static final String DEBUGGER_MODE_REMOTE = "remote";
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,233 @@
|
||||||
|
/*******************************************************************************
|
||||||
|
* Copyright (c) 2006 Wind River Systems 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:
|
||||||
|
* Wind River Systems - initial API and implementation
|
||||||
|
*******************************************************************************/
|
||||||
|
package org.eclipse.dd.gdb.launch.launching;
|
||||||
|
|
||||||
|
import org.eclipse.cdt.debug.core.CDebugCorePlugin;
|
||||||
|
import org.eclipse.cdt.debug.core.ICDTLaunchConfigurationConstants;
|
||||||
|
import org.eclipse.cdt.debug.internal.core.sourcelookup.CSourceLookupDirector;
|
||||||
|
import org.eclipse.cdt.debug.mi.core.IMILaunchConfigurationConstants;
|
||||||
|
import org.eclipse.core.runtime.CoreException;
|
||||||
|
import org.eclipse.core.runtime.IPath;
|
||||||
|
import org.eclipse.core.runtime.IStatus;
|
||||||
|
import org.eclipse.core.runtime.Path;
|
||||||
|
import org.eclipse.core.runtime.Status;
|
||||||
|
import org.eclipse.dd.dsf.concurrent.DataRequestMonitor;
|
||||||
|
import org.eclipse.dd.dsf.concurrent.RequestMonitor;
|
||||||
|
import org.eclipse.dd.dsf.concurrent.Sequence;
|
||||||
|
import org.eclipse.dd.dsf.debug.service.StepQueueManager;
|
||||||
|
import org.eclipse.dd.dsf.debug.service.IBreakpoints.IBreakpointsTargetDMContext;
|
||||||
|
import org.eclipse.dd.dsf.debug.service.IRunControl.IContainerDMContext;
|
||||||
|
import org.eclipse.dd.dsf.service.DsfSession;
|
||||||
|
import org.eclipse.dd.gdb.launch.internal.GdbLaunchPlugin;
|
||||||
|
import org.eclipse.dd.gdb.service.GDBRunControl;
|
||||||
|
import org.eclipse.dd.gdb.service.command.GDBControl;
|
||||||
|
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;
|
||||||
|
import org.eclipse.dd.mi.service.command.commands.MIBreakInsert;
|
||||||
|
import org.eclipse.dd.mi.service.command.commands.MIExecRun;
|
||||||
|
import org.eclipse.dd.mi.service.command.output.MIBreakInsertInfo;
|
||||||
|
import org.eclipse.dd.mi.service.command.output.MIInfo;
|
||||||
|
import org.eclipse.debug.core.DebugException;
|
||||||
|
|
||||||
|
public class LaunchSequence extends Sequence {
|
||||||
|
|
||||||
|
Step[] fSteps = new Step[] {
|
||||||
|
// Create and initialize the Connection service.
|
||||||
|
new Step() {
|
||||||
|
@Override
|
||||||
|
public void execute(RequestMonitor requestMonitor) {
|
||||||
|
//
|
||||||
|
// Create the connection.
|
||||||
|
//
|
||||||
|
fCommandControl = new GDBControl(
|
||||||
|
fSession, getGDBPath(), fExecPath, GDBControl.SessionType.RUN, 30);
|
||||||
|
fCommandControl.initialize(requestMonitor);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
new Step() { @Override
|
||||||
|
public void execute(RequestMonitor requestMonitor) {
|
||||||
|
new GDBRunControl(fSession).initialize(requestMonitor);
|
||||||
|
}},
|
||||||
|
new Step() { @Override
|
||||||
|
public void execute(RequestMonitor requestMonitor) {
|
||||||
|
new StepQueueManager(fSession).initialize(requestMonitor);
|
||||||
|
}},
|
||||||
|
new Step() { @Override
|
||||||
|
public void execute(RequestMonitor requestMonitor) {
|
||||||
|
new MIMemory(fSession).initialize(requestMonitor);
|
||||||
|
}},
|
||||||
|
new Step() { @Override
|
||||||
|
public void execute(RequestMonitor requestMonitor) {
|
||||||
|
new MIModules(fSession).initialize(requestMonitor);
|
||||||
|
}},
|
||||||
|
new Step() { @Override
|
||||||
|
public void execute(RequestMonitor requestMonitor) {
|
||||||
|
new MIStack(fSession).initialize(requestMonitor);
|
||||||
|
}},
|
||||||
|
new Step() { @Override
|
||||||
|
public void execute(RequestMonitor requestMonitor) {
|
||||||
|
new ExpressionService(fSession).initialize(requestMonitor);
|
||||||
|
}},
|
||||||
|
new Step() { @Override
|
||||||
|
public void execute(RequestMonitor requestMonitor) {
|
||||||
|
fSourceLookup = new CSourceLookup(fSession);
|
||||||
|
fSourceLookup.initialize(requestMonitor);
|
||||||
|
}},
|
||||||
|
new Step() { @Override
|
||||||
|
public void execute(RequestMonitor requestMonitor) {
|
||||||
|
fSourceLookup.setSourceLookupDirector(
|
||||||
|
fCommandControl.getGDBDMContext(),
|
||||||
|
((CSourceLookupDirector)fLaunch.getSourceLocator()));
|
||||||
|
requestMonitor.done();
|
||||||
|
}},
|
||||||
|
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) {
|
||||||
|
@Override
|
||||||
|
protected void handleOK() {
|
||||||
|
requestMonitor.done();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}},
|
||||||
|
new Step() { @Override
|
||||||
|
public void execute(final RequestMonitor requestMonitor) {
|
||||||
|
// Create high-level breakpoint service and install breakpoints
|
||||||
|
// for the GDB debug context.
|
||||||
|
final MIBreakpointsManager bpmService = new MIBreakpointsManager(fSession, CDebugCorePlugin.PLUGIN_ID);
|
||||||
|
bpmService.initialize(new RequestMonitor(getExecutor(), requestMonitor) {
|
||||||
|
@Override
|
||||||
|
protected void handleOK() {
|
||||||
|
bpmService.startTrackingBreakpoints(fCommandControl.getGDBDMContext(), requestMonitor);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}},
|
||||||
|
new Step() { @Override
|
||||||
|
public void execute(RequestMonitor requestMonitor) {
|
||||||
|
new MIRegisters(fSession).initialize(requestMonitor);
|
||||||
|
}},
|
||||||
|
new Step() { @Override
|
||||||
|
public void execute(RequestMonitor requestMonitor) {
|
||||||
|
new MIDisassembly(fSession).initialize(requestMonitor);
|
||||||
|
}},
|
||||||
|
/*
|
||||||
|
* If needed, insert breakpoint at main and run to it.
|
||||||
|
*/
|
||||||
|
new Step() {
|
||||||
|
private boolean fStopInMain = false;
|
||||||
|
private String fStopSymbol = null;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return The return value actually indicates whether the get operation succeeded,
|
||||||
|
* not whether to stop.
|
||||||
|
*/
|
||||||
|
private boolean readStopAtMain(RequestMonitor requestMonitor) {
|
||||||
|
try {
|
||||||
|
fStopInMain = fLaunch.getLaunchConfiguration().getAttribute( ICDTLaunchConfigurationConstants.ATTR_DEBUGGER_STOP_AT_MAIN, false );
|
||||||
|
} catch (CoreException e) {
|
||||||
|
requestMonitor.setStatus(new Status(IStatus.ERROR, GdbLaunchPlugin.PLUGIN_ID, -1, "Cannot retrieve the entry point symbol", e)); //$NON-NLS-1$
|
||||||
|
requestMonitor.done();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean readStopSymbol(RequestMonitor requestMonitor) {
|
||||||
|
try {
|
||||||
|
fStopSymbol = fLaunch.getLaunchConfiguration().getAttribute( ICDTLaunchConfigurationConstants.ATTR_DEBUGGER_STOP_AT_MAIN_SYMBOL, ICDTLaunchConfigurationConstants.DEBUGGER_STOP_AT_MAIN_SYMBOL_DEFAULT );
|
||||||
|
} catch (CoreException e) {
|
||||||
|
requestMonitor.setStatus(new Status(IStatus.ERROR, GdbLaunchPlugin.PLUGIN_ID, DebugException.CONFIGURATION_INVALID, "Cannot retrieve the entry point symbol", e)); //$NON-NLS-1$
|
||||||
|
requestMonitor.done();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void execute(final RequestMonitor requestMonitor) {
|
||||||
|
if (!readStopAtMain(requestMonitor)) return;
|
||||||
|
if (!fStopInMain) {
|
||||||
|
// Just start the program.
|
||||||
|
fCommandControl.queueCommand(
|
||||||
|
new MIExecRun((IContainerDMContext)fCommandControl.getControlDMContext(), new String[0]),
|
||||||
|
new DataRequestMonitor<MIInfo>(getExecutor(), requestMonitor) {
|
||||||
|
@Override
|
||||||
|
protected void handleOK() {
|
||||||
|
requestMonitor.done();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
if (!readStopSymbol(requestMonitor)) return;
|
||||||
|
|
||||||
|
// Insert a breakpoint at the requested stop symbol.
|
||||||
|
fCommandControl.queueCommand(
|
||||||
|
new MIBreakInsert(
|
||||||
|
(IBreakpointsTargetDMContext)fCommandControl.getControlDMContext(),
|
||||||
|
true, false, null, 0, fStopSymbol, 0),
|
||||||
|
new DataRequestMonitor<MIBreakInsertInfo>(getExecutor(), requestMonitor) {
|
||||||
|
@Override
|
||||||
|
protected void handleOK() {
|
||||||
|
|
||||||
|
// After the break-insert is done, execute the -exec-run command.
|
||||||
|
fCommandControl.queueCommand(
|
||||||
|
new MIExecRun((IContainerDMContext)fCommandControl.getControlDMContext(), new String[0]),
|
||||||
|
new DataRequestMonitor<MIInfo>(getExecutor(), requestMonitor) {
|
||||||
|
@Override
|
||||||
|
protected void handleOK() {
|
||||||
|
requestMonitor.done();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
DsfSession fSession;
|
||||||
|
GdbLaunch fLaunch;
|
||||||
|
IPath fExecPath;
|
||||||
|
|
||||||
|
GDBControl fCommandControl;
|
||||||
|
CSourceLookup fSourceLookup;
|
||||||
|
|
||||||
|
public LaunchSequence(DsfSession session, GdbLaunch launch, IPath execPath) {
|
||||||
|
super(session.getExecutor());
|
||||||
|
fSession = session;
|
||||||
|
fLaunch = launch;
|
||||||
|
fExecPath = execPath;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Step[] getSteps() {
|
||||||
|
return fSteps;
|
||||||
|
}
|
||||||
|
|
||||||
|
private IPath getGDBPath() {
|
||||||
|
IPath retVal = new Path("gdb.exe"); //$NON-NLS-1$
|
||||||
|
try {
|
||||||
|
retVal = new Path( fLaunch.getLaunchConfiguration().getAttribute( IMILaunchConfigurationConstants.ATTR_DEBUG_NAME, IMILaunchConfigurationConstants.DEBUGGER_DEBUG_NAME_DEFAULT ) );
|
||||||
|
} catch (CoreException e) {
|
||||||
|
}
|
||||||
|
return retVal;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,179 @@
|
||||||
|
/*******************************************************************************
|
||||||
|
* Copyright (c) 2006 Wind River Systems 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:
|
||||||
|
* Wind River Systems - initial API and implementation
|
||||||
|
*******************************************************************************/
|
||||||
|
package org.eclipse.dd.gdb.launch.launching;
|
||||||
|
|
||||||
|
import org.eclipse.core.runtime.IStatus;
|
||||||
|
import org.eclipse.core.runtime.Status;
|
||||||
|
import org.eclipse.dd.dsf.concurrent.DsfExecutor;
|
||||||
|
import org.eclipse.dd.dsf.concurrent.RequestMonitor;
|
||||||
|
import org.eclipse.dd.dsf.concurrent.Sequence;
|
||||||
|
import org.eclipse.dd.dsf.service.DsfServicesTracker;
|
||||||
|
import org.eclipse.dd.dsf.service.IDsfService;
|
||||||
|
import org.eclipse.dd.gdb.launch.internal.GdbLaunchPlugin;
|
||||||
|
import org.eclipse.dd.gdb.service.GDBRunControl;
|
||||||
|
import org.eclipse.dd.gdb.service.command.GDBControl;
|
||||||
|
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 ShutdownSequence extends Sequence {
|
||||||
|
|
||||||
|
String fSessionId;
|
||||||
|
|
||||||
|
String fApplicationName;
|
||||||
|
|
||||||
|
String fDebugModelId;
|
||||||
|
|
||||||
|
DsfServicesTracker fTracker;
|
||||||
|
|
||||||
|
public ShutdownSequence(DsfExecutor executor, String sessionId, RequestMonitor requestMonitor) {
|
||||||
|
super(executor, requestMonitor);
|
||||||
|
fSessionId = sessionId;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Step[] getSteps() {
|
||||||
|
return fSteps;
|
||||||
|
}
|
||||||
|
|
||||||
|
private final Step[] fSteps = new Step[] { new Step() {
|
||||||
|
@Override
|
||||||
|
public void execute(RequestMonitor requestMonitor) {
|
||||||
|
assert GdbLaunchPlugin.getBundleContext() != null;
|
||||||
|
fTracker = new DsfServicesTracker(GdbLaunchPlugin.getBundleContext(), fSessionId);
|
||||||
|
requestMonitor.done();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void rollBack(RequestMonitor requestMonitor) {
|
||||||
|
fTracker.dispose();
|
||||||
|
fTracker = null;
|
||||||
|
requestMonitor.done();
|
||||||
|
}
|
||||||
|
}, new Step() {
|
||||||
|
@Override
|
||||||
|
public void execute(RequestMonitor requestMonitor) {
|
||||||
|
shutdownService(MIDisassembly.class, requestMonitor);
|
||||||
|
}
|
||||||
|
}, new Step() {
|
||||||
|
@Override
|
||||||
|
public void execute(RequestMonitor requestMonitor) {
|
||||||
|
shutdownService(MIRegisters.class, requestMonitor);
|
||||||
|
}
|
||||||
|
// TODO: As Pawel about the necessity of this step
|
||||||
|
// Not clear on the purpose of this step since the next one does it also
|
||||||
|
// (stopTrackingBreakpoints() is called as part of the shutdown method)
|
||||||
|
// Besides, the run control is already gone so removing breakpoints from
|
||||||
|
// the back-end is bound to fail...
|
||||||
|
// }, new Step() {
|
||||||
|
// @Override
|
||||||
|
// public void execute(final RequestMonitor requestMonitor) {
|
||||||
|
// MIBreakpointsManager bpm = fTracker.getService(MIBreakpointsManager.class);
|
||||||
|
// GDBControl commandControl = fTracker.getService(GDBControl.class);
|
||||||
|
// if (bpm != null && commandControl != null) {
|
||||||
|
// bpm.stopTrackingBreakpoints(
|
||||||
|
// commandControl.getGDBDMContext(),
|
||||||
|
// new RequestMonitor(getExecutor(), requestMonitor) {
|
||||||
|
// @Override
|
||||||
|
// protected void handleCompleted() {
|
||||||
|
// // If un-installing breakpoints fails, log the error but continue shutting down.
|
||||||
|
// if (!getStatus().isOK()) {
|
||||||
|
// DsfGdbLaunchPlugin.getDefault().getLog().log(getStatus());
|
||||||
|
// }
|
||||||
|
// requestMonitor.done();
|
||||||
|
// }
|
||||||
|
// });
|
||||||
|
// } else {
|
||||||
|
// requestMonitor.setStatus(new Status(IStatus.ERROR, DsfGdbLaunchPlugin.PLUGIN_ID, IDsfService.INTERNAL_ERROR,
|
||||||
|
// "Needed services not found.", null)); //$NON-NLS-1$
|
||||||
|
// requestMonitor.done();
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
}, new Step() {
|
||||||
|
@Override
|
||||||
|
public void execute(RequestMonitor requestMonitor) {
|
||||||
|
shutdownService(MIBreakpointsManager.class, requestMonitor);
|
||||||
|
}
|
||||||
|
}, new Step() {
|
||||||
|
@Override
|
||||||
|
public void execute(RequestMonitor requestMonitor) {
|
||||||
|
shutdownService(MIBreakpoints.class, requestMonitor);
|
||||||
|
}
|
||||||
|
}, new Step() {
|
||||||
|
@Override
|
||||||
|
public void execute(RequestMonitor requestMonitor) {
|
||||||
|
shutdownService(CSourceLookup.class, requestMonitor);
|
||||||
|
}
|
||||||
|
}, new Step() {
|
||||||
|
@Override
|
||||||
|
public void execute(RequestMonitor requestMonitor) {
|
||||||
|
shutdownService(ExpressionService.class, requestMonitor);
|
||||||
|
}
|
||||||
|
}, new Step() {
|
||||||
|
@Override
|
||||||
|
public void execute(RequestMonitor requestMonitor) {
|
||||||
|
shutdownService(MIStack.class, requestMonitor);
|
||||||
|
}
|
||||||
|
}, new Step() {
|
||||||
|
@Override
|
||||||
|
public void execute(RequestMonitor requestMonitor) {
|
||||||
|
shutdownService(MIModules.class, requestMonitor);
|
||||||
|
}
|
||||||
|
}, new Step() {
|
||||||
|
@Override
|
||||||
|
public void execute(RequestMonitor requestMonitor) {
|
||||||
|
shutdownService(MIMemory.class, requestMonitor);
|
||||||
|
}
|
||||||
|
}, new Step() {
|
||||||
|
@Override
|
||||||
|
public void execute(RequestMonitor requestMonitor) {
|
||||||
|
shutdownService(GDBRunControl.class, requestMonitor);
|
||||||
|
}
|
||||||
|
}, new Step() {
|
||||||
|
@Override
|
||||||
|
public void execute(RequestMonitor requestMonitor) {
|
||||||
|
shutdownService(GDBControl.class, requestMonitor);
|
||||||
|
}
|
||||||
|
}, new Step() {
|
||||||
|
@Override
|
||||||
|
public void execute(RequestMonitor requestMonitor) {
|
||||||
|
fTracker.dispose();
|
||||||
|
fTracker = null;
|
||||||
|
requestMonitor.done();
|
||||||
|
}
|
||||||
|
} };
|
||||||
|
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
private void shutdownService(Class clazz, final RequestMonitor requestMonitor) {
|
||||||
|
IDsfService service = fTracker.getService(clazz);
|
||||||
|
if (service != null) {
|
||||||
|
service.shutdown(new RequestMonitor(getExecutor(), requestMonitor) {
|
||||||
|
@Override
|
||||||
|
protected void handleCompleted() {
|
||||||
|
if (!getStatus().isOK()) {
|
||||||
|
GdbLaunchPlugin.getDefault().getLog().log(getStatus());
|
||||||
|
}
|
||||||
|
requestMonitor.done();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
requestMonitor.setStatus(new Status(IStatus.ERROR, GdbLaunchPlugin.PLUGIN_ID, IDsfService.INTERNAL_ERROR,
|
||||||
|
"Service '" + clazz.getName() + "' not found.", null)); //$NON-NLS-1$//$NON-NLS-2$
|
||||||
|
requestMonitor.done();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
Loading…
Add table
Reference in a new issue