From: weiyu Date: Tue, 15 Sep 2020 01:17:04 +0000 (-0700) Subject: Try to catch data races for memcpy X-Git-Url: http://plrg.eecs.uci.edu/git/?p=c11tester.git;a=commitdiff_plain;h=92661595546bc783908d3795fd53265988565e02 Try to catch data races for memcpy --- diff --git a/clockvector.cc b/clockvector.cc index 9820b8f9..ba5d1f4b 100644 --- a/clockvector.cc +++ b/clockvector.cc @@ -24,7 +24,7 @@ ClockVector::ClockVector(ClockVector *parent, const ModelAction *act) clock = (modelclock_t *)snapshot_calloc(num_threads, sizeof(int)); if (parent) - std::memcpy(clock, parent->clock, parent->num_threads * sizeof(modelclock_t)); + real_memcpy(clock, parent->clock, parent->num_threads * sizeof(modelclock_t)); if (act != NULL) clock[id_to_int(act->get_tid())] = act->get_seq_number(); diff --git a/datarace.cc b/datarace.cc index 9c403668..13aa4655 100644 --- a/datarace.cc +++ b/datarace.cc @@ -575,8 +575,8 @@ struct DataRace * fullRaceCheckRead(thread_id_t thread, const void *location, ui int newCapacity = copytoindex * 2; thread_id_t *newthread = (thread_id_t *)snapshot_malloc(sizeof(thread_id_t) * newCapacity); modelclock_t *newreadClock = (modelclock_t *)snapshot_malloc(sizeof(modelclock_t) * newCapacity); - std::memcpy(newthread, record->thread, copytoindex * sizeof(thread_id_t)); - std::memcpy(newreadClock, record->readClock, copytoindex * sizeof(modelclock_t)); + real_memcpy(newthread, record->thread, copytoindex * sizeof(thread_id_t)); + real_memcpy(newreadClock, record->readClock, copytoindex * sizeof(modelclock_t)); snapshot_free(record->readClock); snapshot_free(record->thread); record->readClock = newreadClock; diff --git a/main.cc b/main.cc index b0931f75..36055107 100644 --- a/main.cc +++ b/main.cc @@ -114,7 +114,7 @@ void parse_options(struct model_params *params) { } argc++; //first parameter is executable name char optcpy[index + 1]; - memcpy(optcpy, options, index+1); + real_memcpy(optcpy, options, index+1); char * argv[argc + 1]; argv[0] = NULL; argv[1] = optcpy; diff --git a/model.cc b/model.cc index 4b2143dc..450aac5a 100644 --- a/model.cc +++ b/model.cc @@ -21,6 +21,7 @@ #include "plugins.h" ModelChecker *model = NULL; +int inside_model = 0; void placeholder(void *) { ASSERT(0); @@ -80,6 +81,7 @@ ModelChecker::ModelChecker() : "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"); + init_memory_ops(); memset(&stats,0,sizeof(struct execution_stats)); init_thread = new Thread(execution->get_next_id(), (thrd_t *) model_malloc(sizeof(thrd_t)), &placeholder, NULL, NULL); #ifdef TLS @@ -353,7 +355,7 @@ void ModelChecker::startRunExecution(Thread *old) { Thread *thr = getNextThread(old); if (thr != nullptr) { scheduler->set_current_thread(thr); - + inside_model = 0; if (Thread::swap(old, thr) < 0) { perror("swap threads"); exit(EXIT_FAILURE); @@ -452,6 +454,8 @@ uint64_t ModelChecker::switch_thread(ModelAction *act) delete act; return 0; } + inside_model = 1; + DBG(); Thread *old = thread_current(); old->set_state(THREAD_READY); diff --git a/model.h b/model.h index e35457e1..331ea18a 100644 --- a/model.h +++ b/model.h @@ -104,6 +104,7 @@ private: void print_stats() const; }; +extern int inside_model; extern ModelChecker *model; void parse_options(struct model_params *params); void install_trace_analyses(ModelExecution *execution); diff --git a/mymemory.cc b/mymemory.cc index dd22909c..e82f8d2e 100644 --- a/mymemory.cc +++ b/mymemory.cc @@ -110,3 +110,69 @@ void Thread_free(void *ptr) { snapshot_free(ptr); } + +void * (*volatile real_memcpy)(void * dst, const void *src, size_t n) = NULL; +void * (*volatile real_memmove)(void * dst, const void *src, size_t len) = NULL; +void (*volatile real_bzero)(void * dst, size_t len) = NULL; +void * (*volatile real_memset)(void * dst, int c, size_t len) = NULL; + +void init_memory_ops() +{ + if (!real_memcpy) { + real_memcpy = (void * (*)(void * dst, const void *src, size_t n)) 1; + real_memcpy = (void * (*)(void * dst, const void *src, size_t n))dlsym(RTLD_NEXT, "memcpy"); + } + if (!real_memmove) { + real_memmove = (void * (*)(void * dst, const void *src, size_t n)) 1; + real_memmove = (void * (*)(void * dst, const void *src, size_t n))dlsym(RTLD_NEXT, "memmove"); + } + if (!real_memset) { + real_memset = (void * (*)(void * dst, int c, size_t n)) 1; + real_memset = (void * (*)(void * dst, int c, size_t n))dlsym(RTLD_NEXT, "memset"); + } + if (!real_bzero) { + real_bzero = (void (*)(void * dst, size_t len)) 1; + real_bzero = (void (*)(void * dst, size_t len))dlsym(RTLD_NEXT, "bzero"); + } +} + +void * memcpy(void * dst, const void * src, size_t n) { + if (false && model && !inside_model) { + thread_id_t tid = thread_current_id(); + if (((uintptr_t)src&7) == 0 && ((uintptr_t)dst&7) == 0 && (n&7) == 0) { + for (uint i = 0; i < (n>>3); i++) { + raceCheckRead64(tid, (void *)(((char *)src) + i)); + ((volatile uint64_t *)dst)[i] = ((uint64_t *)src)[i]; + raceCheckWrite64(tid, (void *)(((char *)src) + i)); + } + } else if (((uintptr_t)src&3) == 0 && ((uintptr_t)dst&3) == 0 && (n&3) == 0) { + for (uint i = 0; i < (n>>2); i++) { + raceCheckRead32(tid, (void *)(((char *)src) + i)); + ((volatile uint32_t *)dst)[i] = ((uint32_t *)src)[i]; + raceCheckWrite32(tid, (void *)(((char *)src) + i)); + } + } else if (((uintptr_t)src&1) == 0 && ((uintptr_t)dst&1) == 0 && (n&1) == 0) { + for (uint i = 0; i < (n>>1); i++) { + raceCheckRead16(tid, (void *)(((char *)src) + i)); + ((volatile uint16_t *)dst)[i] = ((uint16_t *)src)[i]; + raceCheckWrite16(tid, (void *)(((char *)src) + i)); + } + } else { + for(uint i=0;i