1
0
Fork 0
mirror of https://github.com/eclipse-cdt/cdt synced 2025-04-23 14:42:11 +02:00

Bug 119683: long messages during launch cause gdb to timeout, launch to fail.

This commit is contained in:
Mikhail Khodjaiants 2006-01-23 20:25:43 +00:00
parent dd546cab07
commit 143d697e5e
14 changed files with 1292 additions and 11 deletions

View file

@ -1,3 +1,15 @@
2006-01-23 Mikhail Khodjaiants
Bug 119683: long messages during launch cause gdb to timeout, launch to fail.
* plugin.xml
* plugin.properties
* MISession.java
+ AbstractGDBCDIDebugger.java
+ CygwinGDBCDIDebugger2.java
+ GDBCDIDebugger2.java
+ GDBServerCDIDebugger2.java
* MIPlugin.java
* MIPluginResources.properties
2006-01-04 Mikhail Khodjaiants
Bug 118900: Display libraries loaded in post-mortem debug.
Applied with modifications the patch from Joanne Woo (jwoo.mvista.com).

View file

@ -99,6 +99,7 @@ public class MISession extends Observable {
* @param miVersion
* @param monitor
* @throws MIException
* @deprecated
*/
public MISession(MIProcess process, IMITTY tty, int type, int commandTimeout, int launchTimeout, String miVersion, IProgressMonitor monitor) throws MIException {
this(process, tty, type, new CommandFactory(miVersion), commandTimeout, launchTimeout, monitor);
@ -113,6 +114,7 @@ public class MISession extends Observable {
* @param pty Terminal to use for the inferior.
* @param timeout time in milliseconds to wait for command response.
* @param type the type of debugin session.
* @deprecated
*/
public MISession(MIProcess process, IMITTY tty, int commandTimeout, int type, int launchTimeout) throws MIException {
this(process, tty, type, commandTimeout, launchTimeout, MIVersion.MI1, new NullProgressMonitor());
@ -130,6 +132,7 @@ public class MISession extends Observable {
* @param Process gdb Process.
* @param pty Terminal to use for the inferior.
* @param timeout time in milliseconds to wait for command response.
* @deprecated
*/
public MISession(MIProcess process, IMITTY tty, int type, CommandFactory commandFactory, int commandTimeout, int launchTimeout, IProgressMonitor monitor) throws MIException {
gdbProcess = process;
@ -157,6 +160,101 @@ public class MISession extends Observable {
setup(launchTimeout, new NullProgressMonitor());
}
/**
* Constructor for MISession. Creates MI wrapper for the given gdb process.
*
* @param type the type of debugging session: <code>PROGRAM</code>, <code>ATTACH</code> or <code>CORE</code>
* @param commandFactory the set of gdb/mi commands supported by given gdb
* @param Process a gdb process
* @param pty terminal to use for the inferior.
* @param timeout time in milliseconds to wait for command response.
*
* @since 3.1
*/
public MISession(MIProcess process, IMITTY tty, int type, CommandFactory commandFactory, int commandTimeout) throws MIException {
gdbProcess = process;
inChannel = process.getInputStream();
outChannel = process.getOutputStream();
factory = commandFactory;
cmdTimeout = commandTimeout;
sessionType = type;
parser = new MIParser();
inferior = new MIInferior(this, tty);
txQueue = new CommandQueue();
rxQueue = new CommandQueue();
eventQueue = new Queue();
txThread = new TxThread(this);
rxThread = new RxThread(this);
eventThread = new EventThread(this);
setup();
txThread.start();
rxThread.start();
eventThread.start();
}
/**
* No need to pass a progress monitor and a launch timeout.
* @since 3.1
*/
protected void setup() throws MIException {
// The Process may have terminated earlier because
// of bad arguments etc .. check this here and bail out.
try {
gdbProcess.exitValue();
InputStream err = gdbProcess.getErrorStream();
BufferedReader reader = new BufferedReader(new InputStreamReader(err));
String line = null;
try {
line = reader.readLine();
reader.close();
} catch (Exception e) {
// the reader may throw a NPE.
}
if (line == null) {
line = MIPlugin.getResourceString("src.MISession.Process_Terminated"); //$NON-NLS-1$
}
throw new MIException(line);
} catch (IllegalThreadStateException e) {
// Ok, it means the process is alive.
}
}
/**
* Initializes the gdb session.
* @since 3.1
*/
public void start() throws MIException {
try {
initialize();
} catch (MIException exc) {
// Kill the Transmition thread.
if (txThread.isAlive()) {
txThread.interrupt();
}
// Kill the Receiving Thread.
if (rxThread.isAlive()) {
rxThread.interrupt();
}
// Kill the event Thread.
if (eventThread.isAlive()) {
eventThread.interrupt();
}
// rethrow up the exception.
throw exc;
}
}
/**
* @deprecated use <code>setup()</code> without parameters
*/
protected void setup(int launchTimeout, IProgressMonitor monitor) throws MIException {
// The Process may have terminated earlier because
// of bad arguments etc .. check this here and bail out.
@ -211,6 +309,37 @@ public class MISession extends Observable {
}
}
/**
* Turns off the "confirm" option of gdb.
* Sets witdth and height of gdb session to 0.
* @since 3.1
*/
protected void initialize() throws MIException {
// Disable a certain number of irritations from gdb.
// Like confirmation and screen size.
MIGDBSet confirm = getCommandFactory().createMIGDBSet(new String[]{"confirm", "off"}); //$NON-NLS-1$ //$NON-NLS-2$
postCommand(confirm);
confirm.getMIInfo();
MIGDBSet width = getCommandFactory().createMIGDBSet(new String[]{"width", "0"}); //$NON-NLS-1$ //$NON-NLS-2$
postCommand(width);
width.getMIInfo();
MIGDBSet height = getCommandFactory().createMIGDBSet(new String[]{"height", "0"}); //$NON-NLS-1$ //$NON-NLS-2$
postCommand(height);
height.getMIInfo();
useInterpreterExecConsole = canUseInterpreterExecConsole();
String prompt = getCLIPrompt();
if (prompt != null) {
getMIParser().cliPrompt = prompt;
}
}
/**
* @deprecated use <code>initialize()</code> without parameters
*/
protected void initialize(int launchTimeout, IProgressMonitor monitor) throws MIException {
// Disable a certain number of irritations from gdb.
// Like confirmation and screen size.

View file

@ -11,6 +11,6 @@
pluginName=C/C++ Development Tools GDB/MI CDI Debugger Core
providerName=Eclipse.org
GDBDebugger.name=GDB Debugger
CygwinGDBDebugger.name=Cygwin GDB Debugger
GDBServer.name=GDB Server
GDBDebugger.name=gdb Debugger
CygwinGDBDebugger.name=Cygwin gdb Debugger
GDBServer.name=gdbserver Debugger

View file

@ -9,7 +9,7 @@
name="%GDBDebugger.name"
modes="run,core,attach"
cpu="native"
class="org.eclipse.cdt.debug.mi.core.GDBCDIDebugger"
class="org.eclipse.cdt.debug.mi.core.GDBCDIDebugger2"
id="org.eclipse.cdt.debug.mi.core.CDebugger">
</debugger>
<debugger
@ -17,7 +17,7 @@
name="%CygwinGDBDebugger.name"
modes="run,core,attach"
cpu="native"
class="org.eclipse.cdt.debug.mi.core.CygwinGDBCDIDebugger"
class="org.eclipse.cdt.debug.mi.core.CygwinGDBCDIDebugger2"
id="org.eclipse.cdt.debug.mi.core.CygwinCDebugger">
</debugger>
<debugger
@ -25,7 +25,7 @@
name="%GDBServer.name"
modes="run"
cpu="*"
class="org.eclipse.cdt.debug.mi.core.GDBServerCDIDebugger"
class="org.eclipse.cdt.debug.mi.core.GDBServerCDIDebugger2"
id="org.eclipse.cdt.debug.mi.core.GDBServerCDebugger">
</debugger>
</extension>

View file

@ -0,0 +1,175 @@
/*******************************************************************************
* Copyright (c) 2004 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.cdt.debug.mi.core;
import java.io.File;
import java.text.DateFormat;
import java.text.MessageFormat;
import java.util.Date;
import org.eclipse.cdt.core.IBinaryParser.IBinaryObject;
import org.eclipse.cdt.debug.core.ICDIDebugger2;
import org.eclipse.cdt.debug.core.ICDTLaunchConfigurationConstants;
import org.eclipse.cdt.debug.core.cdi.CDIException;
import org.eclipse.cdt.debug.core.cdi.ICDISession;
import org.eclipse.cdt.debug.core.cdi.model.ICDITarget;
import org.eclipse.cdt.debug.mi.core.cdi.Session;
import org.eclipse.cdt.debug.mi.core.cdi.model.Target;
import org.eclipse.cdt.debug.mi.core.command.CommandFactory;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.MultiStatus;
import org.eclipse.core.runtime.NullProgressMonitor;
import org.eclipse.core.runtime.OperationCanceledException;
import org.eclipse.core.runtime.Status;
import org.eclipse.debug.core.DebugPlugin;
import org.eclipse.debug.core.ILaunch;
import org.eclipse.debug.core.ILaunchConfiguration;
import org.eclipse.debug.core.model.IProcess;
/**
* Base class for the gdb/mi-based <code>ICDIDebugger</code> extension point
* implementations.
*/
abstract public class AbstractGDBCDIDebugger implements ICDIDebugger2 {
/* (non-Javadoc)
* @see org.eclipse.cdt.debug.core.ICDIDebugger#createDebuggerSession(org.eclipse.debug.core.ILaunch, org.eclipse.cdt.core.IBinaryParser.IBinaryObject, org.eclipse.core.runtime.IProgressMonitor)
*/
public ICDISession createDebuggerSession( ILaunch launch, IBinaryObject exe, IProgressMonitor monitor ) throws CoreException {
return createSession( launch, exe.getPath().toFile(), monitor );
}
/* (non-Javadoc)
* @see org.eclipse.cdt.debug.core.ICDIDebugger2#createSession(org.eclipse.debug.core.ILaunch, java.io.File, org.eclipse.core.runtime.IProgressMonitor)
*/
public ICDISession createSession( ILaunch launch, File executable, IProgressMonitor monitor ) throws CoreException {
boolean failed = false;
if ( monitor == null ) {
monitor = new NullProgressMonitor();
}
if ( monitor.isCanceled() ) {
throw new OperationCanceledException();
}
ILaunchConfiguration config = launch.getLaunchConfiguration();
Session session = createGDBSession( config, executable, monitor );
if ( session != null ) {
ICDITarget[] targets = session.getTargets();
for( int i = 0; i < targets.length; i++ ) {
Process debugger = session.getSessionProcess( targets[i] );
if ( debugger != null ) {
IProcess debuggerProcess = DebugPlugin.newProcess( launch, debugger, renderDebuggerProcessLabel( config ) );
launch.addProcess( debuggerProcess );
}
try {
((Target)targets[i]).getMISession().start();
}
catch( MIException e ) {
failed = true;
throw newCoreException( e );
}
}
}
try {
doStartSession( config, session, monitor );
}
catch( CoreException e ) {
failed = true;
throw e;
}
finally {
try {
if ( failed || monitor.isCanceled() )
session.terminate();
}
catch( CDIException e1 ) {
}
}
return session;
}
protected Session createGDBSession( ILaunchConfiguration config, File executable, IProgressMonitor monitor ) throws CoreException {
String gdb = config.getAttribute( IMILaunchConfigurationConstants.ATTR_DEBUG_NAME, "gdb" ); //$NON-NLS-1$
CommandFactory factory = getCommandFactory( config );
String[] extraArgs = getExtraArguments( config );
boolean usePty = config.getAttribute( ICDTLaunchConfigurationConstants.ATTR_USE_TERMINAL, true );
try {
return MIPlugin.getDefault().createSession( getSessionType( config ), gdb, factory, executable, extraArgs, usePty, monitor );
}
catch( Exception e ) {
// Catch all wrap them up and rethrow
if ( e instanceof CoreException ) {
throw (CoreException)e;
}
throw newCoreException( e );
}
}
protected int getSessionType( ILaunchConfiguration config ) throws CoreException {
String debugMode = config.getAttribute( ICDTLaunchConfigurationConstants.ATTR_DEBUGGER_START_MODE, ICDTLaunchConfigurationConstants.DEBUGGER_MODE_RUN );
if ( ICDTLaunchConfigurationConstants.DEBUGGER_MODE_RUN.equals( debugMode ) )
return MISession.PROGRAM;
if ( ICDTLaunchConfigurationConstants.DEBUGGER_MODE_ATTACH.equals( debugMode ) )
return MISession.ATTACH;
if ( ICDTLaunchConfigurationConstants.DEBUGGER_MODE_CORE.equals( debugMode ) )
return MISession.CORE;
throw newCoreException( MIPlugin.getResourceString( "src.AbstractGDBCDIDebugger.0" ) + debugMode, null ); //$NON-NLS-1$
}
abstract protected String[] getExtraArguments( ILaunchConfiguration config ) throws CoreException;
abstract protected CommandFactory getCommandFactory( ILaunchConfiguration config ) throws CoreException;
protected void doStartSession( ILaunchConfiguration config, Session session, IProgressMonitor monitor ) throws CoreException {
}
protected String renderDebuggerProcessLabel( ILaunchConfiguration config ) {
String format = "{0} ({1})"; //$NON-NLS-1$
String timestamp = DateFormat.getInstance().format( new Date( System.currentTimeMillis() ) );
String label = MIPlugin.getResourceString( "src.AbstractGDBCDIDebugger.0" ); //$NON-NLS-1$
try {
label = config.getAttribute( IMILaunchConfigurationConstants.ATTR_DEBUG_NAME, "gdb" ); //$NON-NLS-1$
}
catch( CoreException e ) {
}
return MessageFormat.format( format, new String[]{ label, timestamp } );
}
/**
* Throws a core exception with an error status object built from
* the lower level exception and error code.
*
* @param exception lower level exception associated with the error,
* or <code>null</code> if none
* @param code error code
*/
protected CoreException newCoreException( Throwable exception ) {
String message = MIPlugin.getResourceString( "src.AbstractGDBCDIDebugger.1" ); //$NON-NLS-1$
return newCoreException( message, exception );
}
/**
* Throws a core exception with an error status object built from the given
* message, lower level exception, and error code.
*
* @param message the status message
* @param exception lower level exception associated with the error,
* or <code>null</code> if none
* @param code error code
*/
protected CoreException newCoreException( String message, Throwable exception ) {
int code = ICDTLaunchConfigurationConstants.ERR_INTERNAL_ERROR;
String ID = MIPlugin.getUniqueIdentifier();
MultiStatus status = new MultiStatus( ID, code, message, exception );
status.add( new Status( IStatus.ERROR, ID, code, exception == null ? new String() : exception.getLocalizedMessage(), exception ) );
return new CoreException( status );
}
}

View file

@ -0,0 +1,62 @@
/*******************************************************************************
* Copyright (c) 2004 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.cdt.debug.mi.core;
import org.eclipse.cdt.debug.mi.core.cdi.Session;
import org.eclipse.cdt.debug.mi.core.command.CommandFactory;
import org.eclipse.cdt.debug.mi.core.command.MIGDBSet;
import org.eclipse.cdt.debug.mi.core.output.MIInfo;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.debug.core.ILaunchConfiguration;
/**
* Cygwin debugger extension point.
*/
public class CygwinGDBCDIDebugger2 extends GDBCDIDebugger2 {
/* (non-Javadoc)
* @see org.eclipse.cdt.debug.mi.core.GDBCDIDebugger2#getCommandFactory(org.eclipse.debug.core.ILaunchConfiguration)
*/
protected CommandFactory getCommandFactory( ILaunchConfiguration config ) throws CoreException {
return new CygwinCommandFactory( getMIVersion( config ) );
}
/* (non-Javadoc)
* @see org.eclipse.cdt.debug.mi.core.GDBCDIDebugger2#doStartSession(org.eclipse.debug.core.ILaunchConfiguration, org.eclipse.cdt.debug.mi.core.cdi.Session, org.eclipse.core.runtime.IProgressMonitor)
*/
protected void doStartSession( ILaunchConfiguration config, Session session, IProgressMonitor monitor ) throws CoreException {
// For windows we need to start the inferior in a new console window
// to separate the Inferior std{in,out,err} from gdb std{in,out,err}
MISession miSession = getMISession( session );
try {
CommandFactory factory = miSession.getCommandFactory();
MIGDBSet set = factory.createMIGDBSet( new String[]{ "new-console" } ); //$NON-NLS-1$
miSession.postCommand( set );
MIInfo info = set.getMIInfo();
if ( info == null ) {
throw new MIException( MIPlugin.getResourceString( "src.common.No_answer" ) ); //$NON-NLS-1$
}
}
catch( MIException e ) {
// We ignore this exception, for example
// on GNU/Linux the new-console is an error.
}
super.doStartSession( config, session, monitor );
}
/* (non-Javadoc)
* @see org.eclipse.cdt.debug.mi.core.GDBCDIDebugger2#initializeLibraries(org.eclipse.debug.core.ILaunchConfiguration, org.eclipse.cdt.debug.mi.core.cdi.Session)
*/
protected void initializeLibraries( ILaunchConfiguration config, Session session ) throws CoreException {
// the "search-solib-path" and "stop-on-solib-events" options are not supported in CygWin
}
}

View file

@ -0,0 +1,212 @@
/*******************************************************************************
* Copyright (c) 2004 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.cdt.debug.mi.core;
import java.io.File;
import java.text.MessageFormat;
import java.util.Collections;
import java.util.List;
import org.eclipse.cdt.debug.core.ICDTLaunchConfigurationConstants;
import org.eclipse.cdt.debug.core.cdi.CDIException;
import org.eclipse.cdt.debug.core.cdi.model.ICDITarget;
import org.eclipse.cdt.debug.mi.core.cdi.Session;
import org.eclipse.cdt.debug.mi.core.cdi.SharedLibraryManager;
import org.eclipse.cdt.debug.mi.core.cdi.model.Target;
import org.eclipse.cdt.debug.mi.core.command.CLITargetAttach;
import org.eclipse.cdt.debug.mi.core.command.CommandFactory;
import org.eclipse.cdt.debug.mi.core.output.MIInfo;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.OperationCanceledException;
import org.eclipse.core.runtime.Path;
import org.eclipse.debug.core.ILaunchConfiguration;
/**
* Implementing the cdebugger extension point for basic launch configurations.
*/
public class GDBCDIDebugger2 extends AbstractGDBCDIDebugger {
protected String[] getExtraArguments( ILaunchConfiguration config ) throws CoreException {
String debugMode = config.getAttribute( ICDTLaunchConfigurationConstants.ATTR_DEBUGGER_START_MODE, ICDTLaunchConfigurationConstants.DEBUGGER_MODE_RUN );
if ( ICDTLaunchConfigurationConstants.DEBUGGER_MODE_RUN.equals( debugMode ) )
return getRunArguments( config );
if ( ICDTLaunchConfigurationConstants.DEBUGGER_MODE_ATTACH.equals( debugMode ) )
return getAttachArguments( config );
if ( ICDTLaunchConfigurationConstants.DEBUGGER_MODE_CORE.equals( debugMode ) )
return getCoreArguments( config );
return new String[0];
}
protected String[] getRunArguments( ILaunchConfiguration config ) throws CoreException {
return new String[]{ getWorkingDirectory( config ), getCommandFile( config ) };
}
protected String[] getAttachArguments( ILaunchConfiguration config ) throws CoreException {
return new String[]{ getWorkingDirectory( config ), getCommandFile( config ) };
}
protected String[] getCoreArguments( ILaunchConfiguration config ) throws CoreException {
IPath coreFile = new Path( config.getAttribute( ICDTLaunchConfigurationConstants.ATTR_COREFILE_PATH, (String)null ) );
return new String[]{ getWorkingDirectory( config ), getCommandFile( config ), "-c", coreFile.toFile().getAbsolutePath() }; //$NON-NLS-1$
}
protected CommandFactory getCommandFactory( ILaunchConfiguration config ) throws CoreException {
return new CommandFactory( getMIVersion( config ) );
}
public static IPath getProjectPath( ILaunchConfiguration configuration ) throws CoreException {
String projectName = getProjectName( configuration );
if ( projectName != null ) {
projectName = projectName.trim();
if ( projectName.length() > 0 ) {
IProject project = ResourcesPlugin.getWorkspace().getRoot().getProject( projectName );
IPath p = project.getLocation();
if ( p != null ) {
return p;
}
}
}
return Path.EMPTY;
}
public static String getProjectName( ILaunchConfiguration configuration ) throws CoreException {
return configuration.getAttribute( ICDTLaunchConfigurationConstants.ATTR_PROJECT_NAME, (String)null );
}
protected String getMIVersion( ILaunchConfiguration config ) {
return MIPlugin.getMIVersion( config );
}
/* (non-Javadoc)
* @see org.eclipse.cdt.debug.mi.core.AbstractGDBCDIDebugger#doStartSession(org.eclipse.debug.core.ILaunchConfiguration, org.eclipse.cdt.debug.mi.core.cdi.Session, org.eclipse.core.runtime.IProgressMonitor)
*/
protected void doStartSession( ILaunchConfiguration config, Session session, IProgressMonitor monitor ) throws CoreException {
initializeLibraries( config, session );
if ( monitor.isCanceled() ) {
throw new OperationCanceledException();
}
String debugMode = config.getAttribute( ICDTLaunchConfigurationConstants.ATTR_DEBUGGER_START_MODE, ICDTLaunchConfigurationConstants.DEBUGGER_MODE_RUN );
if ( ICDTLaunchConfigurationConstants.DEBUGGER_MODE_RUN.equals( debugMode ) )
startLocalGDBSession( config, session, monitor );
if ( ICDTLaunchConfigurationConstants.DEBUGGER_MODE_ATTACH.equals( debugMode ) )
startAttachGDBSession( config, session, monitor );
if ( ICDTLaunchConfigurationConstants.DEBUGGER_MODE_CORE.equals( debugMode ) )
startCoreGDBSession( config, session, monitor );
}
protected void startLocalGDBSession( ILaunchConfiguration config, Session session, IProgressMonitor monitor ) throws CoreException {
}
protected void startAttachGDBSession( ILaunchConfiguration config, Session session, IProgressMonitor monitor ) throws CoreException {
MISession miSession = getMISession( session );
CommandFactory factory = miSession.getCommandFactory();
int pid = -1;
try {
pid = config.getAttribute( ICDTLaunchConfigurationConstants.ATTR_ATTACH_PROCESS_ID, -1 );
}
catch( CoreException e ) {
throw newCoreException( MIPlugin.getResourceString( "src.GDBCDIDebugger2.0" ), e ); //$NON-NLS-1$
}
if ( pid <= 0 ) {
throw newCoreException( MIPlugin.getResourceString( "src.GDBCDIDebugger2.1" ), null ); //$NON-NLS-1$
}
try {
CLITargetAttach attach = factory.createCLITargetAttach( pid );
miSession.postCommand( attach );
MIInfo info = attach.getMIInfo();
if ( info == null ) {
throw new MIException( MIPlugin.getResourceString( "src.common.No_answer" ) ); //$NON-NLS-1$
}
miSession.getMIInferior().setInferiorPID( pid );
// @@@ for attach we nee to manually set the connected state
// attach does not send the ^connected ack
miSession.getMIInferior().setConnected();
}
catch( MIException e ) {
throw newCoreException( MessageFormat.format( MIPlugin.getResourceString( "src.GDBCDIDebugger2.2" ), new Integer[] { Integer.valueOf( pid ) } ), e ); //$NON-NLS-1$
}
// @@@ We have to set the suspended state manually
miSession.getMIInferior().setSuspended();
miSession.getMIInferior().update();
}
protected void startCoreGDBSession( ILaunchConfiguration config, Session session, IProgressMonitor monitor ) throws CoreException {
getMISession( session ).getMIInferior().setSuspended();
try {
session.getSharedLibraryManager().update();
}
catch( CDIException e ) {
throw newCoreException( e );
}
}
protected MISession getMISession( Session session ) {
ICDITarget[] targets = session.getTargets();
if ( targets.length == 0 || !(targets[0] instanceof Target) )
return null;
return ((Target)targets[0]).getMISession();
}
protected void initializeLibraries( ILaunchConfiguration config, Session session ) throws CoreException {
try {
SharedLibraryManager sharedMgr = session.getSharedLibraryManager();
boolean autolib = config.getAttribute( IMILaunchConfigurationConstants.ATTR_DEBUGGER_AUTO_SOLIB, IMILaunchConfigurationConstants.DEBUGGER_AUTO_SOLIB_DEFAULT );
boolean stopOnSolibEvents = config.getAttribute( IMILaunchConfigurationConstants.ATTR_DEBUGGER_STOP_ON_SOLIB_EVENTS, IMILaunchConfigurationConstants.DEBUGGER_STOP_ON_SOLIB_EVENTS_DEFAULT );
List p = config.getAttribute( IMILaunchConfigurationConstants.ATTR_DEBUGGER_SOLIB_PATH, Collections.EMPTY_LIST );
ICDITarget[] dtargets = session.getTargets();
for( int i = 0; i < dtargets.length; ++i ) {
Target target = (Target)dtargets[i];
try {
sharedMgr.setAutoLoadSymbols( target, autolib );
sharedMgr.setStopOnSolibEvents( target, stopOnSolibEvents );
// The idea is that if the user set autolib, by default
// we provide with the capability of deferred breakpoints
// And we set setStopOnSolib events for them(but they should not see those things.
//
// If the user explicitly set stopOnSolibEvents well it probably
// means that they wanted to see those events so do no do deferred breakpoints.
if ( autolib && !stopOnSolibEvents ) {
sharedMgr.setDeferredBreakpoint( true );
sharedMgr.setStopOnSolibEvents( target, true );
}
}
catch( CDIException e ) {
// Ignore this error
// it seems to be a real problem on many gdb platform
}
if ( p.size() > 0 ) {
String[] oldPaths = sharedMgr.getSharedLibraryPaths( target );
String[] paths = new String[oldPaths.length + p.size()];
System.arraycopy( p.toArray( new String[p.size()] ), 0, paths, 0, p.size() );
System.arraycopy( oldPaths, 0, paths, p.size(), oldPaths.length );
sharedMgr.setSharedLibraryPaths( target, paths );
}
}
}
catch( CDIException e ) {
throw newCoreException( MIPlugin.getResourceString( "src.GDBDebugger.Error_initializing_shared_lib_options" ) + e.getMessage(), e ); //$NON-NLS-1$
}
}
private String getWorkingDirectory( ILaunchConfiguration config ) throws CoreException {
File cwd = getProjectPath( config ).toFile();
return "--cd=" + cwd.getAbsolutePath(); //$NON-NLS-1$
}
private String getCommandFile( ILaunchConfiguration config ) throws CoreException {
String gdbinit = config.getAttribute( IMILaunchConfigurationConstants.ATTR_GDB_INIT, IMILaunchConfigurationConstants.DEBUGGER_GDB_INIT_DEFAULT );
return (gdbinit != null && gdbinit.length() > 0) ? "--command=" + gdbinit : "--nx"; //$NON-NLS-1$ //$NON-NLS-2$
}
}

View file

@ -0,0 +1,122 @@
/*******************************************************************************
* Copyright (c) 2004 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.cdt.debug.mi.core;
import org.eclipse.cdt.debug.core.ICDTLaunchConfigurationConstants;
import org.eclipse.cdt.debug.core.cdi.model.ICDITarget;
import org.eclipse.cdt.debug.mi.core.cdi.Session;
import org.eclipse.cdt.debug.mi.core.cdi.model.Target;
import org.eclipse.cdt.debug.mi.core.command.CommandFactory;
import org.eclipse.cdt.debug.mi.core.command.MIGDBSet;
import org.eclipse.cdt.debug.mi.core.command.MITargetSelect;
import org.eclipse.cdt.debug.mi.core.output.MIInfo;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.OperationCanceledException;
import org.eclipse.debug.core.ILaunchConfiguration;
/**
* Implementing the cdebugger extension point for gdbserver.
*/
public class GDBServerCDIDebugger2 extends GDBCDIDebugger2 {
/* (non-Javadoc)
* @see org.eclipse.cdt.debug.mi.core.GDBCDIDebugger2#doStartSession(org.eclipse.debug.core.ILaunchConfiguration, org.eclipse.cdt.debug.mi.core.cdi.Session, org.eclipse.core.runtime.IProgressMonitor)
*/
protected void doStartSession( ILaunchConfiguration config, Session session, IProgressMonitor monitor ) throws CoreException {
initializeLibraries( config, session );
if ( monitor.isCanceled() ) {
throw new OperationCanceledException();
}
String debugMode = config.getAttribute( ICDTLaunchConfigurationConstants.ATTR_DEBUGGER_START_MODE, ICDTLaunchConfigurationConstants.DEBUGGER_MODE_RUN );
if ( ICDTLaunchConfigurationConstants.DEBUGGER_MODE_RUN.equals( debugMode ) )
startGDBServerSession( config, session, monitor );
if ( ICDTLaunchConfigurationConstants.DEBUGGER_MODE_ATTACH.equals( debugMode ) ) {
String msg = MIPlugin.getResourceString( "src.GDBServerDebugger.GDBServer_attaching_unsupported" ); //$NON-NLS-1$
throw newCoreException( msg, null );
}
if ( ICDTLaunchConfigurationConstants.DEBUGGER_MODE_CORE.equals( debugMode ) ) {
String msg = MIPlugin.getResourceString( "src.GDBServerDebugger.GDBServer_corefiles_unsupported" ); //$NON-NLS-1$
throw newCoreException( msg, null );
}
}
protected void startGDBServerSession( ILaunchConfiguration config, Session session, IProgressMonitor monitor ) throws CoreException {
if ( monitor.isCanceled() ) {
throw new OperationCanceledException();
}
ICDITarget[] targets = session.getTargets();
int launchTimeout = MIPlugin.getLaunchTimeout();
boolean tcpConnection = config.getAttribute( IGDBServerMILaunchConfigurationConstants.ATTR_REMOTE_TCP, false );
// Set serial line parameters
if ( !tcpConnection ) {
String remoteBaud = config.getAttribute( IGDBServerMILaunchConfigurationConstants.ATTR_DEV_SPEED, "invalid" ); //$NON-NLS-1$
for( int i = 0; i < targets.length; ++i ) {
if ( monitor.isCanceled() ) {
throw new OperationCanceledException();
}
Target target = (Target)targets[i];
MISession miSession = target.getMISession();
CommandFactory factory = miSession.getCommandFactory();
MIGDBSet setRemoteBaud = factory.createMIGDBSet( new String[]{ "remotebaud", remoteBaud } ); //$NON-NLS-1$
// Set serial line parameters
MIInfo info = null;
MIException ex = null;
try {
// shouldn't we use the command timeout instead?
miSession.postCommand( setRemoteBaud, launchTimeout );
info = setRemoteBaud.getMIInfo();
}
catch( MIException e ) {
ex = e;
}
if ( info == null ) {
throw newCoreException( MIPlugin.getResourceString( "src.GDBServerDebugger.Can_not_set_Baud" ), ex ); //$NON-NLS-1$
}
}
}
for( int i = 0; i < targets.length; ++i ) {
if ( monitor.isCanceled() ) {
throw new OperationCanceledException();
}
Target target = (Target)targets[i];
MISession miSession = target.getMISession();
CommandFactory factory = miSession.getCommandFactory();
String[] targetParams = getTargetParams( config, tcpConnection );
MITargetSelect select = factory.createMITargetSelect( targetParams );
MIInfo info = null;
MIException ex = null;
try {
miSession.postCommand( select, launchTimeout );
info = select.getMIInfo();
}
catch( MIException e ) {
ex = e;
}
if ( info == null ) {
throw newCoreException( MIPlugin.getResourceString( "src.GDBServerCDIDebugger.target_selection_failed" ), ex ); //$NON-NLS-1$
}
}
}
protected String[] getTargetParams( ILaunchConfiguration config, boolean tcpConnection ) throws CoreException {
String remote = null;
if ( tcpConnection ) {
remote = config.getAttribute( IGDBServerMILaunchConfigurationConstants.ATTR_HOST, "invalid" ); //$NON-NLS-1$
remote += ":"; //$NON-NLS-1$
remote += config.getAttribute( IGDBServerMILaunchConfigurationConstants.ATTR_PORT, "invalid" ); //$NON-NLS-1$
}
else {
remote = config.getAttribute( IGDBServerMILaunchConfigurationConstants.ATTR_DEV, "invalid" ); //$NON-NLS-1$
}
return new String[]{ "remote", remote }; //$NON-NLS-1$
}
}

View file

@ -15,9 +15,10 @@ import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.text.MessageFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.MissingResourceException;
import java.util.ResourceBundle;
import org.eclipse.cdt.debug.core.ICDTLaunchConfigurationConstants;
import org.eclipse.cdt.debug.mi.core.cdi.Session;
import org.eclipse.cdt.debug.mi.core.command.CLITargetAttach;
@ -83,6 +84,8 @@ public class MIPlugin extends Plugin {
* @param int
* @throws MIException
* @return MISession
*
* @deprecated
*/
public MISession createMISession(MIProcess process, IMITTY pty, int timeout, int type, int launchTimeout, String miVersion, IProgressMonitor monitor) throws MIException {
return new MISession(process, pty, type, timeout, launchTimeout, miVersion, monitor);
@ -95,6 +98,8 @@ public class MIPlugin extends Plugin {
* @param type
* @throws MIException
* @return MISession
*
* @deprecated
*/
public MISession createMISession(MIProcess process, IMITTY pty, int type, String miVersion, IProgressMonitor monitor) throws MIException {
MIPlugin miPlugin = getDefault();
@ -104,12 +109,18 @@ public class MIPlugin extends Plugin {
return createMISession(process, pty, timeout, type, launchTimeout, miVersion, monitor);
}
private MISession createMISession0(int type, MIProcess process, CommandFactory commandFactory, IMITTY pty, int timeout) throws MIException {
return new MISession(process, pty, type, commandFactory, timeout);
}
/**
* Method createCSession; Create an new PTY instance and launch gdb in mi for local debug.
*
* @param program
* @return ICDISession
* @throws MIException
*
* @deprecated use <code>createSession</code>
*/
public Session createCSession(String gdb, String miVersion, File program, File cwd, String gdbinit, IProgressMonitor monitor) throws IOException, MIException {
IMITTY pty = null;
@ -155,6 +166,8 @@ public class MIPlugin extends Plugin {
* @param program
* @return ICDISession
* @throws IOException
*
* @deprecated use <code>createSession</code>
*/
public Session createCSession(String gdb, String miVersion, File program, File cwd, String gdbinit, IMITTY pty, IProgressMonitor monitor) throws IOException, MIException {
if (gdb == null || gdb.length() == 0) {
@ -228,6 +241,8 @@ public class MIPlugin extends Plugin {
* @param core
* @return ICDISession
* @throws IOException
*
* @deprecated use <code>createSession</code>
*/
public Session createCSession(String gdb, String miVersion, File program, File core, File cwd, String gdbinit, IProgressMonitor monitor) throws IOException, MIException {
if (gdb == null || gdb.length() == 0) {
@ -277,6 +292,8 @@ public class MIPlugin extends Plugin {
* @param pid
* @return ICDISession
* @throws IOException
*
* @deprecated use <code>createSession</code>
*/
public Session createCSession(String gdb, String miVersion, File program, int pid, String[] targetParams, File cwd, String gdbinit, IProgressMonitor monitor) throws IOException, MIException {
if (gdb == null || gdb.length() == 0) {
@ -347,6 +364,84 @@ public class MIPlugin extends Plugin {
return new Session(session, true);
}
/**
* Starts a process by executing the following command:
* gdb -q -nw -i <mi_version>(extracted from the command factory)
* -tty<pty_name> (if <code>usePTY</code> is <code>true</code>)
* extraArgs program (if <code>program</code> is not <code>null</code>)
*
* @param sessionType the type of debugging session:
* <code>MISession.PROGRAM</code>,
* <code>MISession.ATTACH</code>
* or <code>MISession.CORE</code>
* @param gdb the name of the gdb file
* @param factory the command set supported by gdb
* @param program a program to debug or <code>null</code>
* @param extraArgs arguments to pass to gdb
* @param usePty whether to use pty or not
* @param monitor a progress monitor
* @return an instance of <code>ICDISession</code>
* @throws IOException
* @throws MIException
*/
public Session createSession(int sessionType, String gdb, CommandFactory factory, File program, String[] extraArgs, boolean usePty, IProgressMonitor monitor) throws IOException, MIException {
if (monitor == null) {
monitor = new NullProgressMonitor();
}
if (gdb == null || gdb.length() == 0) {
gdb = GDB;
}
IMITTY pty = null;
if (usePty) {
try {
PTY pseudo = new PTY();
pty = new MITTYAdapter(pseudo);
} catch (IOException e) {
// Should we not print/log this ?
}
}
ArrayList argList = new ArrayList(extraArgs.length + 8);
argList.add(gdb);
argList.add("-q"); //$NON-NLS-1$
argList.add("-nw"); //$NON-NLS-1$
argList.add("-i"); //$NON-NLS-1$
argList.add(factory.getMIVersion());
if (pty != null) {
argList.add("-tty"); //$NON-NLS-1$
argList.add(pty.getSlaveName());
}
argList.addAll(Arrays.asList(extraArgs));
if (program != null) {
argList.add(program.getAbsolutePath());
}
String[] args = (String[])argList.toArray(new String[argList.size()]);
int launchTimeout = MIPlugin.getDefault().getPluginPreferences().getInt(IMIConstants.PREF_REQUEST_LAUNCH_TIMEOUT);
MIProcess pgdb = new MIProcessAdapter(args, launchTimeout, monitor);
if (MIPlugin.getDefault().isDebugging()) {
StringBuffer sb = new StringBuffer();
for (int i = 0; i < args.length; ++i) {
sb.append(args[i]);
sb.append(' ');
}
MIPlugin.getDefault().debugLog(sb.toString());
}
MISession miSession;
try {
miSession = createMISession0(sessionType, pgdb, factory, pty, getCommandTimeout());
} catch (MIException e) {
pgdb.destroy();
throw e;
}
return new Session(miSession);
}
/**
* Convenience method which returns the unique identifier of this plugin.
*/
@ -407,6 +502,16 @@ public class MIPlugin extends Plugin {
super.stop(context);
}
public static int getCommandTimeout() {
Preferences prefs = getDefault().getPluginPreferences();
return prefs.getInt(IMIConstants.PREF_REQUEST_TIMEOUT);
}
public static int getLaunchTimeout() {
Preferences prefs = plugin.getPluginPreferences();
return prefs.getInt(IMIConstants.PREF_REQUEST_LAUNCH_TIMEOUT);
}
public static String getMIVersion( ILaunchConfiguration config ) {
String miVersion = ""; //$NON-NLS-1$
try {

View file

@ -10,10 +10,14 @@
###############################################################################
src.common.No_answer=No answer
src.GDBCDIDebugger2.0=Unable to get pid.
src.GDBCDIDebugger2.1=Invalid pid.
src.GDBCDIDebugger2.2=Attach to process {0} failed.
src.GDBServerDebugger.Error_initializing=Error initializing:
src.GDBServerDebugger.Can_not_set_Baud=Can not set Baud
src.GDBServerDebugger.GDBServer_attaching_unsupported=GDBServer does not support attaching
src.GDBServerDebugger.GDBServer_corefiles_unsupported=GDBServer does not support core files
src.GDBServerCDIDebugger.target_selection_failed=Target selection failed.
src.GDBDebugger.Error_initializing_shared_lib_options=Error initializing shared library options:
src.GDBDebugger.Error_creating_session=Error creating session:
src.GDBDebugger.Error_launch_timeout=Launch timeout
@ -29,3 +33,6 @@ src.MIInferior.target_is_suspended=target is suspended
src.MIInferior.No_session=No MI Session
src.MIInferior.Failed_to_interrupt=Failed to interrupt
src.AbstractGDBCDIDebugger.0=Invalid session type:
src.AbstractGDBCDIDebugger.0=Debugger Process
src.AbstractGDBCDIDebugger.1=Error creating session

View file

@ -1,3 +1,9 @@
2006-01-23 Mikhail Khodjaiants
Bug 119683: long messages during launch cause gdb to timeout, launch to fail.
+ LocalCDILaunchDelegate.java
* LaunchMessages.properties
* plugin.xml
2006-01-06 Mikhail Khodjaiants
Bug 120509: CDebuggerTab invokes wong initialization code (in addition to right code).
* CDebuggerTab.java

View file

@ -6,7 +6,7 @@
point="org.eclipse.debug.core.launchConfigurationTypes">
<launchConfigurationType
sourceLocatorId="org.eclipse.cdt.debug.core.sourceLocator"
delegate="org.eclipse.cdt.launch.internal.LocalRunLaunchDelegate"
delegate="org.eclipse.cdt.launch.internal.LocalCDILaunchDelegate"
public="true"
sourcePathComputerId="org.eclipse.cdt.debug.core.sourcePathComputer"
name="%LocalCDTLaunch.name"
@ -14,7 +14,7 @@
modes="run,debug">
</launchConfigurationType>
<launchConfigurationType
delegate="org.eclipse.cdt.launch.internal.LocalAttachLaunchDelegate"
delegate="org.eclipse.cdt.launch.internal.LocalCDILaunchDelegate"
id="org.eclipse.cdt.launch.localAttachCLaunch"
modes="debug"
name="%LocalAttachCDTLaunch.name"
@ -23,7 +23,7 @@
sourcePathComputerId="org.eclipse.cdt.debug.core.sourcePathComputer">
</launchConfigurationType>
<launchConfigurationType
delegate="org.eclipse.cdt.launch.internal.CoreFileLaunchDelegate"
delegate="org.eclipse.cdt.launch.internal.LocalCDILaunchDelegate"
id="org.eclipse.cdt.launch.coreFileCLaunch"
modes="debug"
name="%CoreFileCDTLaunch.name"

View file

@ -0,0 +1,440 @@
/*******************************************************************************
* Copyright (c) 2004 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.cdt.launch.internal;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import org.eclipse.cdt.core.IBinaryParser.IBinaryObject;
import org.eclipse.cdt.core.model.ICProject;
import org.eclipse.cdt.debug.core.CDIDebugModel;
import org.eclipse.cdt.debug.core.ICDIDebugger;
import org.eclipse.cdt.debug.core.ICDIDebugger2;
import org.eclipse.cdt.debug.core.ICDTLaunchConfigurationConstants;
import org.eclipse.cdt.debug.core.ICDebugConfiguration;
import org.eclipse.cdt.debug.core.cdi.CDIException;
import org.eclipse.cdt.debug.core.cdi.ICDISession;
import org.eclipse.cdt.debug.core.cdi.model.ICDIRuntimeOptions;
import org.eclipse.cdt.debug.core.cdi.model.ICDITarget;
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.resources.IProject;
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.core.runtime.SubProgressMonitor;
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.IProcess;
/**
* The launch configuration delegate for the CDI debugger session types.
*/
public class LocalCDILaunchDelegate extends AbstractCLaunchDelegate {
/* (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)
*/
public void launch( ILaunchConfiguration config, String mode, ILaunch launch, IProgressMonitor monitor ) throws CoreException {
if ( monitor == null ) {
monitor = new NullProgressMonitor();
}
if ( mode.equals( ILaunchManager.RUN_MODE ) ) {
runLocalApplication( config, launch, monitor );
}
if ( mode.equals( ILaunchManager.DEBUG_MODE ) ) {
launchDebugger( config, launch, monitor );
}
}
private void runLocalApplication( ILaunchConfiguration config, ILaunch launch, IProgressMonitor monitor ) throws CoreException {
monitor.beginTask( LaunchMessages.getString( "LocalCDILaunchDelegate.0" ), 10 ); //$NON-NLS-1$
if ( monitor.isCanceled() ) {
return;
}
monitor.worked( 1 );
try {
IPath exePath = verifyProgramPath( config );
File wd = getWorkingDirectory( config );
if ( wd == null ) {
wd = new File( System.getProperty( "user.home", "." ) ); //$NON-NLS-1$ //$NON-NLS-2$
}
String arguments[] = getProgramArgumentsArray( config );
ArrayList command = new ArrayList( 1 + arguments.length );
command.add( exePath.toOSString() );
command.addAll( Arrays.asList( arguments ) );
String[] commandArray = (String[])command.toArray( new String[command.size()] );
boolean usePty = config.getAttribute( ICDTLaunchConfigurationConstants.ATTR_USE_TERMINAL, ICDTLaunchConfigurationConstants.USE_TERMINAL_DEFAULT );
monitor.worked( 2 );
Process process = exec( commandArray, getEnvironment( config ), wd, usePty );
monitor.worked( 6 );
DebugPlugin.newProcess( launch, process, renderProcessLabel( commandArray[0] ) );
}
finally {
monitor.done();
}
}
private void launchDebugger( ILaunchConfiguration config, ILaunch launch, IProgressMonitor monitor ) throws CoreException {
monitor.beginTask( LaunchMessages.getString( "LocalCDILaunchDelegate.1" ), 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 );
}
if ( debugMode.equals( ICDTLaunchConfigurationConstants.DEBUGGER_MODE_ATTACH ) ) {
launchAttachDebugSession( config, launch, monitor );
}
if ( debugMode.equals( ICDTLaunchConfigurationConstants.DEBUGGER_MODE_CORE ) ) {
launchCoreDebugSession( config, launch, monitor );
}
}
finally {
monitor.done();
}
}
private void launchLocalDebugSession( ILaunchConfiguration config, ILaunch launch, IProgressMonitor monitor ) throws CoreException {
if ( monitor.isCanceled() ) {
return;
}
monitor.subTask( LaunchMessages.getString( "LocalCDILaunchDelegate.2" ) ); //$NON-NLS-1$
ICDISession dsession = null;
try {
IPath exePath = verifyProgramPath( config );
ICProject project = verifyCProject( config );
IBinaryObject exeFile = null;
if ( exePath != null ) {
exeFile = verifyBinary( project, exePath );
}
ICDebugConfiguration debugConfig = getDebugConfig( config );
setDefaultSourceLocator( launch, config );
dsession = createCDISession( config, launch, debugConfig, monitor );
monitor.worked( 6 );
setRuntimeOptions( config, dsession );
monitor.worked( 1 );
boolean stopInMain = config.getAttribute( ICDTLaunchConfigurationConstants.ATTR_DEBUGGER_STOP_AT_MAIN, false );
ICDITarget[] targets = dsession.getTargets();
for( int i = 0; i < targets.length; i++ ) {
Process process = targets[i].getProcess();
IProcess iprocess = null;
if ( process != null ) {
iprocess = DebugPlugin.newProcess( launch, process, renderProcessLabel( exePath.toOSString() ), getDefaultProcessMap() );
}
CDIDebugModel.newDebugTarget( launch, project.getProject(), targets[i], renderTargetLabel( debugConfig ), iprocess, exeFile, true, false, stopInMain, true );
}
}
catch( CoreException e ) {
try {
if ( dsession != null )
dsession.terminate();
}
catch( CDIException e1 ) {
// ignore
}
throw e;
}
finally {
monitor.done();
}
}
private void launchAttachDebugSession( ILaunchConfiguration config, ILaunch launch, IProgressMonitor monitor ) throws CoreException {
if ( monitor.isCanceled() ) {
return;
}
monitor.subTask( LaunchMessages.getString( "LocalCDILaunchDelegate.3" ) ); //$NON-NLS-1$
ILaunchConfigurationWorkingCopy wc = null;
int pid = config.getAttribute( ICDTLaunchConfigurationConstants.ATTR_ATTACH_PROCESS_ID, -1 );
if ( pid == -1 ) {
pid = promptForProcessID( config );
if ( pid == -1 ) {
cancel( LaunchMessages.getString( "LocalCDILaunchDelegate.4" ), ICDTLaunchConfigurationConstants.ERR_NO_PROCESSID ); //$NON-NLS-1$
}
wc = config.getWorkingCopy();
wc.setAttribute( ICDTLaunchConfigurationConstants.ATTR_ATTACH_PROCESS_ID, pid );
wc.launch( ILaunchManager.DEBUG_MODE, new SubProgressMonitor( monitor, 9 ) );
// We need to reset the process id because the working copy will be saved
// when the target is terminated
wc.setAttribute( ICDTLaunchConfigurationConstants.ATTR_ATTACH_PROCESS_ID, (String)null );
cancel( "", -1 ); //$NON-NLS-1$
}
IPath exePath = verifyProgramPath( config );
ICProject project = verifyCProject( config );
IBinaryObject exeFile = null;
if ( exePath != null ) {
exeFile = verifyBinary( project, exePath );
}
ICDebugConfiguration debugConfig = getDebugConfig( config );
setDefaultSourceLocator( launch, config );
ICDISession dsession = createCDISession( config, launch,debugConfig, monitor );
monitor.worked( 7 );
try {
ICDITarget[] targets = dsession.getTargets();
for( int i = 0; i < targets.length; i++ ) {
Process process = targets[i].getProcess();
IProcess iprocess = null;
if ( process != null ) {
iprocess = DebugPlugin.newProcess( launch, process, renderProcessLabel( exePath.toOSString() ), getDefaultProcessMap() );
}
CDIDebugModel.newDebugTarget( launch, project.getProject(), targets[i], renderTargetLabel( debugConfig ), iprocess, exeFile, true, true, false );
}
}
catch( CoreException e ) {
try {
dsession.terminate();
}
catch( CDIException e1 ) {
// ignore
}
throw e;
}
finally {
if ( wc != null )
wc.setAttribute( ICDTLaunchConfigurationConstants.ATTR_ATTACH_PROCESS_ID, (String)null );
monitor.done();
}
}
private void launchCoreDebugSession( ILaunchConfiguration config, ILaunch launch, IProgressMonitor monitor ) throws CoreException {
if ( monitor.isCanceled() ) {
return;
}
monitor.beginTask( LaunchMessages.getString( "LocalCDILaunchDelegate.5" ), 10 ); //$NON-NLS-1$
ICDISession dsession = null;
ILaunchConfigurationWorkingCopy wc = null;
ICDebugConfiguration debugConfig = getDebugConfig( config );
String path = config.getAttribute( ICDTLaunchConfigurationConstants.ATTR_COREFILE_PATH, (String)null );
if ( path == null ) {
ICProject project = verifyCProject( config );
IPath corefile = promptForCoreFilePath( (IProject)project.getResource(), debugConfig );
if ( corefile == null ) {
cancel( LaunchMessages.getString( "LocalCDILaunchDelegate.6" ), ICDTLaunchConfigurationConstants.ERR_NO_COREFILE ); //$NON-NLS-1$
}
File file = new File( corefile.toString() );
if ( !file.exists() || !file.canRead() ) {
cancel( LaunchMessages.getString( "LocalCDILaunchDelegate.7" ), ICDTLaunchConfigurationConstants.ERR_NO_COREFILE ); //$NON-NLS-1$
}
wc = config.getWorkingCopy();
wc.setAttribute( ICDTLaunchConfigurationConstants.ATTR_COREFILE_PATH, corefile.toString() );
wc.launch( ILaunchManager.DEBUG_MODE, new SubProgressMonitor( monitor, 9 ) );
wc.setAttribute( ICDTLaunchConfigurationConstants.ATTR_COREFILE_PATH, (String)null );
cancel( "", -1 ); //$NON-NLS-1$
}
IPath exePath = verifyProgramPath( config );
ICProject project = verifyCProject( config );
IBinaryObject exeFile = null;
if ( exePath != null ) {
exeFile = verifyBinary( project, exePath );
}
setDefaultSourceLocator( launch, config );
dsession = createCDISession( config, launch, debugConfig, monitor );
monitor.worked( 7 );
try {
ICDITarget[] targets = dsession.getTargets();
for( int i = 0; i < targets.length; i++ ) {
Process process = targets[i].getProcess();
IProcess iprocess = null;
if ( process != null ) {
iprocess = DebugPlugin.newProcess( launch, process, renderProcessLabel( exePath.toOSString() ), getDefaultProcessMap() );
}
CDIDebugModel.newDebugTarget( launch, project.getProject(), targets[i], renderTargetLabel( debugConfig ), iprocess, exeFile, true, false, false );
}
}
catch( CoreException e ) {
try {
if ( dsession != null )
dsession.terminate();
}
catch( CDIException e1 ) {
// ignore
}
throw e;
}
finally {
if ( wc != null )
wc.setAttribute( ICDTLaunchConfigurationConstants.ATTR_COREFILE_PATH, (String)null );
monitor.done();
}
}
private ICDISession launchOldDebugSession( ILaunchConfiguration config, ILaunch launch, ICDIDebugger debugger, IProgressMonitor monitor ) throws CoreException {
IBinaryObject exeFile = null;
IPath exePath = verifyProgramPath( config );
ICProject project = verifyCProject( config );
if ( exePath != null ) {
exeFile = verifyBinary( project, exePath );
}
return debugger.createDebuggerSession( launch, exeFile, monitor );
}
private ICDISession launchDebugSession( ILaunchConfiguration config, ILaunch launch, ICDIDebugger2 debugger, IProgressMonitor monitor ) throws CoreException {
IPath path = verifyProgramPath( config );
return debugger.createSession( launch, path.toFile(), monitor );
}
/* (non-Javadoc)
* @see org.eclipse.cdt.launch.AbstractCLaunchDelegate#getPluginID()
*/
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( LaunchMessages.getString( "LocalCDILaunchDelegate.8" ), 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( "LocalCDILaunchDelegate.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;
}
protected int promptForProcessID( ILaunchConfiguration config ) throws CoreException {
IStatus fPromptStatus = new Status( IStatus.INFO, "org.eclipse.debug.ui", 200, "", null ); //$NON-NLS-1$//$NON-NLS-2$
IStatus processPrompt = new Status( IStatus.INFO, "org.eclipse.cdt.launch", 100, "", null ); //$NON-NLS-1$//$NON-NLS-2$
// consult a status handler
IStatusHandler prompter = DebugPlugin.getDefault().getStatusHandler( fPromptStatus );
if ( prompter != null ) {
Object result = prompter.handleStatus( processPrompt, config );
if ( result instanceof Integer ) {
return ((Integer)result).intValue();
}
}
return -1;
}
protected IPath promptForCoreFilePath( final IProject project, final ICDebugConfiguration debugConfig ) throws CoreException {
IStatus fPromptStatus = new Status( IStatus.INFO, "org.eclipse.debug.ui", 200, "", null ); //$NON-NLS-1$//$NON-NLS-2$
IStatus processPrompt = new Status( IStatus.INFO, "org.eclipse.cdt.launch", 101, "", null ); //$NON-NLS-1$//$NON-NLS-2$
// consult a status handler
IStatusHandler prompter = DebugPlugin.getDefault().getStatusHandler( fPromptStatus );
if ( prompter != null ) {
Object result = prompter.handleStatus( processPrompt, new Object[]{ project, debugConfig } );
if ( result instanceof IPath ) {
return (IPath)result;
}
}
return null;
}
/* (non-Javadoc)
* @see org.eclipse.cdt.launch.AbstractCLaunchDelegate#preLaunchCheck(org.eclipse.debug.core.ILaunchConfiguration, java.lang.String, org.eclipse.core.runtime.IProgressMonitor)
*/
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 );
}
private void setRuntimeOptions( ILaunchConfiguration config, ICDISession session ) throws CoreException {
String arguments[] = getProgramArgumentsArray( config );
try {
ICDITarget[] dtargets = session.getTargets();
for( int i = 0; i < dtargets.length; ++i ) {
ICDIRuntimeOptions opt = dtargets[i].getRuntimeOptions();
opt.setArguments( arguments );
File wd = getWorkingDirectory( config );
if ( wd != null ) {
opt.setWorkingDirectory( wd.getAbsolutePath() );
}
opt.setEnvironment( getEnvironmentAsProperty( config ) );
}
}
catch( CDIException e ) {
abort( LaunchMessages.getString( "LocalCDILaunchDelegate.10" ), e, ICDTLaunchConfigurationConstants.ERR_INTERNAL_ERROR ); //$NON-NLS-1$
}
}
private ICDISession createCDISession( ILaunchConfiguration config, ILaunch launch, ICDebugConfiguration debugConfig, IProgressMonitor monitor ) throws CoreException {
ICDISession session = null;
ICDIDebugger debugger = debugConfig.createDebugger();
if ( debugger instanceof ICDIDebugger2 )
session = launchDebugSession( config, launch, (ICDIDebugger2)debugger, monitor );
else
// support old debugger types
session = launchOldDebugSession( config, launch, debugger, monitor );
return session;
}
}

View file

@ -143,3 +143,14 @@ Launch.common.QualifierColon=Qualifier:
Launch.common.Browse_1=&Browse...
Launch.common.Browse_2=B&rowse...
Launch.common.Project_does_not_exist=Project does not exist
LocalCDILaunchDelegate.0=Launching Local C/C++ Application
LocalCDILaunchDelegate.1=Launching debugger session
LocalCDILaunchDelegate.2=Debugging local C/C++ application
LocalCDILaunchDelegate.3=Attaching to Local C/C++ Application
LocalCDILaunchDelegate.4=No Process ID selected.
LocalCDILaunchDelegate.5=Launching postmortem debugger session
LocalCDILaunchDelegate.6=No core file selected
LocalCDILaunchDelegate.7=Core file does not exist or is not readable.
LocalCDILaunchDelegate.8=Error starting process.
LocalCDILaunchDelegate.9=Eclipse runtime does not support working directory.
LocalCDILaunchDelegate.10=Failed to set program arguments, environment or working directory.