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:
parent
f5785de8fe
commit
19dadcff48
5 changed files with 194 additions and 9 deletions
|
@ -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();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
|
@ -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
|
||||||
|
@ -421,18 +429,23 @@ public class MIInferiorProcess extends Process
|
||||||
public PTY getPTY() {
|
public PTY getPTY() {
|
||||||
return fPty;
|
return fPty;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @since 1.1
|
* Return the PID of this inferior, or null if not known.
|
||||||
*/
|
*
|
||||||
|
* @since 1.1
|
||||||
|
*/
|
||||||
@ConfinedToDsfExecutor("fSession#getExecutor")
|
@ConfinedToDsfExecutor("fSession#getExecutor")
|
||||||
public String getPid() {
|
public String getPid() {
|
||||||
return fInferiorPid;
|
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")
|
@ConfinedToDsfExecutor("fSession#getExecutor")
|
||||||
public void setPid(String pid) {
|
public void setPid(String pid) {
|
||||||
fInferiorPid = 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 ("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
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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;
|
||||||
|
}
|
||||||
|
}
|
|
@ -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) {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
Loading…
Add table
Reference in a new issue