ESBMC
Efficient SMT-based Context-Bounded Model Checker
Loading...
Searching...
No Matches
reachability_tree.h
Go to the documentation of this file.
1#ifndef REACHABILITY_TREE_H_
2#define REACHABILITY_TREE_H_
3
4#include <deque>
5#include <map>
11
12#include <unordered_map>
13#include <unordered_set>
15#include <util/config/options.h>
16
19inline bool is_esbmc_internal_symbol(const std::string &n)
20{
21 return n == "c:@__ESBMC_alloc" || n == "c:@__ESBMC_alloc_size" ||
22 n == "c:@__ESBMC_is_dynamic" ||
23 n == "c:@__ESBMC_blocked_threads_count" ||
24 n == "c:@__ESBMC_rounding_mode" ||
25 n.find("c:pthread_lib") != std::string::npos;
26}
27
63
65{
66public:
81 const namespacet &ns,
82 optionst &opts,
83 std::shared_ptr<symex_targett> target,
84 contextt &context);
85
89 virtual ~reachability_treet() = default;
90
96
107 const execution_statet &get_cur_state() const;
108
117
122 bool has_more_states();
123
129 int get_CS_bound() const;
130
140
151 bool check_thread_viable(unsigned int tid, bool quiet) const;
152
156
161 bool check_for_hash_collision() const;
162
168
173
181
191 void create_next_state();
192
201 bool step_next_state();
202
211 unsigned int decide_ileave_direction(execution_statet &ex_state);
212
220 void print_ileave_trace() const;
221
227
236 void go_next_state();
237
245
246 // Interface for bmc operation goes here
247
254
262
268 bool setup_next_formula();
269
290
296 {
299 unsigned long peak_threads = 1;
310 unsigned long schedules_explored = 0;
313 unsigned long pruned_by_mpor = 0;
314 unsigned long pruned_by_hash = 0;
320 unsigned long pruned_by_sleep = 0;
323 unsigned long pruned_by_cs_bound = 0;
324
325 bool is_concurrent() const
326 {
327 return peak_threads > 1;
328 }
329 };
331
334 void report_reduction_stats() const;
335
358
359protected:
361 {
362 std::vector<bool> explored_threads;
368 std::map<unsigned int, execution_statet::transition_footprintt> sleeping;
369
370 void ensure_thread_count(unsigned int count);
371 void reset(unsigned int count);
372 void mark_all_explored(unsigned int count);
373 bool is_explored(unsigned int tid) const;
374 void mark_explored(unsigned int tid);
375 bool is_sleeping(unsigned int tid) const;
376 };
377
379 {
380 std::shared_ptr<execution_statet> state;
384 unsigned int entered_via = UINT_MAX;
389 bool exhaustive = true;
390 };
391
394
398
399 bool dfs_explore_thread(unsigned int tid);
400 void erase_current_frame();
401
408 void drain_to_unexplored(bool add_leak_checks);
409
417 std::list<exploration_framet> exploration_frames;
419 std::list<exploration_framet>::iterator cur_frame_it;
421 std::shared_ptr<symex_targett> schedule_target;
425 std::shared_ptr<symex_targett> target_template;
439 unsigned int next_thread_id;
441 bool por;
448 std::unordered_map<std::size_t, int> hit_hashes;
456
457 /* Map to store the expression and thread ID,
458 * which that expression belongs to. */
459 std::unordered_map<expr2tc, std::list<unsigned int>, irep2_hash> vars_map;
460 /* associative container that contains global writes in */
461 std::unordered_set<expr2tc, irep2_hash> is_global;
462
467 std::unordered_set<irep_idt, irep_id_hash> ever_written_globals;
468
474 std::unordered_set<irep_idt, irep_id_hash> address_taken_globals;
475
478 std::unordered_set<irep_idt, irep_id_hash> address_taken_locals;
479
484 bool any_indirect_write = false;
485
488
491 void scan_program_writes();
492
494 void scan_address_taken();
495
496public:
498 static bool has_shared_lifetime(const symbolt &s)
499 {
500 return s.static_lifetime || s.get_type().is_dynamic_set();
501 }
502
503 bool is_address_taken_local(const irep_idt &name) const
504 {
505 return address_taken_locals.count(name) != 0;
506 }
507
509 bool is_shared_storage(const symbolt &s) const
510 {
511 return has_shared_lifetime(s) || address_taken_locals.count(s.id) != 0;
512 }
513
516 bool may_be_written(const irep_idt &name) const
517 {
518 if (!readonly_global_opt || address_taken_locals.count(name) != 0)
519 return true;
520 // A direct, named write somewhere in the program.
521 if (ever_written_globals.count(name) != 0)
522 return true;
523 // A write through an unresolved pointer can only target a global whose
524 // address has escaped; a never-address-taken global stays read-only.
525 return any_indirect_write && address_taken_globals.count(name) != 0;
526 }
527
528protected:
529 friend class execution_statet;
531};
532
533#endif /* REACHABILITY_TREE_H_ */
Definition context.h:57
Definition goto_functions.h:56
Class recording the outcome of symbolic execution.
Definition goto_symex.h:106
Definition irep_idt.h:12
bool is_dynamic_set() const
Definition irep.h:452
Definition namespace.h:10
Definition options.h:11
optionst & options
Options that are enabled.
Definition reachability_tree.h:286
void scan_program_writes()
Walk all goto instructions once and collect the names of every global that may be written.
Definition reachability_tree.cpp:255
bool step_next_state()
Force a context switch, and take it.
Definition reachability_tree.cpp:564
reduction_statst reduction_stats
Definition reachability_tree.h:330
bool is_has_complete_formula()
Have we generated a full program trace.
Definition reachability_tree.cpp:625
bool check_for_hash_collision() const
Check whether current ex_state is a state hash collision.
Definition reachability_tree.cpp:489
reachability_treet(goto_functionst &goto_functions, const namespacet &ns, optionst &opts, std::shared_ptr< symex_targett > target, contextt &context)
Default constructor.
Definition reachability_tree.cpp:12
contextt & permanent_context
Context we're operating upon.
Definition reachability_tree.h:273
void wake_dependent_sleepers()
Wake any sleeping thread the transition just taken is dependent on.
Definition reachability_tree.cpp:823
bool smt_during_symex
Are we using the –smt-during-symex method?
Definition reachability_tree.h:455
const namespacet & ns
Namespace we're operating in.
Definition reachability_tree.h:284
std::unordered_set< irep_idt, irep_id_hash > address_taken_locals
Non-static locals whose address is taken anywhere.
Definition reachability_tree.h:478
std::unordered_map< expr2tc, std::list< unsigned int >, irep2_hash > vars_map
Definition reachability_tree.h:459
friend class execution_statet
Definition reachability_tree.h:529
bool schedule
Are we using the –schedule scheduling method?
Definition reachability_tree.h:453
unsigned int next_thread_id
Next thread ID to switch to, decided by analyse_* routines.
Definition reachability_tree.h:439
virtual ~reachability_treet()=default
Default destructor.
void mark_active_thread_explored()
Mark the active thread as already explored in the current scheduler frame.
Definition reachability_tree.cpp:765
void mark_search_truncated()
Record that the subtree below the frame being explored was cut short – by the context bound,...
Definition reachability_tree.cpp:461
void post_hash_collision_cleanup()
Perform various pieces of accounting after a hash collision - primarily, ensuring that no further pat...
Definition reachability_tree.cpp:510
void drain_to_unexplored(bool add_leak_checks)
Drain fully-explored frames from the top of exploration_frames until step_next_state finds an unexplo...
Definition reachability_tree.cpp:654
bool check_thread_viable(unsigned int tid, bool quiet) const
Determine if a thread can be run.
Definition reachability_tree.cpp:730
bool any_indirect_write
Set when the static scan sees a write through a pointer it cannot resolve.
Definition reachability_tree.h:484
std::shared_ptr< symex_targett > schedule_target
"Global" symex target for output from –schedule exploration
Definition reachability_tree.h:421
friend void build_goto_symex_classes()
void remove_hash_collision_entry()
Remove the current state's hash from the seen set.
Definition reachability_tree.cpp:529
goto_symext::symex_resultt get_next_formula()
Run threads to generate new trace.
Definition reachability_tree.cpp:836
bool directed_interleavings
Functions dictate interleavings; perform no exploration.
Definition reachability_tree.h:282
scheduler_framet & get_cur_scheduler_frame()
Definition reachability_tree.cpp:469
std::unordered_set< expr2tc, irep2_hash > is_global
Definition reachability_tree.h:461
int get_ileave_direction_from_user() const
Ask user for context switch to take.
Definition reachability_tree_cin.cpp:5
bool readonly_global_opt
Master switch; wired to –cswitch-skip-readonly-globals.
Definition reachability_tree.h:487
void switch_to_next_execution_state()
Switch into just-generated execution state.
Definition reachability_tree.cpp:630
unsigned int schedule_simplified_claims
Number of trivial claims in current –schedule exploration.
Definition reachability_tree.h:435
goto_functionst & goto_functions
GOTO functions we're operating over.
Definition reachability_tree.h:271
int get_CS_bound() const
Permitted number of context switches to take.
Definition reachability_tree.cpp:484
bool state_hashing
State hashing is enabled.
Definition reachability_tree.h:279
std::unordered_map< std::size_t, int > hit_hashes
State hashes discovered, mapped to the smallest context-switch count at which each was seen.
Definition reachability_tree.h:448
bool may_be_written(const irep_idt &name) const
True if name may be written by some thread somewhere in the program.
Definition reachability_tree.h:516
bool is_address_taken_local(const irep_idt &name) const
Definition reachability_tree.h:503
void print_ileave_trace() const
Prints state of execution_statet stack.
Definition reachability_tree.cpp:717
goto_symext::symex_resultt generate_schedule_formula()
Run threads in –schedule manner.
Definition reachability_tree.cpp:936
bool cs_bound_pruned
–context-bound cut an available switch: the schedule space was truncated rather than exhausted (issue...
Definition reachability_tree.h:289
bool setup_next_formula()
Reset ex_state stack to unexplored state.
Definition reachability_tree.cpp:931
std::shared_ptr< symex_targett > target_template
Target template; from which all targets are cloned.
Definition reachability_tree.h:425
bool is_shared_storage(const symbolt &s) const
Static or heap storage, or a local whose address may reach a thread.
Definition reachability_tree.h:509
int CS_bound
Limit on context switches; -1 for no limit.
Definition reachability_tree.h:427
void go_next_state()
Advance to the next exploration frame, draining if we're at the top.
Definition reachability_tree.cpp:707
void update_hash_collision_set()
Update seen state hashes to contain current state.
Definition reachability_tree.cpp:516
bool por
Whether partial-order-reduction is enabled.
Definition reachability_tree.h:441
unsigned int schedule_bounded_loop_truncations
Loops cut off at the unwinding bound in current –schedule exploration.
Definition reachability_tree.h:437
void erase_current_frame()
Definition reachability_tree.cpp:794
unsigned int schedule_total_claims
Number of claims in current –schedule exploration.
Definition reachability_tree.h:431
execution_statet & get_cur_state()
Return current execution_statet being explored / symex'd.
Definition reachability_tree.cpp:407
bool interactive_ileaves
Flag as to whether we're picking interleaving directions explicitly.
Definition reachability_tree.h:451
int TS_slice
Timeslice limit read from the "time-slice" option; currently unused.
Definition reachability_tree.h:429
unsigned int decide_ileave_direction(execution_statet &ex_state)
Pick a context switch to take.
Definition reachability_tree.cpp:577
std::list< exploration_framet >::iterator cur_frame_it
Iterator recording the exploration frame we're operating on.
Definition reachability_tree.h:419
void report_reduction_stats() const
Log the reduction counters.
Definition reachability_tree.cpp:914
void create_next_state()
Perform context switch operation triggered elsewhere.
Definition reachability_tree.cpp:537
bool has_complete_formula
Flag indicating we've executed all threads to exhaustion.
Definition reachability_tree.h:277
bool dfs_explore_thread(unsigned int tid)
Definition reachability_tree.cpp:774
unsigned int schedule_remaining_claims
Number of remaining claims in current –schedule exploration.
Definition reachability_tree.h:433
std::list< exploration_framet > exploration_frames
Stack of exploration frames representing the current interleaving.
Definition reachability_tree.h:417
std::unordered_set< irep_idt, irep_id_hash > address_taken_globals
Globals whose address is taken anywhere in the program (including the global initialisers in __ESBMC_...
Definition reachability_tree.h:474
bool sleep_sets
Whether sleep sets prune the search (–sleep-sets).
Definition reachability_tree.h:443
static bool has_shared_lifetime(const symbolt &s)
Static or heap storage: shared however it is reached.
Definition reachability_tree.h:498
bool has_more_states()
Are there more execution_statet s to explore.
Definition reachability_tree.cpp:421
void setup_for_new_explore()
Reinitialize for making new exploration of given functions.
Definition reachability_tree.cpp:331
void scan_address_taken()
Fill address_taken_globals and address_taken_locals from every body.
Definition reachability_tree.cpp:317
bool reset_to_unexplored_state()
Walks back to an unexplored context switch.
Definition reachability_tree.cpp:675
std::unordered_set< irep_idt, irep_id_hash > ever_written_globals
Static over-approximation of globals that may be written anywhere in the program.
Definition reachability_tree.h:467
Definition symbol.h:12
bool static_lifetime
Definition symbol.h:24
irep_idt id
Definition symbol.h:15
const typet & get_type() const
Definition symbol.cpp:106
int count
Definition cuda.h:51
#define UINT_MAX
Definition limits.h:32
bool is_esbmc_internal_symbol(const std::string &n)
White-list of ESBMC internal symbol names that must never be treated as race-eligible user globals.
Definition reachability_tree.h:19
Definition irep2.h:1161
Definition reachability_tree.h:379
bool exhaustive
Whether everything below this frame was actually explored.
Definition reachability_tree.h:389
scheduler_framet scheduler
Definition reachability_tree.h:381
unsigned int entered_via
Thread whose switch created this frame; on backtracking it goes into the parent's sleep set.
Definition reachability_tree.h:384
std::shared_ptr< execution_statet > state
Definition reachability_tree.h:380
Why the schedule space shrank.
Definition reachability_tree.h:296
unsigned long pruned_by_hash
Definition reachability_tree.h:314
unsigned long pruned_by_sleep
Switch targets a sleep set removed.
Definition reachability_tree.h:320
unsigned long peak_threads
Largest thread count any explored state reached, main included.
Definition reachability_tree.h:299
bool is_concurrent() const
Definition reachability_tree.h:325
unsigned long pruned_by_mpor
These three prune counters share a unit: context-switch points at which that reduction stopped the se...
Definition reachability_tree.h:313
unsigned long pruned_by_cs_bound
Only counts points where a switch was still available, i.e.
Definition reachability_tree.h:323
unsigned long schedules_explored
Formulas handed to the caller.
Definition reachability_tree.h:310
Definition reachability_tree.h:361
bool is_sleeping(unsigned int tid) const
Definition reachability_tree.cpp:456
void reset(unsigned int count)
Definition reachability_tree.cpp:433
void mark_all_explored(unsigned int count)
Definition reachability_tree.cpp:439
bool is_explored(unsigned int tid) const
Definition reachability_tree.cpp:445
std::vector< bool > explored_threads
Definition reachability_tree.h:362
void mark_explored(unsigned int tid)
Definition reachability_tree.cpp:450
void ensure_thread_count(unsigned int count)
Definition reachability_tree.cpp:426
std::map< unsigned int, execution_statet::transition_footprintt > sleeping
Sleep set (–sleep-sets): threads whose exploration from this node would revisit an equivalent interle...
Definition reachability_tree.h:368