Beispiel #1
0
  public static void main(String args[]) {
    RuntimeConfiguration.get().getOutStream().println("TLC Worker " + TLCGlobals.versionOfTLC);

    String specFile = null;
    String configFile = null;
    String serverName = null;

    // Must have at least two args: a filename and a hostname.
    int index = 0;
    while (index < args.length) {
      if (args[index].equals("-config")) {
        index++;
        if (index < args.length) {
          configFile = args[index];
          int len = configFile.length();
          if (configFile.startsWith(".cfg", len - 4)) {
            configFile = configFile.substring(0, len - 4);
          }
          index++;
        } else {
          printErrorMsg("Error: configuration file required.");
          System.exit(0);
        }
      } else {
        if (args[index].charAt(0) == '-') {
          printErrorMsg("Error: unrecognized option: " + args[index]);
          System.exit(0);
        }
        if (specFile == null) {
          specFile = args[index++];
          int len = specFile.length();
          if (specFile.startsWith(".tla", len - 4)) {
            specFile = specFile.substring(0, len - 4);
          }
        } else if (serverName == null) {
          serverName = args[index++];
        } else {
          printErrorMsg("Error: more than one input files: " + specFile + " and " + args[index]);
          System.exit(0);
        }
      }
    }

    if (specFile == null) {
      printErrorMsg("Error: Missing input TLA+ module.");
      return;
    }
    if (serverName == null) {
      printErrorMsg("Error: Missing hostname of the TLC server to be contacted.");
      return;
    }
    if (configFile == null) configFile = specFile;

    String hostname = "Unknown";
    try {
      hostname = InetAddress.getLocalHost().getHostName();
      String url = "//" + serverName + ":" + TLCServer.Port + "/TLCServer";
      TLCServerRMI server = (TLCServerRMI) Naming.lookup(url);

      long irredPoly = server.getIrredPolyForFP();
      FP64.Init(irredPoly);

      int lastSep = specFile.lastIndexOf(File.separatorChar);
      String specDir = (lastSep == -1) ? "" : specFile.substring(0, lastSep + 1);
      specFile = specFile.substring(lastSep + 1);
      Object[] appArgs = new Object[5];
      appArgs[0] = specDir;
      appArgs[1] = specFile;
      appArgs[2] = configFile;
      appArgs[3] = server.getCheckDeadlock();
      appArgs[4] = server.getPreprocess();

      String appName = server.getAppName();
      Class appClass = Class.forName(appName);
      Class[] classOfArgs = new Class[appArgs.length];
      for (int i = 0; i < classOfArgs.length; i++) {
        classOfArgs[i] = appArgs[i].getClass();
      }
      Constructor appConstructor = appClass.getDeclaredConstructor(classOfArgs);
      DistApp work = (DistApp) appConstructor.newInstance(appArgs);

      UniqueString.setSource((InternRMI) server);

      FPSetManager fpSetManager = server.getFPSetManager();
      TLCWorkerRMI worker = new TLCWorker(work, fpSetManager);
      server.registerWorker(worker, hostname);

      RuntimeConfiguration.get().getOutStream().println("TLC worker at " + hostname + " is ready.");
    } catch (Throwable e) {
      RuntimeConfiguration.get()
          .getErrStream()
          .println(
              "Error: Failed to start worker at "
                  + hostname
                  + " for server "
                  + serverName
                  + ".\n"
                  + e.getMessage());
    }
  }
  /**
   * CheckImplFile and the simulation engine communicate via files:
   *
   * <p>1. The simulation engine stores in files the abstract view of the states it generates during
   * the simulation run. The abstract view of simulation state is computed by a refinement function.
   * CheckImplFile checks the abstract states in the files.
   *
   * <p>2. CheckImplFile maintains coverage information while doing the checking. It continuously
   * generates traces to uncovered states, and store the traces in files. The simulation engine uses
   * the traces in the files to guide the simulation into the parts of the state space that
   * simulation fails to reach up to that point.
   *
   * <p>Usage: java tlc.tool.CheckImplFile [options] spec[.tla]
   *
   * <p>Below is a list of the command line options: o -config file: provide the config file.
   * Defaults to spec.cfg if not provided o -deadlock: do not check for deadlock. Defaults to
   * checking deadlock if not specified o -recover path: recover from checkpoint in path Defaults to
   * scratch run if not specified o -workers num: the number of TLC worker threads Defaults to 1 o
   * -depth num: the depth of the initial (partial) state space Defaults to 20 o -trace filename:
   * the prefix of the trace file name. o -coverage seconds: collect coverage information on the
   * spec, print out the information every seconds Defaults to no coverage if not specified
   */
  public static void main(String[] args) {
    RuntimeConfiguration.get().getOutStream().println("TLC " + TLCGlobals.versionOfTLC);

    String mainFile = null;
    String configFile = null;
    String traceFile = null;
    boolean deadlock = true;
    int depth = 20;
    String fromChkpt = null;

    int index = 0;
    while (index < args.length) {
      if (args[index].equals("-config")) {
        index++;
        if (index < args.length) {
          configFile = args[index++];
          int len = configFile.length();
          if (configFile.startsWith(".cfg", len - 4)) {
            configFile = configFile.substring(0, len - 4);
          }
        } else {
          printErrorMsg("Error: expect a file name for -config option.");
          return;
        }
      } else if (args[index].equals("-deadlock")) {
        index++;
        deadlock = false;
      } else if (args[index].equals("-recover")) {
        index++;
        if (index < args.length) {
          fromChkpt = args[index++] + File.separator;
        } else {
          printErrorMsg("Error: need to specify the metadata directory for recovery.");
          return;
        }
      } else if (args[index].equals("-workers")) {
        index++;
        if (index < args.length) {
          try {
            TLCGlobals.setNumWorkers(Integer.parseInt(args[index]));
            index++;
          } catch (Exception e) {
            printErrorMsg("Error: worker number required. But encountered " + args[index]);
            return;
          }
          if (TLCGlobals.getNumWorkers() < 1) {
            printErrorMsg("Error: at least one worker required.");
            return;
          }
        } else {
          printErrorMsg("Error: expect an integer for -workers option.");
          return;
        }
      } else if (args[index].equals("-depth")) {
        index++;
        if (index < args.length) {
          try {
            depth = Integer.parseInt(args[index]);
            index++;
          } catch (Exception e) {
            printErrorMsg("Error: depth must be an integer. But encountered " + args[index]);
            return;
          }
        } else {
          printErrorMsg("Error: expect an integer for -depth option.");
          return;
        }
      } else if (args[index].equals("-trace")) {
        index++;
        if (index < args.length) {
          traceFile = args[index++];
        } else {
          printErrorMsg("Error: expect a filename for -trace option.");
          return;
        }
      } else if (args[index].equals("-coverage")) {
        index++;
        TLCGlobals.coverage = true;
        if (index < args.length) {
          try {
            TLCGlobals.coverageInterval = Integer.parseInt(args[index]) * 1000;
            index++;
          } catch (Exception e) {
            printErrorMsg(
                "Error: An integer for coverage report interval required."
                    + " But encountered "
                    + args[index]);
            return;
          }
        } else {
          printErrorMsg("Error: coverage report interval required.");
          return;
        }
      } else {
        if (args[index].charAt(0) == '-') {
          printErrorMsg("Error: unrecognized option: " + args[index]);
          return;
        }
        if (mainFile != null) {
          printErrorMsg("Error: more than one input files: " + mainFile + " and " + args[index]);
          return;
        }
        mainFile = args[index++];
        int len = mainFile.length();
        if (mainFile.startsWith(".tla", len - 4)) {
          mainFile = mainFile.substring(0, len - 4);
        }
      }
    }

    if (mainFile == null) {
      printErrorMsg("Error: Missing input TLA+ module.");
      return;
    }

    if (configFile == null) configFile = mainFile;
    if (traceFile == null) traceFile = mainFile + "_trace";

    try {
      // Initialize:
      if (fromChkpt != null) {
        // We must recover the intern var table as early as possible
        UniqueString.internTbl.recover(fromChkpt);
      }
      FP64.Init(0);

      // Start the checker:
      CheckImplFile checker =
          new CheckImplFile(mainFile, configFile, deadlock, depth, fromChkpt, traceFile);
      checker.init();
      while (true) {
        // Get a trace and check it.
        checker.export();
        boolean ok = checker.getTrace();
        if (ok) {
          checker.checkTrace();
        } else {
          synchronized (checker) {
            checker.wait(WaitForTrace);
          }
        }
      }
    } catch (Throwable e) {
      // e.printStackTrace();
      RuntimeConfiguration.get()
          .getErrStream()
          .println("Error: TLC failed in checking traces. " + e.getMessage());
    }
    System.exit(0);
  }