{"record":{"id":"989b2ec9801b4e4a","repo":"Tencent/tinker","slug":"bad-isa-num-989b2e","errorCode":null,"errorMessage":"Bad isa num: {}","messagePattern":"Bad isa num: (.+?)","errorType":"exception","errorClass":"IOException","httpStatus":null,"severity":"error","filePath":"tinker-android/tinker-android-loader/src/main/java/com/tencent/tinker/loader/shareutil/ShareOatUtil.java","lineNumber":100,"sourceCode":"            try {\n                Integer.parseInt(oatVersion);\n            } catch (NumberFormatException e) {\n                throw new IOException(\"Bad oat version: \" + oatVersion);\n            }\n\n            ByteBuffer buffer = ByteBuffer.allocate(128);\n            buffer.order(elfFile.getDataOrder());\n            // TODO This is a risk point, since each oat version may use a different offset.\n            // So far it's ok. Perhaps we should use oatVersionNum to judge the right offset in\n            // the future.\n            final int isaNumOffsetFromOatBegin = 12;\n            channel.position(roDataHdr.shOffset + isaNumOffsetFromOatBegin);\n            buffer.limit(4);\n            ShareElfFile.readUntilLimit(channel, buffer, \"Failed to read isa num.\");\n\n            int isaNum = buffer.getInt();\n            if (isaNum < 0 || isaNum >= InstructionSet.values().length) {\n                throw new IOException(\"Bad isa num: \" + isaNum);\n            }\n\n            switch (InstructionSet.values()[isaNum]) {\n                case kArm:\n                case kThumb2:\n                    result = \"arm\";\n                    break;\n                case kArm64:\n                    result = \"arm64\";\n                    break;\n                case kX86:\n                    result = \"x86\";\n                    break;\n                case kX86_64:\n                    result = \"x86_64\";\n                    break;\n                case kMips:\n                    result = \"mips\";","sourceCodeStart":82,"sourceCodeEnd":118,"githubUrl":"https://github.com/Tencent/tinker/blob/1b7ea02c239840f563ea64fb5bd286eb98d4011e/tinker-android/tinker-android-loader/src/main/java/com/tencent/tinker/loader/shareutil/ShareOatUtil.java#L82-L118","documentation":"ShareOatUtil reads the instruction-set number at offset 12 of the oat header and indexes the InstructionSet enum with it. If the int is negative or >= InstructionSet.values().length it throws IOException(\"Bad isa num: <n>\"). The value read is not a valid InstructionSet ordinal, meaning the oat header layout differs from what the parser assumes or the file is corrupt.","triggerScenarios":"getOatFileInstructionSet where bytes at rodata offset 12 decode to an out-of-range int — oat version with different header layout (the code's TODO notes the offset risk), or a corrupted odex.","commonSituations":"Newer oat versions changing the isa field offset; unusual ABIs; corrupted odex produced or modified during OTA.","solutions":["Hex-inspect the oat header around offset 12 for the device's ART version and confirm the field is where the parser expects.","Use getCurrentInstructionSet() (ABI-based) as a fallback when oat parsing throws.","Upgrade Tinker for newer Android support.","Delete the odex to force regeneration, then retry."],"exampleFix":null,"handlingStrategy":"fallback","validationCode":null,"typeGuard":null,"tryCatchPattern":"try {\n    isa = ShareOatUtil.getOatFileInstructionSet(odexFile);\n} catch (IOException ioe) {\n    // 'Bad isa num': header layout mismatch, fall back to ABI-derived ISA\n    isa = ShareTinkerInternals.getCurrentInstructionSet();\n}","preventionTips":["The isa offset (12) is version-sensitive; validate against each ART version you support.","Always implement an ABI-based instruction-set fallback.","Log the bad isa number to correlate with device/ART versions."],"tags":["android","tinker","oat","instruction-set","abi"],"backgroundTag":null,"analyzedSha":"1b7ea02c239840f563ea64fb5bd286eb98d4011e","analyzedAt":"2026-08-14T15:16:52.110Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}