X-Git-Url: http://plrg.eecs.uci.edu/git/?a=blobdiff_plain;ds=sidebyside;f=model.cc;h=f1df6ae8bfbbdacd806f56976de6b1c2f2bc8099;hb=3e2ec3ed4b37f4e6aa8e5e0e9e3241890948c3ac;hp=69df0d226023ec9b212e55e5276c2993c2d001cb;hpb=67becf49b3c3cbc967a272dd92936812bd571fd4;p=c11tester.git diff --git a/model.cc b/model.cc index 69df0d22..f1df6ae8 100644 --- a/model.cc +++ b/model.cc @@ -18,14 +18,49 @@ #include "history.h" #include "bugmessage.h" #include "params.h" +#include "plugins.h" ModelChecker *model = NULL; +void placeholder(void *) { + ASSERT(0); +} + +#include + +#define SIGSTACKSIZE 65536 +static void mprot_handle_pf(int sig, siginfo_t *si, void *unused) +{ + model_print("Segmentation fault at %p\n", si->si_addr); + model_print("For debugging, place breakpoint at: %s:%d\n", + __FILE__, __LINE__); + print_trace(); // Trace printing may cause dynamic memory allocation + while(1) + ; +} + +void install_handler() { + stack_t ss; + ss.ss_sp = model_malloc(SIGSTACKSIZE); + ss.ss_size = SIGSTACKSIZE; + ss.ss_flags = 0; + sigaltstack(&ss, NULL); + struct sigaction sa; + sa.sa_flags = SA_SIGINFO | SA_NODEFER | SA_RESTART | SA_ONSTACK; + sigemptyset(&sa.sa_mask); + sa.sa_sigaction = mprot_handle_pf; + + if (sigaction(SIGSEGV, &sa, NULL) == -1) { + perror("sigaction(SIGSEGV)"); + exit(EXIT_FAILURE); + } + +} + /** @brief Constructor */ ModelChecker::ModelChecker() : /* Initialize default scheduler */ params(), - restart_flag(false), scheduler(new Scheduler()), history(new ModelHistory()), execution(new ModelExecution(this, scheduler)), @@ -33,12 +68,12 @@ ModelChecker::ModelChecker() : trace_analyses(), inspect_plugin(NULL) { - printf("C11Tester\n" - "Copyright (c) 2013 and 2019 Regents of the University of California. All rights reserved.\n" - "Distributed under the GPLv2\n" - "Written by Weiyu Luo, Brian Norris, and Brian Demsky\n\n"); + model_print("C11Tester\n" + "Copyright (c) 2013 and 2019 Regents of the University of California. All rights reserved.\n" + "Distributed under the GPLv2\n" + "Written by Weiyu Luo, Brian Norris, and Brian Demsky\n\n"); memset(&stats,0,sizeof(struct execution_stats)); - init_thread = new Thread(execution->get_next_id(), (thrd_t *) model_malloc(sizeof(thrd_t)), NULL, NULL, NULL); + init_thread = new Thread(execution->get_next_id(), (thrd_t *) model_malloc(sizeof(thrd_t)), &placeholder, NULL, NULL); #ifdef TLS init_thread->setTLS((char *)get_tls_addr()); #endif @@ -50,8 +85,7 @@ ModelChecker::ModelChecker() : parse_options(¶ms); initRaceDetector(); /* Configure output redirection for the model-checker */ - redirect_output(); - install_trace_analyses(model->get_execution()); + install_handler(); } /** @brief Destructor */ @@ -80,7 +114,7 @@ void ModelChecker::reset_to_initial_state() for (unsigned int i = 0;i < get_num_threads();i++) delete get_thread(int_to_id(i))->get_pending(); - snapshot_backtrack_before(0); + snapshot_roll_back(snapshot); } /** @return the number of user threads created during this execution */ @@ -232,7 +266,7 @@ void ModelChecker::print_execution(bool printbugs) const * @return If there are more executions to explore, return true. Otherwise, * return false. */ -bool ModelChecker::next_execution() +void ModelChecker::finish_execution(bool more_executions) { DBG(); /* Is this execution a feasible execution that's worth bug-checking? */ @@ -254,15 +288,12 @@ bool ModelChecker::next_execution() else clear_program_output(); - if (restart_flag) { - do_restart(); - return true; - } // test code execution_number ++; - reset_to_initial_state(); + if (more_executions) + reset_to_initial_state(); + history->set_new_exec_flag(); - return false; } /** @brief Run trace analyses on complete trace */ @@ -351,8 +382,11 @@ static void runChecker() { void ModelChecker::startChecker() { startExecution(get_system_context(), runChecker); - snapshot_stack_init(); - snapshot_record(0); + snapshot = take_snapshot(); + + install_trace_analyses(get_execution()); + redirect_output(); + initMainThread(); } bool ModelChecker::should_terminate_execution() @@ -366,38 +400,25 @@ bool ModelChecker::should_terminate_execution() return false; } -/** @brief Restart ModelChecker upon returning to the run loop of the - * model checker. */ -void ModelChecker::restart() -{ - restart_flag = true; -} - -void ModelChecker::do_restart() -{ - restart_flag = false; - reset_to_initial_state(); - memset(&stats,0,sizeof(struct execution_stats)); - execution_number = 1; -} - -void ModelChecker::startMainThread() { - init_thread->set_state(THREAD_RUNNING); - scheduler->set_current_thread(init_thread); - main_thread_startup(); -} - /** @brief Run ModelChecker for the user program */ void ModelChecker::run() { //Need to initial random number generator state to avoid resets on rollback char random_state[256]; initstate(423121, random_state, sizeof(random_state)); - + modelclock_t checkfree = params.checkthreshold; for(int exec = 0;exec < params.maxexecutions;exec++) { Thread * t = init_thread; do { + /* Check whether we need to free model actions. */ + + if (params.traceminsize != 0 && + execution->get_curr_seq_num() > checkfree) { + checkfree += params.checkthreshold; + execution->collectActions(); + } + /* * Stash next pending action(s) for thread(s). There * should only need to stash one thread's action--the @@ -465,7 +486,7 @@ void ModelChecker::run() t->set_pending(NULL); t = execution->take_step(curr); } while (!should_terminate_execution()); - next_execution(); + finish_execution((exec+1) < params.maxexecutions); //restore random number generator state after rollback setstate(random_state); }