towards fuzzing only
[c11tester.git] / model.cc
1 #include <stdio.h>
2 #include <algorithm>
3 #include <new>
4 #include <stdarg.h>
5 #include <string.h>
6 #include <cstdlib>
7
8 #include "model.h"
9 #include "action.h"
10 #include "nodestack.h"
11 #include "schedule.h"
12 #include "snapshot-interface.h"
13 #include "common.h"
14 #include "datarace.h"
15 #include "threads-model.h"
16 #include "output.h"
17 #include "traceanalysis.h"
18 #include "execution.h"
19 #include "bugmessage.h"
20
21 ModelChecker *model;
22
23 /** @brief Constructor */
24 ModelChecker::ModelChecker(struct model_params params) :
25         /* Initialize default scheduler */
26         params(params),
27         restart_flag(false),
28         exit_flag(false),
29         scheduler(new Scheduler()),
30         node_stack(new NodeStack()),
31         execution(new ModelExecution(this, &this->params, scheduler, node_stack)),      // L: Model thread is created inside
32         execution_number(1),
33         diverge(NULL),
34         earliest_diverge(NULL),
35         trace_analyses(),
36         inspect_plugin(NULL)
37 {
38         memset(&stats,0,sizeof(struct execution_stats));
39 }
40
41 /** @brief Destructor */
42 ModelChecker::~ModelChecker()
43 {
44         delete node_stack;
45         delete scheduler;
46 }
47
48 /**
49  * Restores user program to initial state and resets all model-checker data
50  * structures.
51  */
52 void ModelChecker::reset_to_initial_state()
53 {
54         DEBUG("+++ Resetting to initial state +++\n");
55         node_stack->reset_execution();
56
57         /**
58          * FIXME: if we utilize partial rollback, we will need to free only
59          * those pending actions which were NOT pending before the rollback
60          * point
61          */
62         for (unsigned int i = 0; i < get_num_threads(); i++)
63                 delete get_thread(int_to_id(i))->get_pending();
64
65         snapshot_backtrack_before(0);
66 }
67
68 /** @return the number of user threads created during this execution */
69 unsigned int ModelChecker::get_num_threads() const
70 {
71         return execution->get_num_threads();
72 }
73
74 /**
75  * Must be called from user-thread context (e.g., through the global
76  * thread_current() interface)
77  *
78  * @return The currently executing Thread.
79  */
80 Thread * ModelChecker::get_current_thread() const
81 {
82         return scheduler->get_current_thread();
83 }
84
85 /**
86  * @brief Choose the next thread to execute.
87  *
88  * This function chooses the next thread that should execute. It can enforce
89  * execution replay/backtracking or, if the model-checker has no preference
90  * regarding the next thread (i.e., when exploring a new execution ordering),
91  * we defer to the scheduler.
92  *
93  * @return The next chosen thread to run, if any exist. Or else if the current
94  * execution should terminate, return NULL.
95  */
96 Thread * ModelChecker::get_next_thread()
97 {
98
99         /*
100          * Have we completed exploring the preselected path? Then let the
101          * scheduler decide
102          */
103         return scheduler->select_next_thread(node_stack->get_head());
104 }
105
106 /**
107  * We need to know what the next actions of all threads in the sleep
108  * set will be.  This method computes them and stores the actions at
109  * the corresponding thread object's pending action.
110  */
111 void ModelChecker::execute_sleep_set()
112 {
113         for (unsigned int i = 0; i < get_num_threads(); i++) {
114                 thread_id_t tid = int_to_id(i);
115                 Thread *thr = get_thread(tid);
116                 if (scheduler->is_sleep_set(thr) && thr->get_pending()) {
117                         thr->get_pending()->set_sleep_flag();
118                 }
119         }
120 }
121
122 /**
123  * @brief Assert a bug in the executing program.
124  *
125  * Use this function to assert any sort of bug in the user program. If the
126  * current trace is feasible (actually, a prefix of some feasible execution),
127  * then this execution will be aborted, printing the appropriate message. If
128  * the current trace is not yet feasible, the error message will be stashed and
129  * printed if the execution ever becomes feasible.
130  *
131  * @param msg Descriptive message for the bug (do not include newline char)
132  * @return True if bug is immediately-feasible
133  */
134 bool ModelChecker::assert_bug(const char *msg, ...)
135 {
136         char str[800];
137
138         va_list ap;
139         va_start(ap, msg);
140         vsnprintf(str, sizeof(str), msg, ap);
141         va_end(ap);
142
143         return execution->assert_bug(str);
144 }
145
146 /**
147  * @brief Assert a bug in the executing program, asserted by a user thread
148  * @see ModelChecker::assert_bug
149  * @param msg Descriptive message for the bug (do not include newline char)
150  */
151 void ModelChecker::assert_user_bug(const char *msg)
152 {
153         /* If feasible bug, bail out now */
154         if (assert_bug(msg))
155                 switch_to_master(NULL);
156 }
157
158 /** @brief Print bug report listing for this execution (if any bugs exist) */
159 void ModelChecker::print_bugs() const
160 {
161         SnapVector<bug_message *> *bugs = execution->get_bugs();
162
163         model_print("Bug report: %zu bug%s detected\n",
164                         bugs->size(),
165                         bugs->size() > 1 ? "s" : "");
166         for (unsigned int i = 0; i < bugs->size(); i++)
167                 (*bugs)[i]->print();
168 }
169
170 /**
171  * @brief Record end-of-execution stats
172  *
173  * Must be run when exiting an execution. Records various stats.
174  * @see struct execution_stats
175  */
176 void ModelChecker::record_stats()
177 {
178         stats.num_total++;
179         if (!execution->isfeasibleprefix())
180                 stats.num_infeasible++;
181         else if (execution->have_bug_reports())
182                 stats.num_buggy_executions++;
183         else if (execution->is_complete_execution())
184                 stats.num_complete++;
185         else {
186                 stats.num_redundant++;
187
188                 /**
189                  * @todo We can violate this ASSERT() when fairness/sleep sets
190                  * conflict to cause an execution to terminate, e.g. with:
191                  * Scheduler: [0: disabled][1: disabled][2: sleep][3: current, enabled]
192                  */
193                 //ASSERT(scheduler->all_threads_sleeping());
194         }
195 }
196
197 /** @brief Print execution stats */
198 void ModelChecker::print_stats() const
199 {
200         model_print("Number of complete, bug-free executions: %d\n", stats.num_complete);
201         model_print("Number of redundant executions: %d\n", stats.num_redundant);
202         model_print("Number of buggy executions: %d\n", stats.num_buggy_executions);
203         model_print("Number of infeasible executions: %d\n", stats.num_infeasible);
204         model_print("Total executions: %d\n", stats.num_total);
205         if (params.verbose)
206                 model_print("Total nodes created: %d\n", node_stack->get_total_nodes());
207 }
208
209 /**
210  * @brief End-of-exeuction print
211  * @param printbugs Should any existing bugs be printed?
212  */
213 void ModelChecker::print_execution(bool printbugs) const
214 {
215         model_print("Program output from execution %d:\n",
216                         get_execution_number());
217         print_program_output();
218
219         if (params.verbose >= 3) {
220                 model_print("\nEarliest divergence point since last feasible execution:\n");
221                 if (earliest_diverge)
222                         earliest_diverge->print();
223                 else
224                         model_print("(Not set)\n");
225
226                 model_print("\n");
227                 print_stats();
228         }
229
230         /* Don't print invalid bugs */
231         if (printbugs && execution->have_bug_reports()) {
232                 model_print("\n");
233                 print_bugs();
234         }
235
236         model_print("\n");
237         execution->print_summary();
238 }
239
240 /**
241  * Queries the model-checker for more executions to explore and, if one
242  * exists, resets the model-checker state to execute a new execution.
243  *
244  * @return If there are more executions to explore, return true. Otherwise,
245  * return false.
246  */
247 bool ModelChecker::next_execution()
248 {
249         DBG();
250         /* Is this execution a feasible execution that's worth bug-checking? */
251         bool complete = execution->isfeasibleprefix() &&
252                 (execution->is_complete_execution() ||
253                  execution->have_bug_reports());
254
255         /* End-of-execution bug checks */
256         if (complete) {
257                 if (execution->is_deadlocked())
258                         assert_bug("Deadlock detected");
259
260                 checkDataRaces();
261                 run_trace_analyses();
262         } 
263
264         record_stats();
265         /* Output */
266         if ( (complete && params.verbose) || params.verbose>1 || (complete && execution->have_bug_reports()))
267                 print_execution(complete);
268         else
269                 clear_program_output();
270
271         if (restart_flag) {
272                 do_restart();
273                 return true;
274         }
275 // test code
276         execution_number++;
277         reset_to_initial_state();
278         node_stack->full_reset();
279         diverge = NULL;
280         return false;
281 /* test
282         if (complete)
283                 earliest_diverge = NULL;
284
285         if (exit_flag)
286                 return false;
287
288 //      diverge = execution->get_next_backtrack();
289         if (diverge == NULL) {
290                 execution_number++;
291                 reset_to_initial_state();
292                 model_print("Does not diverge\n");
293                 return false;
294         } 
295
296         if (DBG_ENABLED()) {
297                 model_print("Next execution will diverge at:\n");
298                 diverge->print();
299         }
300
301         execution_number++;
302
303         if (params.maxexecutions != 0 && stats.num_complete >= params.maxexecutions)
304                 return false;
305
306         reset_to_initial_state();
307         return true;
308 */
309
310 }
311
312 /** @brief Run trace analyses on complete trace */
313 void ModelChecker::run_trace_analyses() {
314         for (unsigned int i = 0; i < trace_analyses.size(); i++)
315                 trace_analyses[i]->analyze(execution->get_action_trace());
316 }
317
318 /**
319  * @brief Get a Thread reference by its ID
320  * @param tid The Thread's ID
321  * @return A Thread reference
322  */
323 Thread * ModelChecker::get_thread(thread_id_t tid) const
324 {
325         return execution->get_thread(tid);
326 }
327
328 /**
329  * @brief Get a reference to the Thread in which a ModelAction was executed
330  * @param act The ModelAction
331  * @return A Thread reference
332  */
333 Thread * ModelChecker::get_thread(const ModelAction *act) const
334 {
335         return execution->get_thread(act);
336 }
337
338 /**
339  * Switch from a model-checker context to a user-thread context. This is the
340  * complement of ModelChecker::switch_to_master and must be called from the
341  * model-checker context
342  *
343  * @param thread The user-thread to switch to
344  */
345 void ModelChecker::switch_from_master(Thread *thread)
346 {
347         scheduler->set_current_thread(thread);
348         Thread::swap(&system_context, thread);
349 }
350
351 /**
352  * Switch from a user-context to the "master thread" context (a.k.a. system
353  * context). This switch is made with the intention of exploring a particular
354  * model-checking action (described by a ModelAction object). Must be called
355  * from a user-thread context.
356  *
357  * @param act The current action that will be explored. May be NULL only if
358  * trace is exiting via an assertion (see ModelExecution::set_assert and
359  * ModelExecution::has_asserted).
360  * @return Return the value returned by the current action
361  */
362 uint64_t ModelChecker::switch_to_master(ModelAction *act)
363 {
364         DBG();
365         Thread *old = thread_current();
366         scheduler->set_current_thread(NULL);
367         ASSERT(!old->get_pending());
368 /* W: No plugin
369         if (inspect_plugin != NULL) {
370                 inspect_plugin->inspectModelAction(act); 
371         }*/
372         old->set_pending(act);
373         if (Thread::swap(old, &system_context) < 0) {
374                 perror("swap threads");
375                 exit(EXIT_FAILURE);
376         }
377         return old->get_return_value();
378 }
379
380 /** Wrapper to run the user's main function, with appropriate arguments */
381 void user_main_wrapper(void *)
382 {
383         user_main(model->params.argc, model->params.argv);
384 }
385
386 bool ModelChecker::should_terminate_execution()
387 {
388         /* Infeasible -> don't take any more steps */
389         if (execution->is_infeasible())
390                 return true;
391         else if (execution->isfeasibleprefix() && execution->have_bug_reports()) {
392                 execution->set_assert();
393                 return true;
394         }
395
396         if (execution->too_many_steps())
397                 return true;
398         return false;
399 }
400
401 /** @brief Exit ModelChecker upon returning to the run loop of the
402  *      model checker. */
403 void ModelChecker::exit_model_checker()
404 {
405         exit_flag = true;
406 }
407
408 /** @brief Restart ModelChecker upon returning to the run loop of the
409  *      model checker. */
410 void ModelChecker::restart()
411 {
412         restart_flag = true;
413 }
414
415 void ModelChecker::do_restart()
416 {
417         restart_flag = false;
418         diverge = NULL;
419         earliest_diverge = NULL;
420         reset_to_initial_state();
421         node_stack->full_reset();
422         memset(&stats,0,sizeof(struct execution_stats));
423         execution_number = 1;
424 }
425
426 /** @brief Run ModelChecker for the user program */
427 void ModelChecker::run()
428 {
429         int i = 0;
430         //Need to initial random number generator state to avoid resets on rollback
431         char random_state[256];
432         initstate(423121, random_state, sizeof(random_state));
433         do {
434                 thrd_t user_thread;
435                 Thread *t = new Thread(execution->get_next_id(), &user_thread, &user_main_wrapper, NULL, NULL); // L: user_main_wrapper passes the user program
436                 execution->add_thread(t);
437                 //Need to seed random number generator, otherwise its state gets reset
438                 do {
439                         /*
440                          * Stash next pending action(s) for thread(s). There
441                          * should only need to stash one thread's action--the
442                          * thread which just took a step--plus the first step
443                          * for any newly-created thread
444                          */
445
446                         for (unsigned int i = 0; i < get_num_threads(); i++) {
447                                 thread_id_t tid = int_to_id(i);
448                                 Thread *thr = get_thread(tid);
449                                 if (!thr->is_model_thread() && !thr->is_complete() && !thr->get_pending()) {
450                                         switch_from_master(thr);        // L: context swapped, and action type of thr changed. 
451                                         if (thr->is_waiting_on(thr))
452                                                 assert_bug("Deadlock detected (thread %u)", i);
453                                 }
454                         }
455
456                         /* Don't schedule threads which should be disabled */
457                         for (unsigned int i = 0; i < get_num_threads(); i++) {
458                                 Thread *th = get_thread(int_to_id(i));
459                                 ModelAction *act = th->get_pending();
460                                 if (act && execution->is_enabled(th) && !execution->check_action_enabled(act)) {
461                                         scheduler->sleep(th);
462                                 }
463                         }
464
465                         for (unsigned int i = 1; i < get_num_threads(); i++) {
466                                 Thread *th = get_thread(int_to_id(i));
467                                 ModelAction *act = th->get_pending();
468                                 if (act && execution->is_enabled(th) && (th->get_state() != THREAD_BLOCKED) ){
469                                         if (act->is_write()){
470                                                 std::memory_order order = act->get_mo(); 
471                                                 if (order == std::memory_order_relaxed || \
472                                                         order == std::memory_order_release) {
473                                                         t = th;
474                                                         break;
475                                                 }
476                                         } else if (act->get_type() == THREAD_CREATE || \
477                                                         act->get_type() == PTHREAD_CREATE || \
478                                                         act->get_type() == THREAD_START || \
479                                                         act->get_type() == THREAD_FINISH) {
480                                                 t = th;
481                                                 break;
482                                         }                               
483                                 }
484                         }
485
486                         /* Catch assertions from prior take_step or from
487                          * between-ModelAction bugs (e.g., data races) */
488
489                         if (execution->has_asserted())
490                                 break;
491                         if (!t)                         
492                                 t = get_next_thread();
493                         if (!t || t->is_model_thread())
494                                 break;
495
496                         /* Consume the next action for a Thread */
497                         ModelAction *curr = t->get_pending();
498                         t->set_pending(NULL);
499                         t = execution->take_step(curr);
500                 } while (!should_terminate_execution());
501                 next_execution();
502                 i++;
503                 //restore random number generator state after rollback
504                 setstate(random_state);
505         } while (i<5); // while (has_next);
506
507         model_print("******* Model-checking complete: *******\n");
508         print_stats();
509
510         /* Have the trace analyses dump their output. */
511         for (unsigned int i = 0; i < trace_analyses.size(); i++)
512                 trace_analyses[i]->finish();
513 }