gmu-swe/phosphor

NPE instrumenting Oracle JDK 1.8.0_121 with control flow tracking

Closed this issue · 1 comments

Output as follows

Generating Phosphor-instrumented JVM ...\GitHub\phosphor\integration-tests\target\jvm-inst-control with options: {controlTrack=true, q=true, enum=true, acmpeq=true}
Data flow tracking: enabled
Control flow tracking: enabled
Branch not taken: enabled
Starting analysis
Analysis Completed: Beginning Instrumentation Phase
Exception occurred while instrumenting org/apache/derby/iapi/types/XML:
java.lang.NullPointerException
	at edu.columbia.cs.psl.phosphor.instrumenter.analyzer.NeverNullArgAnalyzerAdapter.push(NeverNullArgAnalyzerAdapter.java:585)
	at edu.columbia.cs.psl.phosphor.instrumenter.analyzer.NeverNullArgAnalyzerAdapter.execute(NeverNullArgAnalyzerAdapter.java:959)
	at edu.columbia.cs.psl.phosphor.instrumenter.analyzer.NeverNullArgAnalyzerAdapter.visitInsn(NeverNullArgAnalyzerAdapter.java:312)
	at edu.columbia.cs.psl.phosphor.org.objectweb.asm.MethodVisitor.visitInsn(MethodVisitor.java:313)
	at edu.columbia.cs.psl.phosphor.org.objectweb.asm.MethodVisitor.visitInsn(MethodVisitor.java:313)
	at edu.columbia.cs.psl.phosphor.org.objectweb.asm.MethodVisitor.visitInsn(MethodVisitor.java:313)
	at edu.columbia.cs.psl.phosphor.control.ControlStackRestoringMV.visitInsn(ControlStackRestoringMV.java:93)
	at edu.columbia.cs.psl.phosphor.org.objectweb.asm.MethodVisitor.visitInsn(MethodVisitor.java:313)
	at edu.columbia.cs.psl.phosphor.instrumenter.ReflectionHidingMV.visitInsn(ReflectionHidingMV.java:236)
	at edu.columbia.cs.psl.phosphor.org.objectweb.asm.MethodVisitor.visitInsn(MethodVisitor.java:313)
	at edu.columbia.cs.psl.phosphor.org.objectweb.asm.MethodVisitor.visitInsn(MethodVisitor.java:313)
	at edu.columbia.cs.psl.phosphor.instrumenter.TaintPassingMV.visitReturn(TaintPassingMV.java:1292)
	at edu.columbia.cs.psl.phosphor.instrumenter.TaintPassingMV.visitInsn(TaintPassingMV.java:1121)
	at edu.columbia.cs.psl.phosphor.org.objectweb.asm.MethodVisitor.visitInsn(MethodVisitor.java:313)
	at edu.columbia.cs.psl.phosphor.org.objectweb.asm.MethodVisitor.visitInsn(MethodVisitor.java:313)
	at edu.columbia.cs.psl.phosphor.instrumenter.LocalVariableManager.visitInsn(LocalVariableManager.java:86)
	at edu.columbia.cs.psl.phosphor.org.objectweb.asm.MethodVisitor.visitInsn(MethodVisitor.java:313)
	at edu.columbia.cs.psl.phosphor.org.objectweb.asm.tree.InsnNode.accept(InsnNode.java:65)
	at edu.columbia.cs.psl.phosphor.org.objectweb.asm.tree.InsnList.accept(InsnList.java:144)
	at edu.columbia.cs.psl.phosphor.org.objectweb.asm.tree.MethodNode.accept(MethodNode.java:784)
	at edu.columbia.cs.psl.phosphor.instrumenter.TaintLoadCoercer$UninstTaintLoadCoercerMN.visitEnd(TaintLoadCoercer.java:295)
	at edu.columbia.cs.psl.phosphor.org.objectweb.asm.MethodVisitor.visitEnd(MethodVisitor.java:772)
	at edu.columbia.cs.psl.phosphor.org.objectweb.asm.tree.MethodNode.accept(MethodNode.java:805)
	at edu.columbia.cs.psl.phosphor.instrumenter.PrimitiveArrayAnalyzer$PrimitiveArrayAnalyzerMN.visitEnd(PrimitiveArrayAnalyzer.java:422)
	at edu.columbia.cs.psl.phosphor.org.objectweb.asm.MethodVisitor.visitEnd(MethodVisitor.java:772)
	at edu.columbia.cs.psl.phosphor.instrumenter.PrimitiveArrayAnalyzer.visitEnd(PrimitiveArrayAnalyzer.java:245)
	at edu.columbia.cs.psl.phosphor.org.objectweb.asm.MethodVisitor.visitEnd(MethodVisitor.java:772)
	at edu.columbia.cs.psl.phosphor.org.objectweb.asm.tree.MethodNode.accept(MethodNode.java:805)
	at edu.columbia.cs.psl.phosphor.instrumenter.TaintTrackingClassVisitor$4.visitEnd(TaintTrackingClassVisitor.java:511)
	at edu.columbia.cs.psl.phosphor.org.objectweb.asm.ClassReader.readMethod(ClassReader.java:1287)
	at edu.columbia.cs.psl.phosphor.org.objectweb.asm.ClassReader.accept(ClassReader.java:688)
	at edu.columbia.cs.psl.phosphor.org.objectweb.asm.ClassReader.accept(ClassReader.java:400)
	at edu.columbia.cs.psl.phosphor.PreMain$PCLoggingTransformer.instrumentWithRetry(PreMain.java:173)
	at edu.columbia.cs.psl.phosphor.PreMain$PCLoggingTransformer._transform(PreMain.java:361)
	at edu.columbia.cs.psl.phosphor.PreMain$PCLoggingTransformer.transform(PreMain.java:110)
	at edu.columbia.cs.psl.phosphor.Instrumenter.instrumentClass(Instrumenter.java:169)
	at edu.columbia.cs.psl.phosphor.Instrumenter$4.call(Instrumenter.java:467)
	at edu.columbia.cs.psl.phosphor.Instrumenter$4.call(Instrumenter.java:462)
	at java.util.concurrent.FutureTask.run(FutureTask.java:266)
	at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
	at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
	at java.lang.Thread.run(Thread.java:745)

The specific method involved is public BooleanDataValue XMLExists(SqlXmlUtil sqlxUtil)in org/apache/derby/iapi/types/XML.

The NPE occurs in void push(Object, Object, Object) (as shown in the stack trace) when the first parameter is null. I backtracked the source of thisnull value and it turns out that a null value is added to the the List<Object> stack field in void visitMethodInsn(int, String, String, String, boolean) line 408. Here u = uninitializedTypes.get(t) results in the null value because that map does not contain t.
At some point, the Label values in stack end up being different objects from the Label keys in uninitializedTypes which leads to null return from get(t). I attempted to trace this difference further back but it became a little confusing for me because I'm not very familiar with ASM. I believe NeverNullArgAnalyzerAdapter.visitFrame(...) may be involved because I did witness that method storing the offending Local objects into the stack field from its stack parameter but I'm not sure where they came from before that and why they aren't the same Local objects that are in the uninitializedTypes map.

Thanks for reporting this, and for trying to debug it too. This happens when a new label gets inserted by phosphor before a NEW instruction. The workaround for that apparently didn't work in cases where there was already more than one NEW instruction there - I just patched it to work on such cases.