Skip to content

fix: don't mark a method's throws as visited before its blocks are loaded - #3028

Merged
skylot merged 1 commit into
skylot:masterfrom
HuzaifaChaudary:fix/method-throws-unloaded-callee
Oct 24, 2026
Merged

skylot merged 1 commit into
skylot:masterfrom
HuzaifaChaudary:fix/method-throws-unloaded-callee

Conversation

@HuzaifaChaudary

Copy link
Copy Markdown
Contributor

Description

MethodThrowsVisitor.visit sets the visited flag and then reads the method's blocks . when it is reached through a call from another class that is processed first , the callee's class isn't loaded yet , its blocks are null , nothing is collected , and the flag stays set . when the callee's own class is processed later the visit is skipped , so the method never gets its throws declaration even though it throws a checked exception . the output then doesn't compile .

this happens with a dependency cycle : A depends on B , B is processed first as a dependency of A , and its call to A.check() visits A.check before A is loaded . the flag is now only set once the blocks exist , so A.check is analyzed when A is processed .

found by decompiling the apk from #2892 . single threaded the output was stable but android.ext.qt.a(String, int, String) came out without throws InterruptedException , although it calls FutureTask.get(long, TimeUnit) and only catches ExecutionException and TimeoutException . luaj.lib.OsLib.a(String) throws new IOException(...) and had no throws either . with this change 10 methods in 3 classes get their throws and nothing else in the 813 classes changes . with -j 8 the throws clauses used to differ between two runs of the same build , with the change two runs are identical .

the new smali test is the cycle above and fails without the change . jadx-core tests : 1034 passed .

one thing this does not fix : a caller that is analyzed before its callee still doesn't see the callee's throws , B.use and A.run in the test stay without it . that needs the analysis to wait for the callee , which is a bigger change , happy to look at it if you want it .

Copilot AI balanced review requested due to automatic review settings October 22, 2026 17:57

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.

@skylot skylot left a comment •

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks.
I need to mention that this is only a workaround, and proper fix will require new scanner implementation, check this comment last part for details.

@skylot
skylot merged commit 305894f into skylot:master Oct 24, 2026
2 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants