@ -353,16 +353,7 @@ let reset_prop_metrics () =
exception RE_EXE_ERROR
exception RE_EXE_ERROR
let pp_name fmt = F . pp_print_string fmt " interproc "
let pp_name fmt = F . pp_print_string fmt " biabduction "
let do_before_node session node =
AnalysisState . set_node node ;
AnalysisState . set_session session ;
L . reset_delayed_prints () ;
Printer . node_start_session ~ pp_name node ( session :> int )
let do_after_node node = Printer . node_finish_session node
(* * Return the list of normal ids occurring in the instructions *)
(* * Return the list of normal ids occurring in the instructions *)
let instrs_get_normal_vars instrs =
let instrs_get_normal_vars instrs =
@ -395,13 +386,6 @@ let do_symbolic_execution exe_env summary proc_cfg handle_exn tenv
pset
pset
let mark_visited summary node =
if not ! BiabductionConfig . footprint then
let node_id = ( Procdesc . Node . get_id node :> int ) in
let stats = summary . Summary . stats in
Summary . Stats . add_visited stats node_id
let forward_tabulate summary exe_env tenv proc_cfg wl =
let forward_tabulate summary exe_env tenv proc_cfg wl =
let pname = Procdesc . get_proc_name ( ProcCfg . Exceptional . proc_desc proc_cfg ) in
let pname = Procdesc . get_proc_name ( ProcCfg . Exceptional . proc_desc proc_cfg ) in
let handle_exn_node curr_node exn =
let handle_exn_node curr_node exn =
@ -427,7 +411,7 @@ let forward_tabulate summary exe_env tenv proc_cfg wl =
let exe prop path = State . set_path path None ; incr cnt ; f prop path ! cnt ps_size in
let exe prop path = State . set_path path None ; incr cnt ; f prop path ! cnt ps_size in
Paths . PathSet . iter exe pathset
Paths . PathSet . iter exe pathset
in
in
let print_node_preamble curr_node session pathset_todo =
let print_node_preamble curr_node pathset_todo =
let log_string proc_name =
let log_string proc_name =
let phase_string =
let phase_string =
let open BiabductionSummary in
let open BiabductionSummary in
@ -437,8 +421,8 @@ let forward_tabulate summary exe_env tenv proc_cfg wl =
F . sprintf " [%s:%s] %s " phase_string ( Summary . Status . to_string status )
F . sprintf " [%s:%s] %s " phase_string ( Summary . Status . to_string status )
( Procname . to_string proc_name )
( Procname . to_string proc_name )
in
in
L . d_printfln " **** %s Node: %a, Procedure: %a, Session: %d, Todo: %d ****" ( log_string pname )
L . d_printfln " **** %s Node: %a, Procedure: %a, Todo: %d ****" ( log_string pname )
Procdesc . Node . pp curr_node Procname . pp pname session ( Paths . PathSet . size pathset_todo ) ;
Procdesc . Node . pp curr_node Procname . pp pname ( Paths . PathSet . size pathset_todo ) ;
L . d_increase_indent () ;
L . d_increase_indent () ;
Propset . d Prop . prop_emp ( Paths . PathSet . to_propset tenv pathset_todo ) ;
Propset . d Prop . prop_emp ( Paths . PathSet . to_propset tenv pathset_todo ) ;
L . d_strln " .... Instructions: .... " ;
L . d_strln " .... Instructions: .... " ;
@ -464,20 +448,16 @@ let forward_tabulate summary exe_env tenv proc_cfg wl =
L . d_decrease_indent () ;
L . d_decrease_indent () ;
L . d_ln ()
L . d_ln ()
in
in
let do_node curr_node pathset_todo session handle_exn =
let do_node curr_node pathset_todo handle_exn =
check_prop_size pathset_todo ;
check_prop_size pathset_todo ;
print_node_preamble curr_node session pathset_todo ;
print_node_preamble curr_node pathset_todo ;
match Procdesc . Node . get_kind curr_node with
match Procdesc . Node . get_kind curr_node with
| Procdesc . Node . Join_node ->
| Join_node ->
do_symexec_join proc_cfg tenv wl curr_node pathset_todo
do_symexec_join proc_cfg tenv wl curr_node pathset_todo
| Procdesc . Node . Stmt_node _
| Stmt_node _ | Prune_node _ | Exit_node | Skip_node _ | Start_node ->
| Procdesc . Node . Prune_node _
| Procdesc . Node . Exit_node
| Procdesc . Node . Skip_node _
| Procdesc . Node . Start_node ->
exe_iter ( do_prop curr_node handle_exn ) pathset_todo
exe_iter ( do_prop curr_node handle_exn ) pathset_todo
in
in
let do_node_and_handle curr_node session =
let do_node_and_handle curr_node =
let pathset_todo = path_set_checkout_todo wl curr_node in
let pathset_todo = path_set_checkout_todo wl curr_node in
try
try
let handle_exn_called = ref false in
let handle_exn_called = ref false in
@ -485,26 +465,16 @@ let forward_tabulate summary exe_env tenv proc_cfg wl =
handle_exn_called := true ;
handle_exn_called := true ;
handle_exn_node curr_node exn
handle_exn_node curr_node exn
in
in
do_node curr_node pathset_todo session handle_exn ;
do_node curr_node pathset_todo handle_exn
if ! handle_exn_called then Printer . force_delayed_prints () ;
do_after_node curr_node
with exn ->
with exn ->
IExn . reraise_if exn ~ f : ( fun () -> not ( Exceptions . handle_exception exn ) ) ;
IExn . reraise_if exn ~ f : ( fun () -> not ( Exceptions . handle_exception exn ) ) ;
handle_exn_node curr_node exn ;
handle_exn_node curr_node exn ;
Printer . force_delayed_prints () ;
do_after_node curr_node ;
if not ! BiabductionConfig . footprint then raise RE_EXE_ERROR
if not ! BiabductionConfig . footprint then raise RE_EXE_ERROR
in
in
while not ( Worklist . is_empty wl ) do
while not ( Worklist . is_empty wl ) do
let curr_node = Worklist . remove wl in
let curr_node = Worklist . remove wl in
mark_visited summary curr_node ;
AnalysisData . html_debug_new_node_session ~ pp_name curr_node ~ f : ( fun () ->
(* mark nodes visited in fp and re phases *)
do_node_and_handle curr_node )
let session =
summary . Summary . sessions <- summary . Summary . sessions + 1 ;
summary . Summary . sessions
in
do_before_node session curr_node ;
do_node_and_handle curr_node session
done ;
done ;
L . d_strln " .... Work list empty. Stop .... " ;
L . d_strln " .... Work list empty. Stop .... " ;
L . d_ln ()
L . d_ln ()
@ -733,7 +703,8 @@ let execute_filter_prop summary exe_env tenv proc_cfg
let wl = path_set_create_worklist proc_cfg in
let wl = path_set_create_worklist proc_cfg in
let pdesc = ProcCfg . Exceptional . proc_desc proc_cfg in
let pdesc = ProcCfg . Exceptional . proc_desc proc_cfg in
let pname = Procdesc . get_proc_name pdesc in
let pname = Procdesc . get_proc_name pdesc in
do_before_node 0 init_node ;
let init_edgeset =
AnalysisData . html_debug_new_node_session ~ pp_name init_node ~ f : ( fun () ->
L . d_printfln " #### Start: RE-execution for %a #### " Procname . pp pname ;
L . d_printfln " #### Start: RE-execution for %a #### " Procname . pp pname ;
L . d_indent 1 ;
L . d_indent 1 ;
L . d_strln " Precond: " ;
L . d_strln " Precond: " ;
@ -743,15 +714,13 @@ let execute_filter_prop summary exe_env tenv proc_cfg
let init_prop =
let init_prop =
initial_prop_from_pre tenv pdesc ( BiabductionSummary . Jprop . to_prop precondition )
initial_prop_from_pre tenv pdesc ( BiabductionSummary . Jprop . to_prop precondition )
in
in
let init_edgeset =
Paths . PathSet . add_renamed_prop init_prop ( Paths . Path . start init_node ) Paths . PathSet . empty )
Paths . PathSet . add_renamed_prop init_prop ( Paths . Path . start init_node ) Paths . PathSet . empty
in
in
do_after_node init_node ;
try
try
Worklist . add wl init_node ;
Worklist . add wl init_node ;
ignore ( path_set_put_todo wl init_node init_edgeset ) ;
ignore ( path_set_put_todo wl init_node init_edgeset ) ;
forward_tabulate summary exe_env tenv proc_cfg wl ;
forward_tabulate summary exe_env tenv proc_cfg wl ;
do_before_node 0 init_node ;
AnalysisData . html_debug_new_node_session ~ pp_name init_node ~ f : ( fun () ->
L . d_printfln ~ color : Green " #### Finished: RE-execution for %a #### " Procname . pp pname ;
L . d_printfln ~ color : Green " #### Finished: RE-execution for %a #### " Procname . pp pname ;
L . d_increase_indent () ;
L . d_increase_indent () ;
L . d_strln " Precond: " ;
L . d_strln " Precond: " ;
@ -767,21 +736,21 @@ let execute_filter_prop summary exe_env tenv proc_cfg
( plist , visited )
( plist , visited )
in
in
let pre =
let pre =
BiabductionSummary . Jprop . shallow_map ~ f : ( PropUtil . remove_locals_ret tenv pdesc ) precondition
BiabductionSummary . Jprop . shallow_map
~ f : ( PropUtil . remove_locals_ret tenv pdesc )
precondition
in
in
let spec = BiabductionSummary . { pre ; posts ; visited } in
let spec = BiabductionSummary . { pre ; posts ; visited } in
L . d_decrease_indent () ; do_after_node init_node ; Some spec
L . d_decrease_indent () ; Some spec )
with RE_EXE_ERROR ->
with RE_EXE_ERROR ->
do_before_node 0 init_node ;
AnalysisData . html_debug_new_node_session ~ pp_name init_node ~ f : ( fun () ->
Printer . force_delayed_prints () ;
L . d_printfln ~ color : Red " #### [FUNCTION %a] ...ERROR " Procname . pp pname ;
L . d_printfln ~ color : Red " #### [FUNCTION %a] ...ERROR " Procname . pp pname ;
L . d_increase_indent () ;
L . d_increase_indent () ;
L . d_strln " when starting from pre: " ;
L . d_strln " when starting from pre: " ;
Prop . d_prop ( BiabductionSummary . Jprop . to_prop precondition ) ;
Prop . d_prop ( BiabductionSummary . Jprop . to_prop precondition ) ;
L . d_strln " This precondition is filtered out. " ;
L . d_strln " This precondition is filtered out. " ;
L . d_decrease_indent () ;
L . d_decrease_indent () ;
do_after_node init_node ;
None )
None
type exe_phase =
type exe_phase =
@ -1109,25 +1078,27 @@ let perform_transition proc_cfg tenv proc_name summary =
let joined_pres =
let joined_pres =
let allow_leak = ! BiabductionConfig . allow_leak in
let allow_leak = ! BiabductionConfig . allow_leak in
(* apply the start node to f, and do nothing in case of exception *)
(* apply the start node to f, and do nothing in case of exception *)
let apply_start_node f =
let with_start_node_session ~ f =
try f ( ProcCfg . Exceptional . start_node proc_cfg )
match ProcCfg . Exceptional . start_node proc_cfg with
with exn when SymOp . exn_not_failure exn -> ()
| start_node ->
in
AnalysisData . html_debug_new_node_session ~ pp_name start_node ~ f
apply_start_node ( do_before_node 0 ) ;
| exception exn when SymOp . exn_not_failure exn ->
f ()
in
with_start_node_session ~ f : ( fun () ->
try
try
BiabductionConfig . allow_leak := true ;
BiabductionConfig . allow_leak := true ;
let res = collect_preconditions tenv summary in
let res = collect_preconditions tenv summary in
BiabductionConfig . allow_leak := allow_leak ;
BiabductionConfig . allow_leak := allow_leak ;
apply_start_node do_after_node ;
res
res
with exn when SymOp . exn_not_failure exn ->
with exn when SymOp . exn_not_failure exn ->
apply_start_node do_after_node ;
BiabductionConfig . allow_leak := allow_leak ;
BiabductionConfig . allow_leak := allow_leak ;
L . ( debug Analysis Medium ) " Error in collect_preconditions for %a@. " Procname . pp proc_name ;
L . ( debug Analysis Medium )
" Error in collect_preconditions for %a@. " Procname . pp proc_name ;
let error = Exceptions . recognize_exception exn in
let error = Exceptions . recognize_exception exn in
let err_str = " exception raised " ^ error . name . IssueType . unique_id in
let err_str = " exception raised " ^ error . name . IssueType . unique_id in
L . ( debug Analysis Medium ) " Error: %s %a@. " err_str L . pp_ocaml_pos_opt error . ocaml_pos ;
L . ( debug Analysis Medium ) " Error: %s %a@. " err_str L . pp_ocaml_pos_opt error . ocaml_pos ;
[]
[] )
in
in
transition_footprint_re_exe summary tenv joined_pres
transition_footprint_re_exe summary tenv joined_pres
in
in