diff --git a/debug/org.eclipse.cdt.debug.core/src/org/eclipse/cdt/debug/internal/core/sourcelookup/CSourceLookupDirector.java b/debug/org.eclipse.cdt.debug.core/src/org/eclipse/cdt/debug/internal/core/sourcelookup/CSourceLookupDirector.java index 9654f8436c5..315453c2dc5 100644 --- a/debug/org.eclipse.cdt.debug.core/src/org/eclipse/cdt/debug/internal/core/sourcelookup/CSourceLookupDirector.java +++ b/debug/org.eclipse.cdt.debug.core/src/org/eclipse/cdt/debug/internal/core/sourcelookup/CSourceLookupDirector.java @@ -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 @@ -51,28 +51,30 @@ import org.eclipse.debug.core.sourcelookup.containers.ProjectSourceContainer; * * An instance is either associated with a particular launch configuration or it * has no association (global). + * + * This class is created by the {@link ILaunchManager#newSourceLocator(String)} + * (e.g. DebugPlugin.getDefault().getLaunchManager().newSourceLocator(type)) and + * must have a no-arguments constructor. */ public class CSourceLookupDirector extends AbstractSourceLookupDirector { private static Set fSupportedTypes; private static Object fSupportedTypesLock = new Object(); - /* (non-Javadoc) - * @see org.eclipse.debug.core.sourcelookup.ISourceLookupDirector#initializeParticipants() - */ @Override public void initializeParticipants() { addParticipants(new ISourceLookupParticipant[] { new CSourceLookupParticipant() }); } - /* (non-Javadoc) - * @see org.eclipse.debug.core.sourcelookup.ISourceLookupDirector#supportsSourceContainerType(org.eclipse.debug.core.sourcelookup.ISourceContainerType) - */ @Override public boolean supportsSourceContainerType(ISourceContainerType type) { readSupportedContainerTypes(); return fSupportedTypes.contains(type.getId()); } + /** + * @deprecated Only used by CDI, scheduled for removal as part of Bug 484900 + */ + @Deprecated public boolean contains(String source) { for (ISourceContainer cont : getSourceContainers()) { if (contains(cont, source)) @@ -81,6 +83,10 @@ public class CSourceLookupDirector extends AbstractSourceLookupDirector { return false; } + /** + * @deprecated Only used by CDI, scheduled for removal as part of Bug 484900 + */ + @Deprecated public boolean contains(ICBreakpoint breakpoint) { try { String handle = breakpoint.getSourceHandle(); @@ -93,6 +99,10 @@ public class CSourceLookupDirector extends AbstractSourceLookupDirector { return false; } + /** + * @deprecated Only used by CDI, scheduled for removal as part of Bug 484900 + */ + @Deprecated public boolean contains(IProject project) { for (ISourceContainer cont : getSourceContainers()) { if (contains(cont, project)) @@ -101,6 +111,10 @@ public class CSourceLookupDirector extends AbstractSourceLookupDirector { return false; } + /** + * @deprecated Only used by CDI, scheduled for removal as part of Bug 484900 + */ + @Deprecated private boolean contains(ISourceContainer container, IProject project) { if (container instanceof CProjectSourceContainer && project.equals(((CProjectSourceContainer) container).getProject())) { return true; @@ -118,6 +132,10 @@ public class CSourceLookupDirector extends AbstractSourceLookupDirector { return false; } + /** + * @deprecated Only used by CDI, scheduled for removal as part of Bug 484900 + */ + @Deprecated private boolean contains(ISourceContainer container, String sourceName) { IPath path = new Path(sourceName); if (!path.isValidPath(sourceName)) @@ -174,6 +192,18 @@ public class CSourceLookupDirector extends AbstractSourceLookupDirector { return false; } + /** + * Translate a local file name to a name understood by the backend. + * + * This method is used when CDT needs to send a command to the backend + * containing a file name. For example, inserting a breakpoint. The platform + * breakpoint's file name is a path of a file on the user's machine, but GDB + * needs the path that corresponds to the debug information. + * + * @param sourceName + * file name of a local file + * @return file name as understood by the debugger backend + */ public IPath getCompilationPath(String sourceName) { for (ISourceContainer container : getSourceContainers()) { IPath path = SourceUtils.getCompilationPath(container, sourceName); @@ -184,7 +214,12 @@ public class CSourceLookupDirector extends AbstractSourceLookupDirector { return null; } - // >> Bugzilla 279473 + /** + * Load and cache the source container types which are supported for CDT + * debugging. + * + * See Bug 279473 for more information. + */ private void readSupportedContainerTypes() { synchronized (fSupportedTypesLock) { if (fSupportedTypes == null) { @@ -203,5 +238,4 @@ public class CSourceLookupDirector extends AbstractSourceLookupDirector { } } } - // << Bugzilla 279473 } diff --git a/dsf-gdb/org.eclipse.cdt.tests.dsf.gdb/src/org/eclipse/cdt/tests/dsf/gdb/tests/SourceLookupTest.java b/dsf-gdb/org.eclipse.cdt.tests.dsf.gdb/src/org/eclipse/cdt/tests/dsf/gdb/tests/SourceLookupTest.java index 63a62491a5c..ca9bd790a13 100644 --- a/dsf-gdb/org.eclipse.cdt.tests.dsf.gdb/src/org/eclipse/cdt/tests/dsf/gdb/tests/SourceLookupTest.java +++ b/dsf-gdb/org.eclipse.cdt.tests.dsf.gdb/src/org/eclipse/cdt/tests/dsf/gdb/tests/SourceLookupTest.java @@ -42,10 +42,12 @@ 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.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.mi.service.command.output.MIMixedInstruction; 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; @@ -701,4 +703,37 @@ public class SourceLookupTest extends BaseTestCase { assertFinderDoesNotFind(EXEC_AC_NAME, new File(BUILD_PATH, SOURCE_NAME).getAbsolutePath()); } + + /** + * This test verifies that doing a source lookup where the absolute name of + * the file is provided by the backend resolves. + * + * In the normal DSF case + * {@link ISourceLookupDirector#findSourceElements(Object)} is called with a + * {@link IDMContext}, e.g. a stack frame DMC. + * + * However, the disassembly view/editor does the lookup on a String (it + * passes the result of {@link MIMixedInstruction#getFileName()} to + * findSourceElements). + * + * In both the CDI and DSF participants there is special handling to ensure + * that absolute file names are resolved even if there are no source + * containers in the launch configuration. + */ + @Test + public void noExplicitSourceContainers() throws Throwable { + // create a director with no containers so that the memento can be + // created. + AbstractSourceLookupDirector tmpDirector = (AbstractSourceLookupDirector) DebugPlugin.getDefault() + .getLaunchManager().newSourceLocator("org.eclipse.cdt.debug.core.sourceLocator"); + tmpDirector.setSourceContainers(new ISourceContainer[0]); + setLaunchAttribute(ILaunchConfiguration.ATTR_SOURCE_LOCATOR_MEMENTO, tmpDirector.getMemento()); + setLaunchAttribute(ILaunchConfiguration.ATTR_SOURCE_LOCATOR_ID, tmpDirector.getId()); + + // We are using the version of the executable that is resolvable, i.e + // the one that has not had its source file moved since we compiled. + doLaunch(EXEC_PATH + EXEC_NAME); + + assertSourceFound(); + } } diff --git a/dsf/org.eclipse.cdt.dsf/src/org/eclipse/cdt/dsf/debug/sourcelookup/DsfSourceLookupDirector.java b/dsf/org.eclipse.cdt.dsf/src/org/eclipse/cdt/dsf/debug/sourcelookup/DsfSourceLookupDirector.java index 76f3cc5af29..236171fd110 100644 --- a/dsf/org.eclipse.cdt.dsf/src/org/eclipse/cdt/dsf/debug/sourcelookup/DsfSourceLookupDirector.java +++ b/dsf/org.eclipse.cdt.dsf/src/org/eclipse/cdt/dsf/debug/sourcelookup/DsfSourceLookupDirector.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2004, 2009 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 @@ -19,22 +19,23 @@ import org.eclipse.debug.core.sourcelookup.ISourceLookupParticipant; /** * DSF source lookup director. * + * When a launch (or the global) source lookup containers are being edited it is + * an instance of CSourceLookupDirector that is created. However, when using DSF + * launch, the subclass DsfSourceLookupDirector is actually instantiated because + * connection to the DsfSession is needed. + * * @since 1.0 */ public class DsfSourceLookupDirector extends CSourceLookupDirector { private final DsfSession fSession; - public DsfSourceLookupDirector(DsfSession session) { - fSession = session; - } + public DsfSourceLookupDirector(DsfSession session) { + fSession = session; + } - /* (non-Javadoc) - * @see org.eclipse.debug.core.sourcelookup.ISourceLookupDirector#initializeParticipants() - */ @Override - public void initializeParticipants() { - super.initializeParticipants(); + public void initializeParticipants() { addParticipants( new ISourceLookupParticipant[]{ new DsfSourceLookupParticipant(fSession) } ); } diff --git a/dsf/org.eclipse.cdt.dsf/src/org/eclipse/cdt/dsf/debug/sourcelookup/DsfSourceLookupParticipant.java b/dsf/org.eclipse.cdt.dsf/src/org/eclipse/cdt/dsf/debug/sourcelookup/DsfSourceLookupParticipant.java index 262a7111f61..b99cc348193 100644 --- a/dsf/org.eclipse.cdt.dsf/src/org/eclipse/cdt/dsf/debug/sourcelookup/DsfSourceLookupParticipant.java +++ b/dsf/org.eclipse.cdt.dsf/src/org/eclipse/cdt/dsf/debug/sourcelookup/DsfSourceLookupParticipant.java @@ -37,23 +37,20 @@ import org.eclipse.core.runtime.IStatus; import org.eclipse.core.runtime.MultiStatus; import org.eclipse.core.runtime.Status; import org.eclipse.debug.core.DebugPlugin; +import org.eclipse.debug.core.sourcelookup.AbstractSourceLookupParticipant; import org.eclipse.debug.core.sourcelookup.ISourceContainer; import org.eclipse.debug.core.sourcelookup.ISourceLookupDirector; -import org.eclipse.debug.core.sourcelookup.ISourceLookupParticipant; /** * Source lookup participant that should be used with DSF-based debuggers. - * + * * @since 1.0 */ @ThreadSafe -public class DsfSourceLookupParticipant implements ISourceLookupParticipant { - protected static final Object[] EMPTY = new Object[0]; - +public class DsfSourceLookupParticipant extends AbstractSourceLookupParticipant { private DsfExecutor fExecutor; private String fSessionId; private DsfServicesTracker fServicesTracker; - private ISourceLookupDirector fDirector; private Map> fLookupCache = Collections.synchronizedMap(new HashMap>()); public DsfSourceLookupParticipant(DsfSession session) { @@ -61,27 +58,19 @@ public class DsfSourceLookupParticipant implements ISourceLookupParticipant { fExecutor = session.getExecutor(); fServicesTracker = new DsfServicesTracker(DsfPlugin.getBundleContext(), fSessionId); } - - /* (non-Javadoc) - * @see org.eclipse.debug.core.sourcelookup.ISourceLookupParticipant#init(org.eclipse.debug.core.sourcelookup.ISourceLookupDirector) - */ - @Override - public void init(ISourceLookupDirector director) { - fDirector = director; - } - /* (non-Javadoc) - * @see org.eclipse.debug.core.sourcelookup.ISourceLookupParticipant#dispose() - */ @Override public void dispose() { fServicesTracker.dispose(); - fDirector = null; + super.dispose(); } - /* (non-Javadoc) - * @see org.eclipse.debug.core.sourcelookup.ISourceLookupParticipant#findSourceElements(java.lang.Object) - */ + /** + * This method does the same thing (is almost copy-and-paste) as + * {@link AbstractSourceLookupParticipant#findSourceElements(Object), but it + * surrounds the lookup with a cache (#fLookupCache) that needs to be + * cleared if the source containers change. + */ @Override public Object[] findSourceElements(Object object) throws CoreException { CoreException single = null; @@ -102,7 +91,7 @@ public class DsfSourceLookupParticipant implements ISourceLookupParticipant { containers = new ISourceContainer[] { new AbsolutePathSourceContainer() }; for (int i = 0; i < containers.length; i++) { try { - ISourceContainer container = containers[i]; + ISourceContainer container = getDelegateContainer(containers[i]); if (container != null) { Object[] objects = container.findSourceElements(name); if (objects.length > 0) { @@ -145,50 +134,17 @@ public class DsfSourceLookupParticipant implements ISourceLookupParticipant { return results.toArray(); } - /** - * Returns whether this participant's source lookup director is configured - * to search for duplicate source elements. - * - * @return whether this participant's source lookup director is configured - * to search for duplicate source elements - */ - protected boolean isFindDuplicates() { - ISourceLookupDirector director = fDirector; - if (director != null) { - return director.isFindDuplicates(); - } - return false; - } - - /** - * Returns the source containers currently registered with this participant's - * source lookup director. - * - * @return the source containers currently registered with this participant's - * source lookup director - */ - protected ISourceContainer[] getSourceContainers() { - ISourceLookupDirector director = fDirector; - if (director != null) { - return director.getSourceContainers(); - } - return new ISourceContainer[0]; - } - - /* (non-Javadoc) - * @see org.eclipse.debug.core.sourcelookup.ISourceLookupParticipant#sourceContainersChanged(org.eclipse.debug.core.sourcelookup.ISourceLookupDirector) - */ @Override public void sourceContainersChanged(ISourceLookupDirector director) { fLookupCache.clear(); } - /* (non-Javadoc) - * @see org.eclipse.debug.internal.core.sourcelookup.ISourceLookupParticipant#getSourceName(java.lang.Object) - */ @Override - public String getSourceName(Object object) throws CoreException { - if ( !(object instanceof IDMContext) || + public String getSourceName(Object object) throws CoreException { + if (object instanceof String) { + return (String)object; + } + if ( !(object instanceof IDMContext) || !((IDMContext)object).getSessionId().equals(fSessionId) ) { return null;