Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Avoid Exceptions with Phantom Superclasses #335

Closed
wants to merge 1 commit into from
Closed

Avoid Exceptions with Phantom Superclasses #335

wants to merge 1 commit into from

Conversation

subarnob
Copy link

@msridhar /cc @lazaroclapp
Building the CFG fails with NoSuperclassFoundException when a callee method has a phantom superclass.
Continue by returning null instead.

@@ -296,7 +296,8 @@ public IClass getSuperclass() {
computeSuperclass();
}
if (superClass == null && !getReference().equals(TypeReference.JavaLangObject)) {
throw new NoSuperclassFoundException("No superclass found for " + this + " Superclass name " + superName);
//throw new NoSuperclassFoundException("No superclass found for " + this + " Superclass name " + superName);
Copy link
Member

Choose a reason for hiding this comment

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

Why do we need this change? What fails if we continue to throw the exception? I'm hesitant about his change as this code has been throwing an exception for quite a while.

Copy link
Author

Choose a reason for hiding this comment

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

It throws NoSuperclassFoundException while making CFG when the callee is in a BytecodeClass but has a PhantomClass superclass, as follows:

com.ibm.wala.classLoader.NoSuperclassFoundException: No superclass found for <Application,Landroid/support/v4/view/AsyncLayoutInflater$BasicInflater> Superclass name Landroid/view/LayoutInflater at com.ibm.wala.classLoader.BytecodeClass.getSuperclass(BytecodeClass.java:299) at com.ibm.wala.classLoader.BytecodeClass.getMethod(BytecodeClass.java:464) at com.ibm.wala.classLoader.JavaLanguage.inferInvokeExceptions(JavaLanguage.java:585) at com.ibm.wala.cfg.ShrikeCFG$BasicBlock.addExceptionalEdges(ShrikeCFG.java:287) at com.ibm.wala.cfg.ShrikeCFG$BasicBlock.computeOutgoingEdges(ShrikeCFG.java:243) at com.ibm.wala.cfg.ShrikeCFG$BasicBlock.access$0(ShrikeCFG.java:232) at com.ibm.wala.cfg.ShrikeCFG.computeEdges(ShrikeCFG.java:133) at com.ibm.wala.cfg.ShrikeCFG.<init>(ShrikeCFG.java:76) at com.ibm.wala.cfg.ShrikeCFG.make(ShrikeCFG.java:63) at com.ibm.wala.classLoader.ShrikeIRFactory.makeCFG(ShrikeIRFactory.java:43) at com.ibm.wala.classLoader.ShrikeIRFactory.makeIR(ShrikeIRFactory.java:58) at com.ibm.wala.ssa.DefaultIRFactory.makeIR(DefaultIRFactory.java:69)

Copy link
Member

Choose a reason for hiding this comment

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

Ah ok; ugh. Thanks for pointing this out. I'd like to think a bit more about the right fix here. It's possible I should just tweak the phantom class hacky implementation to work properly.

Copy link
Member

@msridhar msridhar left a comment

Choose a reason for hiding this comment

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

Marking this as with requested changes as it needs work. I might have to rework this functionality significantly.

@reddr
Copy link
Contributor

reddr commented Oct 4, 2018

During testing WALA master, I also stumpled across this issue.
It suffices to call IClass.isSuperClass() on a class that has a PhantomClass as a super class.

This triggers BytecodeClass.computeSuperClass() which executes this line in the else branch:
this.superClass = this.loader.lookupClass(TypeName.findOrCreate(this.superName));
loader.lookupClass fails, returns null and subsequently triggers the NoSuperClassFoundException.

Without checking for possible side-effects, a solution could be that ClassLoaderImpl.lookupClass
returns a PhantomClass instead of null, when ClassHierarchyFactory.makeWithPhantom was used.

@msridhar
Copy link
Member

msridhar commented Oct 4, 2018

@reddr I think my approach to the whole phantom superclass thing was kind of half-baked. I suggest you not rely on it for now and try to get the relevant superclass into your AnalysisScope. My thinking is when I have time I should revamp the whole way phantom superclasses are implemented to be more robust.

@reddr
Copy link
Contributor

reddr commented Oct 5, 2018

@msridhar Unfortunately, this seems to be last puzzle piece for my tool to be adapted to WALA master. I'm automatically analyzing apps where it might happen that, in particular, dead code classes contain unresolvable superclasses (i.e., the superclass is part of a library that is not statically linked).
Still, I have to keep the class as I extract code fingerprints.

When I first stumpled across this issue, I patched it in my custom WALA version in a way that
unresolvable superclasses were simply replaced with the class hierarchy root. This worked flawlessly, but as a side-effect, you might loose some information (e.g., name of superclass(es)).

Such an option would be a quick fix to this problem, while if you want to keep references, the PhantomClass concept could be another option. Just let me know if such a dual approach could be interesting for you or whether you just want to have a single clean solution. In the meantime, I still have to use my custom version to resolve this issue.

@msridhar
Copy link
Member

msridhar commented Oct 9, 2018

@reddr I need to think more here. Your use of class hierarchy root makes sense, and I thought about it at first but for some reason concluded it was risky. Now I've forgotten why :-) Let me think more and then we can figure out how to proceed.

@msridhar
Copy link
Member

Closing as out-of-date. I think we have better phantom superclass handling on master now; see #377

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