1
0
Fork 0
mirror of https://github.com/eclipse-cdt/cdt synced 2025-04-23 22:52:11 +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.MIProcesses;
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.core.runtime.CoreException;
import org.eclipse.core.runtime.IStatus;
@ -94,12 +96,15 @@ public class GDBProcesses extends MIProcesses {
IContainerDMContext containerDmc = createContainerContext(procDmc, MIProcesses.UNIQUE_GROUP_ID);
fGdb.getInferiorProcess().setContainerContext(containerDmc);
getSession().addServiceEventListener(this, null);
requestMonitor.done();
}
@Override
public void shutdown(RequestMonitor requestMonitor) {
unregister();
getSession().removeServiceEventListener(this);
super.shutdown(requestMonitor);
}
@ -291,4 +296,13 @@ public class GDBProcesses extends MIProcesses {
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.CLIDetach;
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.CLIInfoThreads;
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.MIVarUpdate;
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.CLIInfoThreadsInfo;
import org.eclipse.cdt.dsf.mi.service.command.output.CLIThreadInfo;
@ -194,6 +196,10 @@ public class CommandFactory {
return new CLIExecAbort(ctx);
}
public ICommand<CLIInfoProgramInfo> createCLIInfoProgram(IContainerDMContext ctx) {
return new CLIInfoProgram(ctx);
}
public ICommand<CLIInfoSharedLibraryInfo> createCLIInfoSharedLibrary(ISymbolDMContext 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.MIProcesses.ContainerExitedDMEvent;
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.MIExecAsyncOutput;
import org.eclipse.cdt.dsf.mi.service.command.output.MIGDBShowExitCodeInfo;
@ -104,13 +105,20 @@ public class MIInferiorProcess extends Process
*/
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
Integer fExitCode = null;
private State fState = State.RUNNING;
@ConfinedToDsfExecutor("fSession#getExecutor")
private String fInferiorPid = null;
private String fInferiorPid;
/**
* Creates an inferior process object which uses the given output stream
@ -421,18 +429,23 @@ public class MIInferiorProcess extends Process
public PTY getPTY() {
return fPty;
}
/**
* @since 1.1
*/
/**
* Return the PID of this inferior, or null if not known.
*
* @since 1.1
*/
@ConfinedToDsfExecutor("fSession#getExecutor")
public String getPid() {
return fInferiorPid;
}
/**
* @since 1.1
*/
/**
* Record the PID of this inferior. The PID may not be known at the time of
* our instantiation.
*
* @since 1.1
*/
@ConfinedToDsfExecutor("fSession#getExecutor")
public void setPid(String pid) {
fInferiorPid = pid;
@ -511,4 +524,36 @@ public class MIInferiorProcess extends Process
else if ("exit".equals(state)) { setState(State.TERMINATED); }//$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) {
}
}
}
}
}
}
}