private void add(PptTopLevel ppt, ValueTuple vt, int nonce) {

      // if this is a numbered exit, apply to the combined exit as well
      if (ppt.ppt_name.isNumberedExitPoint()) {

        // Daikon.create_combined_exits(all_ppts);
        PptTopLevel parent = all_ppts.get(ppt.ppt_name.makeExit());
        if (parent != null) {
          parent.get_missingOutOfBounds(ppt, vt);
          add(parent, vt, nonce);

        } else {
          // make parent and apply

          // this is a hack. it should probably filter out orig and derived
          // vars instead of taking the first n.
          int len = ppt.num_tracevars + ppt.num_static_constant_vars;
          VarInfo[] exit_vars = new VarInfo[len];
          for (int j = 0; j < len; j++) {
            exit_vars[j] = new VarInfo(ppt.var_infos[j]);
            exit_vars[j].varinfo_index = ppt.var_infos[j].varinfo_index;
            exit_vars[j].value_index = ppt.var_infos[j].value_index;
            exit_vars[j].equalitySet = null;
          }

          parent = new PptTopLevel(ppt.ppt_name.makeExit().getName(), exit_vars);
          Daikon.init_ppt(parent, all_ppts);
          all_ppts.add(parent);
          parent.get_missingOutOfBounds(ppt, vt);
          add(parent, vt, nonce);
        }
      }

      // If the point has no variables, skip it
      if (ppt.var_infos.length == 0) {
        // The sample should be skipped but Daikon does not do this so
        // DaikonSimple will not do this to be consistent.
        // The better idea is for Daikon to assert that these valuetuples are
        // empty and then skip the sample.
        assert vt.size() == 0;
        return;
      }

      // Instantiate slices and invariants if this is the first sample
      if (ppt.num_samples() == 0) {
        instantiate_views_and_invariants(ppt);
      }

      // manually inc the sample number because DaikonSimple does not
      // use any of PptTopLevel's add methods which increase the sample
      // number
      ppt.incSampleNumber();

      // Loop through each slice
      for (Iterator<PptSlice> i = ppt.views_iterator(); i.hasNext(); ) {
        PptSlice slice = i.next();
        Iterator<Invariant> k = slice.invs.iterator();
        boolean missing = false;

        for (VarInfo v : slice.var_infos) {
          // If any var has encountered out of array bounds values,
          // stop all invariants in this slice. The presumption here is that
          // an index out of bounds implies that the derived variable (eg a[i])
          // doesn't really make any sense (essentially that i is not a valid
          // index for a). Invariants on the derived variable are thus not
          // relevant.
          // If any variables are out of bounds, remove the invariants
          if (v.missingOutOfBounds()) {
            while (k.hasNext()) {
              Invariant inv = k.next();
              k.remove();
            }
            missing = true;
            break;
          }

          // If any variables are missing, skip this slice
          if (v.isMissing(vt)) {
            missing = true;
            break;
          }
        }

        // keep a list of the falsified invariants
        if (!missing) {
          while (k.hasNext()) {

            Invariant inv = k.next();
            Invariant pre_inv = inv.clone();
            for (VarInfo vi : inv.ppt.var_infos) {
              assert vt.getValue(vi) != null : vi;
            }
            if (inv.ppt instanceof PptSlice2) assert inv.ppt.var_infos.length == 2;
            InvariantStatus status = inv.add_sample(vt, 1);
            if (status == InvariantStatus.FALSIFIED) {
              k.remove();
            }
          }
        }

        // update num_samples and num_values of a slice manually
        // because DaikonSimple does not call any of PptTopLevel's
        // add methods
        for (int j = 0; j < vt.vals.length; j++) {
          if (!vt.isMissing(j)) {
            ValueSet vs = ppt.value_sets[j];
            vs.add(vt.vals[j]);
          }
        }
        ppt.mbtracker.add(vt, 1);
      }
    }
Esempio n. 2
0
    private void add(PptTopLevel ppt, ValueTuple vt) {
      // Add the sample to any splitters
      if (ppt.has_splitters()) {
        for (PptSplitter ppt_split : ppt.splitters) {
          PptConditional ppt_cond = ppt_split.choose_conditional(vt);
          if (ppt_cond != null) add(ppt_cond, vt);
          else debug.fine(": sample doesn't pick conditional");
        }
      }

      // if this is a numbered exit, apply to the combined exit as well
      if (!(ppt instanceof PptConditional) && ppt.ppt_name.isNumberedExitPoint()) {
        PptTopLevel parent = all_ppts.get(ppt.ppt_name.makeExit());
        if (parent != null) {
          parent.get_missingOutOfBounds(ppt, vt);
          add(parent, vt);
        }
      }

      // If the point has no variables, skip it
      if (ppt.var_infos.length == 0) return;

      // We should have received sample here before, or there is nothing
      // to check.
      // Yoav added: It can be that the different dtrace and inv files have different program points
      if (false && ppt.num_samples() <= 0)
        Assert.assertTrue(
            ppt.num_samples() > 0,
            "ppt " + ppt.name + " has 0 samples and " + ppt.var_infos.length + " variables");

      // Loop through each slice
      slice_loop:
      for (Iterator<PptSlice> i = ppt.views_iterator(); i.hasNext(); ) {
        PptSlice slice = i.next();
        if (debug_detail.isLoggable(Level.FINE))
          debug_detail.fine(
              ": processing slice " + slice + "vars: " + Debug.toString(slice.var_infos, vt));

        // If any variables are missing, skip this slice
        for (int j = 0; j < slice.var_infos.length; j++) {
          VarInfo v = slice.var_infos[j];
          int mod = vt.getModified(v);
          if (v.isMissing(vt)) {
            if (debug_detail.isLoggable(Level.FINE))
              debug_detail.fine(": : Skipping slice, " + v.name() + " missing");
            continue slice_loop;
          }
          if (v.missingOutOfBounds()) {
            if (debug_detail.isLoggable(Level.FINE))
              debug.fine(": : Skipping slice, " + v.name() + " out of bounds");
            continue slice_loop;
          }
        }

        // Loop through each invariant
        for (Invariant inv : slice.invs) {
          if (debug_detail.isLoggable(Level.FINE))
            debug_detail.fine(": : Processing invariant: " + inv);
          if (!inv.isActive()) {
            if (debug_detail.isLoggable(Level.FINE))
              debug_detail.fine(": : skipped non-active " + inv);
            continue;
          }

          // Yoav added
          if (!activeInvariants.contains(inv)) {
            // System.out.printf ("skipping invariant %s:%s\n", inv.ppt.name(),
            //                   inv.format());
            continue;
          }

          // String invRep = invariant2str(ppt, inv);
          testedInvariants.add(inv);

          InvariantStatus status = inv.add_sample(vt, 1);
          sample_cnt++;
          if (status != InvariantStatus.NO_CHANGE) {
            LineNumberReader lnr = FileIO.data_trace_state.reader;
            String line = (lnr == null) ? "?" : String.valueOf(lnr.getLineNumber());
            if (!quiet) {
              output_stream.println(
                  "At ppt "
                      + ppt.name
                      + ", Invariant '"
                      + inv.format()
                      + "' invalidated by sample "
                      + Debug.toString(slice.var_infos, vt)
                      + "at line "
                      + line
                      + " in file "
                      + FileIO.data_trace_state.filename);
            }
            failedInvariants.add(inv);
            activeInvariants.remove(inv);
            error_cnt++;
          }
        }
      }
    }