Mercurial > hg > Members > kono > jpf-core
view src/main/gov/nasa/jpf/listener/TraceStorer.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 source
/* * 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.JPF; import gov.nasa.jpf.ListenerAdapter; import gov.nasa.jpf.jvm.bytecode.JVMInvokeInstruction; import gov.nasa.jpf.search.Search; import gov.nasa.jpf.util.StringSetMatcher; import gov.nasa.jpf.vm.Instruction; import gov.nasa.jpf.vm.VM; import gov.nasa.jpf.vm.ThreadInfo; /** * tool to save traces upon various conditions like * - property violation * - call of a certain method * - reaching a certain search depth * - creating a certain thread */ public class TraceStorer extends ListenerAdapter { int nTrace = 1; String traceFileName; // do we store to the same file? (i.e. overwrite previously stored traces) // if set to 'true', store all traces (in <traceFileName>.n) boolean storeMultiple; // do we want to terminate after first store, even if it's triggered by a // property violation? boolean terminateOnStore; boolean storeOnConstraintHit; // search depth at what we store the tace int storeDepth; // calls that should trigger a store StringSetMatcher storeCalls; // thread starts that should trigger a store StringSetMatcher storeThreads; // do we want verbose output boolean verbose; Search search; VM vm; public TraceStorer (Config config, JPF jpf){ traceFileName = config.getString("trace.file", "trace"); storeMultiple = config.getBoolean("trace.multiple", false); storeDepth = config.getInt("trace.depth", Integer.MAX_VALUE); verbose = config.getBoolean("trace.verbose", false); terminateOnStore = config.getBoolean("trace.terminate", false); storeOnConstraintHit = config.getBoolean("trace.store_constraint", false); storeCalls = StringSetMatcher.getNonEmpty(config.getStringArray("trace.store_calls")); storeThreads = StringSetMatcher.getNonEmpty(config.getStringArray("trace.store_threads")); vm = jpf.getVM(); search = jpf.getSearch(); } void storeTrace(String reason) { String fname = traceFileName; if (storeMultiple){ fname = fname + '.' + nTrace++; } vm.storeTrace(fname, reason, verbose); // <2do> maybe some comment would be in order } @Override public void propertyViolated (Search search){ // Ok, this is unconditional storeTrace("violated property: " + search.getLastError().getDetails()); // no need to terminate (and we don't want to interfere with search.multiple_errors) } @Override public void stateAdvanced (Search search){ if (search.getDepth() == storeDepth){ storeTrace("search depth reached: " + storeDepth); checkSearchTermination(); } } @Override public void searchConstraintHit (Search search){ if (storeOnConstraintHit){ storeTrace("search constraint hit: " + search.getLastSearchConstraint()); } } @Override public void instructionExecuted (VM vm, ThreadInfo ti, Instruction nextInsn, Instruction executedInsn){ if (storeCalls != null){ if (executedInsn instanceof JVMInvokeInstruction) { JVMInvokeInstruction iinsn = (JVMInvokeInstruction)executedInsn; String clsName = iinsn.getInvokedMethodClassName(); String mthName = iinsn.getInvokedMethodName(); String mn = clsName + '.' + mthName; if (storeCalls.matchesAny(mn)){ storeTrace("call: " + mn); checkVMTermination(ti); } } } } @Override public void threadStarted(VM vm, ThreadInfo ti) { if (storeThreads != null){ String tname = ti.getName(); if (storeThreads.matchesAny( tname)){ storeTrace("thread started: " + tname); checkVMTermination(ti); } } } boolean checkVMTermination(ThreadInfo ti) { if (terminateOnStore){ ti.breakTransition("storeTraceTermination"); search.terminate(); return true; } return false; } boolean checkSearchTermination() { if (terminateOnStore){ search.terminate(); return true; } return false; } }