{"record":{"id":"fc8ab70ddcbfc3eb","repo":"skylot/jadx","slug":"live-variable-analysis-reach-iterations-limit-blo","errorCode":null,"errorMessage":"Live variable analysis reach iterations limit, blocks count: {}","messagePattern":"Live variable analysis reach iterations limit, blocks count: (.+?)","errorType":"exception","errorClass":"JadxRuntimeException","httpStatus":null,"severity":"error","filePath":"jadx-core/src/main/java/jadx/core/dex/visitors/ssa/LiveVarAnalysis.java","lineNumber":106,"sourceCode":"\t\tint k = 0;\n\t\tdo {\n\t\t\tchanged = false;\n\t\t\tfor (BlockNode block : blocks) {\n\t\t\t\tint blockId = block.getId();\n\t\t\t\tBitSet prevIn = liveInBlocks[blockId];\n\t\t\t\tBitSet newIn = new BitSet(regsCount);\n\t\t\t\tfor (BlockNode successor : block.getSuccessors()) {\n\t\t\t\t\tnewIn.or(liveInBlocks[successor.getId()]);\n\t\t\t\t}\n\t\t\t\tnewIn.andNot(defs[blockId]);\n\t\t\t\tnewIn.or(uses[blockId]);\n\t\t\t\tif (!prevIn.equals(newIn)) {\n\t\t\t\t\tchanged = true;\n\t\t\t\t\tliveInBlocks[blockId] = newIn;\n\t\t\t\t}\n\t\t\t}\n\t\t\tif (k++ > iterationsLimit) {\n\t\t\t\tthrow new JadxRuntimeException(\"Live variable analysis reach iterations limit, blocks count: \" + blocksCount);\n\t\t\t}\n\t\t} while (changed);\n\n\t\tthis.liveIn = liveInBlocks;\n\t}\n\n\tprivate static BitSet[] initBitSetArray(int length, int bitsCount) {\n\t\tBitSet[] array = new BitSet[length];\n\t\tfor (int i = 0; i < length; i++) {\n\t\t\tarray[i] = new BitSet(bitsCount);\n\t\t}\n\t\treturn array;\n\t}\n}\n","sourceCodeStart":88,"sourceCodeEnd":121,"githubUrl":"https://github.com/skylot/jadx/blob/e738a26571d02919f01df40de93bc9a44dee4e18/jadx-core/src/main/java/jadx/core/dex/visitors/ssa/LiveVarAnalysis.java#L88-L121","documentation":"Thrown by LiveVarAnalysis.processLiveInfo when the backward live-variable dataflow does not converge within blocksCount * 10 iterations. The analysis is a monotone fixed-point computation over a finite lattice, so it mathematically must converge; non-convergence signals either a corrupted/inconsistent CFG (e.g. successor block ids out of range, malformed loop edges) or a jadx bug. Hitting it means liveness used by SSA/phi placement could not be computed for one method.","triggerScenarios":"Running SSATransform or any pass that calls LiveVarAnalysis.runAnalysis on a method whose block graph was built inconsistently (block ids not matching the liveInBlocks array indexing, or a bug in successor linking), so live-in sets keep changing every round past the 10 * block-count cap.","commonSituations":"Rare; usually seen on hand-edited or post-processed DEX, on outputs of unusual compilers that jadx's block builder mis-handles, or as a secondary effect of a visitor that mutated the CFG without re-indexing blocks. Often indicates a jadx internal bug rather than a problem with your input.","solutions":["File a jadx bug with the input sample and the method name; this should never fire on well-formed DEX.","Update to the newest jadx - block-building and SSA passes are constantly hardened.","Skip the failing method/class so the rest of the batch completes.","If embedding jadx, catch JadxRuntimeException per method."],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"try {\n    cls.decompile();\n} catch (JadxRuntimeException e) {\n    if (e.getMessage().contains(\"Live variable analysis reach iterations limit\")) {\n        cls.addError(\"liveness non-convergence\", e);\n    } else { throw e; }\n}","preventionTips":["Treat this as a jadx internal bug, not a user config issue - report it.","Keep jadx up to date; block/SSA builder fixes land regularly.","Isolate per-method decompilation so one failure does not lose the whole batch."],"tags":["decompiler","ssa","dataflow","liveness","invariant-violation"],"backgroundTag":null,"analyzedSha":"e738a26571d02919f01df40de93bc9a44dee4e18","analyzedAt":"2026-08-14T00:10:24.238Z","schemaVersion":2},"datasetVersion":"2026-08-14T05:17:29.042Z"}