diff --git a/NewAndNoteworthy/CDT-11.0.md b/NewAndNoteworthy/CDT-11.0.md index c10915f9e40..5a6a622f5b4 100644 --- a/NewAndNoteworthy/CDT-11.0.md +++ b/NewAndNoteworthy/CDT-11.0.md @@ -55,6 +55,10 @@ It may have other uses to other API consumers as well and is therefore included This should allow ISV's to create MBS based project with a vendor-specific build-system ID without using internal API. +## Binary Parser code uses AutoCloseable + +The binary parser classes which open binary files now implement AutoCloseable so they can (and should) be used in a try-with-resources block. +See https://github.com/eclipse-cdt/cdt/pull/132 # Bugs Fixed in this Release diff --git a/NewAndNoteworthy/CHANGELOG-API.md b/NewAndNoteworthy/CHANGELOG-API.md index 7ad64116462..2eaf7fc0100 100644 --- a/NewAndNoteworthy/CHANGELOG-API.md +++ b/NewAndNoteworthy/CHANGELOG-API.md @@ -14,6 +14,7 @@ This section describes API removals that occurred in past releases, and upcoming - [Removal of deprecated CBuildConfiguration.watchProcess() methods](#watchProcessCBuildConfig) - [Rework of API to determine GDB command line in org.eclipse.cdt.dsf.gdb](#gdbBackendDebuggerCommandLine) - [Removal of Qt plug-ins and features](#qt-plugins) +- [Removal of constructor org.eclipse.cdt.utils.coff.CodeViewReader(RandomAccessFile, int, boolean)](#CodeViewReader-constructor-removal) ## API Changes in CDT 10.5.0 @@ -163,6 +164,14 @@ The following bundles and all their related API has been removed: See https://github.com/eclipse-cdt/cdt/issues/123 +### Removal of constructor org.eclipse.cdt.utils.coff.CodeViewReader(RandomAccessFile, int, boolean) + +Same instance of RandomAccessFile was shared between multiple objects which +causes problems in closing it properly. A new constructor is introduced which +accepts filename and opens a RandomAccessFile. + +See https://github.com/eclipse-cdt/cdt/pull/132 + --- ## API Changes in CDT 10.5.0. 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 17a4a36e620..0616dc4d205 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 @@ -306,11 +306,14 @@ public class Binary extends Openable implements IBinary { // Try to get the list of source files used to build the binary from the // symbol information. - ISymbolReader symbolreader = obj.getAdapter(ISymbolReader.class); - if (symbolreader == null) - return false; + String[] sourceFiles = null; + try (ISymbolReader symbolreader = obj.getAdapter(ISymbolReader.class)) { + if (symbolreader == null) + return false; + + sourceFiles = symbolreader.getSourceFiles(); + } - String[] sourceFiles = symbolreader.getSourceFiles(); if (sourceFiles != null && sourceFiles.length > 0) { ISourceFinder srcFinder = getAdapter(ISourceFinder.class); try { diff --git a/core/org.eclipse.cdt.core/src/org/eclipse/cdt/core/ISymbolReader.java b/core/org.eclipse.cdt.core/src/org/eclipse/cdt/core/ISymbolReader.java index cb5d4f9e26c..c6311e8853a 100644 --- a/core/org.eclipse.cdt.core/src/org/eclipse/cdt/core/ISymbolReader.java +++ b/core/org.eclipse.cdt.core/src/org/eclipse/cdt/core/ISymbolReader.java @@ -23,7 +23,7 @@ import org.eclipse.core.runtime.IProgressMonitor; * @noextend This interface is not intended to be extended by clients. * @noimplement This interface is not intended to be implemented by clients. */ -public interface ISymbolReader { +public interface ISymbolReader extends AutoCloseable { String[] getSourceFiles(); @@ -35,4 +35,7 @@ public interface ISymbolReader { * @since 5.2 */ String[] getSourceFiles(IProgressMonitor monitor); + + @Override + void close(); } diff --git a/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/coff/CodeViewReader.java b/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/coff/CodeViewReader.java index 6ccb3b53db6..854d042c386 100644 --- a/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/coff/CodeViewReader.java +++ b/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/coff/CodeViewReader.java @@ -13,6 +13,7 @@ *******************************************************************************/ package org.eclipse.cdt.utils.coff; +import java.io.FileNotFoundException; import java.io.IOException; import java.io.RandomAccessFile; import java.util.ArrayList; @@ -30,14 +31,44 @@ public class CodeViewReader implements ISymbolReader { private String[] files = null; private boolean parsed = false; - public CodeViewReader(RandomAccessFile accessFile, int dataOffset, boolean littleEndian) { - file = accessFile; + /** + * @since 8.0 + */ + public CodeViewReader(String filename, int dataOffset, boolean littleEndian) throws FileNotFoundException { + file = new RandomAccessFile(filename, "r"); //$NON-NLS-1$ cvData = dataOffset; isLe = littleEndian; fileList = new ArrayList<>(); } + @Override + public void close() { + dispose(); + } + + /** + * @since 8.0 + */ + public void dispose() { + if (file != null) { + try { + file.close(); + } catch (IOException e) { + } + file = null; + } + } + + @Override + protected void finalize() throws Throwable { + try { + dispose(); + } finally { + super.finalize(); + } + } + @Override public String[] getSourceFiles() { if (!parsed) { diff --git a/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/coff/PE.java b/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/coff/PE.java index f9e3c00c689..d9a26c206d7 100644 --- a/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/coff/PE.java +++ b/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/coff/PE.java @@ -579,13 +579,16 @@ public class PE implements AutoCloseable { } @Override - public void close() throws IOException { + public void close() { dispose(); } - public void dispose() throws IOException { + public void dispose() { if (rfile != null) { - rfile.close(); + try { + rfile.close(); + } catch (IOException e) { + } rfile = null; } } @@ -771,7 +774,6 @@ public class PE implements AutoCloseable { } private ISymbolReader createCodeViewReader() { - ISymbolReader symReader = null; final int IMAGE_DIRECTORY_ENTRY_DEBUG = 6; try { @@ -813,8 +815,7 @@ public class PE implements AutoCloseable { String s2 = accessFile.readLine(); if (s2.startsWith("NB11")) { //$NON-NLS-1$ Attribute att = getAttribute(); - symReader = new CodeViewReader(accessFile, debugBase, att.isLittleEndian()); - return symReader; + return new CodeViewReader(filename, debugBase, att.isLittleEndian()); } } fileOffset += dir.DEBUGDIRSZ; @@ -825,7 +826,7 @@ public class PE implements AutoCloseable { e.printStackTrace(); } - return symReader; + return null; } private ISymbolReader createStabsReader() { diff --git a/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/coff/PE64.java b/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/coff/PE64.java index 5e4d8a4ba17..24a66ad1ad1 100644 --- a/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/coff/PE64.java +++ b/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/coff/PE64.java @@ -673,13 +673,16 @@ public class PE64 implements AutoCloseable { } @Override - public void close() throws IOException { + public void close() { dispose(); } - public void dispose() throws IOException { + public void dispose() { if (rfile != null) { - rfile.close(); + try { + rfile.close(); + } catch (IOException e) { + } rfile = null; } } @@ -881,7 +884,6 @@ public class PE64 implements AutoCloseable { } private ISymbolReader createCodeViewReader() { - ISymbolReader symReader = null; final int IMAGE_DIRECTORY_ENTRY_DEBUG = 6; try { @@ -942,8 +944,7 @@ public class PE64 implements AutoCloseable { String s2 = accessFile.readLine(); if (s2.startsWith("NB11")) { //$NON-NLS-1$ Attribute att = getAttribute(); - symReader = new CodeViewReader(accessFile, debugBase, att.isLittleEndian()); - return symReader; + return new CodeViewReader(filename, debugBase, att.isLittleEndian()); } } fileOffset += dir.DEBUGDIRSZ; @@ -954,7 +955,7 @@ public class PE64 implements AutoCloseable { e.printStackTrace(); } - return symReader; + return null; } private ISymbolReader createStabsReader() { diff --git a/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/coff/parser/PEBinaryObject.java b/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/coff/parser/PEBinaryObject.java index 9f7fd4e81fc..adeee3a10cd 100644 --- a/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/coff/parser/PEBinaryObject.java +++ b/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/coff/parser/PEBinaryObject.java @@ -107,9 +107,10 @@ public class PEBinaryObject extends BinaryObjectAdapter { } } if (adapter.equals(ISymbolReader.class)) { - PE pe = getAdapter(PE.class); - if (pe != null) { - return (T) pe.getSymbolReader(); + try (PE pe = getAdapter(PE.class)) { + if (pe != null) { + return (T) pe.getSymbolReader(); + } } } return super.getAdapter(adapter); diff --git a/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/coff/parser/PEBinaryObject64.java b/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/coff/parser/PEBinaryObject64.java index 849f36e355b..00eac1cce76 100644 --- a/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/coff/parser/PEBinaryObject64.java +++ b/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/coff/parser/PEBinaryObject64.java @@ -109,9 +109,10 @@ public class PEBinaryObject64 extends BinaryObjectAdapter { } } if (adapter.equals(ISymbolReader.class)) { - PE64 pe = getAdapter(PE64.class); - if (pe != null) { - return (T) pe.getSymbolReader(); + try (PE64 pe = getAdapter(PE64.class)) { + if (pe != null) { + return (T) pe.getSymbolReader(); + } } } return super.getAdapter(adapter); diff --git a/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/debug/dwarf/Dwarf.java b/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/debug/dwarf/Dwarf.java index 132d8e026ca..2e7f0322eb8 100644 --- a/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/debug/dwarf/Dwarf.java +++ b/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/debug/dwarf/Dwarf.java @@ -39,7 +39,7 @@ import org.eclipse.cdt.utils.elf.Elf.Section; import org.eclipse.core.runtime.IPath; import org.eclipse.core.runtime.Path; -public class Dwarf { +public class Dwarf implements AutoCloseable { /* Section names. */ final static String DWARF_DEBUG_INFO = ".debug_info"; //$NON-NLS-1$ @@ -359,6 +359,26 @@ public class Dwarf { } + private void dispose() { + dwarfSections.clear(); + dwarfAltSections.clear(); + System.gc(); + } + + @Override + public void close() { + dispose(); + } + + @Override + protected void finalize() throws Throwable { + try { + dispose(); + } finally { + super.finalize(); + } + } + int read_4_bytes(ByteBuffer in) throws IOException { try { byte[] bytes = new byte[4]; diff --git a/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/debug/stabs/StabsReader.java b/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/debug/stabs/StabsReader.java index 20f50982176..bfc7ec73488 100644 --- a/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/debug/stabs/StabsReader.java +++ b/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/debug/stabs/StabsReader.java @@ -248,4 +248,7 @@ public class StabsReader implements ISymbolReader { return getSourceFiles(); } + @Override + public void close() { + } } diff --git a/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/elf/Elf.java b/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/elf/Elf.java index 9e3090e2a8d..fa3cc455aba 100644 --- a/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/elf/Elf.java +++ b/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/elf/Elf.java @@ -59,7 +59,6 @@ public class Elf implements AutoCloseable { private Symbol[] symbolsTable; /** .dynSym section */ private Symbol[] dynamicSymbols; - private boolean areSectionsMapped; // Have sections been mapped? Used to clean up properly in Elf.Dispose. protected String EMPTY_STRING = ""; //$NON-NLS-1$ private long elfOffset; @@ -339,7 +338,6 @@ public class Elf implements AutoCloseable { */ public ByteBuffer mapSectionData() throws IOException { makeSureNotCompressed(); - areSectionsMapped = true; return efile.getChannel().map(MapMode.READ_ONLY, sh_offset, sh_size).load().asReadOnlyBuffer(); } @@ -987,9 +985,6 @@ public class Elf implements AutoCloseable { if (efile != null) { efile.close(); efile = null; - // ensure the mappings get cleaned up - if (areSectionsMapped) - System.gc(); } } catch (IOException e) { } @@ -1304,6 +1299,12 @@ public class Elf implements AutoCloseable { return reader; } + /** + * Creates a new symbol reader instance on each call. Caller is responsible for closing + * the symbol reader + * + * @return symbol reader or {@code null} if couldn't create symbol reader + */ public ISymbolReader getSymbolReader() { ISymbolReader reader = null; reader = createDwarfReader(); diff --git a/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/elf/parser/ElfBinaryObject.java b/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/elf/parser/ElfBinaryObject.java index 1edf66298ce..a60d9a048d2 100644 --- a/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/elf/parser/ElfBinaryObject.java +++ b/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/elf/parser/ElfBinaryObject.java @@ -187,9 +187,10 @@ public class ElfBinaryObject extends BinaryObjectAdapter { } } if (adapter.equals(ISymbolReader.class)) { - Elf elf = getAdapter(Elf.class); - if (elf != null) { - return (T) elf.getSymbolReader(); + try (Elf elf = getAdapter(Elf.class)) { + if (elf != null) { + return (T) elf.getSymbolReader(); + } } } return super.getAdapter(adapter); diff --git a/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/macho/MachO.java b/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/macho/MachO.java index 91b70fc5629..891a042cb99 100644 --- a/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/macho/MachO.java +++ b/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/macho/MachO.java @@ -34,7 +34,7 @@ import org.eclipse.cdt.utils.debug.stabs.StabsReader; * This class is planned for removal in next major release. */ @Deprecated -public class MachO { +public class MachO implements AutoCloseable { protected ERandomAccessFile efile; protected MachOhdr mhdr; @@ -1109,6 +1109,11 @@ public class MachO { } } + @Override + public void close() { + dispose(); + } + public void dispose() { if (cppFilt != null) { cppFilt.dispose(); diff --git a/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/macho/MachO64.java b/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/macho/MachO64.java index b319a0c1ecc..72d511e638b 100644 --- a/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/macho/MachO64.java +++ b/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/macho/MachO64.java @@ -32,7 +32,7 @@ import org.eclipse.cdt.utils.debug.stabs.StabsReader; /** * @since 5.2 */ -public class MachO64 { +public class MachO64 implements AutoCloseable { protected ERandomAccessFile efile; protected MachOhdr mhdr; @@ -1184,6 +1184,11 @@ public class MachO64 { } } + @Override + public void close() { + dispose(); + } + public void dispose() { if (cppFilt != null) { cppFilt.dispose(); diff --git a/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/macho/parser/MachOBinaryObject.java b/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/macho/parser/MachOBinaryObject.java index 1bf78ab259a..f26873d5045 100644 --- a/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/macho/parser/MachOBinaryObject.java +++ b/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/macho/parser/MachOBinaryObject.java @@ -395,9 +395,10 @@ public class MachOBinaryObject extends BinaryObjectAdapter { } } if (adapter.equals(ISymbolReader.class)) { - MachO macho = getAdapter(MachO.class); - if (macho != null) { - return (T) macho.getSymbolReader(); + try (MachO macho = getAdapter(MachO.class)) { + if (macho != null) { + return (T) macho.getSymbolReader(); + } } } return super.getAdapter(adapter); diff --git a/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/macho/parser/MachOBinaryObject64.java b/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/macho/parser/MachOBinaryObject64.java index 342ec03a0c1..f72e50ccfdc 100644 --- a/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/macho/parser/MachOBinaryObject64.java +++ b/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/macho/parser/MachOBinaryObject64.java @@ -410,9 +410,10 @@ public class MachOBinaryObject64 extends BinaryObjectAdapter { } } if (adapter.equals(ISymbolReader.class)) { - MachO64 macho = getAdapter(MachO64.class); - if (macho != null) { - return (T) macho.getSymbolReader(); + try (MachO64 macho = getAdapter(MachO64.class)) { + if (macho != null) { + return (T) macho.getSymbolReader(); + } } } return super.getAdapter(adapter); diff --git a/debug/org.eclipse.cdt.debug.application/src/org/eclipse/cdt/internal/debug/application/CompilerOptionParser.java b/debug/org.eclipse.cdt.debug.application/src/org/eclipse/cdt/internal/debug/application/CompilerOptionParser.java index 9227e448486..6d6a6238f94 100644 --- a/debug/org.eclipse.cdt.debug.application/src/org/eclipse/cdt/internal/debug/application/CompilerOptionParser.java +++ b/debug/org.eclipse.cdt.debug.application/src/org/eclipse/cdt/internal/debug/application/CompilerOptionParser.java @@ -66,6 +66,7 @@ public class CompilerOptionParser implements IWorkspaceRunnable { @Override public void run(IProgressMonitor monitor) { + ISymbolReader reader = null; try { // Calculate how many source files we have to process and use that as a basis // for our work estimate. @@ -102,7 +103,7 @@ public class CompilerOptionParser implements IWorkspaceRunnable { return; } - ISymbolReader reader = bf.getAdapter(ISymbolReader.class); + reader = bf.getAdapter(ISymbolReader.class); String[] sourceFiles = reader.getSourceFiles(); monitor.beginTask(Messages.GetCompilerOptions, sourceFiles.length * 2 + 1); @@ -157,6 +158,9 @@ public class CompilerOptionParser implements IWorkspaceRunnable { e.printStackTrace(); } catch (IOException e1) { e1.printStackTrace(); + } finally { + if (reader != null) + reader.close(); } monitor.done(); } diff --git a/debug/org.eclipse.cdt.debug.core/src/org/eclipse/cdt/debug/internal/core/executables/StandardSourceFilesProvider.java b/debug/org.eclipse.cdt.debug.core/src/org/eclipse/cdt/debug/internal/core/executables/StandardSourceFilesProvider.java index 86467ffc52e..29752f98f41 100644 --- a/debug/org.eclipse.cdt.debug.core/src/org/eclipse/cdt/debug/internal/core/executables/StandardSourceFilesProvider.java +++ b/debug/org.eclipse.cdt.debug.core/src/org/eclipse/cdt/debug/internal/core/executables/StandardSourceFilesProvider.java @@ -120,11 +120,11 @@ public class StandardSourceFilesProvider extends PlatformObject implements ISour IBinaryFile bin = createBinaryFile(executable); if (bin != null) { - ISymbolReader symbolreader = bin.getAdapter(ISymbolReader.class); - if (symbolreader != null) { - return symbolreader.getSourceFiles(monitor); + try (ISymbolReader symbolreader = bin.getAdapter(ISymbolReader.class)) { + if (symbolreader != null) { + return symbolreader.getSourceFiles(monitor); + } } - } return new String[0]; }