From 5f1ce08f4cc344f5c72026a4cdd05efe09fe1e4d Mon Sep 17 00:00:00 2001 From: Simon Billemont Date: Thu, 1 May 2014 11:47:17 +0200 Subject: [PATCH] BridJ: Extract debug symbol files accompanying a shared library (.pdb/.debug/.dSYM) --- .../src/main/java/org/bridj/Platform.java | 114 ++++++++++++------ 1 file changed, 78 insertions(+), 36 deletions(-) mode change 100644 => 100755 libraries/BridJ/src/main/java/org/bridj/Platform.java diff --git a/libraries/BridJ/src/main/java/org/bridj/Platform.java b/libraries/BridJ/src/main/java/org/bridj/Platform.java old mode 100644 new mode 100755 index 1304d34ba..d1ef5db2f --- a/libraries/BridJ/src/main/java/org/bridj/Platform.java +++ b/libraries/BridJ/src/main/java/org/bridj/Platform.java @@ -32,18 +32,15 @@ import org.bridj.util.ProcessUtils; import java.util.Set; -import java.util.HashSet; import java.util.regex.Pattern; import java.io.*; import java.net.URL; import java.util.List; import java.util.Collections; -import java.util.Collection; import java.util.ArrayList; import java.net.MalformedURLException; import java.net.URLClassLoader; -import java.util.Arrays; import java.util.Iterator; import java.util.LinkedHashSet; import java.util.LinkedList; @@ -661,47 +658,92 @@ public void run() { } static final long DELETE_OLD_BINARIES_AFTER_MILLIS = 24 * 60 * 60 * 1000; // 24 hours - static File extractEmbeddedLibraryResource(String name) throws IOException { - String firstLibraryResource = null; + /** + * Extracts a single embedded file from the a JAR, to the {@link #extractedLibrariesTempDir} directory. + *

+ * If the embedded library resource cannot be located, null is returned. + *

+ * + * @param libraryResource Path of the file in the jar to extract. + * @return If successful, the extracted File reference, otherwise null. + */ + static File extractEmbeddedResource(String libraryResource) throws IOException { + InputStream in = getResourceAsStream(libraryResource); + if (in == null) { + File f = new File(libraryResource); + if (!f.exists()) { + f = new File(f.getName()); + } + if (f.exists()) { + return f.getCanonicalFile(); + } else { + return null; + } + } + int len; + byte[] b = new byte[8196]; + String fileName = new File(libraryResource).getName(); + File libFile = new File(extractedLibrariesTempDir, fileName); + OutputStream out = new BufferedOutputStream(new FileOutputStream(libFile)); + while ((len = in.read(b)) > 0) { + out.write(b, 0, len); + } + out.close(); + in.close(); + + addTemporaryExtractedLibraryFileToDeleteOnExit(libFile); + addTemporaryExtractedLibraryFileToDeleteOnExit(libFile.getParentFile()); - List libraryResources = getEmbeddedLibraryResource(name); - if (BridJ.veryVerbose) { - BridJ.info("Library resources for " + name + ": " + libraryResources); + return libFile; + } + + /** + * Extracts a single library from the classpath JARs to {@link #extractedLibrariesTempDir}. + *

+ * Tries to extract the library based on the possible paths generated by {@link #getEmbeddedLibraryResource}. + * Additionally, if available, accompanying debug symbol files are extracted into the same folder. + *

+ *

+ * If no matching library was found and extracted, null is returned. + *

+ * + * @param name Name of the library to extract (without extension). + * @return If found, a File reference to the extracted library, otherwise null. + */ + static File extractEmbeddedLibraryResource(String name) throws IOException { + List libraryResources = getEmbeddedLibraryResource(name); + if (BridJ.veryVerbose) { + BridJ.info("Library resources for " + name + ": " + libraryResources); } for (String libraryResource : libraryResources) { - if (firstLibraryResource == null) { - firstLibraryResource = libraryResource; - } - int i = libraryResource.lastIndexOf('.'); - int len; - byte[] b = new byte[8196]; - InputStream in = getResourceAsStream(libraryResource); - if (in == null) { - File f = new File(libraryResource); - if (!f.exists()) { - f = new File(f.getName()); - } - if (f.exists()) { - return f.getCanonicalFile(); + // Try to extract the library resource + File libFile = extractEmbeddedResource(libraryResource); + // If successful, try to extract accompanying debug symbol files + if (libFile != null) { + // The library file without its shared library extension + String basePath = libraryResource.substring(0, libraryResource.lastIndexOf('.')); + + if ( isWindows() ) { + // MSVC debug symbol file, eg: foo.pdb + extractEmbeddedResource(basePath + ".pdb"); + } else if ( isMacOSX() ) { + // Apple debug symbol file, eg: foo.dylib.dSYM + extractEmbeddedResource(libraryResource + ".dSYM"); + // Apple debug symbol file, eg: foo.dSYM + extractEmbeddedResource(basePath + ".dSYM"); + } else { + // GCC debug symbol file, eg: foo.so.debug + extractEmbeddedResource(libraryResource + ".debug"); + // GCC debug symbol file, eg: foo.debug + extractEmbeddedResource(basePath + ".debug"); } - continue; - } - String fileName = new File(libraryResource).getName(); - File libFile = new File(extractedLibrariesTempDir, fileName); - OutputStream out = new BufferedOutputStream(new FileOutputStream(libFile)); - while ((len = in.read(b)) > 0) { - out.write(b, 0, len); - } - out.close(); - in.close(); - addTemporaryExtractedLibraryFileToDeleteOnExit(libFile); - addTemporaryExtractedLibraryFileToDeleteOnExit(libFile.getParentFile()); - - return libFile; + return libFile; + } } return null; } + static final int maxTempFileAttempts = 20; static File createTempDir(String prefix) throws IOException {