public void analyzeMethod() throws CheckedAnalysisException {
      if (DEBUG_METHOD != null && !methodDescriptor.getName().equals(DEBUG_METHOD)) {
        return;
      }

      if (DEBUG) {
        System.out.println("*** Analyzing method " + methodDescriptor);
      }

      xmethod = XFactory.createXMethod(methodDescriptor);
      analysisCache = Global.getAnalysisCache();

      //
      // Execute the obligation dataflow analysis
      //
      try {
        dataflow = analysisCache.getMethodAnalysis(ObligationDataflow.class, methodDescriptor);
      } catch (ObligationAcquiredOrReleasedInLoopException e) {
        // It is not possible to analyze this method.
        if (DEBUG) {
          System.out.println(
              "FindUnsatisifedObligation: " + methodDescriptor + ": " + e.getMessage());
        }
        return;
      }

      //
      // Additional analyses
      // needed these to apply the false-positive
      // suppression heuristics.
      //
      cpg =
          analysisCache.getClassAnalysis(
              ConstantPoolGen.class, methodDescriptor.getClassDescriptor());
      typeDataflow = analysisCache.getMethodAnalysis(TypeDataflow.class, methodDescriptor);
      subtypes2 = Global.getAnalysisCache().getDatabase(Subtypes2.class);

      //
      // Main loop: looking at the StateSet at the exit block of the CFG,
      // see if there are any states with nonempty obligation sets.
      //
      Map<Obligation, State> leakedObligationMap = new HashMap<Obligation, State>();
      StateSet factAtExit = dataflow.getResultFact(cfg.getExit());
      for (Iterator<State> i = factAtExit.stateIterator(); i.hasNext(); ) {
        State state = i.next();
        checkStateForLeakedObligations(state, leakedObligationMap);
      }

      //
      // Report a separate BugInstance for each Obligation,State pair.
      // (Two different obligations may be leaked in the same state.)
      //
      for (Map.Entry<Obligation, State> entry : leakedObligationMap.entrySet()) {
        Obligation obligation = entry.getKey();
        State state = entry.getValue();
        reportWarning(obligation, state, factAtExit);
      }
      // TODO: closing of nonexistent resources

    }
  /* (non-Javadoc)
   * @see edu.umd.cs.findbugs.classfile.IAnalysisEngine#analyze(edu.umd.cs.findbugs.classfile.IAnalysisCache, java.lang.Object)
   */
  public Method analyze(IAnalysisCache analysisCache, MethodDescriptor descriptor)
      throws CheckedAnalysisException {
    JavaClass jclass =
        analysisCache.getClassAnalysis(JavaClass.class, descriptor.getClassDescriptor());
    Method[] methodList = jclass.getMethods();

    Method result = null;

    // As a side-effect, cache all of the Methods for this JavaClass
    for (Method method : methodList) {
      MethodDescriptor methodDescriptor =
          DescriptorFactory.instance()
              .getMethodDescriptor(
                  descriptor.getSlashedClassName(),
                  method.getName(),
                  method.getSignature(),
                  method.isStatic());

      // Put in cache eagerly
      analysisCache.eagerlyPutMethodAnalysis(Method.class, methodDescriptor, method);

      if (methodDescriptor.equals(descriptor)) {
        result = method;
      }
    }

    return result;
  }
    private void reportWarning(Obligation obligation, State state, StateSet factAtExit) {
      String className = obligation.getClassName();

      if (methodDescriptor.isStatic()
          && methodDescriptor.getName().equals("main")
          && methodDescriptor.getSignature().equals("([Ljava/lang/String;)V")
          && (className.contains("InputStream")
              || className.contains("Reader")
              || factAtExit.isOnExceptionPath())) {
        // Don't report unclosed input streams and readers in main()
        // methods
        return;
      }
      String bugPattern =
          factAtExit.isOnExceptionPath()
              ? "OBL_UNSATISFIED_OBLIGATION_EXCEPTION_EDGE"
              : "OBL_UNSATISFIED_OBLIGATION";
      BugInstance bugInstance =
          new BugInstance(FindUnsatisfiedObligation.this, bugPattern, NORMAL_PRIORITY)
              .addClassAndMethod(methodDescriptor)
              .addClass(className)
              .describe("CLASS_REFTYPE");

      // Report how many instances of the obligation are remaining
      bugInstance
          .addInt(state.getObligationSet().getCount(obligation.getId()))
          .describe(IntAnnotation.INT_OBLIGATIONS_REMAINING);

      // Add source line information
      annotateWarningWithSourceLineInformation(state, obligation, bugInstance);

      if (REPORT_OBLIGATION_SET) {
        bugInstance
            .addString(state.getObligationSet().toString())
            .describe(StringAnnotation.REMAINING_OBLIGATIONS_ROLE);
      }

      bugReporter.reportBug(bugInstance);
    }
Ejemplo n.º 4
0
  /*
   * (non-Javadoc)
   *
   * @see
   * edu.umd.cs.findbugs.classfile.IAnalysisEngine#analyze(edu.umd.cs.findbugs
   * .classfile.IAnalysisCache, java.lang.Object)
   */
  public LoadedFieldSet analyze(IAnalysisCache analysisCache, MethodDescriptor descriptor)
      throws CheckedAnalysisException {
    MethodGen methodGen = getMethodGen(analysisCache, descriptor);
    if (methodGen == null) return null;
    InstructionList il = methodGen.getInstructionList();

    LoadedFieldSet loadedFieldSet = new LoadedFieldSet(methodGen);
    ConstantPoolGen cpg = getConstantPoolGen(analysisCache, descriptor.getClassDescriptor());

    for (InstructionHandle handle = il.getStart(); handle != null; handle = handle.getNext()) {
      Instruction ins = handle.getInstruction();
      short opcode = ins.getOpcode();
      try {
        if (opcode == Constants.INVOKESTATIC) {
          INVOKESTATIC inv = (INVOKESTATIC) ins;
          if (Hierarchy.isInnerClassAccess(inv, cpg)) {
            InnerClassAccess access = Hierarchy.getInnerClassAccess(inv, cpg);
            /*
             * if (access == null) {
             * System.out.println("Missing inner class access in " +
             * SignatureConverter.convertMethodSignature(methodGen)
             * + " at " + inv); }
             */
            if (access != null) {
              if (access.isLoad()) loadedFieldSet.addLoad(handle, access.getField());
              else loadedFieldSet.addStore(handle, access.getField());
            }
          }
        } else if (fieldInstructionOpcodeSet.get(opcode)) {
          boolean isLoad = (opcode == Constants.GETFIELD || opcode == Constants.GETSTATIC);
          XField field = Hierarchy.findXField((FieldInstruction) ins, cpg);
          if (field != null) {
            if (isLoad) loadedFieldSet.addLoad(handle, field);
            else loadedFieldSet.addStore(handle, field);
          }
        }
      } catch (ClassNotFoundException e) {
        AnalysisContext.currentAnalysisContext().getLookupFailureCallback().reportMissingClass(e);
      }
    }

    return loadedFieldSet;
  }