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:
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.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();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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