Mercurial > hg > Members > kono > jpf-core
diff src/main/gov/nasa/jpf/listener/NoStateCycles.java @ 0:61d41facf527
initial v8 import (history reset)
author | Peter Mehlitz <Peter.C.Mehlitz@nasa.gov> |
---|---|
date | Fri, 23 Jan 2015 10:14:01 -0800 |
parents | |
children |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/main/gov/nasa/jpf/listener/NoStateCycles.java Fri Jan 23 10:14:01 2015 -0800 @@ -0,0 +1,126 @@ +/* + * Copyright (C) 2014, United States Government, as represented by the + * Administrator of the National Aeronautics and Space Administration. + * All rights reserved. + * + * The Java Pathfinder core (jpf-core) platform is licensed under the + * Apache License, Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0. + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package gov.nasa.jpf.listener; + +import gov.nasa.jpf.Config; +import gov.nasa.jpf.PropertyListenerAdapter; +import gov.nasa.jpf.search.Search; +import gov.nasa.jpf.vm.VM; +import gov.nasa.jpf.vm.SystemState; + +import java.util.ArrayList; +import java.util.HashSet; + + +/** + * If there is a cycle in the states of the program, JPF doesn't execute the + * already visited states. A cycle in the states may represent the ability for + * the program to hang. This property finds and outputs cycles in the states + * so that they may be investigated. + * + * The following might need to be added to listener property... + * gov.nasa.jpf.tools.SimpleIdleFilter + * gov.nasa.jpf.tools.IdleFilter + */ + +public class NoStateCycles extends PropertyListenerAdapter { + + private final HashSet<Integer> m_inStack = new HashSet<Integer>(); + private final ArrayList<Integer> m_stack = new ArrayList<Integer>(); + + private int m_cycleFound = -1; + private int m_stackPos = -1; + + public NoStateCycles(Config config) { + if (!config.getString("search.class").equals("gov.nasa.jpf.search.DFSearch")) + config.throwException("search.class must be gov.nasa.jpf.search.DFSearch"); // Or any class which does a depth first search. + } + + @Override + public void stateAdvanced(Search search) { + SystemState state; + Integer id; + + state = search.getVM().getSystemState(); + if (state.isInitState()) + return; + + id = state.getId(); + + if ((m_stackPos < 0) && (m_inStack.contains(id))) { + m_cycleFound = id; + + for (m_stackPos = m_stack.size() - 1; m_stackPos >= 0; m_stackPos--) + if (m_stack.get(m_stackPos).equals(id)) + break; + } + + m_stack.add(id); + m_inStack.add(id); + } + + @Override + public void stateBacktracked(Search search) { + Integer id; + int pos; + + pos = m_stack.size() - 1; + id = m_stack.remove(pos); + m_inStack.remove(id); + + if (m_stackPos >= pos) + m_stackPos = -1; + } + + @Override + public boolean check(Search search, VM vm) { + return(m_cycleFound < 0); + } + + @Override + public void reset () { + m_cycleFound = -1; + } + + @Override + public String getErrorMessage () { + StringBuilder result; + int i, id; + + result = new StringBuilder(); + result.append("States:\n"); + + for (i = m_stack.size() - 1; i >= 0; i--) { + id = m_stack.get(i); + + result.append(" "); + result.append(id); + result.append('\n'); + + if (id == m_cycleFound) + break; + } + + return(result.toString()); + } + + @Override + public String getExplanation () { + return("Finds cycles in states. A cycle suggests that the program might be able to hang."); + } +}