1
0
Fork 0
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:
Marc Khouzam 2011-07-25 09:48:53 -04:00
parent f706c92bdf
commit 0c43bc15c7
2 changed files with 146 additions and 3 deletions

View file

@ -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$
}
}

View file

@ -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,11 +351,13 @@ 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;
}
}