mirror of
https://github.com/eclipse-cdt/cdt
synced 2025-06-09 10:46:02 +02:00
Bug 472765: Use gdb's "set substitute-path from to"
Add support for gdb's "set substitute-path from to" by adding a new service called GDBSourceLookup that uses GDB to perform the path mapping. The new GDBSourceLookup service uses the new GdbSourceLookupDirector to get the set of paths that need mapping using GDB's "set substitute-path" and the director resolves compilation path differently so as to leave the GDB backend to handle the local path to compile path resolution. The MappingSourceContainer has been enhanced to allow a per mapping container override of the new behaviour. This is a fallback as the default behaviour when using GDB is to use "set substitute-path". The MappingSourceContainerDialog exposes the new option in MappingSourceContainer as a checkbox at the bottom of the path mapping dialog in a backend agnostic way. The new code is tested in methods called "sourceSubstitute*" and mirror the same tests for the now non-backend handled version which are "sourceMapping*". Note that doMappingAndLaunch/doSubstituteAndLaunch have been updated to explicitly check or uncheck the setIsMappingWithBackendEnabled setting Change-Id: I122d7c597cd461d8e38c4f82522ccfdf9e51a5ba Signed-off-by: Jonah Graham <jonah@kichwacoders.com>
This commit is contained in:
parent
315fc0f5ef
commit
6283890715
18 changed files with 967 additions and 64 deletions
|
@ -1,5 +1,5 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (c) 2004, 2012 QNX Software Systems and others.
|
||||
* Copyright (c) 2004, 2015 QNX Software Systems 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
|
||||
|
@ -40,6 +40,7 @@ public class MappingSourceContainer extends AbstractSourceContainer implements I
|
|||
|
||||
private String fName;
|
||||
private ArrayList<MapEntrySourceContainer> fContainers;
|
||||
private boolean fIsMappingWithBackendEnabled = true;
|
||||
|
||||
/**
|
||||
* Constructor for MappingSourceContainer.
|
||||
|
@ -176,6 +177,7 @@ public class MappingSourceContainer extends AbstractSourceContainer implements I
|
|||
|
||||
public MappingSourceContainer copy() {
|
||||
MappingSourceContainer copy = new MappingSourceContainer(fName);
|
||||
copy.setIsMappingWithBackendEnabled(isMappingWithBackendEnabled());
|
||||
MapEntrySourceContainer[] entries = new MapEntrySourceContainer[fContainers.size()];
|
||||
for (int i = 0; i < entries.length; ++i) {
|
||||
copy.addMapEntry(fContainers.get(i).copy());
|
||||
|
@ -209,4 +211,29 @@ public class MappingSourceContainer extends AbstractSourceContainer implements I
|
|||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return <code>true</code> if the user has allowed this mapping container
|
||||
* to be mapped with the backend (e.g. GDB's set substitute-path) instead of
|
||||
* using {@link #findSourceElements(String)} and
|
||||
* {@link #getCompilationPath(String)}
|
||||
* <p>
|
||||
* The default if otherwise unspecified is to allow the GDB backend to
|
||||
* handle the substitution.
|
||||
*
|
||||
* @since 8.0
|
||||
*/
|
||||
public boolean isMappingWithBackendEnabled() {
|
||||
return fIsMappingWithBackendEnabled;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set whether mapping is enabled. See
|
||||
* {@link #isMappingWithBackendEnabled()}
|
||||
*
|
||||
* @since 8.0
|
||||
*/
|
||||
public void setIsMappingWithBackendEnabled(boolean isMappingWithBackendEnabled) {
|
||||
fIsMappingWithBackendEnabled = isMappingWithBackendEnabled;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (c) 2004, 2012 QNX Software Systems and others.
|
||||
* Copyright (c) 2004, 2015 QNX Software Systems 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
|
||||
|
@ -30,6 +30,7 @@ public class MappingSourceContainerType extends AbstractSourceContainerTypeDeleg
|
|||
private final static String ELEMENT_MAPPING = "mapping"; //$NON-NLS-1$
|
||||
private final static String ELEMENT_MAP_ENTRY = "mapEntry"; //$NON-NLS-1$
|
||||
private final static String ATTR_NAME = "name"; //$NON-NLS-1$
|
||||
private final static String ATTR_BACKEND_ENABLED = "backend_enabled"; //$NON-NLS-1$
|
||||
private final static String ATTR_MEMENTO = "memento"; //$NON-NLS-1$
|
||||
|
||||
/* (non-Javadoc)
|
||||
|
@ -44,6 +45,10 @@ public class MappingSourceContainerType extends AbstractSourceContainerTypeDeleg
|
|||
String name = element.getAttribute(ATTR_NAME);
|
||||
if (name == null)
|
||||
name = ""; //$NON-NLS-1$
|
||||
String backendEnabled = element.getAttribute(ATTR_BACKEND_ENABLED);
|
||||
// When upgrading source locator (See Bug 472765),
|
||||
// do not enable backend path substitution
|
||||
boolean enabled = Boolean.parseBoolean(backendEnabled);
|
||||
List<MapEntrySourceContainer> entries = new ArrayList<MapEntrySourceContainer>();
|
||||
Node childNode = element.getFirstChild();
|
||||
while (childNode != null) {
|
||||
|
@ -62,6 +67,7 @@ public class MappingSourceContainerType extends AbstractSourceContainerTypeDeleg
|
|||
childNode = childNode.getNextSibling();
|
||||
}
|
||||
MappingSourceContainer container = new MappingSourceContainer(name);
|
||||
container.setIsMappingWithBackendEnabled(enabled);
|
||||
for (MapEntrySourceContainer entry : entries) {
|
||||
container.addMapEntry(entry);
|
||||
}
|
||||
|
@ -81,6 +87,8 @@ public class MappingSourceContainerType extends AbstractSourceContainerTypeDeleg
|
|||
Document document = newDocument();
|
||||
Element element = document.createElement(ELEMENT_MAPPING);
|
||||
element.setAttribute(ATTR_NAME, container.getName());
|
||||
boolean backendEnabled = ((MappingSourceContainer)container).isMappingWithBackendEnabled();
|
||||
element.setAttribute(ATTR_BACKEND_ENABLED, String.valueOf(backendEnabled));
|
||||
ISourceContainer[] entries = ((MappingSourceContainer)container).getSourceContainers();
|
||||
for (int i = 0; i < entries.length; ++i) {
|
||||
Element child = document.createElement(ELEMENT_MAP_ENTRY);
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (c) 2009, 2012 ARM Limited and others.
|
||||
* Copyright (c) 2009, 2015 ARM Limited 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
|
||||
|
@ -166,6 +166,7 @@ public class MappingSourceContainerDialog extends TitleAreaDialog {
|
|||
private MappingSourceContainer fContainer;
|
||||
|
||||
private Text fNameText;
|
||||
private Button fMappingWithBackendEnabledCheck;
|
||||
private TableViewer fViewer;
|
||||
private Button fAddButton;
|
||||
private Button fRemoveButton;
|
||||
|
@ -254,6 +255,7 @@ public class MappingSourceContainerDialog extends TitleAreaDialog {
|
|||
createNameArea(composite);
|
||||
createViewer(composite);
|
||||
createViewerButtonBar(composite);
|
||||
createMappingWithBackendEnabledArea(composite);
|
||||
|
||||
PlatformUI.getWorkbench().getHelpSystem().setHelp(getShell(), ICDebugHelpContextIds.SOURCE_PATH_MAP_ENTRY_DIALOG);
|
||||
return control;
|
||||
|
@ -266,6 +268,7 @@ public class MappingSourceContainerDialog extends TitleAreaDialog {
|
|||
protected void okPressed() {
|
||||
fOriginalContainer.clear();
|
||||
fOriginalContainer.setName(fNameText.getText().trim());
|
||||
fOriginalContainer.setIsMappingWithBackendEnabled(fMappingWithBackendEnabledCheck.getSelection());
|
||||
try {
|
||||
fOriginalContainer.addMapEntries((MapEntrySourceContainer[])fContainer.getSourceContainers());
|
||||
} catch (CoreException e) {
|
||||
|
@ -307,6 +310,18 @@ public class MappingSourceContainerDialog extends TitleAreaDialog {
|
|||
});
|
||||
}
|
||||
|
||||
private void createMappingWithBackendEnabledArea(Composite parent) {
|
||||
Composite composite = new Composite(parent, SWT.None);
|
||||
composite.setLayout(new GridLayout(1, false));
|
||||
composite.setLayoutData(new GridData(SWT.FILL, SWT.TOP, true, false, 2, 1));
|
||||
|
||||
fMappingWithBackendEnabledCheck = new Button(composite, SWT.CHECK);
|
||||
fMappingWithBackendEnabledCheck.setText(SourceLookupUIMessages.PathMappingDialog_MappingWithBackendEnabled);
|
||||
fMappingWithBackendEnabledCheck.setToolTipText(SourceLookupUIMessages.PathMappingDialog_MappingWithBackendEnabledTooltip);
|
||||
GridData data = new GridData(SWT.FILL, SWT.CENTER, false, false);
|
||||
fMappingWithBackendEnabledCheck.setLayoutData(data);
|
||||
}
|
||||
|
||||
private void createViewer(Composite parent) {
|
||||
Composite tableComp = new Composite(parent, SWT.NONE);
|
||||
tableComp.setLayout(new GridLayout());
|
||||
|
@ -442,6 +457,7 @@ public class MappingSourceContainerDialog extends TitleAreaDialog {
|
|||
private void initialize() {
|
||||
fNameText.setText(fContainer.getName());
|
||||
fNameText.selectAll();
|
||||
fMappingWithBackendEnabledCheck.setSelection(fContainer.isMappingWithBackendEnabled());
|
||||
fViewer.setInput(fContainer);
|
||||
updateViewerButtons();
|
||||
}
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (c) 2004, 2010 QNX Software Systems and others.
|
||||
* Copyright (c) 2004, 2015 QNX Software Systems 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
|
||||
|
@ -44,6 +44,8 @@ public class SourceLookupUIMessages extends NLS {
|
|||
public static String PathMappingDialog_14;
|
||||
public static String PathMappingDialog_15;
|
||||
public static String PathMappingDialog_16;
|
||||
public static String PathMappingDialog_MappingWithBackendEnabled;
|
||||
public static String PathMappingDialog_MappingWithBackendEnabledTooltip;
|
||||
public static String RemoveAction_0;
|
||||
public static String SourceContainerWorkbenchAdapter_0;
|
||||
public static String UpAction_0;
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
###############################################################################
|
||||
# Copyright (c) 2005, 2010 QNX Software Systems and others.
|
||||
# Copyright (c) 2005, 2015 QNX Software Systems 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
|
||||
|
@ -41,6 +41,8 @@ PathMappingDialog_13=&Add...
|
|||
PathMappingDialog_14=&Edit...
|
||||
PathMappingDialog_15=Re&move
|
||||
PathMappingDialog_16=Path Mappings
|
||||
PathMappingDialog_MappingWithBackendEnabled=Enable performing the mapping with the debugger backend.
|
||||
PathMappingDialog_MappingWithBackendEnabledTooltip=Allow the mapping to be performed with the debugger backend where supported. This allows any direct interaction with the backend (for example via the console) to have a consistent view of file names.
|
||||
RemoveAction_0=Re&move
|
||||
SourceContainerWorkbenchAdapter_0=Path Mapping:
|
||||
UpAction_0=U&p
|
||||
|
|
|
@ -36,11 +36,13 @@ import org.eclipse.cdt.dsf.concurrent.RequestMonitorWithProgress;
|
|||
import org.eclipse.cdt.dsf.datamodel.DataModelInitializedEvent;
|
||||
import org.eclipse.cdt.dsf.datamodel.IDMContext;
|
||||
import org.eclipse.cdt.dsf.debug.service.ISourceLookup.ISourceLookupDMContext;
|
||||
import org.eclipse.cdt.dsf.debug.service.command.ICommandControlService.ICommandControlDMContext;
|
||||
import org.eclipse.cdt.dsf.gdb.IGDBLaunchConfigurationConstants;
|
||||
import org.eclipse.cdt.dsf.gdb.IGdbDebugPreferenceConstants;
|
||||
import org.eclipse.cdt.dsf.gdb.actions.IConnect;
|
||||
import org.eclipse.cdt.dsf.gdb.internal.GdbPlugin;
|
||||
import org.eclipse.cdt.dsf.gdb.service.IGDBBackend;
|
||||
import org.eclipse.cdt.dsf.gdb.service.IGDBSourceLookup;
|
||||
import org.eclipse.cdt.dsf.gdb.service.SessionType;
|
||||
import org.eclipse.cdt.dsf.gdb.service.command.IGDBControl;
|
||||
import org.eclipse.cdt.dsf.mi.service.CSourceLookup;
|
||||
|
@ -111,6 +113,7 @@ public class FinalLaunchSequence extends ReflectionSequence {
|
|||
"stepSourceGDBInitFile", //$NON-NLS-1$
|
||||
"stepSetAutoLoadSharedLibrarySymbols", //$NON-NLS-1$
|
||||
"stepSetSharedLibraryPaths", //$NON-NLS-1$
|
||||
"stepSetSourceSubstitutePath", //$NON-NLS-1$
|
||||
|
||||
// -environment-directory with a lot of paths could
|
||||
// make setting breakpoint incredibly slow, which makes
|
||||
|
@ -483,6 +486,26 @@ public class FinalLaunchSequence extends ReflectionSequence {
|
|||
sourceLookup.setSourceLookupPath(sourceLookupDmc, locator.getSourceContainers(), requestMonitor);
|
||||
}
|
||||
|
||||
/**
|
||||
* Setup the source substitute paths.
|
||||
*
|
||||
* This step tells GDB to to handle all the path re-writing using
|
||||
* "set substitute-path"
|
||||
*
|
||||
* @since 5.0
|
||||
*/
|
||||
@Execute
|
||||
public void stepSetSourceSubstitutePath(RequestMonitor rm) {
|
||||
IGDBSourceLookup sourceSubPath = fTracker.getService(IGDBSourceLookup.class);
|
||||
ICommandControlDMContext context = fCommandControl.getContext();
|
||||
if (sourceSubPath == null || !(context instanceof ISourceLookupDMContext)) {
|
||||
rm.done();
|
||||
} else {
|
||||
ISourceLookupDMContext sourceLookupCtx = (ISourceLookupDMContext) context;
|
||||
sourceSubPath.initializeSourceSubstitutions(sourceLookupCtx, rm);
|
||||
}
|
||||
}
|
||||
|
||||
private static final String INVALID = "invalid"; //$NON-NLS-1$
|
||||
/**
|
||||
* If we are dealing with a remote-attach debugging session, connect to the target.
|
||||
|
|
|
@ -430,7 +430,7 @@ public class GdbLaunchDelegate extends AbstractCLaunchDelegate2
|
|||
* @since 4.1
|
||||
*/
|
||||
protected DsfSourceLookupDirector createDsfSourceLocator(ILaunchConfiguration configuration, DsfSession session) throws CoreException {
|
||||
return new DsfSourceLookupDirector(session);
|
||||
return new GdbSourceLookupDirector(session);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -0,0 +1,175 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (c) 2015 Kichwa Coders 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:
|
||||
* Jonah Graham (Kichwa Coders) - initial API and implementation to Add support for gdb's "set substitute-path" (Bug 472765)
|
||||
*******************************************************************************/
|
||||
package org.eclipse.cdt.dsf.gdb.launching;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import org.eclipse.cdt.debug.core.sourcelookup.IMappingSourceContainer;
|
||||
import org.eclipse.cdt.debug.core.sourcelookup.MappingSourceContainer;
|
||||
import org.eclipse.cdt.debug.internal.core.sourcelookup.MapEntrySourceContainer;
|
||||
import org.eclipse.cdt.dsf.debug.sourcelookup.DsfSourceLookupDirector;
|
||||
import org.eclipse.cdt.dsf.gdb.service.IGDBSourceLookup;
|
||||
import org.eclipse.cdt.dsf.service.DsfSession;
|
||||
import org.eclipse.core.runtime.CoreException;
|
||||
import org.eclipse.core.runtime.IPath;
|
||||
import org.eclipse.core.runtime.Path;
|
||||
import org.eclipse.debug.core.sourcelookup.ISourceContainer;
|
||||
import org.eclipse.debug.core.sourcelookup.ISourceLookupParticipant;
|
||||
import org.eclipse.debug.core.sourcelookup.containers.DefaultSourceContainer;
|
||||
|
||||
/**
|
||||
* A Source Lookup director that extends the standard DSF version to support the
|
||||
* GDB backend handling path substitutions using gdb's "set substitute-path"
|
||||
* mechanism. This director works in tandem with {@link IGDBSourceLookup}
|
||||
* service to synchronise GDB's path substitutions.
|
||||
*
|
||||
* @since 5.0
|
||||
*/
|
||||
public class GdbSourceLookupDirector extends DsfSourceLookupDirector {
|
||||
private final DsfSession fSession;
|
||||
|
||||
public GdbSourceLookupDirector(DsfSession session) {
|
||||
super(session);
|
||||
fSession = session;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void initializeParticipants() {
|
||||
/*
|
||||
* We don't call super as we don't want DsfSourceLookupParticipant to be
|
||||
* added explicitly. Instead we use GdbSourceLookupParticipant which
|
||||
* extends DsfSourceLookupParticipant and does not use the mappings
|
||||
* directly but relies on GDB's "set substitute-path".
|
||||
*/
|
||||
addParticipants(new ISourceLookupParticipant[] { new GdbSourceLookupParticipant(fSession) });
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a map of substitutions with the Key being the compilation path and
|
||||
* the Value being the machine local path.
|
||||
*
|
||||
* @return map of substitutions
|
||||
*/
|
||||
public Map<String, String> getSubstitutionsPaths() {
|
||||
Map<String, String> entries = new HashMap<>();
|
||||
collectSubstitutionsPaths(getSourceContainers(), entries);
|
||||
return entries;
|
||||
}
|
||||
|
||||
protected void collectSubstitutionsPaths(ISourceContainer[] containers, Map<String, String> entries) {
|
||||
for (ISourceContainer container : containers) {
|
||||
if (container instanceof MapEntrySourceContainer) {
|
||||
MapEntrySourceContainer sourceSubContainer = (MapEntrySourceContainer) container;
|
||||
|
||||
IPath from = sourceSubContainer.getBackendPath();
|
||||
IPath to = sourceSubContainer.getLocalPath();
|
||||
if (from != null && to != null) {
|
||||
entries.put(from.toOSString(), to.toOSString());
|
||||
}
|
||||
} else if (container.isComposite()) {
|
||||
ISourceContainer[] childContainers;
|
||||
try {
|
||||
childContainers = container.getSourceContainers();
|
||||
} catch (CoreException e) {
|
||||
/*
|
||||
* Consistent with other uses of getSourceContainers, we
|
||||
* silently ignore these children.
|
||||
*/
|
||||
childContainers = new ISourceContainer[0];
|
||||
}
|
||||
if (container instanceof MappingSourceContainer) {
|
||||
MappingSourceContainer mappingSourceContainer = (MappingSourceContainer) container;
|
||||
if (mappingSourceContainer.isMappingWithBackendEnabled()) {
|
||||
collectSubstitutionsPaths(childContainers, entries);
|
||||
} else {
|
||||
/*
|
||||
* This mapping has explicitly requested *not* to do a
|
||||
* substitute, so don't recurse on children here.
|
||||
*/
|
||||
}
|
||||
} else {
|
||||
/*
|
||||
* There can be MappingSourceContainers in
|
||||
* DefaultSourceContainer, but not in other types of
|
||||
* composite containers (e.g. a DirectorySourceContainer
|
||||
* cannot contain a MappingSourceContainer).
|
||||
*
|
||||
* It is important we don't recurse across all composites
|
||||
* containers for performance reasons. If a
|
||||
* DirectorySourceContainer was recursed here, then it could
|
||||
* means recursing through the entire directory structure
|
||||
* under that container.
|
||||
*/
|
||||
if (container instanceof DefaultSourceContainer) {
|
||||
collectSubstitutionsPaths(childContainers, entries);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the compilation path for the given sourceName. Unlike super's
|
||||
* version, for {@link MappingSourceContainer}s where backend mapping is
|
||||
* enabled this method is a no-op as in those cases the backend already
|
||||
* matches.
|
||||
*/
|
||||
@Override
|
||||
public IPath getCompilationPath(String sourceName) {
|
||||
return getCompilationPath(getSourceContainers(), sourceName);
|
||||
}
|
||||
|
||||
/**
|
||||
* This method mirrors the logic of
|
||||
* {@link #collectSubstitutionsPaths(ISourceContainer[], Map)} on which
|
||||
* containers are iterated and excluded.
|
||||
*/
|
||||
protected IPath getCompilationPath(ISourceContainer[] containers, String sourceName) {
|
||||
for (ISourceContainer container : containers) {
|
||||
|
||||
if (container instanceof IMappingSourceContainer) {
|
||||
IPath mappedPath = ((IMappingSourceContainer) container).getCompilationPath(sourceName);
|
||||
if (mappedPath != null) {
|
||||
if (container instanceof MappingSourceContainer
|
||||
&& ((MappingSourceContainer) container).isMappingWithBackendEnabled()) {
|
||||
/*
|
||||
* This mapping is being handled by GDB backend (i.e. it was
|
||||
* collected by collectSubstitutionsPaths to pass to gdb's
|
||||
* "set substitute-path"). Because GDB is doing the
|
||||
* translation on it, pass the local name to GDB, not the
|
||||
* translated name.
|
||||
*/
|
||||
return new Path(sourceName);
|
||||
}
|
||||
return mappedPath;
|
||||
}
|
||||
} else if (container.isComposite()) {
|
||||
ISourceContainer[] childContainers = null;
|
||||
try {
|
||||
childContainers = container.getSourceContainers();
|
||||
} catch (CoreException e) {
|
||||
/*
|
||||
* Consistent with other uses of getSourceContainers, we
|
||||
* silently ignore these children.
|
||||
*/
|
||||
}
|
||||
if (childContainers != null) {
|
||||
IPath path = getCompilationPath(childContainers, sourceName);
|
||||
if (path != null) {
|
||||
return path;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,133 @@
|
|||
package org.eclipse.cdt.dsf.gdb.launching;
|
||||
|
||||
import java.util.concurrent.ExecutionException;
|
||||
|
||||
import org.eclipse.cdt.dsf.concurrent.ConfinedToDsfExecutor;
|
||||
import org.eclipse.cdt.dsf.concurrent.DataRequestMonitor;
|
||||
import org.eclipse.cdt.dsf.concurrent.DsfExecutor;
|
||||
import org.eclipse.cdt.dsf.concurrent.Query;
|
||||
import org.eclipse.cdt.dsf.concurrent.RequestMonitor;
|
||||
import org.eclipse.cdt.dsf.concurrent.ThreadSafe;
|
||||
import org.eclipse.cdt.dsf.debug.service.ICachingService;
|
||||
import org.eclipse.cdt.dsf.debug.service.ISourceLookup.ISourceLookupDMContext;
|
||||
import org.eclipse.cdt.dsf.debug.service.IStack;
|
||||
import org.eclipse.cdt.dsf.debug.service.command.ICommandControlService;
|
||||
import org.eclipse.cdt.dsf.debug.sourcelookup.DsfSourceLookupParticipant;
|
||||
import org.eclipse.cdt.dsf.gdb.internal.GdbPlugin;
|
||||
import org.eclipse.cdt.dsf.gdb.service.IGDBSourceLookup;
|
||||
import org.eclipse.cdt.dsf.service.DsfServicesTracker;
|
||||
import org.eclipse.cdt.dsf.service.DsfSession;
|
||||
import org.eclipse.debug.core.sourcelookup.ISourceLookupDirector;
|
||||
|
||||
/**
|
||||
* Source Lookup Participant that notifies the {@link IGDBSourceLookup} service
|
||||
* of changes to the lookup path to allow the source lookup service to update
|
||||
* GDB's substituted paths.
|
||||
*
|
||||
* @since 5.0
|
||||
*/
|
||||
@ThreadSafe
|
||||
public class GdbSourceLookupParticipant extends DsfSourceLookupParticipant {
|
||||
|
||||
private DsfExecutor fExecutor;
|
||||
private String fSessionId;
|
||||
private DsfServicesTracker fServicesTracker;
|
||||
|
||||
public GdbSourceLookupParticipant(DsfSession session) {
|
||||
super(session);
|
||||
fSessionId = session.getId();
|
||||
fExecutor = session.getExecutor();
|
||||
fServicesTracker = new DsfServicesTracker(GdbPlugin.getBundleContext(), fSessionId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void init(ISourceLookupDirector director) {
|
||||
super.init(director);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void dispose() {
|
||||
fServicesTracker.dispose();
|
||||
super.dispose();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void sourceContainersChanged(final ISourceLookupDirector director) {
|
||||
super.sourceContainersChanged(director);
|
||||
|
||||
/*
|
||||
* Update the substitution paths in GDB. Ideally we would always run
|
||||
* this atomically to block the source lookup from attempting to do a
|
||||
* lookup until GDB is fully updated.
|
||||
*
|
||||
* However, if we are already on the executor thread there is no way to
|
||||
* make this atomic. In practice this case does not matter as the times
|
||||
* sourceContainersChanged is called when on the executor thread are
|
||||
* when the launch configuration is being saved and in that case the
|
||||
* source containers are not even changing.
|
||||
*/
|
||||
if (fExecutor.isInExecutorThread()) {
|
||||
sourceContainersChangedOnDispatchThread(director, new RequestMonitor(fExecutor, null));
|
||||
} else {
|
||||
Query<Object> query = new Query<Object>() {
|
||||
@Override
|
||||
protected void execute(final DataRequestMonitor<Object> rm) {
|
||||
sourceContainersChangedOnDispatchThread(director, rm);
|
||||
}
|
||||
|
||||
};
|
||||
fExecutor.execute(query);
|
||||
try {
|
||||
query.get();
|
||||
} catch (InterruptedException | ExecutionException e) {
|
||||
// We have failed to update in some way, we don't really have a
|
||||
// path to expose the failure so at least log it.
|
||||
GdbPlugin.log(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ConfinedToDsfExecutor("fExecutor")
|
||||
protected void sourceContainersChangedOnDispatchThread(final ISourceLookupDirector director,
|
||||
final RequestMonitor rm) {
|
||||
IGDBSourceLookup lookup = fServicesTracker.getService(IGDBSourceLookup.class);
|
||||
if (lookup != null) {
|
||||
ICommandControlService command = fServicesTracker.getService(ICommandControlService.class);
|
||||
ISourceLookupDMContext context = (ISourceLookupDMContext) command.getContext();
|
||||
lookup.sourceContainersChanged(context, new DataRequestMonitor<Boolean>(fExecutor, rm) {
|
||||
@Override
|
||||
protected void handleCompleted() {
|
||||
/*
|
||||
* Once GDB is updated, we need to flush the IStack's cache,
|
||||
* so that #getSourceName get the new names.
|
||||
*/
|
||||
if (isSuccess() && getData()) {
|
||||
IStack stackService = fServicesTracker.getService(IStack.class);
|
||||
if (stackService instanceof ICachingService) {
|
||||
/*
|
||||
* XXX: Ideally we would issue an event here to
|
||||
* flush the cache. But if we did that we would have
|
||||
* to add some interlocking to prevent the call to
|
||||
* IStack.getFrameData() (Called from
|
||||
* super.getSourceNameOnDispatchThread) from
|
||||
* returning until the event had been fully
|
||||
* propogated. At the moment there is no way to
|
||||
* ensure that happens.
|
||||
*
|
||||
* XXX: Adding an event would allow other interested
|
||||
* parties (such as the Debug View) from being
|
||||
* notified that the frame data has changed. See Bug
|
||||
* 489607.
|
||||
*/
|
||||
ICachingService cachingStackService = (ICachingService) stackService;
|
||||
cachingStackService.flushCache(null);
|
||||
}
|
||||
}
|
||||
super.handleCompleted();
|
||||
}
|
||||
});
|
||||
} else {
|
||||
rm.done();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,158 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (c) 2015 Kichwa Coders 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:
|
||||
* Jonah Graham (Kichwa Coders) - initial API and implementation to Add support for gdb's "set substitute-path" (Bug 472765)
|
||||
*******************************************************************************/
|
||||
package org.eclipse.cdt.dsf.gdb.service;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.Hashtable;
|
||||
import java.util.Map;
|
||||
|
||||
import org.eclipse.cdt.debug.internal.core.sourcelookup.CSourceLookupDirector;
|
||||
import org.eclipse.cdt.dsf.concurrent.CountingRequestMonitor;
|
||||
import org.eclipse.cdt.dsf.concurrent.DataRequestMonitor;
|
||||
import org.eclipse.cdt.dsf.concurrent.IDsfStatusConstants;
|
||||
import org.eclipse.cdt.dsf.concurrent.ImmediateRequestMonitor;
|
||||
import org.eclipse.cdt.dsf.concurrent.RequestMonitor;
|
||||
import org.eclipse.cdt.dsf.debug.service.command.ICommandControl;
|
||||
import org.eclipse.cdt.dsf.gdb.internal.GdbPlugin;
|
||||
import org.eclipse.cdt.dsf.gdb.launching.GdbSourceLookupDirector;
|
||||
import org.eclipse.cdt.dsf.mi.service.CSourceLookup;
|
||||
import org.eclipse.cdt.dsf.mi.service.IMICommandControl;
|
||||
import org.eclipse.cdt.dsf.mi.service.command.CommandFactory;
|
||||
import org.eclipse.cdt.dsf.mi.service.command.output.MIInfo;
|
||||
import org.eclipse.cdt.dsf.service.DsfSession;
|
||||
import org.eclipse.core.runtime.IStatus;
|
||||
import org.eclipse.core.runtime.Status;
|
||||
|
||||
/**
|
||||
* Default implementation of {@link IGDBSourceLookup}
|
||||
*
|
||||
* @since 5.0
|
||||
*/
|
||||
public class GDBSourceLookup extends CSourceLookup implements IGDBSourceLookup {
|
||||
|
||||
private ICommandControl fCommand;
|
||||
private CommandFactory fCommandFactory;
|
||||
private Map<ISourceLookupDMContext, CSourceLookupDirector> fDirectors = new HashMap<>();
|
||||
/**
|
||||
* The current set of path substitutions that have been set on GDB.
|
||||
*/
|
||||
private Map<String, String> fCachedEntries = Collections.emptyMap();
|
||||
|
||||
public GDBSourceLookup(DsfSession session) {
|
||||
super(session);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void initialize(final RequestMonitor rm) {
|
||||
super.initialize(new ImmediateRequestMonitor(rm) {
|
||||
@Override
|
||||
protected void handleSuccess() {
|
||||
doInitialize(rm);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void doInitialize(RequestMonitor rm) {
|
||||
fCommand = getServicesTracker().getService(ICommandControl.class);
|
||||
fCommandFactory = getServicesTracker().getService(IMICommandControl.class).getCommandFactory();
|
||||
|
||||
register(new String[] { IGDBSourceLookup.class.getName(), GDBSourceLookup.class.getName() },
|
||||
new Hashtable<String, String>());
|
||||
|
||||
rm.done();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void shutdown(final RequestMonitor rm) {
|
||||
unregister();
|
||||
super.shutdown(rm);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setSourceLookupDirector(ISourceLookupDMContext ctx, CSourceLookupDirector director) {
|
||||
fDirectors.put(ctx, director);
|
||||
super.setSourceLookupDirector(ctx, director);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void initializeSourceSubstitutions(final ISourceLookupDMContext sourceLookupCtx, final RequestMonitor rm) {
|
||||
if (!fDirectors.containsKey(sourceLookupCtx)) {
|
||||
rm.setStatus(new Status(IStatus.ERROR, GdbPlugin.PLUGIN_ID, IDsfStatusConstants.INVALID_HANDLE,
|
||||
"No source director configured for given context", null)); //$NON-NLS-1$ );
|
||||
rm.done();
|
||||
return;
|
||||
}
|
||||
setSubstitutePaths(sourceLookupCtx, getSubstitutionsPaths(sourceLookupCtx), rm);
|
||||
}
|
||||
|
||||
private Map<String, String> getSubstitutionsPaths(ISourceLookupDMContext sourceLookupCtx) {
|
||||
CSourceLookupDirector director = fDirectors.get(sourceLookupCtx);
|
||||
if (director instanceof GdbSourceLookupDirector) {
|
||||
return ((GdbSourceLookupDirector) director).getSubstitutionsPaths();
|
||||
}
|
||||
return Collections.emptyMap();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void sourceContainersChanged(final ISourceLookupDMContext sourceLookupCtx,
|
||||
final DataRequestMonitor<Boolean> rm) {
|
||||
if (!fDirectors.containsKey(sourceLookupCtx)) {
|
||||
rm.setStatus(new Status(IStatus.ERROR, GdbPlugin.PLUGIN_ID, IDsfStatusConstants.INVALID_HANDLE,
|
||||
"No source director configured for given context", null)); //$NON-NLS-1$ );
|
||||
rm.done();
|
||||
return;
|
||||
}
|
||||
|
||||
Map<String, String> entries = getSubstitutionsPaths(sourceLookupCtx);
|
||||
if (entries.equals(fCachedEntries)) {
|
||||
rm.done(false);
|
||||
} else {
|
||||
fCommand.queueCommand(fCommandFactory.createCLIUnsetSubstitutePath(sourceLookupCtx),
|
||||
new DataRequestMonitor<MIInfo>(getExecutor(), rm) {
|
||||
@Override
|
||||
protected void handleSuccess() {
|
||||
initializeSourceSubstitutions(sourceLookupCtx, new RequestMonitor(getExecutor(), rm) {
|
||||
@Override
|
||||
protected void handleSuccess() {
|
||||
rm.done(true);
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
protected void setSubstitutePaths(ISourceLookupDMContext sourceLookupCtx, Map<String, String> entries,
|
||||
RequestMonitor rm) {
|
||||
fCachedEntries = entries;
|
||||
CountingRequestMonitor countingRm = new CountingRequestMonitor(getExecutor(), rm) {
|
||||
@Override
|
||||
protected void handleFailure() {
|
||||
/*
|
||||
* We failed to apply the changes. Clear the cache as it does
|
||||
* not represent the state of the backend. However we don't have
|
||||
* a good recovery here, so on future sourceContainersChanged()
|
||||
* calls we will simply reissue the substitutions.
|
||||
*/
|
||||
fCachedEntries = null;
|
||||
rm.done();
|
||||
}
|
||||
};
|
||||
countingRm.setDoneCount(entries.size());
|
||||
for (Map.Entry<String, String> entry : entries.entrySet()) {
|
||||
fCommand.queueCommand(
|
||||
fCommandFactory.createMISetSubstitutePath(sourceLookupCtx, entry.getKey(), entry.getValue()),
|
||||
new DataRequestMonitor<MIInfo>(getExecutor(), countingRm));
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -46,7 +46,6 @@ import org.eclipse.cdt.dsf.gdb.service.command.GDBControl_7_0;
|
|||
import org.eclipse.cdt.dsf.gdb.service.command.GDBControl_7_2;
|
||||
import org.eclipse.cdt.dsf.gdb.service.command.GDBControl_7_4;
|
||||
import org.eclipse.cdt.dsf.gdb.service.command.GDBControl_7_7;
|
||||
import org.eclipse.cdt.dsf.mi.service.CSourceLookup;
|
||||
import org.eclipse.cdt.dsf.mi.service.IMIBackend;
|
||||
import org.eclipse.cdt.dsf.mi.service.IMIExpressions;
|
||||
import org.eclipse.cdt.dsf.mi.service.MIBreakpoints;
|
||||
|
@ -275,7 +274,7 @@ public class GdbDebugServicesFactory extends AbstractDsfDebugServicesFactory {
|
|||
|
||||
@Override
|
||||
protected ISourceLookup createSourceLookupService(DsfSession session) {
|
||||
return new CSourceLookup(session);
|
||||
return new GDBSourceLookup(session);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -0,0 +1,46 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (c) 2015 Kichwa Coders 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:
|
||||
* Jonah Graham (Kichwa Coders) - initial API and implementation to Add support for gdb's "set substitute-path" (Bug 472765)
|
||||
*******************************************************************************/
|
||||
package org.eclipse.cdt.dsf.gdb.service;
|
||||
|
||||
import org.eclipse.cdt.debug.core.sourcelookup.MappingSourceContainer;
|
||||
import org.eclipse.cdt.dsf.concurrent.DataRequestMonitor;
|
||||
import org.eclipse.cdt.dsf.concurrent.RequestMonitor;
|
||||
import org.eclipse.cdt.dsf.debug.service.ISourceLookup;
|
||||
|
||||
/**
|
||||
* Extension to the {@link ISourceLookup} service that allows GDB backend to
|
||||
* handle the path mapping source container type -
|
||||
* {@link MappingSourceContainer} - on the GDB side using GDB's
|
||||
* "set substitute-path" mechanism.
|
||||
*
|
||||
* @since 5.0
|
||||
*/
|
||||
public interface IGDBSourceLookup extends ISourceLookup {
|
||||
|
||||
/**
|
||||
* Initialise the source substitutions on the GDB backend (aka do the
|
||||
* initial "set substitute-path"s)
|
||||
*
|
||||
* @param sourceLookupCtx
|
||||
* @param rm
|
||||
*/
|
||||
void initializeSourceSubstitutions(ISourceLookupDMContext sourceLookupCtx, RequestMonitor rm);
|
||||
|
||||
/**
|
||||
* Update the source substitutions on the GDB backend (aka modify the
|
||||
* "set substitute-path"s)
|
||||
*
|
||||
* @param sourceLookupCtx
|
||||
* @param rm
|
||||
* with the result set to True if a change was made
|
||||
*/
|
||||
void sourceContainersChanged(ISourceLookupDMContext sourceLookupCtx, DataRequestMonitor<Boolean> rm);
|
||||
}
|
|
@ -8,8 +8,8 @@
|
|||
package org.eclipse.cdt.dsf.gdb.service.extensions;
|
||||
|
||||
import org.eclipse.cdt.dsf.debug.service.ISourceLookup;
|
||||
import org.eclipse.cdt.dsf.gdb.service.GDBSourceLookup;
|
||||
import org.eclipse.cdt.dsf.gdb.service.GdbDebugServicesFactory;
|
||||
import org.eclipse.cdt.dsf.mi.service.CSourceLookup;
|
||||
import org.eclipse.cdt.dsf.service.DsfSession;
|
||||
|
||||
/**
|
||||
|
@ -36,7 +36,7 @@ import org.eclipse.cdt.dsf.service.DsfSession;
|
|||
*
|
||||
* @since 4.8
|
||||
*/
|
||||
public class GDBSourceLookup_HEAD extends CSourceLookup {
|
||||
public class GDBSourceLookup_HEAD extends GDBSourceLookup {
|
||||
public GDBSourceLookup_HEAD(DsfSession session) {
|
||||
super(session);
|
||||
|
||||
|
|
|
@ -40,6 +40,7 @@ import org.eclipse.cdt.dsf.debug.service.IModules.IModuleDMContext;
|
|||
import org.eclipse.cdt.dsf.debug.service.IModules.ISymbolDMContext;
|
||||
import org.eclipse.cdt.dsf.debug.service.IRunControl.IContainerDMContext;
|
||||
import org.eclipse.cdt.dsf.debug.service.IRunControl.IExecutionDMContext;
|
||||
import org.eclipse.cdt.dsf.debug.service.ISourceLookup.ISourceLookupDMContext;
|
||||
import org.eclipse.cdt.dsf.debug.service.IStack.IFrameDMContext;
|
||||
import org.eclipse.cdt.dsf.debug.service.command.ICommand;
|
||||
import org.eclipse.cdt.dsf.debug.service.command.ICommandControlService.ICommandControlDMContext;
|
||||
|
@ -69,6 +70,7 @@ import org.eclipse.cdt.dsf.mi.service.command.commands.CLIThread;
|
|||
import org.eclipse.cdt.dsf.mi.service.command.commands.CLITrace;
|
||||
import org.eclipse.cdt.dsf.mi.service.command.commands.CLITraceDump;
|
||||
import org.eclipse.cdt.dsf.mi.service.command.commands.CLIUnsetEnv;
|
||||
import org.eclipse.cdt.dsf.mi.service.command.commands.CLIUnsetSubstitutePath;
|
||||
import org.eclipse.cdt.dsf.mi.service.command.commands.MIAddInferior;
|
||||
import org.eclipse.cdt.dsf.mi.service.command.commands.MIBreakAfter;
|
||||
import org.eclipse.cdt.dsf.mi.service.command.commands.MIBreakCommands;
|
||||
|
@ -150,6 +152,7 @@ import org.eclipse.cdt.dsf.mi.service.command.commands.MIInterpreterExecConsoleK
|
|||
import org.eclipse.cdt.dsf.mi.service.command.commands.MIListFeatures;
|
||||
import org.eclipse.cdt.dsf.mi.service.command.commands.MIListThreadGroups;
|
||||
import org.eclipse.cdt.dsf.mi.service.command.commands.MIRemoveInferior;
|
||||
import org.eclipse.cdt.dsf.mi.service.command.commands.MISetSubstitutePath;
|
||||
import org.eclipse.cdt.dsf.mi.service.command.commands.MIStackInfoDepth;
|
||||
import org.eclipse.cdt.dsf.mi.service.command.commands.MIStackListArguments;
|
||||
import org.eclipse.cdt.dsf.mi.service.command.commands.MIStackListFrames;
|
||||
|
@ -380,6 +383,11 @@ public class CommandFactory {
|
|||
return new CLIUnsetEnv(ctx, name);
|
||||
}
|
||||
|
||||
/** @since 5.0 */
|
||||
public ICommand<MIInfo> createCLIUnsetSubstitutePath(ISourceLookupDMContext ctx) {
|
||||
return new CLIUnsetSubstitutePath(ctx);
|
||||
}
|
||||
|
||||
/** @since 4.0 */
|
||||
public ICommand<MIAddInferiorInfo> createMIAddInferior(ICommandControlDMContext ctx) {
|
||||
return new MIAddInferior(ctx);
|
||||
|
@ -904,6 +912,11 @@ public class CommandFactory {
|
|||
return new MIRemoveInferior(ctx, groupId);
|
||||
}
|
||||
|
||||
/** @since 5.0 */
|
||||
public ICommand<MIInfo> createMISetSubstitutePath(ISourceLookupDMContext context, String from, String to) {
|
||||
return new MISetSubstitutePath(context, from, to);
|
||||
}
|
||||
|
||||
public ICommand<MIStackInfoDepthInfo> createMIStackInfoDepth(IMIExecutionDMContext ctx) {
|
||||
return new MIStackInfoDepth(ctx);
|
||||
}
|
||||
|
|
|
@ -0,0 +1,28 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (c) 2015 Kichwa Coders 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:
|
||||
* Jonah Graham (Kichwa Coders) - initial API and implementation to Add support for gdb's "set substitute-path" (Bug 472765)
|
||||
*******************************************************************************/
|
||||
package org.eclipse.cdt.dsf.mi.service.command.commands;
|
||||
|
||||
import org.eclipse.cdt.dsf.debug.service.ISourceLookup.ISourceLookupDMContext;
|
||||
import org.eclipse.cdt.dsf.mi.service.command.output.MIInfo;
|
||||
|
||||
/**
|
||||
* unset substitute-path
|
||||
*
|
||||
* Deletes all the path substitutions.
|
||||
*
|
||||
* @since 5.0
|
||||
*/
|
||||
public class CLIUnsetSubstitutePath extends MIInterpreterExecConsole<MIInfo> {
|
||||
|
||||
public CLIUnsetSubstitutePath(ISourceLookupDMContext ctx) {
|
||||
super(ctx, "unset substitute-path"); //$NON-NLS-1$
|
||||
}
|
||||
}
|
|
@ -0,0 +1,26 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (c) 2015 Kichwa Coders 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:
|
||||
* Jonah Graham (Kichwa Coders) - initial API and implementation to Add support for gdb's "set substitute-path" (Bug 472765)
|
||||
*******************************************************************************/
|
||||
package org.eclipse.cdt.dsf.mi.service.command.commands;
|
||||
|
||||
import org.eclipse.cdt.dsf.debug.service.ISourceLookup.ISourceLookupDMContext;
|
||||
|
||||
/**
|
||||
* -gdb-set substitute-path from to
|
||||
*
|
||||
* @since 5.0
|
||||
*/
|
||||
public class MISetSubstitutePath extends MIGDBSet {
|
||||
|
||||
public MISetSubstitutePath(ISourceLookupDMContext context, String from, String to) {
|
||||
super(context, new String[] { "substitute-path", from, to }); //$NON-NLS-1$
|
||||
}
|
||||
|
||||
}
|
|
@ -41,12 +41,19 @@ import org.eclipse.cdt.debug.core.sourcelookup.MappingSourceContainer;
|
|||
import org.eclipse.cdt.debug.core.sourcelookup.ProgramRelativePathSourceContainer;
|
||||
import org.eclipse.cdt.debug.internal.core.sourcelookup.CSourceLookupDirector;
|
||||
import org.eclipse.cdt.debug.internal.core.sourcelookup.MapEntrySourceContainer;
|
||||
import org.eclipse.cdt.dsf.concurrent.DataRequestMonitor;
|
||||
import org.eclipse.cdt.dsf.concurrent.Query;
|
||||
import org.eclipse.cdt.dsf.datamodel.IDMContext;
|
||||
import org.eclipse.cdt.dsf.debug.service.IStack.IFrameDMContext;
|
||||
import org.eclipse.cdt.dsf.debug.service.IStack.IFrameDMData;
|
||||
import org.eclipse.cdt.dsf.debug.sourcelookup.DsfSourceLookupDirector;
|
||||
import org.eclipse.cdt.tests.dsf.gdb.framework.AsyncCompletionWaitor;
|
||||
import org.eclipse.cdt.dsf.gdb.service.command.IGDBControl;
|
||||
import org.eclipse.cdt.dsf.mi.service.command.CommandFactory;
|
||||
import org.eclipse.cdt.dsf.mi.service.command.output.MIInfo;
|
||||
import org.eclipse.cdt.dsf.mi.service.command.output.MIMixedInstruction;
|
||||
import org.eclipse.cdt.dsf.service.DsfServicesTracker;
|
||||
import org.eclipse.cdt.dsf.service.DsfSession;
|
||||
import org.eclipse.cdt.tests.dsf.gdb.framework.AsyncCompletionWaitor;
|
||||
import org.eclipse.cdt.tests.dsf.gdb.framework.BackgroundRunner;
|
||||
import org.eclipse.cdt.tests.dsf.gdb.framework.BaseTestCase;
|
||||
import org.eclipse.cdt.tests.dsf.gdb.framework.SyncUtil;
|
||||
|
@ -185,6 +192,9 @@ public class SourceLookupTest extends BaseTestCase {
|
|||
}
|
||||
};
|
||||
|
||||
private IGDBControl fCommandControl;
|
||||
private CommandFactory fCommandFactory;
|
||||
|
||||
@Override
|
||||
public void doBeforeTest() throws Exception {
|
||||
removeTeminatedLaunchesBeforeTest();
|
||||
|
@ -213,6 +223,19 @@ public class SourceLookupTest extends BaseTestCase {
|
|||
protected void doLaunch(String programName) throws Exception {
|
||||
setLaunchAttribute(ICDTLaunchConfigurationConstants.ATTR_PROGRAM_NAME, programName);
|
||||
super.doLaunch();
|
||||
|
||||
final DsfSession session = getGDBLaunch().getSession();
|
||||
Runnable runnable = new Runnable() {
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
DsfServicesTracker tracker = new DsfServicesTracker(TestsPlugin.getBundleContext(), session.getId());
|
||||
fCommandControl = tracker.getService(IGDBControl.class);
|
||||
fCommandFactory = fCommandControl.getCommandFactory();
|
||||
tracker.dispose();
|
||||
}
|
||||
};
|
||||
session.getExecutor().submit(runnable).get();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -234,16 +257,16 @@ public class SourceLookupTest extends BaseTestCase {
|
|||
* file.
|
||||
*/
|
||||
protected void assertSourceNotFound() throws Throwable {
|
||||
// Check file name as returned from back end
|
||||
IFrameDMData frameData = SyncUtil.getFrameData(0, 0);
|
||||
assertFalse("GDB Unexpectedly located the source", fileExists(frameData.getFile()));
|
||||
|
||||
// Check file as resolved by source lookup director
|
||||
ISourceLookupDirector director = (ISourceLookupDirector) getGDBLaunch().getSourceLocator();
|
||||
IFrameDMContext frameDmc = SyncUtil.getStackFrame(0, 0);
|
||||
Object sourceElement = director.getSourceElement(frameDmc);
|
||||
assertNull("Source Locator unexpectedly found the source", sourceElement);
|
||||
|
||||
// Check file name as returned from back end
|
||||
IFrameDMData frameData = SyncUtil.getFrameData(0, 0);
|
||||
assertFalse("GDB Unexpectedly located the source", fileExists(frameData.getFile()));
|
||||
|
||||
// Check file as resolved by ISourceLookup service
|
||||
try {
|
||||
SyncUtil.getSource(frameData.getFile());
|
||||
|
@ -260,16 +283,16 @@ public class SourceLookupTest extends BaseTestCase {
|
|||
* found the source file.
|
||||
*/
|
||||
protected void assertSourceFoundByDirectorOnly() throws Throwable {
|
||||
// Check file name as returned from back end
|
||||
IFrameDMData frameData = SyncUtil.getFrameData(0, 0);
|
||||
assertFalse("GDB Unexpectedly located the source", fileExists(frameData.getFile()));
|
||||
|
||||
// Check file as resolved by source lookup director
|
||||
ISourceLookupDirector director = (ISourceLookupDirector) getGDBLaunch().getSourceLocator();
|
||||
IFrameDMContext frameDmc = SyncUtil.getStackFrame(0, 0);
|
||||
Object sourceElement = director.getSourceElement(frameDmc);
|
||||
assertTrue("Source locator failed to find source", sourceElement instanceof IStorage);
|
||||
|
||||
// Check file name as returned from back end
|
||||
IFrameDMData frameData = SyncUtil.getFrameData(0, 0);
|
||||
assertFalse("GDB Unexpectedly located the source", fileExists(frameData.getFile()));
|
||||
|
||||
// Check file as resolved by ISourceLookup service
|
||||
sourceElement = SyncUtil.getSource(frameData.getFile());
|
||||
assertTrue("Source Lookup service failed to find source", sourceElement instanceof IStorage);
|
||||
|
@ -279,16 +302,16 @@ public class SourceLookupTest extends BaseTestCase {
|
|||
* Custom assertion that GDB and the Source Locator found the source file.
|
||||
*/
|
||||
protected void assertSourceFound() throws Throwable {
|
||||
// Check file name as returned from back end
|
||||
IFrameDMData frameData = SyncUtil.getFrameData(0, 0);
|
||||
assertTrue("GDB failed to find source", fileExists(frameData.getFile()));
|
||||
|
||||
// Check file as resolved by source lookup director
|
||||
ISourceLookupDirector director = (ISourceLookupDirector) getGDBLaunch().getSourceLocator();
|
||||
IFrameDMContext frameDmc = SyncUtil.getStackFrame(0, 0);
|
||||
Object sourceElement = director.getSourceElement(frameDmc);
|
||||
assertTrue("Source locator failed to find source", sourceElement instanceof IStorage);
|
||||
|
||||
// Check file name as returned from back end
|
||||
IFrameDMData frameData = SyncUtil.getFrameData(0, 0);
|
||||
assertTrue("GDB failed to find source", fileExists(frameData.getFile()));
|
||||
|
||||
// Check file as resolved by ISourceLookup service
|
||||
sourceElement = SyncUtil.getSource(frameData.getFile());
|
||||
assertTrue("Source Lookup service failed to find source", sourceElement instanceof IStorage);
|
||||
|
@ -328,10 +351,11 @@ public class SourceLookupTest extends BaseTestCase {
|
|||
/**
|
||||
* Add the mapping source container to the common source lookup
|
||||
*/
|
||||
protected void doMappingInCommon(boolean canonical) {
|
||||
protected void doMappingInCommon(boolean canonical, boolean withBackend) {
|
||||
CSourceLookupDirector commonSourceLookupDirector = CDebugCorePlugin.getDefault()
|
||||
.getCommonSourceLookupDirector();
|
||||
MappingSourceContainer mapContainer = new MappingSourceContainer("Mappings");
|
||||
mapContainer.setIsMappingWithBackendEnabled(withBackend);
|
||||
if (canonical) {
|
||||
mapContainer.addMapEntry(fMapEntrySourceContainerC);
|
||||
} else {
|
||||
|
@ -362,11 +386,10 @@ public class SourceLookupTest extends BaseTestCase {
|
|||
* Set default source locators and a path mapping
|
||||
* {@link MappingSourceContainer} from BUILD_ABSPATH -> SOURCE_ABSPATH and
|
||||
* do the launch
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
protected void doMappingAndLaunch(String programName) throws CoreException, Exception {
|
||||
protected void doMappingAndLaunch(String programName, boolean withBackend) throws CoreException, Exception {
|
||||
MappingSourceContainer mapContainer = new MappingSourceContainer("Mappings");
|
||||
mapContainer.setIsMappingWithBackendEnabled(withBackend);
|
||||
if (programName.endsWith("N.exe")) {
|
||||
mapContainer.addMapEntry(fMapEntrySourceContainerN);
|
||||
} else if (programName.endsWith("C.exe")) {
|
||||
|
@ -379,20 +402,39 @@ public class SourceLookupTest extends BaseTestCase {
|
|||
}
|
||||
|
||||
/**
|
||||
* With mapping test that GDB does not locate the file, but the source
|
||||
* lookup director and the source lookup service do find the file.
|
||||
* Mapping test common.
|
||||
*
|
||||
* If backend is used for mapping then every layer should be able to find
|
||||
* source.
|
||||
*
|
||||
* If backned is not used for mapping then only once the source lookup
|
||||
* director gets involved should the source be found as GDB will not know
|
||||
* how to find it on its own.
|
||||
*/
|
||||
protected void sourceMapping(String programName) throws Throwable {
|
||||
doMappingAndLaunch(programName);
|
||||
assertSourceFoundByDirectorOnly();
|
||||
protected void sourceMapping(String programName, boolean withBackend) throws Throwable {
|
||||
doMappingAndLaunch(programName, withBackend);
|
||||
if (withBackend) {
|
||||
assertSourceFound();
|
||||
} else {
|
||||
assertSourceFoundByDirectorOnly();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* With mapping test breakpoints can be inserted.
|
||||
*/
|
||||
protected void sourceMappingBreakpoints(String programName) throws Throwable {
|
||||
doMappingAndLaunch(programName);
|
||||
protected void sourceMappingBreakpoints(String programName, boolean withBackend) throws Throwable {
|
||||
doMappingAndLaunch(programName, withBackend);
|
||||
|
||||
assertInsertBreakpointSuccessful();
|
||||
}
|
||||
|
||||
/**
|
||||
* Assert that a breakpoint can be successfully inserted. To successfully
|
||||
* insert a breakpoint it means the the mapping of local file names to
|
||||
* compilation paths is working properly.
|
||||
*/
|
||||
protected void assertInsertBreakpointSuccessful() throws Throwable {
|
||||
// insert breakpoint in source file
|
||||
fBreakpointInstalledWait.waitReset();
|
||||
ICLineBreakpoint bp = CDIDebugModel.createLineBreakpoint(
|
||||
|
@ -414,7 +456,16 @@ public class SourceLookupTest extends BaseTestCase {
|
|||
*/
|
||||
@Test
|
||||
public void sourceMappingAC() throws Throwable {
|
||||
sourceMapping(EXEC_AC_NAME);
|
||||
sourceMapping(EXEC_AC_NAME, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test source mappings with executable built with an Absolute and Canonical
|
||||
* build path
|
||||
*/
|
||||
@Test
|
||||
public void sourceSubstituteAC() throws Throwable {
|
||||
sourceMapping(EXEC_AC_NAME, true);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -423,7 +474,17 @@ public class SourceLookupTest extends BaseTestCase {
|
|||
*/
|
||||
@Test
|
||||
public void sourceMappingAN() throws Throwable {
|
||||
sourceMapping(EXEC_AN_NAME);
|
||||
sourceMapping(EXEC_AN_NAME, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test source mappings with executable built with an Absolute and
|
||||
* Non-canonical build path
|
||||
*/
|
||||
@Test
|
||||
@Ignore("Not supported because GDB does not handle non-canonical paths. See Bug 477057")
|
||||
public void sourceSubstituteAN() throws Throwable {
|
||||
sourceMapping(EXEC_AN_NAME, true);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -432,7 +493,16 @@ public class SourceLookupTest extends BaseTestCase {
|
|||
*/
|
||||
@Test
|
||||
public void sourceMappingRC() throws Throwable {
|
||||
sourceMapping(EXEC_RC_NAME);
|
||||
sourceMapping(EXEC_RC_NAME, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test source mappings with executable built with a Relative and Canonical
|
||||
* build path
|
||||
*/
|
||||
@Test
|
||||
public void sourceSubstituteRC() throws Throwable {
|
||||
sourceMapping(EXEC_RC_NAME, true);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -441,7 +511,17 @@ public class SourceLookupTest extends BaseTestCase {
|
|||
*/
|
||||
@Test
|
||||
public void sourceMappingRN() throws Throwable {
|
||||
sourceMapping(EXEC_RN_NAME);
|
||||
sourceMapping(EXEC_RN_NAME, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test source mappings with executable built with a Relative and
|
||||
* Non-canonical build path
|
||||
*/
|
||||
@Test
|
||||
@Ignore("Not supported because GDB does not handle non-canonical paths. See Bug 477057")
|
||||
public void sourceSubstituteRN() throws Throwable {
|
||||
sourceMapping(EXEC_RN_NAME, true);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -450,7 +530,16 @@ public class SourceLookupTest extends BaseTestCase {
|
|||
*/
|
||||
@Test
|
||||
public void sourceMappingBreakpointsAC() throws Throwable {
|
||||
sourceMappingBreakpoints(EXEC_AC_NAME);
|
||||
sourceMappingBreakpoints(EXEC_AC_NAME, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test source mappings with executable built with an Absolute and Canonical
|
||||
* build path
|
||||
*/
|
||||
@Test
|
||||
public void sourceSubstituteBreakpointsAC() throws Throwable {
|
||||
sourceMappingBreakpoints(EXEC_AC_NAME, true);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -460,7 +549,17 @@ public class SourceLookupTest extends BaseTestCase {
|
|||
@Ignore("Not supported because GDB does not handle non-canonical paths. See Bug 477057")
|
||||
@Test
|
||||
public void sourceMappingBreakpointsAN() throws Throwable {
|
||||
sourceMappingBreakpoints(EXEC_AN_NAME);
|
||||
sourceMappingBreakpoints(EXEC_AN_NAME, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test source mappings with executable built with an Absolute and
|
||||
* Non-canonical build path
|
||||
*/
|
||||
@Test
|
||||
@Ignore("Not supported because GDB does not handle non-canonical paths. See Bug 477057")
|
||||
public void sourceSubstituteBreakpointsAN() throws Throwable {
|
||||
sourceMappingBreakpoints(EXEC_AN_NAME, true);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -469,7 +568,16 @@ public class SourceLookupTest extends BaseTestCase {
|
|||
*/
|
||||
@Test
|
||||
public void sourceMappingBreakpointsRC() throws Throwable {
|
||||
sourceMappingBreakpoints(EXEC_RC_NAME);
|
||||
sourceMappingBreakpoints(EXEC_RC_NAME, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test source mappings with executable built with a Relative and Canonical
|
||||
* build path
|
||||
*/
|
||||
@Test
|
||||
public void sourceSubstituteBreakpointsRC() throws Throwable {
|
||||
sourceMappingBreakpoints(EXEC_RC_NAME, true);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -479,7 +587,33 @@ public class SourceLookupTest extends BaseTestCase {
|
|||
@Ignore("Not supported because GDB does not handle non-canonical paths. See Bug 477057")
|
||||
@Test
|
||||
public void sourceMappingBreakpointsRN() throws Throwable {
|
||||
sourceMappingBreakpoints(EXEC_RN_NAME);
|
||||
sourceMappingBreakpoints(EXEC_RN_NAME, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test source mappings with executable built with a Relative and
|
||||
* Non-canonical build path
|
||||
*/
|
||||
@Test
|
||||
@Ignore("Not supported because GDB does not handle non-canonical paths. See Bug 477057")
|
||||
public void sourceSubstituteBreakpointsRN() throws Throwable {
|
||||
sourceMappingBreakpoints(EXEC_RN_NAME, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Change directory to the binary (aka EXEC_PATH)
|
||||
*/
|
||||
protected void doCdToBinDir() throws Exception {
|
||||
Query<MIInfo> query = new Query<MIInfo>() {
|
||||
@Override
|
||||
protected void execute(DataRequestMonitor<MIInfo> rm) {
|
||||
fCommandControl.queueCommand(fCommandFactory.createMIEnvironmentCD(fCommandControl.getContext(),
|
||||
new File(EXEC_PATH).getAbsolutePath()), rm);
|
||||
}
|
||||
};
|
||||
|
||||
fCommandControl.getExecutor().execute(query);
|
||||
query.get();
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -487,15 +621,18 @@ public class SourceLookupTest extends BaseTestCase {
|
|||
* debug session (e.g. with CSourceNotFoundEditor) that the lookups are
|
||||
* updated.
|
||||
*/
|
||||
@Test
|
||||
public void sourceMappingChanges() throws Throwable {
|
||||
doMappingAndLaunch(EXEC_AC_NAME);
|
||||
public void sourceMappingChangesHelper(boolean withBackend) throws Throwable {
|
||||
doMappingAndLaunch(EXEC_AC_NAME, withBackend);
|
||||
|
||||
DsfSourceLookupDirector sourceLocator = (DsfSourceLookupDirector) getGDBLaunch().getSourceLocator();
|
||||
MapEntrySourceContainer incorrectMapEntry = new MapEntrySourceContainer(
|
||||
new Path(BUILD_ABSPATH + "/incorrectsubpath"), new Path(SOURCE_ABSPATH));
|
||||
|
||||
assertSourceFoundByDirectorOnly();
|
||||
if (withBackend) {
|
||||
assertSourceFound();
|
||||
} else {
|
||||
assertSourceFoundByDirectorOnly();
|
||||
}
|
||||
|
||||
// Change the source mappings
|
||||
ISourceContainer[] containers = sourceLocator.getSourceContainers();
|
||||
|
@ -504,6 +641,18 @@ public class SourceLookupTest extends BaseTestCase {
|
|||
mappingSourceContainer.addMapEntry(incorrectMapEntry);
|
||||
sourceLocator.setSourceContainers(containers);
|
||||
|
||||
/*
|
||||
* GDB (pre 7.0) changes the current directory when the above source is
|
||||
* found. As a result GDB is able to find the source even though we have
|
||||
* changed the source lookup paths. To make sure that GDB is really
|
||||
* doing a substitution rather than looking in current directory, change
|
||||
* the current directory. Without this, the assertSourceNotFound fails
|
||||
* because GDB unexpectedly finds the source (for the wrong reason).
|
||||
*/
|
||||
if (withBackend) {
|
||||
doCdToBinDir();
|
||||
}
|
||||
|
||||
assertSourceNotFound();
|
||||
|
||||
// Change the source mappings back
|
||||
|
@ -513,7 +662,21 @@ public class SourceLookupTest extends BaseTestCase {
|
|||
mappingSourceContainer.addMapEntry(fMapEntrySourceContainerC);
|
||||
sourceLocator.setSourceContainers(containers);
|
||||
|
||||
assertSourceFoundByDirectorOnly();
|
||||
if (withBackend) {
|
||||
assertSourceFound();
|
||||
} else {
|
||||
assertSourceFoundByDirectorOnly();
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void sourceMappingChanges() throws Throwable {
|
||||
sourceMappingChangesHelper(false);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void sourceSubstituteChanges() throws Throwable {
|
||||
sourceMappingChangesHelper(true);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -524,8 +687,7 @@ public class SourceLookupTest extends BaseTestCase {
|
|||
* This version is for a new source mapping where there wasn't one
|
||||
* previously.
|
||||
*/
|
||||
@Test
|
||||
public void sourceMappingAdded() throws Throwable {
|
||||
public void sourceMappingAddedHelper(boolean withBackend) throws Throwable {
|
||||
doLaunch(EXEC_PATH + EXEC_AC_NAME);
|
||||
|
||||
assertSourceNotFound();
|
||||
|
@ -534,13 +696,28 @@ public class SourceLookupTest extends BaseTestCase {
|
|||
DsfSourceLookupDirector sourceLocator = (DsfSourceLookupDirector) getGDBLaunch().getSourceLocator();
|
||||
ISourceContainer[] containers = sourceLocator.getSourceContainers();
|
||||
MappingSourceContainer mappingSourceContainer = new MappingSourceContainer("Mappings");
|
||||
mappingSourceContainer.setIsMappingWithBackendEnabled(withBackend);
|
||||
mappingSourceContainer.addMapEntry(fMapEntrySourceContainerC);
|
||||
ISourceContainer[] newContainers = new ISourceContainer[containers.length + 1];
|
||||
System.arraycopy(containers, 0, newContainers, 0, containers.length);
|
||||
newContainers[newContainers.length - 1] = mappingSourceContainer;
|
||||
sourceLocator.setSourceContainers(newContainers);
|
||||
|
||||
assertSourceFoundByDirectorOnly();
|
||||
if (withBackend) {
|
||||
assertSourceFound();
|
||||
} else {
|
||||
assertSourceFoundByDirectorOnly();
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void sourceMappingAdded() throws Throwable {
|
||||
sourceMappingAddedHelper(false);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void sourceSubstituteAdded() throws Throwable {
|
||||
sourceMappingAddedHelper(true);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -635,11 +812,20 @@ public class SourceLookupTest extends BaseTestCase {
|
|||
* In this case, the DSF specific director created as part of the launch
|
||||
* gets used.
|
||||
*/
|
||||
public void sourceFinderMappingAC_ActiveLaunchHelper(boolean withBackend) throws Throwable {
|
||||
assertFinderDoesNotFind(EXEC_AC_NAME, new File(BUILD_PATH, SOURCE_NAME).getAbsolutePath());
|
||||
doMappingAndLaunch(EXEC_AC_NAME, withBackend);
|
||||
assertFinderFinds(EXEC_AC_NAME, new File(SOURCE_PATH, SOURCE_NAME).getAbsolutePath());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void sourceFinderMappingAC_ActiveLaunch() throws Throwable {
|
||||
assertFinderDoesNotFind(EXEC_AC_NAME, new File(BUILD_PATH, SOURCE_NAME).getAbsolutePath());
|
||||
doMappingAndLaunch(EXEC_AC_NAME);
|
||||
assertFinderFinds(EXEC_AC_NAME, new File(SOURCE_PATH, SOURCE_NAME).getAbsolutePath());
|
||||
sourceFinderMappingAC_ActiveLaunchHelper(false);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void sourceFinderSubstituteAC_ActiveLaunch() throws Throwable {
|
||||
sourceFinderMappingAC_ActiveLaunchHelper(true);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -649,15 +835,24 @@ public class SourceLookupTest extends BaseTestCase {
|
|||
* In this case, the DSF specific director created as part of the launch
|
||||
* gets used.
|
||||
*/
|
||||
@Test
|
||||
public void sourceFinderMappingAC_TerminatedLaunch() throws Throwable {
|
||||
sourceFinderMappingAC_ActiveLaunch();
|
||||
public void sourceFinderMappingAC_TerminatedLaunchHelper(boolean withBackend) throws Throwable {
|
||||
sourceFinderMappingAC_ActiveLaunchHelper(withBackend);
|
||||
|
||||
// Terminate the launch, but don't remove it
|
||||
doAfterTest();
|
||||
assertFinderFinds(EXEC_AC_NAME, new File(SOURCE_PATH, SOURCE_NAME).getAbsolutePath());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void sourceFinderMappingAC_TerminatedLaunch() throws Throwable {
|
||||
sourceFinderMappingAC_TerminatedLaunchHelper(false);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void sourceFinderSubstituteAC_TerminatedLaunch() throws Throwable {
|
||||
sourceFinderMappingAC_ActiveLaunchHelper(true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test the CSourceFinder's use of source lookup when there is a not active
|
||||
* launch, but a launch configuration that can be used.
|
||||
|
@ -665,9 +860,8 @@ public class SourceLookupTest extends BaseTestCase {
|
|||
* In this case, the c general director created as part of the launch gets
|
||||
* used.
|
||||
*/
|
||||
@Test
|
||||
public void sourceFinderMappingAC_LaunchConfig() throws Throwable {
|
||||
sourceFinderMappingAC_TerminatedLaunch();
|
||||
public void sourceFinderMappingAC_LaunchConfigHelper(boolean withBackend) throws Throwable {
|
||||
sourceFinderMappingAC_TerminatedLaunchHelper(withBackend);
|
||||
|
||||
// Remove the launch, so that we can test with the existing
|
||||
// configuration
|
||||
|
@ -683,15 +877,24 @@ public class SourceLookupTest extends BaseTestCase {
|
|||
assertFinderFinds(EXEC_AC_NAME, new File(SOURCE_PATH, SOURCE_NAME).getAbsolutePath());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void sourceFinderMappingAC_LaunchConfig() throws Throwable {
|
||||
sourceFinderMappingAC_LaunchConfigHelper(false);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void sourceFinderSubstituteAC_LaunchConfig() throws Throwable {
|
||||
sourceFinderMappingAC_LaunchConfigHelper(true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test that CSourceFinder works with the common source director, i.e. no
|
||||
* launches or launch configs in place.
|
||||
*/
|
||||
@Test
|
||||
public void sourceFinderMappingAC_CommonLocator() throws Throwable {
|
||||
public void sourceFinderMappingAC_CommonLocatorHelper(boolean withBackend) throws Throwable {
|
||||
assertFinderDoesNotFind(EXEC_AC_NAME, new File(BUILD_PATH, SOURCE_NAME).getAbsolutePath());
|
||||
|
||||
doMappingInCommon(true);
|
||||
doMappingInCommon(true, withBackend);
|
||||
try {
|
||||
assertFinderFinds(EXEC_AC_NAME, new File(SOURCE_PATH, SOURCE_NAME).getAbsolutePath());
|
||||
} finally {
|
||||
|
@ -701,6 +904,16 @@ public class SourceLookupTest extends BaseTestCase {
|
|||
assertFinderDoesNotFind(EXEC_AC_NAME, new File(BUILD_PATH, SOURCE_NAME).getAbsolutePath());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void sourceFinderMappingAC_CommonLocator() throws Throwable {
|
||||
sourceFinderMappingAC_CommonLocatorHelper(false);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void sourceFinderSubstituteAC_CommonLocator() throws Throwable {
|
||||
sourceFinderMappingAC_CommonLocatorHelper(true);
|
||||
}
|
||||
|
||||
/**
|
||||
* This test verifies that doing a source lookup where the absolute name of
|
||||
* the file is provided by the backend resolves.
|
||||
|
@ -733,4 +946,38 @@ public class SourceLookupTest extends BaseTestCase {
|
|||
|
||||
assertSourceFound();
|
||||
}
|
||||
|
||||
/**
|
||||
* Test verifies interaction between director that has two mappers, one with
|
||||
* backend enabled and one without with the second being the only valid one.
|
||||
*/
|
||||
@Test
|
||||
public void twoMappersSecondValid() throws Throwable {
|
||||
MappingSourceContainer substituteContainer = new MappingSourceContainer("Mappings With Backend");
|
||||
substituteContainer.setIsMappingWithBackendEnabled(true);
|
||||
/*
|
||||
* the entry here does not matter, as long as it is not the valid
|
||||
* substitution, we want to make sure that we process the other
|
||||
* MappingSourceContainer correctly
|
||||
*/
|
||||
substituteContainer
|
||||
.addMapEntry(new MapEntrySourceContainer(new Path("/from_invalid"), new Path("/to_invalid")));
|
||||
AbstractSourceLookupDirector director = setSourceContainer(substituteContainer);
|
||||
|
||||
// this is the mapping we want to do the work
|
||||
MappingSourceContainer mapContainer = new MappingSourceContainer("Mappings");
|
||||
mapContainer.setIsMappingWithBackendEnabled(false);
|
||||
mapContainer.addMapEntry(fMapEntrySourceContainerC);
|
||||
addSourceContainer(director, mapContainer);
|
||||
|
||||
doLaunch(EXEC_PATH + EXEC_AC_NAME);
|
||||
|
||||
/*
|
||||
* because the backend substitution does not apply, we resolve with the
|
||||
* CDT mapping, in this case that means that only the director should
|
||||
* locate the source.
|
||||
*/
|
||||
assertSourceFoundByDirectorOnly();
|
||||
assertInsertBreakpointSuccessful();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -15,8 +15,8 @@ import org.eclipse.cdt.dsf.concurrent.ImmediateExecutor;
|
|||
import org.eclipse.cdt.dsf.concurrent.Query;
|
||||
import org.eclipse.cdt.dsf.concurrent.RequestMonitorWithProgress;
|
||||
import org.eclipse.cdt.dsf.concurrent.Sequence;
|
||||
import org.eclipse.cdt.dsf.debug.sourcelookup.DsfSourceLookupDirector;
|
||||
import org.eclipse.cdt.dsf.gdb.launching.GdbLaunch;
|
||||
import org.eclipse.cdt.dsf.gdb.launching.GdbSourceLookupDirector;
|
||||
import org.eclipse.cdt.dsf.gdb.launching.ServicesLaunchSequence;
|
||||
import org.eclipse.cdt.dsf.gdb.service.GdbDebugServicesFactory;
|
||||
import org.eclipse.cdt.dsf.gdb.service.command.IGDBControl;
|
||||
|
@ -43,7 +43,7 @@ public class QtLocalDebugLaunchConfigDelegate extends QtLaunchConfigurationDeleg
|
|||
launch.setLaunchTarget(target);
|
||||
launch.initialize();
|
||||
|
||||
DsfSourceLookupDirector locator = new DsfSourceLookupDirector(launch.getSession());
|
||||
GdbSourceLookupDirector locator = new GdbSourceLookupDirector(launch.getSession());
|
||||
String memento = configuration.getAttribute(ILaunchConfiguration.ATTR_SOURCE_LOCATOR_MEMENTO, (String) null);
|
||||
if (memento == null) {
|
||||
locator.initializeDefaults(configuration);
|
||||
|
|
Loading…
Add table
Reference in a new issue