@@ -79,7 +79,7 @@ trait BoogieInterface {
7979
8080 var errormap : Map [Int , VerificationError ] = Map ()
8181 var models : collection.mutable.ListBuffer [String ] = new collection.mutable.ListBuffer [String ]
82- def invokeBoogie (program : Program , options : Seq [String ]): (String ,VerificationResult ) = {
82+ def invokeBoogie (program : Program , options : Seq [String ], timeout : Option [ Int ] ): (String ,VerificationResult ) = {
8383 // find all errors and assign everyone a unique id
8484 errormap = Map ()
8585 program.visit {
@@ -88,22 +88,28 @@ trait BoogieInterface {
8888 }
8989
9090 // invoke Boogie
91- val output = run(program.toString, defaultOptions ++ options)
92-
93- // parse the output
94- parse(output) match {
95- case (version,Nil ) =>
96- (version,Success )
97- case (version,errorIds) => {
98- val errors = (0 until errorIds.length).map(i => {
99- val id = errorIds(i)
100- val error = errormap.get(id).get
101- if (models.nonEmpty)
102- error.failureContexts = Seq (FailureContextImpl (Some (SimpleCounterexample (Model (models(i))))))
103- error
104- })
105- (version,Failure (errors))
106- }
91+ val optOutput = run(program.toString, defaultOptions ++ options, timeout)
92+ optOutput match {
93+ case None =>
94+ // Timeout
95+ (null , Failure (Seq (TimeoutOccurred (timeout.get, " second(s)" ))))
96+ case Some (output) =>
97+ // parse the output
98+ parse(output) match {
99+ case (version, Nil ) =>
100+ (version, Success )
101+ case (version, errorIds) => {
102+ val errors = (0 until errorIds.length).map(i => {
103+ val id = errorIds(i)
104+ val error = errormap.get(id).get
105+ if (models.nonEmpty) {
106+ error.failureContexts = Seq (FailureContextImpl (Some (SimpleCounterexample (Model (models(i))))))
107+ }
108+ error
109+ })
110+ (version, Failure (errors))
111+ }
112+ }
107113 }
108114 }
109115
@@ -157,8 +163,9 @@ trait BoogieInterface {
157163
158164 /**
159165 * Invoke Boogie.
166+ * Returns None if there was a timeout, otherwise the Boogie output.
160167 */
161- private def run (input : String , options : Seq [String ]) = {
168+ private def run (input : String , options : Seq [String ], timeout : Option [ Int ] ) = {
162169 reporter report BackendSubProcessReport (" carbon" , boogiePath, BeforeInputSent , _boogieProcessPid)
163170
164171 // When the filename is "stdin.bpl" Boogie reads the program from standard input.
@@ -193,8 +200,15 @@ trait BoogieInterface {
193200 proc.getOutputStream.write(input.getBytes);
194201 proc.getOutputStream.close()
195202
203+ var boogieTimeout = false
204+
196205 try {
197- proc.waitFor()
206+ timeout match {
207+ case Some (t) if t > 0 =>
208+ boogieTimeout = ! proc.waitFor(t, java.util.concurrent.TimeUnit .SECONDS )
209+ case _ =>
210+ proc.waitFor()
211+ }
198212 } finally {
199213 destroyProcessAndItsChildren(proc, boogiePath)
200214 }
@@ -212,7 +226,10 @@ trait BoogieInterface {
212226 val normalOutput = inputConsumer.result.get
213227 reporter report BackendSubProcessReport (" carbon" , boogiePath, OnExit , _boogieProcessPid)
214228
215- errorOutput + normalOutput
229+ if (boogieTimeout)
230+ None
231+ else
232+ Some (errorOutput + normalOutput)
216233 } catch {
217234 case _ : NoSuchElementException => sys.error(" Could not retrieve output from Boogie" )
218235 }
0 commit comments