Tencent/tinker · error · IOException

dex2oat is interrupted, msg:

Error message

dex2oat is interrupted, msg: 

What it means

While waiting for the forked dex2oat process, the loader thread received an InterruptedException. Tinker converts it to an IOException so the interpret-mode optimization aborts rather than continuing in an undefined state.

Source

Thrown at tinker-android/tinker-android-loader/src/main/java/com/tencent/tinker/loader/TinkerDexOptimizer.java:615

            commandAndParams.add("--instruction-set=" + targetISA);
            if (Build.VERSION.SDK_INT > 25) {
                commandAndParams.add("--compiler-filter=quicken");
            } else {
                commandAndParams.add("--compiler-filter=interpret-only");
            }

            final ProcessBuilder pb = new ProcessBuilder(commandAndParams);
            pb.redirectErrorStream(true);
            final Process dex2oatProcess = pb.start();
            StreamConsumer.consumeInputStream(dex2oatProcess.getInputStream());
            StreamConsumer.consumeInputStream(dex2oatProcess.getErrorStream());
            try {
                final int ret = dex2oatProcess.waitFor();
                if (ret != 0) {
                    throw new IOException("dex2oat works unsuccessfully, exit code: " + ret);
                }
            } catch (InterruptedException e) {
                throw new IOException("dex2oat is interrupted, msg: " + e.getMessage(), e);
            }
        } finally {
            try {
                if (fileLock != null) {
                    fileLock.close();
                }
            } catch (IOException e) {
                ShareTinkerLog.w(TAG, "release interpret Lock error", e);
            }
        }
    }

    private static class StreamConsumer {
        static final Executor STREAM_CONSUMER = Executors.newSingleThreadExecutor();

        static void consumeInputStream(final InputStream is) {
            STREAM_CONSUMER.execute(new Runnable() {
                @Override

View on GitHub (pinned to 1b7ea02c23)

Solutions

  1. Do not interrupt patch loading; let loadTinker run to completion on the main thread as Tinker intends.
  2. If loading on an executor, never call shutdownNow while a patch load may be in flight.
  3. Catch IOException around patch load and simply retry on next process start — Tinker load is restartable.
Defensive patterns

Strategy: try-catch

Try / catch

try {
    int ret = dex2oatProcess.waitFor();
} catch (InterruptedException e) {
    Thread.currentThread().interrupt(); // restore flag
    throw new IOException("dex2oat is interrupted", e);
}

Prevention

When it happens

Trigger: Something interrupted the thread running TinkerLoader.loadTinker — e.g. a watchdog/anr task interrupting the main thread, a timeout framework cancelling patch loading, or app code interrupting the thread pool that hosts patch loading.

Common situations: Patch loading moved off the main thread into a custom executor that is shut down (shutdownNow interrupts workers); ANR monitors that interrupt long-running main-thread work during slow dexopt.

Related errors


AI-assisted analysis of Tencent/tinker@1b7ea02c23 (2026-08-14). Data as JSON: /api/errors/d0c0531d6fc153a2. Report an issue: GitHub.