1
0
Fork 0
mirror of https://github.com/eclipse-cdt/cdt synced 2025-08-15 12:15:47 +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:10:55 -04:00
parent 0b330a4c9e
commit 142ab81593
5 changed files with 190 additions and 3 deletions

View file

@ -7,6 +7,7 @@
* *
* Contributors: * Contributors:
* Onur Akdemir (TUBITAK BILGEM-ITI) - Multi-process debugging (Bug 237306) * Onur Akdemir (TUBITAK BILGEM-ITI) - Multi-process debugging (Bug 237306)
* Marc Khouzam (Ericsson) - Workaround for Bug 352998
*******************************************************************************/ *******************************************************************************/
package org.eclipse.cdt.dsf.gdb.service; package org.eclipse.cdt.dsf.gdb.service;
@ -14,6 +15,7 @@ import java.util.HashSet;
import java.util.Map; import java.util.Map;
import java.util.Set; import java.util.Set;
import org.eclipse.cdt.debug.core.CDebugUtils;
import org.eclipse.cdt.dsf.concurrent.DataRequestMonitor; import org.eclipse.cdt.dsf.concurrent.DataRequestMonitor;
import org.eclipse.cdt.dsf.concurrent.DsfExecutor; import org.eclipse.cdt.dsf.concurrent.DsfExecutor;
import org.eclipse.cdt.dsf.concurrent.ImmediateExecutor; import org.eclipse.cdt.dsf.concurrent.ImmediateExecutor;
@ -56,6 +58,15 @@ public class GDBProcesses_7_2 extends GDBProcesses_7_1 {
private IGDBControl fCommandControl; private IGDBControl fCommandControl;
private IGDBBackend fBackend; 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. * Set of processes that are currently being restarted.
* We use this set for such things as not removing breakpoints * We use this set for such things as not removing breakpoints
@ -162,7 +173,6 @@ public class GDBProcesses_7_2 extends GDBProcesses_7_1 {
if (isInitialProcess()) { if (isInitialProcess()) {
// If it is the first inferior, GDB has already created it for us // 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 // We really should get the id from GDB instead of hard-coding it
setIsInitialProcess(false);
fContainerDmc = createContainerContext(procCtx, "i1"); //$NON-NLS-1$ fContainerDmc = createContainerContext(procCtx, "i1"); //$NON-NLS-1$
rm.done(); rm.done();
return; return;
@ -184,10 +194,45 @@ 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(
fCommandFactory.createMITargetDisconnect(controlDmc),
new DataRequestMonitor<MIInfo>(ImmediateExecutor.getInstance(), rm) {
@Override
protected void handleSuccess() {
fNeedToReconnect = true;
rm.done();
}
});
return;
}
}
}
rm.done();
}
}, },
new Step() { new Step() {
@Override @Override
public void execute(RequestMonitor rm) { public void execute(RequestMonitor rm) {
// Now, set the binary to be used.
if (binaryPath != null) { if (binaryPath != null) {
fCommandControl.queueCommand( fCommandControl.queueCommand(
fCommandFactory.createMIFileExecAndSymbols(fContainerDmc, binaryPath), fCommandFactory.createMIFileExecAndSymbols(fContainerDmc, binaryPath),
@ -195,6 +240,61 @@ public class GDBProcesses_7_2 extends GDBProcesses_7_1 {
return; return;
} }
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) {
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(); rm.done();
} }
}, },
@ -248,11 +348,13 @@ public class GDBProcesses_7_2 extends GDBProcesses_7_1 {
rm.done(); 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() { new Step() {
@Override @Override
public void execute(RequestMonitor rm) { public void execute(RequestMonitor rm) {
dataRm.setData(fContainerDmc); dataRm.setData(fContainerDmc);
setIsInitialProcess(false);
rm.done(); rm.done();
} }
@ -402,5 +504,22 @@ public class GDBProcesses_7_2 extends GDBProcesses_7_1 {
super.eventDispatched(e); 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.
*
* This method can be overridden to easily disable the workaround, for versions
* of GDB that no longer have the bug.
*
* See http://sourceware.org/ml/gdb-patches/2011-03/msg00531.html
* and Bug 352998
*
* @since 4.1
*/
protected boolean needFixForGDB72Bug352998() {
return true;
}
} }

View file

@ -0,0 +1,32 @@
/*******************************************************************************
* 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.service;
import org.eclipse.cdt.dsf.service.DsfSession;
/**
* Version for GDB 7.2.1, which does not need a workaround
* for a bug in GDB 7.2 (Bug 352998)
*
* @since 4.1
*/
public class GDBProcesses_7_2_1 extends GDBProcesses_7_2 {
public GDBProcesses_7_2_1(DsfSession session) {
super(session);
}
@Override
protected boolean needFixForGDB72Bug352998() {
return false;
}
}

View file

@ -53,6 +53,8 @@ public class GdbDebugServicesFactory extends AbstractDsfDebugServicesFactory {
public static final String GDB_7_1_VERSION = "7.1"; //$NON-NLS-1$ public static final String GDB_7_1_VERSION = "7.1"; //$NON-NLS-1$
/** @since 4.0 */ /** @since 4.0 */
public static final String GDB_7_2_VERSION = "7.2"; //$NON-NLS-1$ public static final String GDB_7_2_VERSION = "7.2"; //$NON-NLS-1$
/** @since 4.1 */
public static final String GDB_7_2_1_VERSION = "7.2.1"; //$NON-NLS-1$
private final String fVersion; private final String fVersion;
@ -150,6 +152,9 @@ public class GdbDebugServicesFactory extends AbstractDsfDebugServicesFactory {
@Override @Override
protected IProcesses createProcessesService(DsfSession session) { protected IProcesses createProcessesService(DsfSession session) {
if (GDB_7_2_1_VERSION.compareTo(fVersion) <= 0) {
return new GDBProcesses_7_2_1(session);
}
if (GDB_7_2_VERSION.compareTo(fVersion) <= 0) { if (GDB_7_2_VERSION.compareTo(fVersion) <= 0) {
return new GDBProcesses_7_2(session); return new GDBProcesses_7_2(session);
} }

View file

@ -119,6 +119,7 @@ import org.eclipse.cdt.dsf.mi.service.command.commands.MIStackListLocals;
import org.eclipse.cdt.dsf.mi.service.command.commands.MIStackSelectFrame; import org.eclipse.cdt.dsf.mi.service.command.commands.MIStackSelectFrame;
import org.eclipse.cdt.dsf.mi.service.command.commands.MITargetAttach; import org.eclipse.cdt.dsf.mi.service.command.commands.MITargetAttach;
import org.eclipse.cdt.dsf.mi.service.command.commands.MITargetDetach; import org.eclipse.cdt.dsf.mi.service.command.commands.MITargetDetach;
import org.eclipse.cdt.dsf.mi.service.command.commands.MITargetDisconnect;
import org.eclipse.cdt.dsf.mi.service.command.commands.MITargetDownload; import org.eclipse.cdt.dsf.mi.service.command.commands.MITargetDownload;
import org.eclipse.cdt.dsf.mi.service.command.commands.MITargetSelect; import org.eclipse.cdt.dsf.mi.service.command.commands.MITargetSelect;
import org.eclipse.cdt.dsf.mi.service.command.commands.MITargetSelectCore; import org.eclipse.cdt.dsf.mi.service.command.commands.MITargetSelectCore;
@ -761,6 +762,11 @@ public class CommandFactory {
return new MITargetSelectTFile(ctx, traceFilePath); return new MITargetSelectTFile(ctx, traceFilePath);
} }
/** @since 4.1 */
public ICommand<MIInfo> createMITargetDisconnect(ICommandControlDMContext ctx) {
return new MITargetDisconnect(ctx);
}
public ICommand<MITargetDownloadInfo> createMITargetDownload(ICommandControlDMContext ctx) { public ICommand<MITargetDownloadInfo> createMITargetDownload(ICommandControlDMContext ctx) {
return new MITargetDownload(ctx); return new MITargetDownload(ctx);
} }

View file

@ -0,0 +1,25 @@
/*******************************************************************************
* 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.mi.service.command.commands;
import org.eclipse.cdt.dsf.debug.service.command.ICommandControlService.ICommandControlDMContext;
import org.eclipse.cdt.dsf.mi.service.command.output.MIInfo;
/**
* This command disconnects from the remote target.
* @since 4.1
*/
public class MITargetDisconnect extends MICommand<MIInfo> {
public MITargetDisconnect(ICommandControlDMContext ctx) {
super(ctx, "-target-disconnect"); //$NON-NLS-1$
}
}