📄 dumbmethods.java
字号:
&& getClassConstantOperand().equals("java/lang/String") && getNameConstantOperand().equals("<init>") && getSigConstantOperand().equals("()V")) if (alreadyReported.add(getRefConstantOperand())) bugReporter.reportBug(new BugInstance(this, "DM_STRING_VOID_CTOR", NORMAL_PRIORITY) .addClassAndMethod(this) .addSourceLine(this)); if (!isPublicStaticVoidMain && seen == INVOKESTATIC && getClassConstantOperand().equals("java/lang/System") && getNameConstantOperand().equals("exit") && !getMethodName().equals("processWindowEvent") && !getMethodName().startsWith("windowClos") && getMethodName().indexOf("exit") == -1 && getMethodName().indexOf("Exit") == -1 && getMethodName().indexOf("crash") == -1 && getMethodName().indexOf("Crash") == -1 && getMethodName().indexOf("die") == -1 && getMethodName().indexOf("Die") == -1 && getMethodName().indexOf("main") == -1) accumulator.accumulateBug(new BugInstance(this, "DM_EXIT", getMethod().isStatic() ? LOW_PRIORITY : NORMAL_PRIORITY) .addClassAndMethod(this), SourceLineAnnotation.fromVisitedInstruction(this)); if (((seen == INVOKESTATIC && getClassConstantOperand().equals("java/lang/System")) || (seen == INVOKEVIRTUAL && getClassConstantOperand().equals("java/lang/Runtime"))) && getNameConstantOperand().equals("gc") && getSigConstantOperand().equals("()V") && !getDottedClassName().startsWith("java.lang") && !getMethodName().startsWith("gc") && !getMethodName().endsWith("gc")) if (alreadyReported.add(getRefConstantOperand())) { // System.out.println("Saw call to GC"); if (isPublicStaticVoidMain) { // System.out.println("Skipping GC complaint in main method"); return; } if (isTestMethod(getMethod())) return; // Just save this report in a field; it will be flushed // IFF there were no calls to System.currentTimeMillis(); // in the method. gcInvocationBugReport = new BugInstance(this, "DM_GC", HIGH_PRIORITY) .addClassAndMethod(this) .addSourceLine(this); gcInvocationPC = getPC(); //System.out.println("GC invocation at pc " + PC); } if (!isSynthetic && (seen == INVOKESPECIAL) && getClassConstantOperand().equals("java/lang/Boolean") && getNameConstantOperand().equals("<init>") && !getClassName().equals("java/lang/Boolean") && alreadyReported.add(getRefConstantOperand())) { int majorVersion = getThisClass().getMajor(); if (majorVersion >= MAJOR_1_4) bugReporter.reportBug(new BugInstance(this, "DM_BOOLEAN_CTOR", NORMAL_PRIORITY) .addClassAndMethod(this) .addSourceLine(this)); } if ((seen == INVOKESTATIC) && getClassConstantOperand().equals("java/lang/System") && (getNameConstantOperand().equals("currentTimeMillis") || getNameConstantOperand().equals("nanoTime"))) sawCurrentTimeMillis = true; if ((seen == INVOKEVIRTUAL) && getClassConstantOperand().equals("java/lang/String") && getNameConstantOperand().equals("toString") && getSigConstantOperand().equals("()Ljava/lang/String;")) if (alreadyReported.add(getRefConstantOperand())) bugReporter.reportBug(new BugInstance(this, "DM_STRING_TOSTRING", NORMAL_PRIORITY) .addClassAndMethod(this) .addSourceLine(this)); if ((seen == INVOKEVIRTUAL) && getClassConstantOperand().equals("java/lang/String") && (getNameConstantOperand().equals("toUpperCase") || getNameConstantOperand().equals("toLowerCase")) && getSigConstantOperand().equals("()Ljava/lang/String;")) if (alreadyReported.add(getRefConstantOperand())) bugReporter.reportBug(new BugInstance(this, "DM_CONVERT_CASE", LOW_PRIORITY) .addClassAndMethod(this) .addSourceLine(this)); if ((seen == INVOKESPECIAL) && getNameConstantOperand().equals("<init>")) { String cls = getClassConstantOperand(); String sig = getSigConstantOperand(); if ((cls.equals("java/lang/Integer") && sig.equals("(I)V")) || (cls.equals("java/lang/Float") && sig.equals("(F)V")) || (cls.equals("java/lang/Double") && sig.equals("(D)V")) || (cls.equals("java/lang/Long") && sig.equals("(J)V")) || (cls.equals("java/lang/Byte") && sig.equals("(B)V")) || (cls.equals("java/lang/Character") && sig.equals("(C)V")) || (cls.equals("java/lang/Short") && sig.equals("(S)V")) || (cls.equals("java/lang/Boolean") && sig.equals("(Z)V"))) { primitiveObjCtorSeen = cls; } else { primitiveObjCtorSeen = null; } } else if ((primitiveObjCtorSeen != null) && (seen == INVOKEVIRTUAL) && getNameConstantOperand().equals("toString") && getClassConstantOperand().equals(primitiveObjCtorSeen) && getSigConstantOperand().equals("()Ljava/lang/String;")) { bugReporter.reportBug(new BugInstance(this, "DM_BOXED_PRIMITIVE_TOSTRING", LOW_PRIORITY) .addClassAndMethod(this) .addSourceLine(this)); primitiveObjCtorSeen = null; } else primitiveObjCtorSeen = null; if ((seen == INVOKESPECIAL) && getNameConstantOperand().equals("<init>")) { ctorSeen = true; } else if (ctorSeen && (seen == INVOKEVIRTUAL) && getClassConstantOperand().equals("java/lang/Object") && getNameConstantOperand().equals("getClass") && getSigConstantOperand().equals("()Ljava/lang/Class;")) { accumulator.accumulateBug(new BugInstance(this, "DM_NEW_FOR_GETCLASS", LOW_PRIORITY) .addClassAndMethod(this), this); ctorSeen = false; } else { ctorSeen = false; } if (jdk15ChecksEnabled && (seen == INVOKEVIRTUAL) && isMonitorWait(getNameConstantOperand(), getSigConstantOperand())) { checkMonitorWait(); } if ((seen == INVOKESPECIAL) && getNameConstantOperand().equals("<init>") && getClassConstantOperand().equals("java/lang/Thread")) { String sig = getSigConstantOperand(); if (sig.equals("()V") || sig.equals("(Ljava/lang/String;)V") || sig.equals("(Ljava/lang/ThreadGroup;Ljava/lang/String;)V")) if (!getMethodName().equals("<init>") || (getPC() > 20)) { bugReporter.reportBug(new BugInstance(this, "DM_USELESS_THREAD", LOW_PRIORITY) .addClassAndMethod(this) .addSourceLine(this)); } } } finally { stack.sawOpcode(this,seen); prevOpcode = seen; } } /** * Return index of stack entry that must be nonnegative. * * Return -1 if no stack entry is required to be nonnegative. * @param seen * @return */ private int stackEntryThatMustBeNonnegative(int seen) { switch(seen) { case INVOKEINTERFACE: if (getClassConstantOperand().equals("java/util/List")) { return getStackEntryOfListCallThatMustBeNonnegative(); } break; case INVOKEVIRTUAL: if (getClassConstantOperand().equals("java/util/LinkedList") || getClassConstantOperand().equals("java/util/ArrayList")) { return getStackEntryOfListCallThatMustBeNonnegative(); } break; case IALOAD: case AALOAD: case SALOAD: case CALOAD: case BALOAD: case LALOAD: case DALOAD: case FALOAD: return 0; case IASTORE: case AASTORE: case SASTORE: case CASTORE: case BASTORE: case LASTORE: case DASTORE: case FASTORE: return 1; } return -1; } private int getStackEntryOfListCallThatMustBeNonnegative() { String name = getNameConstantOperand(); if ((name.equals("add") || name.equals("set")) && getSigConstantOperand().startsWith("(I")) return 1; if ((name.equals("get") || name.equals("remove")) && getSigConstantOperand().startsWith("(I)")) return 0; return -1; } private void checkMonitorWait() { try { TypeDataflow typeDataflow = getClassContext().getTypeDataflow(getMethod()); TypeDataflow.LocationAndFactPair pair = typeDataflow.getLocationAndFactForInstruction(getPC()); if (pair == null) return; Type receiver = pair.frame.getInstance( pair.location.getHandle().getInstruction(), getClassContext().getConstantPoolGen() ); if (!(receiver instanceof ReferenceType)) return; if (Hierarchy.isSubtype((ReferenceType) receiver, CONDITION_TYPE)) { bugReporter.reportBug(new BugInstance(this, "DM_MONITOR_WAIT_ON_CONDITION", HIGH_PRIORITY) .addClassAndMethod(this) .addSourceLine(this)); } } catch (ClassNotFoundException e) { bugReporter.reportMissingClass(e); } catch (DataflowAnalysisException e) { bugReporter.logError("Exception caught by DumbMethods", e); } catch (CFGBuilderException e) { bugReporter.logError("Exception caught by DumbMethods", e); } } private boolean isMonitorWait(String name, String sig) {// System.out.println("Check call " + name + "," + sig); return name.equals("wait") && (sig.equals("()V") || sig.equals("(J)V") || sig.equals("(JI)V")); } @Override public void visit(Code obj) { super.visit(obj); flush(); } /** * A heuristic - how long a catch block for OutOfMemoryError might be. */ private static final int OOM_CATCH_LEN = 20; /** * Flush out cached state at the end of a method. */ private void flush() { if (gcInvocationBugReport != null && !sawCurrentTimeMillis) { // Make sure the GC invocation is not in an exception handler // for OutOfMemoryError. boolean outOfMemoryHandler = false; for (CodeException handler : exceptionTable) { if (gcInvocationPC < handler.getHandlerPC() || gcInvocationPC > handler.getHandlerPC() + OOM_CATCH_LEN) continue; int catchTypeIndex = handler.getCatchType(); if (catchTypeIndex > 0) { ConstantPool cp = getThisClass().getConstantPool(); Constant constant = cp.getConstant(catchTypeIndex); if (constant instanceof ConstantClass) { String exClassName = (String) ((ConstantClass) constant).getConstantValue(cp); if (exClassName.equals("java/lang/OutOfMemoryError")) { outOfMemoryHandler = true; break; } } } } if (!outOfMemoryHandler) bugReporter.reportBug(gcInvocationBugReport); } sawCurrentTimeMillis = false; gcInvocationBugReport = null; alreadyReported.clear(); exceptionTable = null; }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -