1
0
Fork 0
mirror of https://github.com/eclipse-cdt/cdt synced 2025-07-23 17:05:26 +02:00

2004-09-22 Alain Magloire

Makes the mi/ source folder independant of the cdt.core
	so we can make it a library.
	To many files to enumerate
This commit is contained in:
Alain Magloire 2004-09-22 20:22:39 +00:00
parent dfaa0dad02
commit de94789d8d
25 changed files with 398 additions and 124 deletions

View file

@ -1,3 +1,8 @@
2004-09-22 Alain Magloire
Makes the mi/ source folder independant of the cdt.core
so we can make it a library.
To many files to enumerate
2004-09-17 Alain Magloire
Support for 64 bits application
PR 74056 74058. Pathc from Artyom Kuanbekov

View file

@ -12,8 +12,8 @@ package org.eclipse.cdt.debug.mi.core.cdi;
import org.eclipse.cdt.debug.core.cdi.ICDIConfiguration;
import org.eclipse.cdt.debug.mi.core.MIInferior;
import org.eclipse.cdt.debug.mi.core.MIProcess;
import org.eclipse.cdt.debug.mi.core.MISession;
import org.eclipse.cdt.utils.spawner.Spawner;
/**
*/
@ -125,8 +125,9 @@ public class Configuration implements ICDIConfiguration {
os = System.getProperty("os.name", ""); //$NON-NLS-1$ //$NON-NLS-2$
} catch (SecurityException e) {
}
Process gdb = miSession.getGDBProcess();
if (gdb instanceof Spawner) {
MIProcess gdb = miSession.getGDBProcess();
MIInferior inferior = miSession.getMIInferior();
if (gdb.canInterrupt(inferior)) {
// If we attached sending a control-c,
// seems to alays work.
if (fAttached) {
@ -136,8 +137,7 @@ public class Configuration implements ICDIConfiguration {
// If we have a pty, sending a control-c will work
// except for solaris.
if (os.equals("SunOS")) { //$NON-NLS-1$
MIInferior inferior = miSession.getMIInferior();
if (inferior.getPTY() != null) {
if (inferior.getTTY() != null) {
// FIXME: bug in Solaris gdb when using -tty, sending a control-c
// does not work.
return false;

View file

@ -0,0 +1,43 @@
/*******************************************************************************
* Copyright (c) 2000, 2004 QNX Software Systems and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Common Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/cpl-v10.html
*
* Contributors:
* QNX Software Systems - Initial API and implementation
*******************************************************************************/
package org.eclipse.cdt.debug.mi.core;
import java.io.InputStream;
import java.io.OutputStream;
/**
*/
public interface IMITTY {
/**
* Returns the name of the slave to pass to gdb --tty command
* ex: --tty=/dev/pty/1
*
* @return
*/
public String getSlaveName();
/**
* Returns the OutputStream of the Master.
*
* @return
*/
public OutputStream getOutputStream();
/**
* Returns the InputStream of the Master
*
* @return
*/
public InputStream getInputStream();
}

View file

@ -24,8 +24,6 @@ import org.eclipse.cdt.debug.mi.core.command.MIInfoProgram;
import org.eclipse.cdt.debug.mi.core.event.MIInferiorExitEvent;
import org.eclipse.cdt.debug.mi.core.output.MIGDBShowExitCodeInfo;
import org.eclipse.cdt.debug.mi.core.output.MIInfoProgramInfo;
import org.eclipse.cdt.utils.pty.PTY;
import org.eclipse.cdt.utils.spawner.Spawner;
/**
*/
@ -49,16 +47,16 @@ public class MIInferior extends Process {
PipedInputStream err;
PipedOutputStream errPiped;
PTY pty;
IMITTY tty;
int inferiorPID;
MIInferior(MISession mi, PTY p) {
MIInferior(MISession mi, IMITTY p) {
session = mi;
pty = p;
if (pty != null) {
out = pty.getOutputStream();
in = pty.getInputStream();
tty = p;
if (tty != null) {
out = tty.getOutputStream();
in = tty.getInputStream();
}
}
@ -181,7 +179,7 @@ public class MIInferior extends Process {
}
public synchronized void interrupt() throws MIException {
Process gdb = session.getGDBProcess();
MIProcess gdb = session.getGDBProcess();
// Check if they can handle the interrupt
// Try the exec-interrupt; this will be for "gdb --async"
CommandFactory factory = session.getCommandFactory();
@ -200,26 +198,8 @@ public class MIInferior extends Process {
}
} catch (MIException e) {
}
} else if (gdb instanceof Spawner) {
Spawner gdbSpawner = (Spawner) gdb;
gdbSpawner.interrupt();
// Allow (5 secs) for the interrupt to propagate.
for (int i = 0;(state == RUNNING) && i < 5; i++) {
try {
wait(1000);
} catch (InterruptedException e) {
}
}
if ((state == RUNNING) && getInferiorPID() > 0) {
// lets try something else.
gdbSpawner.raise(getInferiorPID(), gdbSpawner.INT);
for (int i = 0;(state == RUNNING) && i < 5; i++) {
try {
wait(1000);
} catch (InterruptedException e) {
}
}
}
} else if (gdb.canInterrupt(this)) {
gdb.interrupt(this);
}
// If we've failed throw an exception up.
@ -286,9 +266,9 @@ public class MIInferior extends Process {
//e.printStackTrace();
}
// If pty is not null then we are using a master/slave terminal
// If tty is not null then we are using a master/slave terminal
// emulation close the master to notify the slave.
if (pty != null) {
if (tty != null) {
if (in != null) {
try {
in.close();
@ -320,8 +300,8 @@ public class MIInferior extends Process {
return errPiped;
}
public PTY getPTY() {
return pty;
public IMITTY getTTY() {
return tty;
}
public void update() {

View file

@ -0,0 +1,58 @@
/*******************************************************************************
* Copyright (c) 2000, 2004 QNX Software Systems and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Common Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/cpl-v10.html
*
* Contributors:
* QNX Software Systems - Initial API and implementation
*******************************************************************************/
package org.eclipse.cdt.debug.mi.core;
import java.io.InputStream;
import java.io.OutputStream;
/**
* Check if we can interrupt the inferior.
*
*/
public interface MIProcess {
public abstract boolean canInterrupt(MIInferior inferior);
public abstract void interrupt(MIInferior inferior);
/* (non-Javadoc)
* @see java.lang.Process#destroy()
*/
public void destroy();
/* (non-Javadoc)
* @see java.lang.Process#exitValue()
*/
public int exitValue();
/* (non-Javadoc)
* @see java.lang.Process#getErrorStream()
*/
public InputStream getErrorStream();
/* (non-Javadoc)
* @see java.lang.Process#getInputStream()
*/
public InputStream getInputStream();
/* (non-Javadoc)
* @see java.lang.Process#getOutputStream()
*/
public OutputStream getOutputStream();
/* (non-Javadoc)
* @see java.lang.Process#waitFor()
*/
public int waitFor() throws InterruptedException;
}

View file

@ -28,7 +28,6 @@ import org.eclipse.cdt.debug.mi.core.event.MIEvent;
import org.eclipse.cdt.debug.mi.core.event.MIGDBExitEvent;
import org.eclipse.cdt.debug.mi.core.output.MIOutput;
import org.eclipse.cdt.debug.mi.core.output.MIParser;
import org.eclipse.cdt.utils.pty.PTY;
/**
* Represents a GDB/MI session.
@ -57,7 +56,7 @@ public class MISession extends Observable {
int sessionType;
Process sessionProcess;
Process gdbProcess;
MIProcess gdbProcess;
InputStream inChannel;
OutputStream outChannel;
@ -91,7 +90,7 @@ public class MISession extends Observable {
* @param timeout time in milliseconds to wait for command response.
* @param type the type of debugin session.
*/
public MISession(Process process, PTY pty, int timeout, int type, int launchTimeout) throws MIException {
public MISession(MIProcess process, IMITTY tty, int timeout, int type, int launchTimeout) throws MIException {
gdbProcess = process;
inChannel = process.getInputStream();
@ -105,7 +104,7 @@ public class MISession extends Observable {
parser = new MIParser();
inferior = new MIInferior(this, pty);
inferior = new MIInferior(this, tty);
txQueue = new CommandQueue();
rxQueue = new CommandQueue();
@ -344,7 +343,7 @@ public class MISession extends Observable {
/**
* Return the "gdb" Process.
*/
public Process getGDBProcess() {
public MIProcess getGDBProcess() {
return gdbProcess;
}

View file

@ -139,6 +139,9 @@ public class CommandFactory {
}
public MIExecInterrupt createMIExecInterrupt() {
// return null here to signal that we do not support
// -exec-interrupt and to use to drop a signal to gdb
// instead via the MIProcess class
return null;
}

View file

@ -146,7 +146,7 @@ public class MICommand extends Command {
return command.toString();
}
boolean containsWhitespace(String s) {
protected boolean containsWhitespace(String s) {
for (int i = 0; i < s.length(); i++) {
if (Character.isWhitespace(s.charAt(i))) {
return true;

View file

@ -4,7 +4,11 @@
*
*/
package org.eclipse.cdt.debug.mi.core.command;
package org.eclipse.cdt.debug.mi.core;
import org.eclipse.cdt.debug.mi.core.command.CommandFactory;
import org.eclipse.cdt.debug.mi.core.command.MIEnvironmentCD;
import org.eclipse.cdt.debug.mi.core.command.MIEnvironmentDirectory;
/**
* Cygwin Command Factory overrides the regular Command Factory to allow for

View file

@ -11,7 +11,6 @@ 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.CygwinCommandFactory;
import org.eclipse.cdt.debug.mi.core.command.MIGDBSet;
import org.eclipse.cdt.debug.mi.core.output.MIInfo;
import org.eclipse.core.resources.IFile;

View file

@ -9,12 +9,13 @@
* QNX Software Systems - Initial API and implementation
***********************************************************************/
package org.eclipse.cdt.debug.mi.core.command;
package org.eclipse.cdt.debug.mi.core;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import org.eclipse.cdt.core.CommandLauncher;
import org.eclipse.cdt.debug.mi.core.command.MIEnvironmentCD;
import org.eclipse.core.runtime.Path;
/**
@ -63,10 +64,11 @@ public class CygwinMIEnvironmentCD extends MIEnvironmentCD {
* @see org.eclipse.cdt.debug.mi.core.command.MICommand#parametersToString()
*/
protected String parametersToString() {
if (parameters != null && parameters.length == 1) {
String[] params = getParameters();
if (params != null && params.length == 1) {
StringBuffer sb = new StringBuffer();
// We need to escape the double quotes and the backslash.
String param = parameters[0];
String param = params[0];
for (int j = 0; j < param.length(); j++) {
char c = param.charAt(j);
if (c == '"' || c == '\\') {

View file

@ -4,11 +4,12 @@
*
*/
package org.eclipse.cdt.debug.mi.core.command;
package org.eclipse.cdt.debug.mi.core;
import java.io.ByteArrayOutputStream;
import org.eclipse.cdt.core.CommandLauncher;
import org.eclipse.cdt.debug.mi.core.command.MIEnvironmentDirectory;
import org.eclipse.core.runtime.Path;
/**

View file

@ -10,13 +10,10 @@
*******************************************************************************/
package org.eclipse.cdt.debug.mi.core;
import java.io.BufferedReader;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.Reader;
import java.text.MessageFormat;
import java.util.MissingResourceException;
import java.util.ResourceBundle;
@ -29,7 +26,6 @@ import org.eclipse.cdt.debug.mi.core.command.MITargetAttach;
import org.eclipse.cdt.debug.mi.core.command.MITargetSelect;
import org.eclipse.cdt.debug.mi.core.output.MIInfo;
import org.eclipse.cdt.utils.pty.PTY;
import org.eclipse.cdt.utils.spawner.ProcessFactory;
import org.eclipse.core.runtime.Plugin;
import org.eclipse.core.runtime.Preferences;
import org.osgi.framework.BundleContext;
@ -87,7 +83,7 @@ public class MIPlugin extends Plugin {
* @throws MIException
* @return MISession
*/
public MISession createMISession(Process process, PTY pty, int timeout, int type, int launchTimeout) throws MIException {
public MISession createMISession(MIProcess process, IMITTY pty, int timeout, int type, int launchTimeout) throws MIException {
return new MISession(process, pty, timeout, type, launchTimeout);
}
@ -99,7 +95,7 @@ public class MIPlugin extends Plugin {
* @throws MIException
* @return MISession
*/
public MISession createMISession(Process process, PTY pty, int type) throws MIException {
public MISession createMISession(MIProcess process, IMITTY pty, int type) throws MIException {
MIPlugin miPlugin = getDefault();
Preferences prefs = miPlugin.getPluginPreferences();
int timeout = prefs.getInt(IMIConstants.PREF_REQUEST_TIMEOUT);
@ -114,11 +110,12 @@ public class MIPlugin extends Plugin {
* @throws MIException
*/
public ICDISession createCSession(String gdb, File program, File cwd, String gdbinit) throws IOException, MIException {
PTY pty = null;
IMITTY pty = null;
boolean failed = false;
try {
pty = new PTY();
PTY pseudo = new PTY();
pty = new MITTYAdapter(pseudo);
} catch (IOException e) {
}
@ -156,7 +153,7 @@ public class MIPlugin extends Plugin {
* @return ICDISession
* @throws IOException
*/
public ICDISession createCSession(String gdb, File program, File cwd, String gdbinit, PTY pty) throws IOException, MIException {
public ICDISession createCSession(String gdb, File program, File cwd, String gdbinit, IMITTY pty) throws IOException, MIException {
if (gdb == null || gdb.length() == 0) {
gdb = GDB;
}
@ -180,7 +177,7 @@ public class MIPlugin extends Plugin {
}
}
Process pgdb = getGDBProcess(args);
MIProcess pgdb = new MIProcessAdapter(args);
MISession session;
try {
@ -231,7 +228,7 @@ public class MIPlugin extends Plugin {
} else {
args = new String[] {gdb, "--cd="+cwd.getAbsolutePath(), "--command="+gdbinit, "--quiet", "-nw", "-i", "mi1", "-c", core.getAbsolutePath(), program.getAbsolutePath()}; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ //$NON-NLS-5$ //$NON-NLS-6$ //$NON-NLS-7$
}
Process pgdb = getGDBProcess(args);
MIProcess pgdb = new MIProcessAdapter(args);
MISession session;
try {
session = createMISession(pgdb, null, MISession.CORE);
@ -264,7 +261,7 @@ public class MIPlugin extends Plugin {
} else {
args = new String[] {gdb, "--cd="+cwd.getAbsolutePath(), "--command="+gdbinit, "--quiet", "-nw", "-i", "mi1", program.getAbsolutePath()}; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ //$NON-NLS-5$ //$NON-NLS-6$
}
Process pgdb = getGDBProcess(args);
MIProcess pgdb = new MIProcessAdapter(args);
MISession session;
try {
session = createMISession(pgdb, null, MISession.ATTACH);
@ -345,68 +342,6 @@ public class MIPlugin extends Plugin {
return '#' + key + '#';
}
}
/**
* Do some basic synchronisation, gdb may take some time to load
* for whatever reasons.
* @param args
* @return Process
* @throws IOException
*/
protected Process getGDBProcess(String[] args) throws IOException {
if ( getDefault().isDebugging() )
{
StringBuffer sb = new StringBuffer();
for ( int i = 0; i < args.length; ++i )
{
sb.append( args[i] );
sb.append( ' ' );
}
getDefault().debugLog( sb.toString() );
}
final Process pgdb = ProcessFactory.getFactory().exec(args);
Thread syncStartup = new Thread("GDB Start") { //$NON-NLS-1$
public void run() {
try {
String line;
InputStream stream = pgdb.getInputStream();
Reader r = new InputStreamReader(stream);
BufferedReader reader = new BufferedReader(r);
while ((line = reader.readLine()) != null) {
line = line.trim();
//System.out.println("GDB " + line);
if (line.endsWith("(gdb)")) { //$NON-NLS-1$
break;
}
}
} catch (Exception e) {
// Do nothing
}
synchronized (pgdb) {
pgdb.notifyAll();
}
}
};
syncStartup.start();
synchronized (pgdb) {
MIPlugin miPlugin = getDefault();
Preferences prefs = miPlugin.getPluginPreferences();
int launchTimeout = prefs.getInt(IMIConstants.PREF_REQUEST_LAUNCH_TIMEOUT);
while (syncStartup.isAlive()) {
try {
pgdb.wait(launchTimeout);
break;
} catch (InterruptedException e) {
}
}
}
try {
syncStartup.interrupt();
syncStartup.join(1000);
} catch (InterruptedException e) {
}
return pgdb;
}
/* (non-Javadoc)
* @see org.eclipse.core.runtime.Plugin#startup()

View file

@ -0,0 +1,193 @@
/*******************************************************************************
* Copyright (c) 2000, 2004 QNX Software Systems and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Common Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/cpl-v10.html
*
* Contributors:
* QNX Software Systems - Initial API and implementation
*******************************************************************************/
package org.eclipse.cdt.debug.mi.core;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.Reader;
import org.eclipse.cdt.utils.spawner.ProcessFactory;
import org.eclipse.cdt.utils.spawner.Spawner;
import org.eclipse.core.runtime.Preferences;
/**
*/
public class MIProcessAdapter implements MIProcess {
Process fGDBProcess;
public MIProcessAdapter(String[] args) throws IOException {
fGDBProcess = getGDBProcess(args);
}
/**
* Do some basic synchronisation, gdb may take some time to load for
* whatever reasons.
*
* @param args
* @return Process
* @throws IOException
*/
protected Process getGDBProcess(String[] args) throws IOException {
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());
}
final Process pgdb = ProcessFactory.getFactory().exec(args);
Thread syncStartup = new Thread("GDB Start") { //$NON-NLS-1$
public void run() {
try {
String line;
InputStream stream = pgdb.getInputStream();
Reader r = new InputStreamReader(stream);
BufferedReader reader = new BufferedReader(r);
while ((line = reader.readLine()) != null) {
line = line.trim();
//System.out.println("GDB " + line);
if (line.endsWith("(gdb)")) { //$NON-NLS-1$
break;
}
}
} catch (Exception e) {
// Do nothing
}
synchronized (pgdb) {
pgdb.notifyAll();
}
}
};
syncStartup.start();
synchronized (pgdb) {
MIPlugin miPlugin = MIPlugin.getDefault();
Preferences prefs = miPlugin.getPluginPreferences();
int launchTimeout = prefs
.getInt(IMIConstants.PREF_REQUEST_LAUNCH_TIMEOUT);
while (syncStartup.isAlive()) {
try {
pgdb.wait(launchTimeout);
break;
} catch (InterruptedException e) {
}
}
}
try {
syncStartup.interrupt();
syncStartup.join(1000);
} catch (InterruptedException e) {
}
return pgdb;
}
/*
* (non-Javadoc)
*
* @see org.eclipse.cdt.debug.mi.core.MIProcess#canInterrupt()
*/
public boolean canInterrupt(MIInferior inferior) {
return fGDBProcess instanceof Spawner;
}
/*
* (non-Javadoc)
*
* @see org.eclipse.cdt.debug.mi.core.MIProcess#interrupt()
*/
public void interrupt(MIInferior inferior) {
if (fGDBProcess instanceof Spawner) {
Spawner gdbSpawner = (Spawner) fGDBProcess;
gdbSpawner.interrupt();
int state;
// Allow (5 secs) for the interrupt to propagate.
for (int i = 0; inferior.isRunning() && i < 5; i++) {
try {
wait(1000);
} catch (InterruptedException e) {
}
}
// If we are still running try to drop the sig to the PID
if (inferior.isRunning() && inferior.getInferiorPID() > 0) {
// lets try something else.
gdbSpawner.raise(inferior.getInferiorPID(), gdbSpawner.INT);
for (int i = 0; inferior.isRunning() && i < 5; i++) {
try {
wait(1000);
} catch (InterruptedException e) {
}
}
}
}
}
/*
* (non-Javadoc)
*
* @see java.lang.Process#exitValue()
*/
public int exitValue() {
return fGDBProcess.exitValue();
}
/*
* (non-Javadoc)
*
* @see java.lang.Process#waitFor()
*/
public int waitFor() throws InterruptedException {
return fGDBProcess.waitFor();
}
/*
* (non-Javadoc)
*
* @see java.lang.Process#destroy()
*/
public void destroy() {
fGDBProcess.destroy();
}
/*
* (non-Javadoc)
*
* @see java.lang.Process#getErrorStream()
*/
public InputStream getErrorStream() {
return fGDBProcess.getErrorStream();
}
/*
* (non-Javadoc)
*
* @see java.lang.Process#getInputStream()
*/
public InputStream getInputStream() {
return fGDBProcess.getInputStream();
}
/*
* (non-Javadoc)
*
* @see java.lang.Process#getOutputStream()
*/
public OutputStream getOutputStream() {
return fGDBProcess.getOutputStream();
}
}

View file

@ -0,0 +1,52 @@
/*******************************************************************************
* Copyright (c) 2000, 2004 QNX Software Systems and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Common Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/cpl-v10.html
*
* Contributors:
* QNX Software Systems - Initial API and implementation
*******************************************************************************/
package org.eclipse.cdt.debug.mi.core;
import java.io.InputStream;
import java.io.OutputStream;
import org.eclipse.cdt.utils.pty.PTY;
/**
* Adapt the PTY code to IMITTY
*
*/
public class MITTYAdapter implements IMITTY {
PTY fPty;
public MITTYAdapter(PTY pty) {
fPty = pty;
}
/* (non-Javadoc)
* @see org.eclipse.cdt.debug.mi.core.IMITTY#getSlaveName()
*/
public String getSlaveName() {
return fPty.getSlaveName();
}
/* (non-Javadoc)
* @see org.eclipse.cdt.debug.mi.core.IMITTY#getOutputStream()
*/
public OutputStream getOutputStream() {
return fPty.getOutputStream();
}
/* (non-Javadoc)
* @see org.eclipse.cdt.debug.mi.core.IMITTY#getInputStream()
*/
public InputStream getInputStream() {
return fPty.getInputStream();
}
}