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.