GP-1211: Better error handling of missing native components

This commit is contained in:
Ryan Kurtz 2021-09-09 13:18:52 -04:00
parent b5b4f94eed
commit 7394199cb3
7 changed files with 131 additions and 42 deletions

View File

@ -116,7 +116,7 @@ public class DecompileProcess {
nativeProcess.destroy(); // Make sure previous bad process is killed
nativeProcess = null;
}
if (exepath == null) {
if (exepath == null || exepath.length == 0 || exepath[0] == null) {
throw new IOException("Could not find decompiler executable");
}
try {

View File

@ -16,7 +16,6 @@
package ghidra.app.decompiler;
import java.io.File;
import java.io.FileNotFoundException;
import ghidra.framework.*;
import ghidra.util.Msg;
@ -30,6 +29,8 @@ public class DecompileProcessFactory {
private static final String EXECNAME = "decompile";
private static final String WIN32_EXECNAME = "decompile.exe";
private static boolean errorDisplayed = false;
public synchronized static DecompileProcess get() {
getExePath();
DecompileProcess currentProcess = new DecompileProcess(exepath);
@ -57,9 +58,12 @@ public class DecompileProcessFactory {
File file = Application.getOSFile(exeName);
exepath = file.getAbsolutePath();
}
catch (FileNotFoundException e) {
Msg.showError(DecompileProcessFactory.class, null, "Decompiler missing",
"Could not find decompiler executable " + exeName);
catch (OSFileNotFoundException e) {
if (!errorDisplayed) {
errorDisplayed = true;
Msg.showError(DecompileProcessFactory.class, null, "Decompiler missing",
e.getMessage());
}
}
}
}

View File

@ -24,8 +24,7 @@ import org.apache.commons.io.IOUtils;
import org.apache.commons.lang3.ArrayUtils;
import org.apache.commons.lang3.StringUtils;
import ghidra.framework.Application;
import ghidra.framework.Platform;
import ghidra.framework.*;
/**
* A class that allows for the reuse of native demangler executable processes. This class will
@ -168,7 +167,7 @@ public class GnuDemanglerNativeProcess {
processesByName.put(key, this);
}
private String[] buildCommand() throws FileNotFoundException {
private String[] buildCommand() throws OSFileNotFoundException {
String executableName =
applicationName + Platform.CURRENT_PLATFORM.getExecutableExtension();

View File

@ -15,9 +15,8 @@
*/
package ghidra.app.util.bin.format.pdb;
import java.util.*;
import java.io.*;
import java.util.*;
import org.xml.sax.SAXException;
@ -285,8 +284,8 @@ public class PdbParser {
pdbExeFile = Application.getOSFile(PDB_EXE);
pdbExe = pdbExeFile.getAbsolutePath();
}
catch (FileNotFoundException e) {
throw new PdbException("Unable to find " + PDB_EXE);
catch (OSFileNotFoundException e) {
throw new PdbException(e.getMessage());
}
if (noValidation) {

View File

@ -454,7 +454,8 @@ public class Application {
return null;
}
private File getModuleOSFile(String exactFilename, String moduleName) {
private File getModuleOSFile(String exactFilename, String moduleName)
throws OSFileNotFoundException {
GModule module = app.layout.getModules().get(moduleName);
if (module == null) {
@ -479,7 +480,7 @@ public class Application {
exactFilename);
}
return file;
throw new OSFileNotFoundException(exactFilename);
}
private File findModuleFile(String subdirPath, String exactFilename) {
@ -492,7 +493,7 @@ public class Application {
return null;
}
private File getOSFileInAnyModule(String path) throws FileNotFoundException {
private File getOSFileInAnyModule(String path) throws OSFileNotFoundException {
File file =
findModuleFile("build/os/" + Platform.CURRENT_PLATFORM.getDirectoryName(), path);
@ -510,8 +511,7 @@ public class Application {
}
if (file == null) {
throw new FileNotFoundException("os/" + Platform.CURRENT_PLATFORM.getDirectoryName() +
"/" + path + " does not exist");
throw new OSFileNotFoundException(path);
}
return file;
}
@ -904,24 +904,23 @@ public class Application {
* Returns the OS specific file within the given module with the given name.
* @param moduleName the name of the module
* @param exactFilename the name of the OS file within the module.
* @throws FileNotFoundException if the file does not exist.
* @throws OSFileNotFoundException if the file does not exist.
*/
public static File getOSFile(String moduleName, String exactFilename)
throws FileNotFoundException {
throws OSFileNotFoundException {
File osFile = app.getModuleOSFile(exactFilename, moduleName);
if (osFile != null) {
return osFile;
}
throw new FileNotFoundException(
"Could not find file " + exactFilename + " in module " + moduleName);
throw new OSFileNotFoundException(moduleName, exactFilename);
}
/**
* Returns the OS specific file in the calling class's module.
* @param exactFilename the name of the OS specific file.
* @throws FileNotFoundException if the file does not exist.
* @throws OSFileNotFoundException if the file does not exist.
*/
public static File getOSFile(String exactFilename) throws FileNotFoundException {
public static File getOSFile(String exactFilename) throws OSFileNotFoundException {
ResourceFile myModuleRootDirectory = getMyModuleRootDirectory();
if (myModuleRootDirectory == null) {
// not in a module; may be in a script?

View File

@ -0,0 +1,79 @@
/* ###
* IP: GHIDRA
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package ghidra.framework;
import java.io.FileNotFoundException;
/**
* Signals that an attempt to find a Ghidra "OS-file" (native binary) has failed.
* <p>
* This exception provides a consistent way to display information about the missing OS-file that
* will aid in error reporting and debugging.
*/
public class OSFileNotFoundException extends FileNotFoundException {
private Platform platform;
/**
* Creates a new {@link OSFileNotFoundException}
*
* @param platform The {@link Platform} associated with this exception
* @param moduleName The module name associated with this exception
* @param fileName The file name associated with this exception, from the given module
*/
public OSFileNotFoundException(Platform platform, String moduleName, String fileName) {
super(String.format("%sos/%s/%s does not exist", moduleName != null ? moduleName + "/" : "",
platform.getDirectoryName(), fileName));
this.platform = platform;
}
/**
* Creates a new {@link OSFileNotFoundException} with an unknown module
*
* @param platform The {@link Platform} associated with this exception
* @param fileName The file name associated with this exception, from an unknown module
*/
public OSFileNotFoundException(Platform platform, String fileName) {
this(platform, null, fileName);
}
/**
* Creates a new {@link OSFileNotFoundException} for the current {@link Platform}
*
* @param moduleName The module name associated with this exception
* @param fileName The file name associated with this exception, from the given module
*/
public OSFileNotFoundException(String moduleName, String fileName) {
this(Platform.CURRENT_PLATFORM, moduleName, fileName);
}
/**
* Creates a new {@link OSFileNotFoundException} for the current {@link Platform} with an
* unknown module
*
* @param fileName The file name associated with this exception, from an unknown module
*/
public OSFileNotFoundException(String fileName) {
this(Platform.CURRENT_PLATFORM, null, fileName);
}
/** Gets the {@link Platform} associated with this exception
*
* @return The {@link Platform} associated with this exception
*/
public Platform getPlatform() {
return platform;
}
}

View File

@ -35,12 +35,6 @@ public enum Platform {
*/
WIN_X86_64(OperatingSystem.WINDOWS, Architecture.X86_64, "win_x86_64", ".dll", ".exe"),
/**
* Identifies a Windows OS, the architecture for which we do not know or have not encountered.
* We'll treat it as {@link #WIN_X86_64} and hope for the best.
*/
WIN_UNKOWN(OperatingSystem.WINDOWS, Architecture.UNKNOWN, "win_x86_64", ".dll", ".exe"),
/**
* Identifies a Linux x86 32-bit OS.
*/
@ -56,12 +50,6 @@ public enum Platform {
*/
LINUX_ARM_64(OperatingSystem.LINUX, Architecture.ARM_64, "linux_arm_64", ".so", ""),
/**
* Identifies a Linux OS, the architecture for which we do not know or have not encountered.
* We'll treat it as {@link #LINUX_X86_64} and hope for the best.
*/
LINUX_UKNOWN(OperatingSystem.LINUX, Architecture.UNKNOWN, "linux_x86_64", ".so", ""),
/**
* Identifies a macOS x86 32-bit OS.
*/
@ -77,12 +65,6 @@ public enum Platform {
*/
MAC_ARM_64(OperatingSystem.MAC_OS_X, Architecture.ARM_64, "mac_arm_64", ".so", ""),
/**
* Identifies a macOS OS, the architecture for which we do not know or have not encountered.
* We'll treat it as {@link #MAC_X86_64} and hope for the best.
*/
MAC_UNKNOWN(OperatingSystem.MAC_OS_X, Architecture.UNKNOWN, "mac_x86_64", ".dylib", ""),
/**
* Identifies an unsupported OS.
*/
@ -95,6 +77,15 @@ public enum Platform {
*/
@Deprecated(since = "10.1", forRemoval = true)
WIN_64(OperatingSystem.WINDOWS, Architecture.X86_64, "win_x86_64", ".dll", ".exe"),
/**
* Identifies a Windows OS, the architecture for which we do not know or have not encountered.
* We'll treat it as {@link #WIN_X86_64} and hope for the best.
*
* @deprecated Unknown architectures are not supported
*/
@Deprecated(since = "10.1", forRemoval = true)
WIN_UNKOWN(OperatingSystem.WINDOWS, Architecture.UNKNOWN, "win_x86_64", ".dll", ".exe"),
/**
* Identifies a Linux X86 32-bit OS.
@ -111,6 +102,15 @@ public enum Platform {
*/
@Deprecated(since = "10.1", forRemoval = true)
LINUX_64(OperatingSystem.LINUX, Architecture.X86_64, "linux_x86_64", ".so", ""),
/**
* Identifies a Linux OS, the architecture for which we do not know or have not encountered.
* We'll treat it as {@link #LINUX_X86_64} and hope for the best.
*
* @deprecated Unknown architectures are not supported
*/
@Deprecated(since = "10.1", forRemoval = true)
LINUX_UKNOWN(OperatingSystem.LINUX, Architecture.UNKNOWN, "linux_x86_64", ".so", ""),
/**
* Identifies a macOS X86 32-bit OS.
@ -126,7 +126,16 @@ public enum Platform {
* @deprecated Use {@link #MAC_X86_64} instead.
*/
@Deprecated(since = "10.1", forRemoval = true)
MAC_OSX_64(OperatingSystem.MAC_OS_X, Architecture.X86_64, "mac_x86_64", ".dylib", "");
MAC_OSX_64(OperatingSystem.MAC_OS_X, Architecture.X86_64, "mac_x86_64", ".dylib", ""),
/**
* Identifies a macOS OS, the architecture for which we do not know or have not encountered.
* We'll treat it as {@link #MAC_X86_64} and hope for the best.
*
* @deprecated Use {@link #MAC_X86_64} instead.
*/
@Deprecated(since = "10.1", forRemoval = true)
MAC_UNKNOWN(OperatingSystem.MAC_OS_X, Architecture.UNKNOWN, "mac_x86_64", ".dylib", "");
/**
* A constant identifying the current platform.