当前位置: 首页 > 知识库问答 >
问题:

从UncaughtExceptionHandler引发的异常

阳昊
2023-03-14

我在写一个apk分析程序。我不能深入细节,因为这是研究材料。然而,重点在于,当我执行分析例程时,不时会得到以下消息:

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

这只是主要代码。我必须执行三个主要操作。为了不泄露特定信息,我把它们重新命名为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;
}

我将这个问题标记为multithread,因为在多线程版本中也会发生同样的情况,为了调试错误,我使用此代码对该版本进行了序列化。请注意,NullPointerException位于线程主线程中,而不是其他由执行器派生的线程中。

共有1个答案

云建木
2023-03-14

如果没有堆栈跟踪,这可能意味着代码中抛出了一些疯狂的异常(请参见Java中的Exception with stack trace),但更有可能的是JVM正在重用异常对象作为性能优化,并且-xx:-OmitStackTraceInfastThrowJVM选项将对您有所帮助。

有关详细信息,请参阅本文

 类似资料:
  • 我有一个Netbeans Maven Java项目,在其中我使用Jasper报表。在Netbeans中,一切都很好,但是当我运行带有依赖项文件的jar时,程序一直工作到我试图从数据库中获取带有数据的报表为止。当我按下按钮在两个日期之间返回报表中的数据时,程序在线程“AWT-EventQueue-0”中抛出错误-异常:从线程“AWT-EventQueue-0”中的UncaughtExceptionH

  • 我正在实施重试策略。基本上,我想做的是在一个单独的线程上重试POST请求。我在用杰曼的故障保护(https://github.com/jhalterman/failsafe#asynchronous-api集成)这是我的代码 我不想抓住这里的例外。它由重试策略处理。目前不会重试,因为我在这里捕获了异常。是否有方法从“SupplySync”引发异常,以便由重试策略处理?谢谢谢谢

  • 这是一个windows表单应用程序,我在其中有一个特定的表单。在这个表单上,我显示了一些应该在后台异步发生的处理的进度。所有这些都很好,除了当我尝试处理后台处理中捕获的异常时…… 这是表单代码中调用Async函数的子函数,该函数位于包含所有后台处理代码的模块中: 这是它调用的异步函数,它位于一个单独的模块中: 这是由异步函数调用的常规sub: 当我使用我知道最终会在子B中生成错误的数据运行此代码时

  • 我对从JBPM工作项处理程序抛出异常并在业务流程的其他地方处理异常的主题有点困惑。我们使用JBPM 6.0.3在Jboss EAP 6.1中运行。 JBPM用户指南暗示您永远不应该从WorkItemHandler中抛出异常。相反,处理程序应该捕获它们并以某种方式处理它们,或者将它们转换为错误消息、信号或类似信息。JBPM甚至提供了工作项处理程序包装器,用于捕获信号并将它们转换为消息。用户指南中没有

  • 我为一个更大的应用程序构建了一个库/模块,它从一个函数中抛出一个异常。如果找不到文件或者文件包含错误的格式,就会抛出异常。 该方法类似于: 异常将终止我的模块,因为它将被捕获在使用我的模块的应用程序中,但没关系,因为格式不好。 我想知道的是——像这样从递归函数中抛出异常是一种不好的做法吗?

  • 给定Java8代码 java中的Lambdas看起来对错误处理不太友好...