X-Git-Url: http://demsky.eecs.uci.edu/git/?a=blobdiff_plain;f=model.cc;h=58a785923d2826673cfb259962cd306dda3cbed1;hb=533aa98d0e7df1435defd4b0698aedf5300a1ad3;hp=7f38adc37e149403828d993676e366fb70bc653d;hpb=c56ca6ef155dc69125bfc53bf9893016b699a0c2;p=c11tester.git diff --git a/model.cc b/model.cc index 7f38adc3..58a78592 100644 --- a/model.cc +++ b/model.cc @@ -7,7 +7,6 @@ #include "model.h" #include "action.h" -#include "nodestack.h" #include "schedule.h" #include "snapshot-interface.h" #include "common.h" @@ -34,25 +33,27 @@ ModelChecker::ModelChecker() : params(), restart_flag(false), scheduler(new Scheduler()), - node_stack(new NodeStack()), - execution(new ModelExecution(this, scheduler, node_stack)), + execution(new ModelExecution(this, scheduler)), history(new ModelHistory()), execution_number(1), trace_analyses(), inspect_plugin(NULL) { memset(&stats,0,sizeof(struct execution_stats)); - init_thread = new Thread(execution->get_next_id(), (thrd_t *) malloc(sizeof(thrd_t)), &user_main_wrapper, NULL, NULL); // L: user_main_wrapper passes the user program + init_thread = new Thread(execution->get_next_id(), (thrd_t *) model_malloc(sizeof(thrd_t)), &user_main_wrapper, NULL, NULL); +#ifdef TLS + init_thread->setTLS((char *)get_tls_addr()); +#endif execution->add_thread(init_thread); scheduler->set_current_thread(init_thread); execution->setParams(¶ms); param_defaults(¶ms); + initRaceDetector(); } /** @brief Destructor */ ModelChecker::~ModelChecker() { - delete node_stack; delete scheduler; } @@ -114,7 +115,7 @@ Thread * ModelChecker::get_next_thread() * Have we completed exploring the preselected path? Then let the * scheduler decide */ - return scheduler->select_next_thread(node_stack->get_head()); + return scheduler->select_next_thread(); } /** @@ -162,7 +163,7 @@ void ModelChecker::print_bugs() const bugs->size(), bugs->size() > 1 ? "s" : ""); for (unsigned int i = 0;i < bugs->size();i++) - (*bugs)[i]->print(); + (*bugs)[i] -> print(); } /** @@ -173,15 +174,15 @@ void ModelChecker::print_bugs() const */ void ModelChecker::record_stats() { - stats.num_total++; + stats.num_total ++; if (!execution->isfeasibleprefix()) - stats.num_infeasible++; + stats.num_infeasible ++; else if (execution->have_bug_reports()) - stats.num_buggy_executions++; + stats.num_buggy_executions ++; else if (execution->is_complete_execution()) - stats.num_complete++; + stats.num_complete ++; else { - stats.num_redundant++; + stats.num_redundant ++; /** * @todo We can violate this ASSERT() when fairness/sleep sets @@ -246,7 +247,6 @@ bool ModelChecker::next_execution() if (execution->is_deadlocked()) assert_bug("Deadlock detected"); - checkDataRaces(); run_trace_analyses(); } @@ -262,15 +262,16 @@ bool ModelChecker::next_execution() return true; } // test code - execution_number++; + execution_number ++; reset_to_initial_state(); + history->set_new_exec_flag(); return false; } /** @brief Run trace analyses on complete trace */ void ModelChecker::run_trace_analyses() { - for (unsigned int i = 0;i < trace_analyses.size();i++) - trace_analyses[i]->analyze(execution->get_action_trace()); + for (unsigned int i = 0;i < trace_analyses.size();i ++) + trace_analyses[i] -> analyze(execution->get_action_trace()); } /** @@ -319,6 +320,16 @@ void ModelChecker::switch_from_master(Thread *thread) */ uint64_t ModelChecker::switch_to_master(ModelAction *act) { + if (modellock) { + static bool fork_message_printed = false; + + if (!fork_message_printed) { + model_print("Fork handler or dead thread trying to call into model checker...\n"); + fork_message_printed = true; + } + delete act; + return 0; + } DBG(); Thread *old = thread_current(); scheduler->set_current_thread(NULL); @@ -343,6 +354,8 @@ static void runChecker() { void ModelChecker::startChecker() { startExecution(get_system_context(), runChecker); + snapshot_stack_init(); + snapshot_record(0); } bool ModelChecker::should_terminate_execution() @@ -350,9 +363,11 @@ bool ModelChecker::should_terminate_execution() /* Infeasible -> don't take any more steps */ if (execution->is_infeasible()) return true; - else if (execution->isfeasibleprefix() && execution->have_bug_reports()) { + else if (execution->isfeasibleprefix() && execution->have_fatal_bug_reports()) { execution->set_assert(); return true; + } else if (execution->isFinished()) { + return true; } return false; } @@ -373,7 +388,9 @@ void ModelChecker::do_restart() } void ModelChecker::startMainThread() { - init_thread->setContext(); + init_thread->set_state(THREAD_RUNNING); + scheduler->set_current_thread(init_thread); + main_thread_startup(); } /** @brief Run ModelChecker for the user program */ @@ -393,11 +410,10 @@ void ModelChecker::run() * thread which just took a step--plus the first step * for any newly-created thread */ - for (unsigned int i = 0;i < get_num_threads();i++) { thread_id_t tid = int_to_id(i); Thread *thr = get_thread(tid); - if (!thr->is_model_thread() && !thr->is_complete() && !thr->get_pending()) { + if (!thr->is_model_thread() && !thr->is_complete() && (!thr->get_pending())) { switch_from_master(thr); // L: context swapped, and action type of thr changed. if (thr->is_waiting_on(thr)) assert_bug("Deadlock detected (thread %u)", i); @@ -460,4 +476,9 @@ void ModelChecker::run() /* Have the trace analyses dump their output. */ for (unsigned int i = 0;i < trace_analyses.size();i++) trace_analyses[i]->finish(); + + /* unlink tmp file created by last child process */ + char filename[256]; + snprintf_(filename, sizeof(filename), "C11FuzzerTmp%d", getpid()); + unlink(filename); }