Adding a null value filter in the tracker; Adding a new conflict variable for lights.
[jpf-core.git] / src / main / gov / nasa / jpf / listener / VariableConflictTracker.java
index cee0d24b62df5953a0cc4fd8f58d32a54594fdaa..04182946a09aa2d4b066949a18696091447d2dbc 100644 (file)
@@ -43,9 +43,8 @@ public class VariableConflictTracker extends ListenerAdapter {
   private final HashSet<String> conflictSet = new HashSet<>();
   private final HashSet<String> appSet = new HashSet<>();
   private boolean trackLocationVar;
-  private int timeout;
-  private Timer timeoutTimer;
-  private TimeoutTask timeoutTask;
+  private long timeout;
+  private long startTime;
 
   private final String SET_LOCATION_METHOD = "setLocationMode";
   private final String LOCATION_VAR = "location.mode";
@@ -66,42 +65,21 @@ public class VariableConflictTracker extends ListenerAdapter {
       }
     }
     trackLocationVar = config.getBoolean("track_location_var_conflict", false);
-    // Timeout is in minutes
-    timeout = config.getInt("timeout", 0);
-    timeoutTimer = null;
-    timeoutTask = null;
-  }
-
-  // Create a task for timer to do a timeout
-  private class TimeoutTask extends TimerTask {
-
-    VM vm;
-    Timer timer;
-
-    public TimeoutTask(VM vm, Timer timer) {
-      this.vm = vm;
-      this.timer = timer;
-    }
-
-    @Override
-    public void run() {
-      StringBuilder sb = new StringBuilder();
-      sb.append("Execution timeout!\n");
-      ThreadInfo ti = this.vm.getCurrentThread();
-      Instruction nextIns = ti.createAndThrowException("java.lang.RuntimeException", sb.toString());
-      ti.setNextPC(nextIns);
-      this.cancel();
-      this.timer.cancel();
-    }
+    // Timeout input from config is in minutes, so we need to convert into millis
+    timeout = config.getInt("timeout", 0) * 60 * 1000;
+    startTime = System.currentTimeMillis();
   }
 
   @Override
   public void instructionExecuted(VM vm, ThreadInfo ti, Instruction nextInsn, Instruction executedInsn) {
     // Instantiate timeoutTimer
-    if (timeout > 0 && timeoutTimer == null && timeoutTask == null) {
-      timeoutTimer = new Timer();
-      timeoutTask = new TimeoutTask(vm, timeoutTimer);
-      timeoutTimer.schedule(timeoutTask, timeout * 60 * 1000);
+    if (timeout > 0) {
+      if (System.currentTimeMillis() - startTime > timeout) {
+        StringBuilder sb = new StringBuilder();
+        sb.append("Execution timeout: " + (timeout / (60 * 1000)) + " minutes have passed!");
+        Instruction nextIns = ti.createAndThrowException("java.lang.RuntimeException", sb.toString());
+        ti.setNextPC(nextIns);
+      }
     }
 
     // CASE #1: Detecting variable write-after-write conflict
@@ -115,7 +93,7 @@ public class VariableConflictTracker extends ListenerAdapter {
           byte type  = getType(ti, executedInsn);
           String value = getValue(ti, executedInsn, type);
           //System.out.println("\n\n" + ti.getStackTrace() + "\n\n");
-          String writer = getWriter(ti.getStack());
+          String writer = getWriter(ti.getStack());         
           // Just return if the writer is not one of the listed apps in the .jpf file
           if (writer == null)
             return;
@@ -154,6 +132,14 @@ public class VariableConflictTracker extends ListenerAdapter {
         // Conflict is declared when:
         // 1) Current writer != previous writer, e.g., App1 vs. App2
         // 2) Current value != previous value, e.g., "locked" vs. "unlocked"
+        if (current.value == null) {
+
+          StringBuilder sb = new StringBuilder();
+          sb.append("Conflict between apps " + current.writer + " and " + writer + ": ");
+          sb.append("Current value cannot be read (null value)... Please double check with your app output!");
+          Instruction nextIns = ti.createAndThrowException("java.lang.RuntimeException", sb.toString());
+          ti.setNextPC(nextIns);
+        }
         if (!current.value.equals(value)) {
 
           StringBuilder sb = new StringBuilder();