从UncaughtExceptionHandler抛出异常

时间:2015-01-22 15:43:30

标签: java multithreading nullpointerexception apk

我正在编写一个apk分析程序。我不能深入细节,因为它是研究材料。但是,重点是我不时执行分析例程时收到以下消息:

Exception: java.lang.NullPointerException thrown from the UncaughtExceptionHandler in thread "main"

如果我不覆盖UncaughtExceptionHandler,并且如果我这样做,则会发生这种情况,正如您将从下面的代码中看到的那样。由于没有stacktrace 数据,我无法知道该异常的来源以及原因究竟是什么。

我希望你能帮助我......

这只是主要代码。我必须执行三个主要操作。为了不泄露特定信息,我将它们重命名为A,B和C

public class MainScannerSequential {
public static void main(String[] args) throws ParserConfigurationException, IOException, InterruptedException {
    final File target = new File(args[1]);
    final File result = new File(args[2]);
    final Options options = new Options(args);

    silentMode = options.contains("-s");
    noA = options.contains("-nl");
    noC = options.contains("-ne");

    aStrategy = Factory.createA();
    bScanner = Factory.createB();
    cDetector = Factory.createcC();

    examinedFiles = new PersistentFileList(Globals.EXAMINED_FILES_LIST_FILE);

    if (result.exists())
        resultsWriter = new BufferedWriter(new FileWriter(result, true));
    else {
        resultsWriter = new BufferedWriter(new FileWriter(result));
        resultsWriter.write("***");
        resultsWriter.newLine();
    }

    if (Globals.PERFORMANCE_FILE.exists())
        performancesWriter = new BufferedWriter(new FileWriter(Globals.PERFORMANCE_FILE, true));
    else {
        performancesWriter = new BufferedWriter(new FileWriter(Globals.PERFORMANCE_FILE));
        performancesWriter.write("***");
        performancesWriter.newLine();
    }

    Thread.currentThread().setUncaughtExceptionHandler(new Thread.UncaughtExceptionHandler() {
        @Override
        public void uncaughtException(Thread t, Throwable e) {
            if ((t != null) && (t.getName() != null))
                System.out.println("In thread : " + t.getName());

            if ((e != null) && (e.getMessage() != null)) {
                System.out.println(e.getClass().getName() + ": " + e.getMessage());
                if (e.getStackTrace() != null)
                    for (StackTraceElement ste : e.getStackTrace())
                        if (ste != null)
                            System.out.println(ste.getFileName() + " at line " + ste.getLineNumber());
            }
        }
    });

    if (target.isDirectory()) {
        enumerateDirectory(target);
    } else {
        String name = target.getName().toLowerCase();

        if (name.endsWith(".apklist"))
            readFileList(target);
        else if (name.endsWith(".apk"))
            checkFile(target);
    }

    closeWriters();
}

private static void println(String message) {
    if (!silentMode)
        System.out.println(message);
}

private static void print(String message) {
    if (!silentMode)
        System.out.print(message);
}


private static void enumerateDirectory(File directory) {
    for (File file : directory.listFiles()) {
        checkFile(file);

        if (file.isDirectory())
            enumerateDirectory(file);
    }
}

private static void readFileList(File file) {
    try {
        BufferedReader reader = new BufferedReader(new FileReader(file));
        String line = null;

        while((line = reader.readLine()) != null) {
            File readFile = new File(line);

            if (readFile.exists())
                checkFile(readFile);
        }

        reader.close();
    } catch (Exception e) {
        e.printStackTrace();
    }
}

private static void checkFile(File file) {
    if (examinedFiles.contains(file)) {
        println("Skipped: " + file.getName());
        return;
    }

    if (!file.getName().toLowerCase().endsWith(".apk")) {
        return;
    }

    final Wrapper<Double> unpackingTime = new Wrapper<Double>(0.0);
    final ApplicationData data = unpack(file, unpackingTime);

    if (data == null) {
        return;
    }

    scanData(data, unpackingTime.value);
}


private static ApplicationData unpack(final File file, final Wrapper<Double> unpackingTime) {
    final Wrapper<ApplicationData> resultWrapper = new Wrapper<ApplicationData>(null);
    final Wrapper<Exception> exceptionWrapper = new Wrapper<Exception>(null);

    println("Unpacking: " + file.getName());

    unpackingTime.value = Stopwatch.time(new Runnable() {
        @Override
        public void run() {
            try {
                resultWrapper.value = ApplicationData.open(file);
            } catch (Exception e) {
                exceptionWrapper.value = e;
            }
        }
    });

    if (resultWrapper.value != null)
        println("Unpacked: " + file.getName());
    else if (exceptionWrapper.value != null)
        println("Dropped: " + file.getName() + " : " + exceptionWrapper.value.getMessage());

    return resultWrapper.value;
}

private static void scanData(final ApplicationData applicationData, Double unpackingTime) {
    String apkName = applicationData.getDecodedPackage().getOriginalApk().getAbsolutePath();
    println("Submitted: " + apkName);

    examinedFiles.add(applicationData.getDecodedPackage().getOriginalApk());

    final Wrapper<Boolean> aDetected = new Wrapper<Boolean>(false);
    final Wrapper<Result> bDetected = new Wrapper<Result>(new Result());
    final Wrapper<Boolean> cDetected = new Wrapper<Boolean>(false);

    final Wrapper<Double> aDetectionTime = new Wrapper<Double>((double)ANALYSIS_TIMEOUT);
    final Wrapper<Double> bDetectionTime = new Wrapper<Double>((double)ANALYSIS_TIMEOUT);
    final Wrapper<Double> cDetectionTime = new Wrapper<Double>((double)ANALYSIS_TIMEOUT);

    ExecutorService executor = Executors.newFixedThreadPool(3);

    executor.submit(new Runnable() {
        @Override
        public void run() {
            textDetectionTime.value = Stopwatch.time(new Runnable() {
                @Override
                public void run() {
                    bScanner.setUnpackedApkDirectory(applicationData.getDecodedPackage().getDecodedDirectory());
                    bDetected.value = bScanner.evaluate();
                }
            });
        }
    });

    if (!noA)
        executor.submit(new Runnable() {
            @Override
            public void run() {
                lockDetectionTime.value = Stopwatch.time(new Runnable() {
                    @Override
                    public void run() {
                        aStrategy.setTarget(applicationData.getDecodedPackage());
                        aDetected.value = aStrategy.detect();
                    }
                });
            }
        });

    if (!noC)
        executor.submit(new Runnable() {
            @Override
            public void run() {
                encryptionDetectionTime.value = Stopwatch.time(new Runnable() {
                    @Override
                    public void run() {
                        cDetector.setTarget(applicationData.getDecodedPackage());
                        cDetected.value = cDetector.detect();
                    }
                });
            }
        });

    boolean timedOut = false;
    executor.shutdown();

    try {
        if (!executor.awaitTermination(ANALYSIS_TIMEOUT, TimeUnit.SECONDS)) {
            executor.shutdownNow();
            timedOut = true;
        }
    } catch (InterruptedException e) {
        e.printStackTrace();
    }

    try {
        resultsWriter.write(String.format("%s, %b, %b, %f, %b, \"%s\", %b\n",
                apkName,
                aDetected.value,
                bDetected.value.isAccepted(),
                bDetected.value.getScore(),
                cDetected.value,
                bDetected.value.getComment(),
                timedOut));

        performancesWriter.write(String.format("%s, %f, %f, %f, %f, %d, %dl, %dl\n",
                apkName,
                aDetectionTime.value,
                bDetectionTime.value,
                cDetectionTime.value,
                unpackingTime,
                applicationData.getSmaliLoader().getClassesCount(),
                applicationData.getSmaliLoader().getTotalClassesSize(),
                applicationData.getDecodedPackage().getOriginalApk().length()));

        resultsWriter.flush();
        performancesWriter.flush();
    } catch (IOException e) { }

    // No longer deleting temp files

    if (!timedOut)
        println("Completed: " + apkName);
    else {
        print("Timeout");

        if (bDetectionTime.value == 0) print(" TextDetection");
        if (!noA && (aDetectionTime.value == 0)) print(" LockDetection");
        if (!noC && (cDetectionTime.value == 0)) print(" EncryptionDetection");

        println(": " + apkName);
    }
}


private static void closeWriters() throws IOException {
    resultsWriter.close();
    performancesWriter.close();
    examinedFiles.dispose();
}


private static final int ANALYSIS_TIMEOUT = 40; // seconds

private static Boolean silentMode = false;
private static Boolean noA = false;
private static Boolean noC = false;

private static PersistentFileList examinedFiles;
private static BufferedWriter resultsWriter;
private static BufferedWriter performancesWriter;

private static A aStrategy;
private static B bScanner;
private static C cDetector;
}

我将问题标记为多线程,因为在多线程版本中也是如此,我使用此代码序列化以调试该错误。请注意,NullPointerException是在线程main中,而不是在其他Executor生成的线程中。

1 个答案:

答案 0 :(得分:2)

如果您没有堆栈跟踪,则可能意味着您的代码中存在一些疯狂的异常(请参阅Exception without stack trace in Java),但更有可能的是JVM重新使用异常对象性能优化和-XX:-OmitStackTraceInFastThrow JVM选项可以帮助您。

有关详细信息,请参阅this article