我正在尝试使用Findbugs编写一个错误检测器来查找方法调用"System.out.println"的实例.
据我所知,字节码中的"System.out.println"被编译为对GETSTATIC的调用,后者将"System.out"推送到堆栈上.对INVOKEVIRTUAL的调用会从堆栈中弹出"System.out"并调用该方法.
我准备了一些代码(如下所示),它找到了正确的GETSTATIC和INVOKEVIRTUAL调用,但是无法将两者连接在一起.我怀疑我可能需要以某种方式使用OpcodeStack,但我很难理解如何使用它.任何帮助,将不胜感激.
@Override
public void sawOpcode(int seen) {
// if opcode is getstatic
if (seen == GETSTATIC) {
String clsName = getClassConstantOperand();
if ("java/lang/System".equals(clsName)) {
String fldName = getNameConstantOperand();
if ("out".equals(fldName)) {
System.out.println("SYSTEM.OUT here");
}
}
}
// if opcode is invokevirtual
if (seen == INVOKEVIRTUAL) {
String cls = getDottedClassConstantOperand();
if ("java.io.PrintStream".equals(cls)) {
String methodName = getNameConstantOperand();
if ("println".equals(methodName)) {
bugReporter.reportBug(new BugInstance("SYSTEM_OUT_PRINTLN",
NORMAL_PRIORITY).addClassAndMethod(this)
.addSourceLine(this));
}
}
}
}
Run Code Online (Sandbox Code Playgroud)