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++; } } } }
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); } }
private static void checkInvariants() throws IOException { // Read the invariant file PptMap ppts = FileIO.read_serialized_pptmap(inv_file, true); // Yoav: make sure we have unique invariants InvariantFilters fi = InvariantFilters.defaultFilters(); // Set<String> allInvariantsStr = new HashSet<String>(); Set<Invariant> allInvariants = new HashSet<Invariant>(); for (PptTopLevel ppt : ppts.all_ppts()) for (Iterator<PptSlice> i = ppt.views_iterator(); i.hasNext(); ) { PptSlice slice = i.next(); for (Invariant inv : slice.invs) { if (doConf && inv.getConfidence() < Invariant.dkconfig_confidence_limit) { // System.out.printf ("inv ignored (conf): %s:%s\n", inv.ppt.name(), // inv.format()); continue; } if (doFilter && fi.shouldKeep(inv) == null) { // System.out.printf ("inv ignored (filter): %s:%s\n", // inv.ppt.name(), inv.format()); continue; } activeInvariants.add(inv); // String n = invariant2str(ppt, inv); // if (!allInvariants.contains(inv) && allInvariantsStr.contains(n)) throw new // Daikon.TerminationMessage("Two invariants have the same ppt.name+inv.rep:"+n); allInvariants.add(inv); // allInvariantsStr.add(n); } } // Read and process the data trace files FileIO.Processor processor = new InvariantCheckProcessor(); Daikon.FileIOProgress progress = new Daikon.FileIOProgress(); progress.start(); progress.clear(); FileIO.read_data_trace_files(dtrace_files, ppts, processor, false); progress.shouldStop = true; System.out.println(); System.out.printf( "%s: %,d errors found in %,d samples (%s)\n", inv_file, error_cnt, sample_cnt, toPercentage(error_cnt, sample_cnt)); int failedCount = failedInvariants.size(); int testedCount = testedInvariants.size(); String percent = toPercentage(failedCount, testedCount); System.out.println( inv_file + ": " + failedCount + " false positives, out of " + testedCount + ", which is " + percent + "."); if (false) { for (Invariant inv : failedInvariants) { System.out.printf("+%s:%s\n", inv.ppt.name(), inv.format()); } } }