package cute.concolic.generateinputandschedule;
import cute.Cute;
import cute.concolic.Globals;
import cute.concolic.Information;
import cute.concolic.input.InputMap;
import cute.concolic.logging.BranchCoverageLog;
import cute.concolic.logging.ExecutionLog;
import cute.concolic.logging.JUnitTestGenerator;
import cute.concolic.logging.Logger;
import cute.concolic.pathconstraint.DSchedule;
import cute.concolic.pathconstraint.PathConstraint;
import cute.concolic.pathconstraint.ScheduleConstraint;
import cute.concolic.symbolicexecution.BranchHistory;
import java.io.File;
import java.util.Random;
import java.util.Vector;
/**
* Author: Koushik Sen <ksen@cs.uiuc.edu>
*/
public class GenerateInputAndSchedule {
private Information information;
private InputMap input;
private PathConstraint path;
private BranchHistory history;
public ExecutionLog ptrace;
public Logger logger;
public JUnitTestGenerator junitTest;
public Random rand;
public BranchCoverageLog coverage;
public GenerateInputAndSchedule(Information information, InputMap input,
PathConstraint path, BranchHistory history,
ExecutionLog ptrace, Logger logger,
JUnitTestGenerator junitTest, Random rand,
BranchCoverageLog coverage) {
this.information = information;
this.input = input;
this.path = path;
this.history = history;
this.ptrace = ptrace;
this.logger = logger;
this.junitTest = junitTest;
this.rand = rand;
this.coverage = coverage;
}
private int findDepth(){
int i,j,k;
i = path.size()-1;
k=0;
if (information.depth > 0) {
for (j=0;j<=i;j++) {
if (path.getArith(j)!=null
|| path.getPointer(j)!=null
|| path.getSchedule(j)!=null
|| path.getDSchedule(j)!=null ) {
k++;
if (k>=information.depth) {
return information.brackTrackAt>=0?(information.brackTrackAt>=j?j:information.brackTrackAt):j;
}
}
}
}
return information.brackTrackAt>=0?(information.brackTrackAt>=i?i:information.brackTrackAt):i;
}
private int findBackTrackingPoints(int i){
int j,k;
k=0;
for (j=0;j<=i;j++) {
if (path.getArith(j)!=null
|| path.getPointer(j)!=null
|| (path.getSchedule(j)!=null
&& path.getSchedule(j).isBackTrackingPoint())
|| path.getDSchedule(j)!=null ) {
k++;
}
}
return k;
}
private Vector getBranchingIndices(){
Vector ret = new Vector(1000);
int i,k;
k = path.size();
for(i=0;i<k;i++){
if (path.getArith(i)!=null
|| path.getPointer(i)!=null
|| path.getSchedule(i)!=null
|| path.getDSchedule(i)!=null) {
ScheduleConstraint pe = path.getSchedule(i);
if(pe!=null){
if(pe.isBackTrackingRequired()){
ret.add(new Integer(i));
}
} else
ret.add(new Integer(i));
}
}
return ret;
}
private void predictDirected(){
int i,counter;
if (!history.isOK()) {
(new File(Globals.NEW+"Inputs")).delete();
(new File(Globals.BACK+"Inputs")).renameTo(new File(Globals.NEW+"Inputs"));
(new File(Globals.NEW+"Branches")).delete();
(new File(Globals.BACK+"Branches")).renameTo(new File(Globals.NEW+"Branches"));
Counter.inc(information);
return;
}
counter = Counter.get(information);
i = findDepth();
while(true){
while (i>=0 && history.getStatus(i)) {
i--;
}
if (i<=-1) {
writeHistoryAndInput(i);
System.out.println("*************************** One complete search is over ************************");
(new File(Globals.NEW+"Branches")).delete();
(new File(Globals.NEW+"Inputs")).delete();
(new File(Globals.NEW+"Counter")).delete();
coverage.write();
information.returnVal = Cute.EXIT_COMPLETE+information.returnVal;
return;
}
if (path.getArith(i)!=null) {
history.setBranchAndStatus(i,
!history.getBranch(i),history.getStatus(i));
if ((new ArithmeticSolver(path,input,information.optimized))
.solveArith(i,counter)) {
if (counter!=0) {
i--;
counter--;
continue;
}
writeHistoryAndInput(i);
return;
}
}
if (path.getPointer(i)!=null) {
history.setBranchAndStatus(i,
!history.getBranch(i),history.getStatus(i));
if ((new PointerSolver(path,input)).solvePointer(i,counter)) {
if (counter!=0) {
i--;
counter--;
continue;
}
writeHistoryAndInput(i);
return;
}
}
ScheduleConstraint pe = path.getSchedule(i);
if(pe!=null){
if(pe.isBackTrackingRequired()){
writeHistoryAndInput(i);
return;
}
}
DSchedule ds = path.getDSchedule(i);
if(ds!=null){
if(ds.nextPid!=-1){
if(ds.pid==ds.nextPid){
ds.mid = ds.nextMid;
writeHistoryAndInput(i);
return;
} else if(ds.isRace){
if(information.optimalDistributed)
ds.isRace = false;
ds.pid = ds.nextPid;
ds.mid = ds.nextMid;
writeHistoryAndInput(i);
return;
}
}
}
i--;
}
}
private void predictRandom2(){
int max = findDepth();
int i = history.getInitSize();
boolean first = true;
while(true){
if(i>max){
i=0;
if(first){
first = false;
coverage.incLastIncrementedAt();
}
}
long la = coverage.getLastAt();
la = (la>50)?la:50;
if (coverage.getLastIncrementedAt()>la) {
writeHistoryAndInput(-1);
System.out.println("*********************** jCUTE may not find any more bug ********************");
(new File(Globals.NEW+"Branches")).delete();
(new File(Globals.NEW+"Inputs")).delete();
coverage.write();
information.returnVal = Cute.EXIT_COMPLETE+information.returnVal;
return;
}
boolean b = rand.nextBoolean();
if (path.getArith(i)!=null &&
(b || !path.isOtherBranchTaken(i))) {
if ((new ArithmeticSolver(path,input,information.optimized))
.solveArith(i,0)) {
history.setBranchAndStatus(i,
!history.getBranch(i),history.getStatus(i));
writeHistoryAndInput(i);
return;
}
}
if (path.getPointer(i)!=null &&
(b || !path.isOtherBranchTaken(i))) {
if ((new PointerSolver(path,input)).solvePointer(i,0)) {
history.setBranchAndStatus(i,
!history.getBranch(i),history.getStatus(i));
writeHistoryAndInput(i);
return;
}
}
ScheduleConstraint pe = path.getSchedule(i);
if(pe!=null && b){
if(pe.isBackTrackingRequired()){
writeHistoryAndInput(i);
return;
}
}
DSchedule ds = path.getDSchedule(i);
if(ds!=null && b){
if(ds.nextPid!=-1){
if(ds.pid==ds.nextPid){
ds.mid = ds.nextMid;
writeHistoryAndInput(i);
return;
} else if(ds.isRace){
if(information.optimalDistributed)
ds.isRace = false;
ds.pid = ds.nextPid;
ds.mid = ds.nextMid;
writeHistoryAndInput(i);
return;
}
}
}
i++;
}
}
private void predictQuick(){
int i;
i = findDepth();
while(true){
if (i<=-1) {
return;
}
if (path.getArith(i)!=null
&& !path.isOtherBranchTaken(i)) {
if ((new ArithmeticSolver(path,input,information.optimized))
.solveArith(i,0)) {
history.setBranchAndStatus(i,
!history.getBranch(i),
!history.getStatus(i));
writeHistoryAndInput(i);
System.out.println("**************** Quick Search Hit found");
return;
}
}
if (path.getPointer(i)!=null
&& !path.isOtherBranchTaken(i)) {
if ((new PointerSolver(path,input)).solvePointer(i,0)) {
history.setBranchAndStatus(i,
!history.getBranch(i),
!history.getStatus(i));
writeHistoryAndInput(i);
System.out.println("***************** Quick Search Hit found");
return;
}
}
i--;
}
}
private void writeHistoryAndInput(int i){
if(information.searchMode!=Globals.SEARCH_QUICK){
int total = findBackTrackingPoints(path.size()-1);
int current = findBackTrackingPoints(i);
ProgressLog plog = new ProgressLog(information);
plog.read(null);
plog.setLog(total,current,path.size());
plog.write();
}
if(i>=0){
input.write();
history.write(i+1);
}
}
private void predictRandom(){
int i,k;
Vector indices = getBranchingIndices();
k = indices.size();
if (k==0) {
writeHistoryAndInput(-1);
System.out.println("******************** One complete search is over *********************");
return;
}
while(true){
i = rand.nextInt();
if(i<0) i = -i;
i = i % k;
i = ((Integer)indices.get(i)).intValue();
if (path.getArith(i)!=null) {
if ((new ArithmeticSolver(path,input,information.optimized))
.solveArith(i,0)) {
writeHistoryAndInput(i);
return;
}
}
if (path.getPointer(i)!=null) {
if ((new PointerSolver(path,input)).solvePointer(i,0)) {
writeHistoryAndInput(i);
return;
}
}
ScheduleConstraint pe = path.getSchedule(i);
if(pe!=null){
if(pe.isBackTrackingRequired()){
writeHistoryAndInput(i);
return;
}
}
DSchedule ds = path.getDSchedule(i);
if(ds!=null){
if(ds.nextPid!=-1){
if(ds.pid==ds.nextPid){
ds.mid = ds.nextMid;
writeHistoryAndInput(i);
return;
} else if(ds.isRace){
if(information.optimalDistributed)
ds.isRace = false;
ds.pid = ds.nextPid;
ds.mid = ds.nextMid;
writeHistoryAndInput(i);
return;
}
}
}
}
}
synchronized public void predict(){
//history.print();
if (information.mode!=Globals.REPLAY_MODE){
if(!information.solved){
information.solved = true;
if((information.debugLevel&64)!=0) logger.info(64,"Old Branch History",history);
if((information.debugLevel&128)!=0) logger.info(128,"Old Input",input);
if (information.searchMode==Globals.SEARCH_RANDOM){
predictRandom();
coverage.write();
}
else if(information.searchMode==Globals.SEARCH_RANDOM2){
predictRandom2();
coverage.write();
}
else if(information.searchMode==Globals.SEARCH_DFS){
predictDirected();
coverage.write();
}
else if(information.searchMode==Globals.SEARCH_QUICK){
predictQuick();
coverage.write();
}
if((information.debugLevel&256)!=0) logger.info(256,"Path Constriant",path);
if((information.debugLevel&64)!=0) logger.info(64,"New Branch History",history);
if((information.debugLevel&128)!=0) logger.info(128,"New Input",input);
}
}
if(coverage.isIncremented())
junitTest.printAll();
ptrace.write();
System.exit(information.returnVal);
}
}