mirror of
https://github.com/eclipse-cdt/cdt
synced 2025-04-29 19:45:01 +02:00
Bug 352998: [remote][attach] Cannot do a remote-attach session with GDB7.2 and CDT8.0
This commit is contained in:
parent
f706c92bdf
commit
0c43bc15c7
2 changed files with 146 additions and 3 deletions
|
@ -0,0 +1,26 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (c) 2011 Ericsson 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:
|
||||
* Marc Khouzam (Ericsson) - Initial API and implementation
|
||||
*******************************************************************************/
|
||||
package org.eclipse.cdt.dsf.gdb.internal.commands;
|
||||
|
||||
import org.eclipse.cdt.dsf.debug.service.command.ICommandControlService.ICommandControlDMContext;
|
||||
import org.eclipse.cdt.dsf.mi.service.command.commands.MICommand;
|
||||
import org.eclipse.cdt.dsf.mi.service.command.output.MIInfo;
|
||||
|
||||
/**
|
||||
* This command disconnects from the remote target.
|
||||
* This command is created in an internal package for the maintenance branch only.
|
||||
*/
|
||||
public class MITargetDisconnect extends MICommand<MIInfo> {
|
||||
|
||||
public MITargetDisconnect(ICommandControlDMContext ctx) {
|
||||
super(ctx, "-target-disconnect"); //$NON-NLS-1$
|
||||
}
|
||||
}
|
|
@ -7,6 +7,7 @@
|
|||
*
|
||||
* Contributors:
|
||||
* Onur Akdemir (TUBITAK BILGEM-ITI) - Multi-process debugging (Bug 237306)
|
||||
* Marc Khouzam (Ericsson) - Workaround for Bug 352998
|
||||
*******************************************************************************/
|
||||
package org.eclipse.cdt.dsf.gdb.service;
|
||||
|
||||
|
@ -14,6 +15,7 @@ import java.util.HashSet;
|
|||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import org.eclipse.cdt.debug.core.CDebugUtils;
|
||||
import org.eclipse.cdt.dsf.concurrent.DataRequestMonitor;
|
||||
import org.eclipse.cdt.dsf.concurrent.DsfExecutor;
|
||||
import org.eclipse.cdt.dsf.concurrent.ImmediateExecutor;
|
||||
|
@ -27,6 +29,7 @@ import org.eclipse.cdt.dsf.debug.service.IRunControl.IExitedDMEvent;
|
|||
import org.eclipse.cdt.dsf.debug.service.command.ICommandControlService.ICommandControlDMContext;
|
||||
import org.eclipse.cdt.dsf.gdb.IGDBLaunchConfigurationConstants;
|
||||
import org.eclipse.cdt.dsf.gdb.internal.GdbPlugin;
|
||||
import org.eclipse.cdt.dsf.gdb.internal.commands.MITargetDisconnect;
|
||||
import org.eclipse.cdt.dsf.gdb.service.command.IGDBControl;
|
||||
import org.eclipse.cdt.dsf.mi.service.IMICommandControl;
|
||||
import org.eclipse.cdt.dsf.mi.service.IMIContainerDMContext;
|
||||
|
@ -56,6 +59,15 @@ public class GDBProcesses_7_2 extends GDBProcesses_7_1 {
|
|||
private IGDBControl fCommandControl;
|
||||
private IGDBBackend fBackend;
|
||||
|
||||
private final static String INVALID = "invalid"; //$NON-NLS-1$
|
||||
|
||||
/**
|
||||
* Keep track if we need to reconnect to the target
|
||||
* due to a workaround because of a GDB 7.2 bug.
|
||||
* Bug 352998
|
||||
*/
|
||||
private boolean fNeedToReconnect;
|
||||
|
||||
/**
|
||||
* Set of processes that are currently being restarted.
|
||||
* We use this set for such things as not removing breakpoints
|
||||
|
@ -162,7 +174,6 @@ public class GDBProcesses_7_2 extends GDBProcesses_7_1 {
|
|||
if (isInitialProcess()) {
|
||||
// If it is the first inferior, GDB has already created it for us
|
||||
// We really should get the id from GDB instead of hard-coding it
|
||||
setIsInitialProcess(false);
|
||||
fContainerDmc = createContainerContext(procCtx, "i1"); //$NON-NLS-1$
|
||||
rm.done();
|
||||
return;
|
||||
|
@ -184,10 +195,46 @@ public class GDBProcesses_7_2 extends GDBProcesses_7_1 {
|
|||
}
|
||||
});
|
||||
}
|
||||
},
|
||||
new Step() {
|
||||
@Override
|
||||
public void execute(final RequestMonitor rm) {
|
||||
// Because of a GDB 7.2 bug, for remote-attach sessions,
|
||||
// we need to be disconnected from the target
|
||||
// when we set the very first binary to be used.
|
||||
// So, lets disconnect.
|
||||
// Bug 352998
|
||||
if (needFixForGDB72Bug352998()) {
|
||||
// The bug only applies to remote sessions
|
||||
if (fBackend.getSessionType() == SessionType.REMOTE) {
|
||||
assert fBackend.getIsAttachSession();
|
||||
assert binaryPath != null;
|
||||
|
||||
// We only need the workaround for the very first process we attach to
|
||||
if (isInitialProcess()) {
|
||||
ICommandControlDMContext controlDmc = DMContexts.getAncestorOfType(procCtx, ICommandControlDMContext.class);
|
||||
fCommandControl.queueCommand(
|
||||
// We don't use the command factory because we couldn't add the API to the maintenance branch
|
||||
new MITargetDisconnect(controlDmc),
|
||||
new DataRequestMonitor<MIInfo>(ImmediateExecutor.getInstance(), rm) {
|
||||
@Override
|
||||
protected void handleSuccess() {
|
||||
fNeedToReconnect = true;
|
||||
rm.done();
|
||||
}
|
||||
});
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
rm.done();
|
||||
}
|
||||
},
|
||||
new Step() {
|
||||
@Override
|
||||
public void execute(RequestMonitor rm) {
|
||||
// Now, set the binary to be used.
|
||||
if (binaryPath != null) {
|
||||
fCommandControl.queueCommand(
|
||||
fCommandFactory.createMIFileExecAndSymbols(fContainerDmc, binaryPath),
|
||||
|
@ -198,6 +245,62 @@ public class GDBProcesses_7_2 extends GDBProcesses_7_1 {
|
|||
rm.done();
|
||||
}
|
||||
},
|
||||
new Step() {
|
||||
@Override
|
||||
@SuppressWarnings("unchecked")
|
||||
public void execute(final RequestMonitor rm) {
|
||||
// Because of a GDB 7.2 bug, for remote-attach sessions,
|
||||
// we need to be disconnected from the target
|
||||
// when we set the very first binary to be used.
|
||||
// Now that we have disconnected and set the binary,
|
||||
// lets reconnect.
|
||||
// Bug 352998
|
||||
if (fNeedToReconnect) {
|
||||
fNeedToReconnect = false;
|
||||
ILaunch launch = (ILaunch)procCtx.getAdapter(ILaunch.class);
|
||||
assert launch != null;
|
||||
if (launch != null) {
|
||||
Map<String, Object> attributes = null;
|
||||
try {
|
||||
attributes = launch.getLaunchConfiguration().getAttributes();
|
||||
} catch (CoreException e) {}
|
||||
|
||||
boolean isTcpConnection = CDebugUtils.getAttribute(
|
||||
attributes,
|
||||
IGDBLaunchConfigurationConstants.ATTR_REMOTE_TCP,
|
||||
false);
|
||||
|
||||
if (isTcpConnection) {
|
||||
String remoteTcpHost = CDebugUtils.getAttribute(
|
||||
attributes,
|
||||
IGDBLaunchConfigurationConstants.ATTR_HOST, INVALID);
|
||||
String remoteTcpPort = CDebugUtils.getAttribute(
|
||||
attributes,
|
||||
IGDBLaunchConfigurationConstants.ATTR_PORT, INVALID);
|
||||
|
||||
fCommandControl.queueCommand(
|
||||
fCommandFactory.createMITargetSelect(fCommandControl.getContext(),
|
||||
remoteTcpHost, remoteTcpPort, true),
|
||||
new DataRequestMonitor<MIInfo>(ImmediateExecutor.getInstance(), rm));
|
||||
} else {
|
||||
String serialDevice = CDebugUtils.getAttribute(
|
||||
attributes,
|
||||
IGDBLaunchConfigurationConstants.ATTR_DEV, INVALID);
|
||||
|
||||
fCommandControl.queueCommand(
|
||||
fCommandFactory.createMITargetSelect(fCommandControl.getContext(),
|
||||
serialDevice, true),
|
||||
new DataRequestMonitor<MIInfo>(ImmediateExecutor.getInstance(), rm));
|
||||
}
|
||||
return;
|
||||
} else {
|
||||
rm.setStatus(new Status(IStatus.ERROR, GdbPlugin.PLUGIN_ID, INTERNAL_ERROR, "Cannot reconnect to target.", null)); //$NON-NLS-1$
|
||||
}
|
||||
}
|
||||
|
||||
rm.done();
|
||||
}
|
||||
},
|
||||
// Now, actually do the attach
|
||||
new Step() {
|
||||
@Override
|
||||
|
@ -248,12 +351,14 @@ public class GDBProcesses_7_2 extends GDBProcesses_7_1 {
|
|||
rm.done();
|
||||
}
|
||||
},
|
||||
// Store the fully formed container context so it can be returned to the caller.
|
||||
// Store the fully formed container context so it can be returned to the caller
|
||||
// and mark that we are not dealing with the first process anymore.
|
||||
new Step() {
|
||||
@Override
|
||||
public void execute(RequestMonitor rm) {
|
||||
dataRm.setData(fContainerDmc);
|
||||
|
||||
setIsInitialProcess(false);
|
||||
|
||||
rm.done();
|
||||
}
|
||||
},
|
||||
|
@ -402,5 +507,17 @@ public class GDBProcesses_7_2 extends GDBProcesses_7_1 {
|
|||
|
||||
super.eventDispatched(e);
|
||||
}
|
||||
|
||||
/**
|
||||
* GDB 7.2 has a bug which causes a gdbserver crash if we set the binary after we
|
||||
* have connected to the target. Because GDB 7.2.1 was not released when CDT 8.0
|
||||
* was released, we need to workaround the bug in Eclipse.
|
||||
*
|
||||
* See http://sourceware.org/ml/gdb-patches/2011-03/msg00531.html
|
||||
* and Bug 352998
|
||||
* */
|
||||
private boolean needFixForGDB72Bug352998() {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue