/** * process the sample by checking it against each existing invariant and issuing an error if any * invariant is falsified or weakened. */ public void process_sample(PptMap all_ppts, PptTopLevel ppt, ValueTuple vt, Integer nonce) { this.all_ppts = all_ppts; debug.fine("processing sample from: " + ppt.name); // Add orig and derived variables FileIO.add_orig_variables(ppt, vt.vals, vt.mods, nonce); FileIO.add_derived_variables(ppt, vt.vals, vt.mods); // Intern the sample vt = new ValueTuple(vt.vals, vt.mods); // If this is an enter point, just remember it for later if (ppt.ppt_name.isEnterPoint()) { Assert.assertTrue(nonce != null); if (dir_file != null) { // Yoav: I had to do a hack to handle the case that several dtrace files are concatenated // together, // and Sung's dtrace files have unterminated calls, and when concatenating two files you // can have the same nonce. // So I have to remove the nonce found from the call_map call_map.remove(nonce); } else Assert.assertTrue(call_map.get(nonce) == null); call_map.put(nonce, new EnterCall(ppt, vt)); debug.fine("Skipping enter sample"); return; } // If this is an exit point, process the saved enter point if (ppt.ppt_name.isExitPoint()) { Assert.assertTrue(nonce != null); EnterCall ec = call_map.get(nonce); if (ec != null) { call_map.remove(nonce); debug.fine("Processing enter sample from " + ec.ppt.name); add(ec.ppt, ec.vt); } else { // didn't find the enter if (!quiet) System.out.printf("couldn't find enter for nonce %d at ppt %s\n", nonce, ppt.name()); return; } } add(ppt, vt); }
// Store the invariant for later printing. Ignore duplicate // invariants at the same program point. private static boolean store_invariant( String predicate, String index, HashedConsequent consequent, String pptname) { if (!pptname_to_conditions.containsKey(pptname)) { pptname_to_conditions.put(pptname, new HashMap<String, Map<String, HashedConsequent>>()); } Map<String, Map<String, HashedConsequent>> cluster_to_conditions = pptname_to_conditions.get(pptname); if (!cluster_to_conditions.containsKey(predicate)) { cluster_to_conditions.put(predicate, new HashMap<String, HashedConsequent>()); } Map<String, HashedConsequent> conditions = cluster_to_conditions.get(predicate); if (conditions.containsKey(index)) { HashedConsequent old = conditions.get(index); if (old.fakeFor != null && consequent.fakeFor == null) { // We already saw (say) "x != y", but we're "x == y", so replace it. conditions.remove(index); conditions.remove(old.fakeFor); conditions.put(index, consequent); return true; } return false; } else { conditions.put(index, consequent); return true; } }
public static void extract_consequent(PptMap ppts) { // Retrieve Ppt objects in sorted order. // Use a custom comparator for a specific ordering Comparator<PptTopLevel> comparator = new Ppt.NameComparator(); TreeSet<PptTopLevel> ppts_sorted = new TreeSet<PptTopLevel>(comparator); ppts_sorted.addAll(ppts.asCollection()); for (PptTopLevel ppt : ppts_sorted) { extract_consequent_maybe(ppt, ppts); } PrintWriter pw = new PrintWriter(System.out, true); // All conditions at a program point. A TreeSet to enable // deterministic output. TreeSet<String> allConds = new TreeSet<String>(); for (String pptname : pptname_to_conditions.keySet()) { Map<String, Map<String, HashedConsequent>> cluster_to_conditions = pptname_to_conditions.get(pptname); for (Map.Entry</*@KeyFor("cluster_to_conditions")*/ String, Map<String, HashedConsequent>> entry : cluster_to_conditions.entrySet()) { String predicate = entry.getKey(); Map<String, HashedConsequent> conditions = entry.getValue(); StringBuffer conjunctionJava = new StringBuffer(); StringBuffer conjunctionDaikon = new StringBuffer(); StringBuffer conjunctionESC = new StringBuffer(); StringBuffer conjunctionSimplify = new StringBuffer("(AND "); int count = 0; for (Map.Entry</*@KeyFor("conditions")*/ String, HashedConsequent> entry2 : conditions.entrySet()) { count++; String condIndex = entry2.getKey(); HashedConsequent cond = entry2.getValue(); if (cond.fakeFor != null) { count--; continue; } String javaStr = cond.inv.format_using(OutputFormat.JAVA); String daikonStr = cond.inv.format_using(OutputFormat.DAIKON); String escStr = cond.inv.format_using(OutputFormat.ESCJAVA); String simplifyStr = cond.inv.format_using(OutputFormat.SIMPLIFY); allConds.add(combineDummy(condIndex, "<dummy> " + daikonStr, escStr, simplifyStr)); // allConds.add(condIndex); if (count > 0) { conjunctionJava.append(" && "); conjunctionDaikon.append(" and "); conjunctionESC.append(" && "); conjunctionSimplify.append(" "); } conjunctionJava.append(javaStr); conjunctionDaikon.append(daikonStr); conjunctionESC.append(escStr); conjunctionSimplify.append(simplifyStr); } conjunctionSimplify.append(")"); String conj = conjunctionJava.toString(); // Avoid inserting self-contradictory conditions such as "x == 1 && // x == 2", or conjunctions of only a single condition. if (count < 2 || contradict_inv_pattern.matcher(conj).find() || useless_inv_pattern_1.matcher(conj).find() || useless_inv_pattern_2.matcher(conj).find()) { // System.out.println("Suppressing: " + conj); } else { allConds.add( combineDummy( conjunctionJava.toString(), conjunctionDaikon.toString(), conjunctionESC.toString(), conjunctionSimplify.toString())); } } if (allConds.size() > 0) { pw.println(); pw.println("PPT_NAME " + pptname); for (String s : allConds) { pw.println(s); } } allConds.clear(); } pw.flush(); }