1
0
Fork 0
mirror of https://github.com/eclipse-cdt/cdt synced 2025-06-08 10:16:03 +02:00

Bug 305385: The pid of the inferior is not set pre-GDB 7.0

This commit is contained in:
John Cortell 2010-05-20 14:25:35 +00:00
parent f5785de8fe
commit 19dadcff48
5 changed files with 194 additions and 9 deletions

View file

@ -33,6 +33,8 @@ import org.eclipse.cdt.dsf.mi.service.IMIProcessDMContext;
import org.eclipse.cdt.dsf.mi.service.IMIProcesses; import org.eclipse.cdt.dsf.mi.service.IMIProcesses;
import org.eclipse.cdt.dsf.mi.service.MIProcesses; import org.eclipse.cdt.dsf.mi.service.MIProcesses;
import org.eclipse.cdt.dsf.mi.service.command.MIInferiorProcess; import org.eclipse.cdt.dsf.mi.service.command.MIInferiorProcess;
import org.eclipse.cdt.dsf.mi.service.command.events.MIStoppedEvent;
import org.eclipse.cdt.dsf.service.DsfServiceEventHandler;
import org.eclipse.cdt.dsf.service.DsfSession; import org.eclipse.cdt.dsf.service.DsfSession;
import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IStatus; import org.eclipse.core.runtime.IStatus;
@ -94,12 +96,15 @@ public class GDBProcesses extends MIProcesses {
IContainerDMContext containerDmc = createContainerContext(procDmc, MIProcesses.UNIQUE_GROUP_ID); IContainerDMContext containerDmc = createContainerContext(procDmc, MIProcesses.UNIQUE_GROUP_ID);
fGdb.getInferiorProcess().setContainerContext(containerDmc); fGdb.getInferiorProcess().setContainerContext(containerDmc);
getSession().addServiceEventListener(this, null);
requestMonitor.done(); requestMonitor.done();
} }
@Override @Override
public void shutdown(RequestMonitor requestMonitor) { public void shutdown(RequestMonitor requestMonitor) {
unregister(); unregister();
getSession().removeServiceEventListener(this);
super.shutdown(requestMonitor); super.shutdown(requestMonitor);
} }
@ -291,4 +296,13 @@ public class GDBProcesses extends MIProcesses {
rm.done(); rm.done();
} }
} }
/**
* @since 3.0
*/
@DsfServiceEventHandler
public void eventDispatched(MIStoppedEvent e) {
// Get the PID of the inferior through gdb (if we don't have it already)
fGdb.getInferiorProcess().update();
}
} }

View file

@ -30,6 +30,7 @@ import org.eclipse.cdt.dsf.mi.service.command.commands.CLIAttach;
import org.eclipse.cdt.dsf.mi.service.command.commands.CLICatch; import org.eclipse.cdt.dsf.mi.service.command.commands.CLICatch;
import org.eclipse.cdt.dsf.mi.service.command.commands.CLIDetach; import org.eclipse.cdt.dsf.mi.service.command.commands.CLIDetach;
import org.eclipse.cdt.dsf.mi.service.command.commands.CLIExecAbort; import org.eclipse.cdt.dsf.mi.service.command.commands.CLIExecAbort;
import org.eclipse.cdt.dsf.mi.service.command.commands.CLIInfoProgram;
import org.eclipse.cdt.dsf.mi.service.command.commands.CLIInfoSharedLibrary; import org.eclipse.cdt.dsf.mi.service.command.commands.CLIInfoSharedLibrary;
import org.eclipse.cdt.dsf.mi.service.command.commands.CLIInfoThreads; import org.eclipse.cdt.dsf.mi.service.command.commands.CLIInfoThreads;
import org.eclipse.cdt.dsf.mi.service.command.commands.CLIJump; import org.eclipse.cdt.dsf.mi.service.command.commands.CLIJump;
@ -126,6 +127,7 @@ import org.eclipse.cdt.dsf.mi.service.command.commands.MIVarShowAttributes;
import org.eclipse.cdt.dsf.mi.service.command.commands.MIVarShowFormat; import org.eclipse.cdt.dsf.mi.service.command.commands.MIVarShowFormat;
import org.eclipse.cdt.dsf.mi.service.command.commands.MIVarUpdate; import org.eclipse.cdt.dsf.mi.service.command.commands.MIVarUpdate;
import org.eclipse.cdt.dsf.mi.service.command.output.CLICatchInfo; import org.eclipse.cdt.dsf.mi.service.command.output.CLICatchInfo;
import org.eclipse.cdt.dsf.mi.service.command.output.CLIInfoProgramInfo;
import org.eclipse.cdt.dsf.mi.service.command.output.CLIInfoSharedLibraryInfo; import org.eclipse.cdt.dsf.mi.service.command.output.CLIInfoSharedLibraryInfo;
import org.eclipse.cdt.dsf.mi.service.command.output.CLIInfoThreadsInfo; import org.eclipse.cdt.dsf.mi.service.command.output.CLIInfoThreadsInfo;
import org.eclipse.cdt.dsf.mi.service.command.output.CLIThreadInfo; import org.eclipse.cdt.dsf.mi.service.command.output.CLIThreadInfo;
@ -194,6 +196,10 @@ public class CommandFactory {
return new CLIExecAbort(ctx); return new CLIExecAbort(ctx);
} }
public ICommand<CLIInfoProgramInfo> createCLIInfoProgram(IContainerDMContext ctx) {
return new CLIInfoProgram(ctx);
}
public ICommand<CLIInfoSharedLibraryInfo> createCLIInfoSharedLibrary(ISymbolDMContext ctx) { public ICommand<CLIInfoSharedLibraryInfo> createCLIInfoSharedLibrary(ISymbolDMContext ctx) {
return new CLIInfoSharedLibrary(ctx); return new CLIInfoSharedLibrary(ctx);
} }

View file

@ -42,6 +42,7 @@ import org.eclipse.cdt.dsf.gdb.internal.GdbPlugin;
import org.eclipse.cdt.dsf.mi.service.IMICommandControl; import org.eclipse.cdt.dsf.mi.service.IMICommandControl;
import org.eclipse.cdt.dsf.mi.service.MIProcesses.ContainerExitedDMEvent; import org.eclipse.cdt.dsf.mi.service.MIProcesses.ContainerExitedDMEvent;
import org.eclipse.cdt.dsf.mi.service.command.commands.CLICommand; import org.eclipse.cdt.dsf.mi.service.command.commands.CLICommand;
import org.eclipse.cdt.dsf.mi.service.command.output.CLIInfoProgramInfo;
import org.eclipse.cdt.dsf.mi.service.command.output.MIConst; import org.eclipse.cdt.dsf.mi.service.command.output.MIConst;
import org.eclipse.cdt.dsf.mi.service.command.output.MIExecAsyncOutput; import org.eclipse.cdt.dsf.mi.service.command.output.MIExecAsyncOutput;
import org.eclipse.cdt.dsf.mi.service.command.output.MIGDBShowExitCodeInfo; import org.eclipse.cdt.dsf.mi.service.command.output.MIGDBShowExitCodeInfo;
@ -104,13 +105,20 @@ public class MIInferiorProcess extends Process
*/ */
private int fSuppressTargetOutputCounter = 0; private int fSuppressTargetOutputCounter = 0;
/**
* Flag we use to avoid making repeated CLI 'info program' requests to get
* the PID when gdb doesn't provide the PID in the response.
*/
@ConfinedToDsfExecutor("fSession#getExecutor")
private boolean fGiveUpOnPidQuery;
@ThreadSafe @ThreadSafe
Integer fExitCode = null; Integer fExitCode = null;
private State fState = State.RUNNING; private State fState = State.RUNNING;
@ConfinedToDsfExecutor("fSession#getExecutor") @ConfinedToDsfExecutor("fSession#getExecutor")
private String fInferiorPid = null; private String fInferiorPid;
/** /**
* Creates an inferior process object which uses the given output stream * Creates an inferior process object which uses the given output stream
@ -423,6 +431,8 @@ public class MIInferiorProcess extends Process
} }
/** /**
* Return the PID of this inferior, or null if not known.
*
* @since 1.1 * @since 1.1
*/ */
@ConfinedToDsfExecutor("fSession#getExecutor") @ConfinedToDsfExecutor("fSession#getExecutor")
@ -431,6 +441,9 @@ public class MIInferiorProcess extends Process
} }
/** /**
* Record the PID of this inferior. The PID may not be known at the time of
* our instantiation.
*
* @since 1.1 * @since 1.1
*/ */
@ConfinedToDsfExecutor("fSession#getExecutor") @ConfinedToDsfExecutor("fSession#getExecutor")
@ -511,4 +524,36 @@ public class MIInferiorProcess extends Process
else if ("exit".equals(state)) { setState(State.TERMINATED); }//$NON-NLS-1$ else if ("exit".equals(state)) { setState(State.TERMINATED); }//$NON-NLS-1$
else if ("error".equals(state)) { setState(State.STOPPED); }//$NON-NLS-1$ else if ("error".equals(state)) { setState(State.STOPPED); }//$NON-NLS-1$
} }
/**
* @since 3.0
*/
@ConfinedToDsfExecutor("fSession#getExecutor")
public void update() {
// If we don't already know the PID of the inferior, ask GDB for it.
if (getPid() == null && fContainerDMContext != null && !fGiveUpOnPidQuery) {
getCommandControlService().queueCommand(
fCommandFactory.createCLIInfoProgram(fContainerDMContext),
new DataRequestMonitor<CLIInfoProgramInfo>(fSession.getExecutor(), null) {
@Override
protected void handleSuccess() {
if (getPid() == null) { // check again
Long pid = getData().getPID();
if (pid != null) {
setPid(Long.toString(pid));
}
else {
// We made the 'program info' request to
// GDB, it gave us an answer, but it either
// doesn't provide the process PID or we
// can't make it out. No point in trying
// again.
fGiveUpOnPidQuery = true;
assert false; // investigate why this is happening
}
}
}
});
}
}
} }

View file

@ -0,0 +1,39 @@
/*******************************************************************************
* Copyright (c) 2010 QNX Software Systems, Freescale Semiconductor 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:
* Freescale Semiconductor, QNX Software Systems - Initial API and implementation
*******************************************************************************/
package org.eclipse.cdt.dsf.mi.service.command.commands;
import org.eclipse.cdt.dsf.debug.service.IRunControl.IContainerDMContext;
import org.eclipse.cdt.dsf.mi.service.command.output.CLIInfoProgramInfo;
import org.eclipse.cdt.dsf.mi.service.command.output.MIInfo;
import org.eclipse.cdt.dsf.mi.service.command.output.MIOutput;
/**
* @since 3.0
*/
public class CLIInfoProgram extends CLICommand<CLIInfoProgramInfo> {
public CLIInfoProgram(IContainerDMContext ctx) {
super(ctx, "info program"); //$NON-NLS-1$
}
@Override
public CLIInfoProgramInfo getResult(MIOutput output) {
return (CLIInfoProgramInfo)getMIInfo(output);
}
public MIInfo getMIInfo(MIOutput out) {
MIInfo info = null;
if (out != null) {
info = new CLIInfoProgramInfo(out);
}
return info;
}
}

View file

@ -0,0 +1,81 @@
/*******************************************************************************
* Copyright (c) 2010 QNX Software Systems, Freescale Semiconductor 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:
* Freescale Semiconductor, QNX Software Systems - Initial API and implementation
*******************************************************************************/
package org.eclipse.cdt.dsf.mi.service.command.output;
import java.util.StringTokenizer;
/**
* @since 3.0
*/
public class CLIInfoProgramInfo extends MIInfo {
Long fPid;
public CLIInfoProgramInfo(MIOutput out) {
super(out);
parse();
}
/**
* Return the inferior's PID reported in the output, or null if we didn't
* find it there.
*/
public Long getPID() {
return fPid;
}
void parse() {
if (isDone()) {
MIOutput out = getMIOutput();
MIOOBRecord[] oobs = out.getMIOOBRecords();
for (MIOOBRecord oob : oobs) {
if (oob instanceof MIConsoleStreamOutput) {
parseLine(((MIConsoleStreamOutput)oob).getString());
// quit parsing output once we have everything we want out
// of it
if (fPid != null) {
break;
}
}
}
}
}
void parseLine(String str) {
// Sample output on Windows:
// [New thread 4960.0x5d8]
// Using the running image of child thread 4960.0x5d8.
// Program stopped at 0x4012f5.
// It stopped at a breakpoint that has since been deleted.
if (str != null && str.length() > 0) {
str = str.replace('.', ' ').trim();
if (str.startsWith("Using")) { //$NON-NLS-1$
StringTokenizer st = new StringTokenizer(str);
while (st.hasMoreTokens()) {
String s = st.nextToken();
/* Not a process id if LWP is reported */
if (s.equals("LWP")) break; //$NON-NLS-1$
if (Character.isDigit(s.charAt(0))) {
try {
fPid = Long.decode(s).longValue();
break;
} catch (NumberFormatException e) {
}
}
}
}
}
}
}