@@ -48,14 +48,12 @@ import org.utbot.instrumentation.ConcreteExecutor
4848import org.utbot.instrumentation.instrumentation.Instrumentation
4949import org.utbot.instrumentation.instrumentation.execution.UtConcreteExecutionData
5050import org.utbot.instrumentation.instrumentation.execution.UtConcreteExecutionResult
51- import org.utbot.instrumentation.instrumentation.execution.UtExecutionInstrumentation
5251import org.utbot.taint.*
5352import org.utbot.taint.model.TaintConfiguration
5453import soot.jimple.Stmt
5554import soot.tagkit.ParamNamesTag
5655import java.lang.reflect.Method
5756import java.util.function.Consumer
58- import java.util.function.Predicate
5957import kotlin.math.min
6058import kotlin.system.measureTimeMillis
6159
@@ -317,10 +315,7 @@ class UtBotSymbolicEngine(
317315 val concreteExecutionResult =
318316 concreteExecutor.executeConcretely(methodUnderTest, stateBefore, instrumentation, UtSettings .concreteExecutionDefaultTimeoutInInstrumentedProcessMillis)
319317
320- concreteExecutionResult.processedFailure()?.let { failure ->
321- emitFailedConcreteExecutionResult(stateBefore, failure.exception)
322-
323- logger.debug { " Instrumented process failed with exception ${failure.exception} before concrete execution started" }
318+ if (failureCanBeProcessedGracefully(concreteExecutionResult, executionToRollbackOn = null )) {
324319 return @measureTime
325320 }
326321
@@ -668,10 +663,7 @@ class UtBotSymbolicEngine(
668663 UtSettings .concreteExecutionDefaultTimeoutInInstrumentedProcessMillis
669664 )
670665
671- concreteExecutionResult.processedFailure()?.let { failure ->
672- emitFailedConcreteExecutionResult(stateBefore, failure.exception)
673-
674- logger.debug { " Instrumented process failed with exception ${failure.exception} before concrete execution started" }
666+ if (failureCanBeProcessedGracefully(concreteExecutionResult, symbolicUtExecution)) {
675667 return
676668 }
677669
@@ -699,6 +691,29 @@ class UtBotSymbolicEngine(
699691 }
700692 }
701693
694+ private suspend fun FlowCollector<UtResult>.failureCanBeProcessedGracefully (
695+ concreteExecutionResult : UtConcreteExecutionResult ,
696+ executionToRollbackOn : UtExecution ? ,
697+ ): Boolean {
698+ concreteExecutionResult.processedFailure()?.let { failure ->
699+ // If concrete execution failed to some reasons that are not process death or cancellation
700+ // when we call something that is processed successfully by symbolic engine,
701+ // we should:
702+ // - roll back to symbolic execution data ignoring failing concrete (is symbolic execution exists);
703+ // - do not emit an execution if there is nothing to roll back on.
704+
705+ // Note that this situation is suspicious anyway, so we log a WARN message about the failure.
706+ executionToRollbackOn?.let {
707+ emit(it)
708+ }
709+
710+ logger.warn { " Instrumented process failed with exception ${failure.exception} before concrete execution started" }
711+ return true
712+ }
713+
714+ return false
715+ }
716+
702717 /* *
703718 * Collects entry method statement path for ML. Eliminates duplicated statements, e.g. assignment with invocation
704719 * in right part.
0 commit comments