/** * 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); }
/** * This does the work of main, but it never calls System.exit, so it is appropriate to be called * progrmmatically. Termination of the program with a message to the user is indicated by throwing * Daikon.TerminationMessage. * * <p>Difference from Daikon's mainHelper: turn off optimization flags (equality, dynamic * constants, NIS suppression). * * @see #main(String[]) * @see daikon.Daikon.TerminationMessage * @see daikon.Daikon#mainHelper(String[]) */ public static void mainHelper(final String[] args) throws IOException, FileNotFoundException { // set up logging information daikon.LogHelper.setupLogs(daikon.LogHelper.INFO); // No optimizations used in the simple incremental algorithm so // optimizations are turned off. Daikon.use_equality_optimization = false; Daikon.dkconfig_use_dynamic_constant_optimization = false; Daikon.suppress_implied_controlled_invariants = false; NIS.dkconfig_enabled = false; // The flag tells FileIO and Daikon to use DaikonSimple // specific methods (e.g. FileIO.read_declaration_file). // When FileIO reads and processes // samples, it must use the SimpleProcessor rather than the // default Processor. Daikon.using_DaikonSimple = true; // Read command line options Daikon.FileOptions files = Daikon.read_options(args, usage); // DaikonSimple does not supply nor use the spinfo_files and map_files Set<File> decls_files = files.decls; Set<String> dtrace_files = files.dtrace; if ((decls_files.size() == 0) && (dtrace_files.size() == 0)) { throw new Daikon.TerminationMessage("No .decls or .dtrace files specified"); } // Create the list of all invariant types Daikon.setup_proto_invs(); // Create the program points for enter and numbered exits and // initializes the points (adding orig and derived variables) all_ppts = FileIO.read_declaration_files(decls_files); // Create the combined exits (and add orig and derived vars) // Daikon.create_combined_exits(all_ppts); // Read and process the data trace files SimpleProcessor processor = new SimpleProcessor(); FileIO.read_data_trace_files(dtrace_files, all_ppts, processor, true); // System.exit(0); // Print out the invariants for each program point (sort first) for (Iterator<PptTopLevel> t = all_ppts.pptIterator(); t.hasNext(); ) { PptTopLevel ppt = t.next(); // We do not need to print out program points that have not seen // any samples. if (ppt.num_samples() == 0) { continue; } List<Invariant> invs = PrintInvariants.sort_invariant_list(ppt.invariants_vector()); List<Invariant> filtered_invs = Daikon.filter_invs(invs); // The dkconfig_quiet printing is used for creating diffs between // DaikonSimple // and Daikon's output. The second kind of printing is used for // debugging. Since the names of the program points are the same for both // Daikon and DaikonSimple, diffing the two output will result in // only differences in the invariants, but we can not see at which program // points these differing invariants appear. Using the second kind of // printing, // Daikon's output does not have the '+' in the program point name, so in // addition // to the invariants showing up in the diff, we will also see the program // point // names. if (Daikon.dkconfig_quiet) { System.out.println("===================================================="); System.out.println(ppt.name()); } else { System.out.println("===================================================+"); System.out.println(ppt.name() + " +"); } // Sometimes the program points actually differ in number of // samples seen due to differences in how Daikon and DaikonSimple // see the variable hierarchy. System.out.println(ppt.num_samples()); for (Invariant inv : filtered_invs) { System.out.println(inv.getClass()); System.out.println(inv); } } }
/** * Extract consequents from a implications at a single program point. It only searches for top * level Program points because Implications are produced only at those points. */ public static void extract_consequent_maybe(PptTopLevel ppt, PptMap all_ppts) { ppt.simplify_variable_names(); List<Invariant> invs = new ArrayList<Invariant>(); if (invs.size() > 0) { String pptname = cleanup_pptname(ppt.name()); for (Invariant maybe_as_inv : invs) { Implication maybe = (Implication) maybe_as_inv; // don't print redundant invariants. if (Daikon.suppress_redundant_invariants_with_simplify && maybe.ppt.parent.redundant_invs.contains(maybe)) { continue; } // don't print out invariants with min(), max(), or sum() variables boolean mms = false; VarInfo[] varbls = maybe.ppt.var_infos; for (int v = 0; !mms && v < varbls.length; v++) { mms |= varbls[v].isDerivedSequenceMinMaxSum(); } if (mms) { continue; } if (maybe.ppt.parent.ppt_name.isExitPoint()) { for (int i = 0; i < maybe.ppt.var_infos.length; i++) { VarInfo vi = maybe.ppt.var_infos[i]; if (vi.isDerivedParam()) { continue; } } } Invariant consequent = maybe.consequent(); Invariant predicate = maybe.predicate(); Invariant inv, cluster_inv; boolean cons_uses_cluster = false, pred_uses_cluster = false; // extract the consequent (predicate) if the predicate // (consequent) uses the variable "cluster". Ignore if they // both depend on "cluster" if (consequent.usesVarDerived("cluster")) cons_uses_cluster = true; if (predicate.usesVarDerived("cluster")) pred_uses_cluster = true; if (!(pred_uses_cluster ^ cons_uses_cluster)) { continue; } else if (pred_uses_cluster) { inv = consequent; cluster_inv = predicate; } else { inv = predicate; cluster_inv = consequent; } if (!inv.isInteresting()) { continue; } if (!inv.isWorthPrinting()) { continue; } if (contains_constant_non_012(inv)) { continue; } // filter out unwanted invariants // 1) Invariants involving sequences if (inv instanceof daikon.inv.binary.twoSequence.TwoSequence || inv instanceof daikon.inv.binary.sequenceScalar.SequenceScalar || inv instanceof daikon.inv.binary.sequenceString.SequenceString || inv instanceof daikon.inv.unary.sequence.SingleSequence || inv instanceof daikon.inv.unary.stringsequence.SingleStringSequence) { continue; } if (inv instanceof daikon.inv.ternary.threeScalar.LinearTernary || inv instanceof daikon.inv.binary.twoScalar.LinearBinary) { continue; } String inv_string = inv.format_using(OutputFormat.JAVA); if (orig_pattern.matcher(inv_string).find() || dot_class_pattern.matcher(inv_string).find()) { continue; } String fake_inv_string = simplify_inequalities(inv_string); HashedConsequent real = new HashedConsequent(inv, null); if (!fake_inv_string.equals(inv_string)) { // For instance, inv_string is "x != y", fake_inv_string is "x == y" HashedConsequent fake = new HashedConsequent(inv, inv_string); boolean added = store_invariant( cluster_inv.format_using(OutputFormat.JAVA), fake_inv_string, fake, pptname); if (!added) { // We couldn't add "x == y", (when we're "x != y") because // it already exists; so don't add "x == y" either. continue; } } store_invariant(cluster_inv.format_using(OutputFormat.JAVA), inv_string, real, pptname); } } }