Summary: The `Utils` module has another version of try-finally than can swallow exceptions from the restart scheduler. This diff fixes that, but has to also fix the dependency cycle introduced between `SymOp` and `Utils`. This is done by extracting the exception handling from `SymOp` into a new base module `Exception`. Reviewed By: jvillard Differential Revision: D28930082 fbshipit-source-id: 7894d8c89master
parent
85b8ad463c
commit
d5d9a9369a
@ -0,0 +1,57 @@
|
|||||||
|
(*
|
||||||
|
* Copyright (c) Facebook, Inc. and its affiliates.
|
||||||
|
*
|
||||||
|
* This source code is licensed under the MIT license found in the
|
||||||
|
* LICENSE file in the root directory of this source tree.
|
||||||
|
*)
|
||||||
|
|
||||||
|
open! IStd
|
||||||
|
module F = Format
|
||||||
|
|
||||||
|
type failure_kind =
|
||||||
|
| FKtimeout (** max time exceeded *)
|
||||||
|
| FKsymops_timeout of int (** max symop's exceeded *)
|
||||||
|
| FKrecursion_timeout of int (** max recursion level exceeded *)
|
||||||
|
| FKcrash of string (** uncaught exception or failed assertion *)
|
||||||
|
|
||||||
|
(** failure that prevented biabduction analysis from finishing *)
|
||||||
|
exception Analysis_failure_exe of failure_kind
|
||||||
|
|
||||||
|
let exn_not_failure = function
|
||||||
|
| Analysis_failure_exe _ | RestartSchedulerException.ProcnameAlreadyLocked _ ->
|
||||||
|
false
|
||||||
|
| _ ->
|
||||||
|
true
|
||||||
|
|
||||||
|
|
||||||
|
let try_finally ~f ~finally =
|
||||||
|
match f () with
|
||||||
|
| r ->
|
||||||
|
finally () ;
|
||||||
|
r
|
||||||
|
| exception (Analysis_failure_exe _ as f_exn) ->
|
||||||
|
IExn.reraise_after f_exn ~f:(fun () ->
|
||||||
|
try finally ()
|
||||||
|
with finally_exn when RestartSchedulerException.is_not_restart_exception finally_exn ->
|
||||||
|
(* swallow in favor of the original exception unless it's the restart scheduler exception *)
|
||||||
|
() )
|
||||||
|
| exception f_exn when RestartSchedulerException.is_not_restart_exception f_exn ->
|
||||||
|
IExn.reraise_after f_exn ~f:(fun () ->
|
||||||
|
try finally ()
|
||||||
|
with
|
||||||
|
| finally_exn
|
||||||
|
when (* do not swallow Analysis_failure_exe or restart exception thrown from finally *)
|
||||||
|
exn_not_failure finally_exn
|
||||||
|
->
|
||||||
|
() )
|
||||||
|
|
||||||
|
|
||||||
|
let pp_failure_kind fmt = function
|
||||||
|
| FKtimeout ->
|
||||||
|
F.pp_print_string fmt "TIMEOUT"
|
||||||
|
| FKsymops_timeout symops ->
|
||||||
|
F.fprintf fmt "SYMOPS TIMEOUT (%d)" symops
|
||||||
|
| FKrecursion_timeout level ->
|
||||||
|
F.fprintf fmt "RECURSION TIMEOUT (%d)" level
|
||||||
|
| FKcrash msg ->
|
||||||
|
F.fprintf fmt "CRASH (%s)" msg
|
@ -0,0 +1,30 @@
|
|||||||
|
(*
|
||||||
|
* Copyright (c) Facebook, Inc. and its affiliates.
|
||||||
|
*
|
||||||
|
* This source code is licensed under the MIT license found in the
|
||||||
|
* LICENSE file in the root directory of this source tree.
|
||||||
|
*)
|
||||||
|
|
||||||
|
(** The restart scheduler and biabduction use exceptions for control flow (restarts/timeouts
|
||||||
|
respectively). Functions here abstract away the semantics of when an exception can be ignored. *)
|
||||||
|
|
||||||
|
open! IStd
|
||||||
|
|
||||||
|
(** types of biabduction failure due to timeouts *)
|
||||||
|
type failure_kind =
|
||||||
|
| FKtimeout (** max time exceeded *)
|
||||||
|
| FKsymops_timeout of int (** max symop's exceeded *)
|
||||||
|
| FKrecursion_timeout of int (** max recursion level exceeded *)
|
||||||
|
| FKcrash of string (** uncaught exception or failed assertion *)
|
||||||
|
|
||||||
|
val pp_failure_kind : Format.formatter -> failure_kind -> unit
|
||||||
|
|
||||||
|
(** Timeout exception *)
|
||||||
|
exception Analysis_failure_exe of failure_kind
|
||||||
|
|
||||||
|
val exn_not_failure : exn -> bool
|
||||||
|
(** check that the exception is not a biabduction timeout or restart scheduler exception *)
|
||||||
|
|
||||||
|
val try_finally : f:(unit -> 'a) -> finally:(unit -> unit) -> 'a
|
||||||
|
(** [try_finally ~f ~finally] executes [f] and then [finally] even if [f] raises an exception.
|
||||||
|
Biabduction timeouts and restart scheduler exceptions are handled as necessary. *)
|
Loading…
Reference in new issue