diff --git a/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/model/Binary.java b/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/model/Binary.java index 6030282597a..073763d77f0 100644 --- a/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/model/Binary.java +++ b/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/model/Binary.java @@ -309,67 +309,74 @@ public class Binary extends Openable implements IBinary { String[] sourceFiles = symbolreader.getSourceFiles(); if (sourceFiles != null && sourceFiles.length > 0) { ISourceFinder srcFinder = (ISourceFinder) getAdapter(ISourceFinder.class); - - for (String filename : sourceFiles) { - - // Find the file locally - if (srcFinder != null) { - String localPath = srcFinder.toLocalPath(filename); - if (localPath != null) { - filename = localPath; - } - } - - // Be careful how you use this File object. If filename is a relative path, the resulting File - // object will apply the relative path to the working directory, which is not what we want. - // Stay away from methods that return or use the absolute path of the object. Note that - // File.isAbsolute() returns false when the object was constructed with a relative path. - File file = new File(filename); - - // Create a translation unit for this file and add it as a child of the binary - String id = CoreModel.getRegistedContentTypeId(getCProject().getProject(), file.getName()); - if (id == null) { - // Don't add files we can't get an ID for. - continue; - } - - // See if this source file is already in the project. - // We check this to determine if we should create a TranslationUnit or ExternalTranslationUnit - IFile wkspFile = null; - if (file.isAbsolute()) { - IFile[] filesInWP = ResourceLookup.findFilesForLocation(new Path(filename)); - - for (IFile element : filesInWP) { - if (element.isAccessible()) { - wkspFile = element; - break; + try { + for (String filename : sourceFiles) { + + // Find the file locally + if (srcFinder != null) { + String localPath = srcFinder.toLocalPath(filename); + if (localPath != null) { + filename = localPath; } } - } - - TranslationUnit tu; - if (wkspFile != null) - tu = new TranslationUnit(this, wkspFile, id); - else { - // If we have an absolute path (for the host file system), then use an IPath to create the - // ExternalTranslationUnit, as that is the more accurate way to specify the file. If it's - // not, then use the path specification we got from the debug information. We want to - // avoid, e.g., converting a UNIX path to a Windows one when debugging a UNIX-built binary - // on Windows. The opportunity to remap source paths was taken above, when we called - // ISourceFinder. If a mapping didn't occur, we want to preserve whatever the debug - // information told us. See bugzilla 297781 + + // Be careful how you use this File object. If filename is a relative path, the resulting File + // object will apply the relative path to the working directory, which is not what we want. + // Stay away from methods that return or use the absolute path of the object. Note that + // File.isAbsolute() returns false when the object was constructed with a relative path. + File file = new File(filename); + + // Create a translation unit for this file and add it as a child of the binary + String id = CoreModel.getRegistedContentTypeId(getCProject().getProject(), file.getName()); + if (id == null) { + // Don't add files we can't get an ID for. + continue; + } + + // See if this source file is already in the project. + // We check this to determine if we should create a TranslationUnit or ExternalTranslationUnit + IFile wkspFile = null; if (file.isAbsolute()) { - tu = new ExternalTranslationUnit(this, Path.fromOSString(filename), id); + IFile[] filesInWP = ResourceLookup.findFilesForLocation(new Path(filename)); + + for (IFile element : filesInWP) { + if (element.isAccessible()) { + wkspFile = element; + break; + } + } } + + TranslationUnit tu; + if (wkspFile != null) + tu = new TranslationUnit(this, wkspFile, id); else { - tu = new ExternalTranslationUnit(this, URIUtil.toURI(filename), id); + // If we have an absolute path (for the host file system), then use an IPath to create the + // ExternalTranslationUnit, as that is the more accurate way to specify the file. If it's + // not, then use the path specification we got from the debug information. We want to + // avoid, e.g., converting a UNIX path to a Windows one when debugging a UNIX-built binary + // on Windows. The opportunity to remap source paths was taken above, when we called + // ISourceFinder. If a mapping didn't occur, we want to preserve whatever the debug + // information told us. See bugzilla 297781 + if (file.isAbsolute()) { + tu = new ExternalTranslationUnit(this, Path.fromOSString(filename), id); + } + else { + tu = new ExternalTranslationUnit(this, URIUtil.toURI(filename), id); + } } + + if (! info.includesChild(tu)) + info.addChild(tu); } - - if (! info.includesChild(tu)) - info.addChild(tu); + return true; } - return true; + finally { + if (srcFinder != null) { + srcFinder.dispose(); + } + } + } return false; } diff --git a/core/org.eclipse.cdt.core/src/org/eclipse/cdt/core/ISourceFinder.java b/core/org.eclipse.cdt.core/src/org/eclipse/cdt/core/ISourceFinder.java index 1be3717280d..d762b59a345 100644 --- a/core/org.eclipse.cdt.core/src/org/eclipse/cdt/core/ISourceFinder.java +++ b/core/org.eclipse.cdt.core/src/org/eclipse/cdt/core/ISourceFinder.java @@ -50,6 +50,9 @@ import org.eclipse.core.runtime.IPath; * launch configuration. In all cases, the global locator is consulted if no other locator has converted the * file. * + *
A new instance is created every time a Binary object is queried for this interface. Clients must call + * {@link #dispose()} when it is done with the object. + * * @since 5.2 * @noimplement This interface is not intended to be implemented by clients. * @noextend This interface is not intended to be extended by clients. @@ -103,5 +106,10 @@ public interface ISourceFinder { */ public String toLocalPath(IAdaptable launch, String compilationPath); - + /** + * Clients must call this to ensure that the object properly cleans up. E.g., a source finder may register + * itself as a listener for changes that would effect how it searches for files. Calling this method will + * allow it to unregister itself. + */ + public void dispose(); } diff --git a/debug/org.eclipse.cdt.debug.core/src/org/eclipse/cdt/debug/internal/core/executables/StandardSourceFileRemapping.java b/debug/org.eclipse.cdt.debug.core/src/org/eclipse/cdt/debug/internal/core/executables/StandardSourceFileRemapping.java index 5fe4fcfc644..eb7c9bde00c 100644 --- a/debug/org.eclipse.cdt.debug.core/src/org/eclipse/cdt/debug/internal/core/executables/StandardSourceFileRemapping.java +++ b/debug/org.eclipse.cdt.debug.core/src/org/eclipse/cdt/debug/internal/core/executables/StandardSourceFileRemapping.java @@ -33,5 +33,11 @@ public class StandardSourceFileRemapping implements ISourceFileRemapping { } return filePath; } - + + /* (non-Javadoc) + * @see java.lang.Object#finalize() + */ + public void finalize(){ + srcFinder.dispose(); + } } \ No newline at end of file diff --git a/debug/org.eclipse.cdt.debug.core/src/org/eclipse/cdt/debug/internal/core/srcfinder/CSourceFinder.java b/debug/org.eclipse.cdt.debug.core/src/org/eclipse/cdt/debug/internal/core/srcfinder/CSourceFinder.java index 43b10b94489..3cabf2c8654 100644 --- a/debug/org.eclipse.cdt.debug.core/src/org/eclipse/cdt/debug/internal/core/srcfinder/CSourceFinder.java +++ b/debug/org.eclipse.cdt.debug.core/src/org/eclipse/cdt/debug/internal/core/srcfinder/CSourceFinder.java @@ -381,4 +381,13 @@ public class CSourceFinder implements ISourceFinder, ILaunchConfigurationListene public void launchesChanged(ILaunch[] launches) { // don't care. I don't think setting a new locator in a launch would result in us getting notified } + + /* (non-Javadoc) + * @see org.eclipse.cdt.core.ISourceFinder#dispose() + */ + public void dispose() { + ILaunchManager lmgr = DebugPlugin.getDefault().getLaunchManager(); + lmgr.removeLaunchConfigurationListener(this); + lmgr.removeLaunchListener(this); + } }