[biabduction] recognise restart exception in timeout handling

Summary:
Make the biabduction machinery for detecting (biabduction) exceptions that can be swallowed recognise the one thrown by the restart scheduler.

The dependency hierarchy requires declaring that exception in `base`.

Reviewed By: jvillard

Differential Revision: D28773898

fbshipit-source-id: 2136346da
master
Nikos Gorogiannis 4 years ago committed by Facebook GitHub Bot
parent ec976d3be4
commit 64a5fbf14e

@ -328,7 +328,7 @@ module AbstractInterpreterCommon (TransferFunctions : NodeTransferFunctions) = s
post
| Error (exn, backtrace, instr) ->
( match exn with
| TaskSchedulerTypes.ProcnameAlreadyLocked _ ->
| RestartSchedulerException.ProcnameAlreadyLocked _ ->
(* this isn't an error; don't log it *)
()
| _ ->

@ -6,10 +6,6 @@
*)
open! IStd
(** for the Restart scheduler: raise when a worker tries to analyze a procedure already being
analyzed by another process *)
exception ProcnameAlreadyLocked of {dependency_filename: string}
type target =
| Procname of Procname.t
| File of SourceFile.t

@ -51,7 +51,7 @@ let analyze_target : (TaskSchedulerTypes.target, string) Tasks.doer =
Ondemand.analyze_file exe_env source_file ;
if Config.write_html then Printer.write_all_html_files source_file ;
None
with TaskSchedulerTypes.ProcnameAlreadyLocked {dependency_filename} ->
with RestartSchedulerException.ProcnameAlreadyLocked {dependency_filename} ->
Some dependency_filename )
in
(* In call-graph scheduling, log progress every [per_procedure_logging_granularity] procedures.
@ -68,7 +68,7 @@ let analyze_target : (TaskSchedulerTypes.target, string) Tasks.doer =
try
Ondemand.analyze_proc_name_toplevel exe_env proc_name ;
None
with TaskSchedulerTypes.ProcnameAlreadyLocked {dependency_filename} ->
with RestartSchedulerException.ProcnameAlreadyLocked {dependency_filename} ->
Some dependency_filename
in
fun target ->

@ -102,8 +102,8 @@ let lock_exn pname =
else (
unlock_all () ;
raise
(TaskSchedulerTypes.ProcnameAlreadyLocked {dependency_filename= Procname.to_filename pname})
) )
(RestartSchedulerException.ProcnameAlreadyLocked
{dependency_filename= Procname.to_filename pname}) ) )
let unlock pname =

@ -221,7 +221,7 @@ let run_proc_analysis exe_env ~caller_pdesc callee_pdesc =
let backtrace = Printexc.get_backtrace () in
IExn.reraise_if exn ~f:(fun () ->
match exn with
| TaskSchedulerTypes.ProcnameAlreadyLocked _ ->
| RestartSchedulerException.ProcnameAlreadyLocked _ ->
clear_actives () ;
restore_global_state old_state ;
true

@ -0,0 +1,13 @@
(*
* 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
(** for the Restart scheduler: raise when a worker tries to analyze a procedure already being
analyzed by another process *)
exception ProcnameAlreadyLocked of {dependency_filename: string}
let is_not_restart_exception = function ProcnameAlreadyLocked _ -> false | _ -> true

@ -0,0 +1,14 @@
(*
* 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
(** for the Restart scheduler: raise when a worker tries to analyze a procedure already being
analyzed by another process *)
exception ProcnameAlreadyLocked of {dependency_filename: string}
val is_not_restart_exception : exn -> bool
(** check if the exception passed is the one defined above *)

@ -20,7 +20,12 @@ type failure_kind =
(** failure that prevented analysis from finishing *)
exception Analysis_failure_exe of failure_kind
let exn_not_failure = function Analysis_failure_exe _ -> false | _ -> true
let exn_not_failure = function
| Analysis_failure_exe _ | RestartSchedulerException.ProcnameAlreadyLocked _ ->
false
| _ ->
true
let try_finally ~f ~finally =
match f () with
@ -29,14 +34,17 @@ let try_finally ~f ~finally =
r
| exception (Analysis_failure_exe _ as f_exn) ->
IExn.reraise_after f_exn ~f:(fun () ->
try finally () with _ -> (* swallow in favor of the original exception *) () )
| exception f_exn ->
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 thrown from finally *)
match finally_exn with Analysis_failure_exe _ -> false | _ -> true
exn_not_failure finally_exn
->
() )

@ -194,6 +194,10 @@ let print_exception_html s exn =
(** Return true if the exception is not serious and should be handled in timeout mode *)
let handle_exception exn =
match exn with
| RestartSchedulerException.ProcnameAlreadyLocked _ ->
false
| _ ->
let error = recognize_exception exn in
IssueType.equal_visibility error.issue_type.visibility User
|| IssueType.equal_visibility error.issue_type.visibility Developer

Loading…
Cancel
Save