Skip to content

Invokedynamic failures #619

@SoniaZaldana

Description

@SoniaZaldana

Hi there,

I’ve been investigating some failures parsing invokedynamic instructions. I first saw a similar issue raised in #574.

Just noting that I originally encountered the problem in v1.0.0 but it persists in v1.1.0.

I ran into some issues parsing record classes. I was getting various stack underrun errors when attempting to get the bodies of these methods. For example, the record class generates an equals(), hashCode() and string() method by default - all of which trigger an indy.

Public record RecordTest(String a, String b) {
	public RecordTest(String a, String b) {
		this.a = a; 
		this.b = b; 
	}
}

When I attempt to get the method body for equals(), I get the following stack trace:

Exception in thread "main" java.lang.RuntimeException: Failed to convert <jlink.RecordTest: boolean equals(java.lang.Object)>
	at sootup.java.bytecode.frontend.AsmMethodSource.resolveBody(AsmMethodSource.java:201)
	at sootup.core.model.SootMethod.lazyBodyInitializer(SootMethod.java:95)
	at com.google.common.base.Suppliers$NonSerializableMemoizingSupplier.get(Suppliers.java:166)
	at sootup.core.model.SootMethod.getBody(SootMethod.java:134)
	at org.ifds.IFDSSetUp.setupSoot(IFDSSetUp.java:68)
	at org.ifds.IFDSSetUp.executeStaticAnalysis(IFDSSetUp.java:30)
	at org.ifds.Main.main(Main.java:15)
Caused by: java.lang.RuntimeException: Stack underrun
	at sootup.java.bytecode.frontend.OperandStack.pop(OperandStack.java:90)
	at sootup.java.bytecode.frontend.OperandStack.popImmediate(OperandStack.java:162)
	at sootup.java.bytecode.frontend.OperandStack.popImmediate(OperandStack.java:172)
	at sootup.java.bytecode.frontend.AsmMethodSource.convertInvokeDynamicInsn(AsmMethodSource.java:1341)
	at sootup.java.bytecode.frontend.AsmMethodSource.convert(AsmMethodSource.java:1759)
	at sootup.java.bytecode.frontend.AsmMethodSource.resolveBody(AsmMethodSource.java:198)
	... 6 more

I think the issue lies here https://github.com/soot-oss/SootUp/blob/v1.1.0/sootup.java.bytecode/src/main/java/sootup/java/bytecode/frontend/AsmMethodSource.java#L1171

My understanding is we shouldn’t pop the operand stack to generate the method handle, as this leaves us with an empty stack when we generate the arguments here https://github.com/soot-oss/SootUp/blob/v1.1.0/sootup.java.bytecode/src/main/java/sootup/java/bytecode/frontend/AsmMethodSource.java#L1354.

I’ve currently been working around this by adding a dummy “unknown value”, as opposed to popping the operand stack.

Aside from that, I think there some logic issues in this stretch of code:

https://github.com/soot-oss/SootUp/blob/v1.1.0/sootup.java.bytecode/src/main/java/sootup/java/bytecode/frontend/AsmMethodSource.java#L1383

The variable nrArgs is set to the size - 1 to account for arrays starting at 0, however in line 1391 (https://github.com/soot-oss/SootUp/blob/v1.1.0/sootup.java.bytecode/src/main/java/sootup/java/bytecode/frontend/AsmMethodSource.java#LL1391C1-L1392C1), we preemptively decrease the value of nrArgs by 1 again before entering the while statement, meaning we are never popping the full extent of the operand stack.

Finally, I think the check if the expression is a static invocation here is backwards (https://github.com/soot-oss/SootUp/blob/v1.1.0/sootup.java.bytecode/src/main/java/sootup/java/bytecode/frontend/AsmMethodSource.java#L1394).

If the expression is static, we’d like to pop the stack once more, not the other way around.

Apologies for the convoluted message in advance! Resolving the 2 issues I mentioned above helped me get rid of the error messages I was getting but I’d much rather verify if this is correct.

Thanks!

Sonia

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions