extern "C" void free(void *ptr) { if (fred_wrappers_initializing) { JASSERT(mem_allocated_for_initializing_wrappers); JASSERT(ptr == wrapper_init_buf); return; } void *return_addr = GET_RETURN_ADDRESS(); if ((!shouldSynchronize(return_addr) && !log_all_allocs) || ptr == NULL || jalib::Filesystem::GetProgramName() == "gdb") { _real_pthread_mutex_lock(&allocation_lock); _real_free(ptr); _real_pthread_mutex_unlock(&allocation_lock); return; } log_entry_t my_entry = create_free_entry(my_clone_id, free_event, ptr); void *retval = NULL; if (SYNC_IS_REPLAY) { waitForTurn(&my_entry, &free_turn_check); _real_pthread_mutex_lock(&allocation_lock); _real_free(ptr); _real_pthread_mutex_unlock(&allocation_lock); WRAPPER_REPLAY_END(free); } else if (SYNC_IS_RECORD) { // Not restart; we should be logging. _real_pthread_mutex_lock(&allocation_lock); _real_free(ptr); WRAPPER_LOG_WRITE_ENTRY(my_entry); _real_pthread_mutex_unlock(&allocation_lock); } }
static void *my_malloc_hook (size_t size, const void *caller) { _real_pthread_mutex_lock(&hook_lock); void *result; /* Restore all old hooks */ __malloc_hook = old_malloc_hook; __realloc_hook = old_realloc_hook; __memalign_hook = old_memalign_hook; __free_hook = old_free_hook; result = _real_malloc (size); /* Save underlying hooks */ old_malloc_hook = __malloc_hook; old_free_hook = __free_hook; if (log_all_allocs && strcmp(progname, "gdb") != 0) { static int tyler_pid = _real_getpid(); printf ("<%d> malloc (%u) returns %p\n", tyler_pid, (unsigned int) size, result); } /*static int tyler_pid = _real_getpid(); void *buffer[10]; int nptrs; // NB: In order to use backtrace, you must disable log_all_allocs. // AND remove the locks around !log_all_allocs real_malloc in malloc wrapper nptrs = backtrace (buffer, 10); backtrace_symbols_fd ( buffer, nptrs, 1); printf ("<%d> malloc (%u) returns %p\n", tyler_pid, (unsigned int) size, result);*/ /* Restore our own hooks */ __malloc_hook = my_malloc_hook; __realloc_hook = my_realloc_hook; __memalign_hook = my_memalign_hook; __free_hook = my_free_hook; _real_pthread_mutex_unlock(&hook_lock); return result; }
extern "C" void *mremap(void *old_address, size_t old_size, size_t new_size, int flags, ...) { va_list ap; va_start( ap, flags ); void *new_address = va_arg ( ap, void * ); va_end ( ap ); MALLOC_FAMILY_WRAPPER_HEADER(mremap, old_address, old_size, new_size, flags, new_address); if (SYNC_IS_REPLAY) { MALLOC_FAMILY_WRAPPER_REPLAY_START(mremap); void *addr = GET_COMMON(my_entry, retval); flags |= (MREMAP_MAYMOVE | MREMAP_FIXED); retval = _real_mremap (old_address, old_size, new_size, flags, addr); JASSERT ( retval == GET_COMMON(my_entry, retval) ); MALLOC_FAMILY_WRAPPER_REPLAY_END(mremap); } else if (SYNC_IS_RECORD) { _real_pthread_mutex_lock(&mmap_lock); retval = _real_mremap (old_address, old_size, new_size, flags, new_address); WRAPPER_LOG_WRITE_ENTRY(my_entry); _real_pthread_mutex_unlock(&mmap_lock); } return retval; }
static void *my_memalign_hook (size_t boundary, size_t size, const void *caller) { _real_pthread_mutex_lock(&hook_lock); void *result; /* Restore all old hooks */ __malloc_hook = old_malloc_hook; __realloc_hook = old_realloc_hook; __memalign_hook = old_memalign_hook; __free_hook = old_free_hook; result = _real_libc_memalign (boundary, size); /* Save underlying hooks */ old_malloc_hook = __malloc_hook; old_free_hook = __free_hook; if (log_all_allocs && strcmp(progname, "gdb") != 0) { static int tyler_pid = _real_getpid(); printf ("<%d> memalign (%u,%u) returns %p\n", tyler_pid, (unsigned int)boundary, (unsigned int) size, result); } __malloc_hook = my_malloc_hook; __realloc_hook = my_realloc_hook; __memalign_hook = my_memalign_hook; __free_hook = my_free_hook; _real_pthread_mutex_unlock(&hook_lock); return result; }
extern "C" int munmap(void *addr, size_t length) { MALLOC_FAMILY_WRAPPER_HEADER_TYPED(int, munmap, addr, length); if (SYNC_IS_REPLAY) { WRAPPER_REPLAY_START(munmap); _real_pthread_mutex_lock(&allocation_lock); retval = _real_munmap (addr, length); JASSERT (retval == (int)(unsigned long)GET_COMMON(my_entry, retval)); _real_pthread_mutex_unlock(&allocation_lock); WRAPPER_REPLAY_END(munmap); } else if (SYNC_IS_RECORD) { _real_pthread_mutex_lock(&mmap_lock); retval = _real_munmap (addr, length); WRAPPER_LOG_WRITE_ENTRY(my_entry); _real_pthread_mutex_unlock(&mmap_lock); } return retval; }
extern "C" int pthread_mutex_lock(pthread_mutex_t *mutex) { WRAPPER_HEADER(int, pthread_mutex_lock, _real_pthread_mutex_lock, mutex); /* NOTE: Don't call JTRACE (or anything that calls JTRACE) before this point. */ if (SYNC_IS_REPLAY) { WRAPPER_REPLAY(pthread_mutex_lock); } else if (SYNC_IS_RECORD) { retval = _real_pthread_mutex_lock(mutex); WRAPPER_LOG_WRITE_ENTRY(pthread_mutex_lock); } return retval; }
static void my_init_hooks(void) { strncpy(progname, jalib::Filesystem::GetProgramName().c_str(), 200); /* Save old hook functions (from libc) and set them to our own hooks. */ _real_pthread_mutex_lock(&hook_lock); if (!initHook) { old_malloc_hook = __malloc_hook; old_realloc_hook = __realloc_hook; old_memalign_hook = __memalign_hook; old_free_hook = __free_hook; __malloc_hook = my_malloc_hook; __realloc_hook = my_realloc_hook; __memalign_hook = my_memalign_hook; __free_hook = my_free_hook; initHook = 1; } _real_pthread_mutex_unlock(&hook_lock); }
/* mmap/mmap64 * TODO: Remove the PROT_WRITE flag on REPLAY phase if it was not part of * original flags. * FIXME: MAP_SHARED areas are restored as MAP_PRIVATE, check for correctness. */ extern "C" void *mmap(void *addr, size_t length, int prot, int flags, int fd, off_t offset) { SET_IN_MMAP_WRAPPER(); MMAP_WRAPPER_HEADER(mmap, addr, length, prot, flags, fd, offset); if (SYNC_IS_REPLAY) { bool mmap_read_from_readlog = false; MMAP_WRAPPER_REPLAY_START(mmap); //JWARNING ( addr == NULL ).Text("Unimplemented to have non-null addr."); addr = GET_COMMON(my_entry, retval); if (retval != MAP_FAILED && fd != -1 && ((flags & MAP_PRIVATE) != 0 || (flags & MAP_SHARED) != 0)) { flags &= ~MAP_SHARED; flags |= MAP_PRIVATE; flags |= MAP_ANONYMOUS; fd = -1; offset = 0; size_t page_size = sysconf(_SC_PAGESIZE); size_t page_mask = ~(page_size - 1); length = (length + page_size - 1) & page_mask ; mmap_read_from_readlog = true; } flags |= MAP_FIXED; retval = _real_mmap (addr, length, prot | PROT_WRITE, flags, fd, offset); if (retval != GET_COMMON(my_entry, retval)) sleep(20); JASSERT ( retval == GET_COMMON(my_entry, retval) ) (retval) (GET_COMMON(my_entry, retval)) (JASSERT_ERRNO); if (mmap_read_from_readlog) { WRAPPER_REPLAY_READ_FROM_READ_LOG(mmap, retval, length); } MMAP_WRAPPER_REPLAY_END(mmap); } else if (SYNC_IS_RECORD) { _real_pthread_mutex_lock(&mmap_lock); retval = _real_mmap (addr, length, prot, flags, fd, offset); if (retval != MAP_FAILED && fd != -1 && ((flags & MAP_PRIVATE) != 0 || (flags & MAP_SHARED) != 0)) { WRAPPER_LOG_WRITE_INTO_READ_LOG(mmap, retval, length); } WRAPPER_LOG_WRITE_ENTRY(my_entry); _real_pthread_mutex_unlock(&mmap_lock); } UNSET_IN_MMAP_WRAPPER(); return retval; }
extern "C" void *mremap(void *old_address, size_t old_size, size_t new_size, int flags) { MALLOC_FAMILY_WRAPPER_HEADER(mremap, old_address, old_size, new_size, flags, NULL); if (SYNC_IS_REPLAY) { MALLOC_FAMILY_WRAPPER_REPLAY_START(mremap); void *addr = GET_COMMON(my_entry, retval); flags |= MREMAP_MAYMOVE; retval = _real_mremap (old_address, old_size, new_size, flags, addr); JASSERT ( retval == GET_COMMON(my_entry, retval) ); MALLOC_FAMILY_WRAPPER_REPLAY_END(mremap); } else if (SYNC_IS_RECORD) { _real_pthread_mutex_lock(&mmap_lock); retval = _real_mremap (old_address, old_size, new_size, flags, 0); WRAPPER_LOG_WRITE_ENTRY(my_entry); _real_pthread_mutex_unlock(&mmap_lock); } return retval; }
static void my_free_hook (void *ptr, const void *caller) { _real_pthread_mutex_lock(&hook_lock); /* Restore all old hooks */ __malloc_hook = old_malloc_hook; __realloc_hook = old_realloc_hook; __memalign_hook = old_memalign_hook; __free_hook = old_free_hook; _real_free (ptr); /* Save underlying hooks */ old_malloc_hook = __malloc_hook; old_free_hook = __free_hook; /* printf might call free, so protect it too. */ if (log_all_allocs) { static int tyler_pid = _real_getpid(); printf ("<%d> freed pointer %p\n", tyler_pid, ptr); } /* Restore our own hooks */ __malloc_hook = my_malloc_hook; __realloc_hook = my_realloc_hook; __memalign_hook = my_memalign_hook; __free_hook = my_free_hook; _real_pthread_mutex_unlock(&hook_lock); }
static void _do_lock_tbl() { JASSERT(_real_pthread_mutex_lock(&tblLock) == 0) (JASSERT_ERRNO); }
extern "C" int pthread_mutex_lock(pthread_mutex_t *mutex) { return _real_pthread_mutex_lock(mutex); }
// FIXME: Are these primitives (_dmtcp_lock, _dmtcp_unlock) required anymore? void _dmtcp_lock() { _real_pthread_mutex_lock (&theMutex); }