Exemple #1
0
extern "C" int getpwuid_r(uid_t uid, struct passwd *pwd,
                          char *buf, size_t buflen, struct passwd **result)
{
  WRAPPER_HEADER(int, getpwuid_r, _real_getpwuid_r, uid, pwd, buf, buflen, result);
  if (SYNC_IS_REPLAY) {
    WRAPPER_REPLAY_START(getpwuid_r);
    if (retval == 0 &&
        GET_FIELD(my_entry, getpwuid_r, ret_result) != NULL) {
      *pwd = GET_FIELD(my_entry, getpwuid_r, ret_pwd);
      WRAPPER_REPLAY_READ_FROM_READ_LOG(getpwuid_r, buf, buflen);
    }
    *result = GET_FIELD(my_entry, getpwuid_r, ret_result);
    WRAPPER_REPLAY_END(getpwuid_r);
  } else if (SYNC_IS_RECORD) {
    isOptionalEvent = true;
    retval = _real_getpwuid_r(uid, pwd, buf, buflen, result);
    isOptionalEvent = false;
    if (retval == 0 && result != NULL) {
      SET_FIELD2(my_entry, getpwuid_r, ret_pwd, *pwd);
      WRAPPER_LOG_WRITE_INTO_READ_LOG(getpwuid_r, buf, buflen);
    }
    SET_FIELD2(my_entry, getpwuid_r, ret_result, *result);
    WRAPPER_LOG_WRITE_ENTRY(my_entry);
  }
  return retval;
}
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);
  }
}
Exemple #3
0
extern "C" char *getcwd(char *buf, size_t size)
{
  WRAPPER_HEADER(char *, getcwd, _real_getcwd, buf, size);
  if (SYNC_IS_REPLAY) {
    WRAPPER_REPLAY_START_TYPED(char*, getcwd);
    if (retval != NULL) {
      /* retval will be a pointer to whatever buffer was used. If the
         user provided a NULL buffer, _real_getcwd allocated one on
         RECORD, but the optional event handler allocated it on REPLAY
         before we arrive here. Memory accurate replay allows us to
         depend on 'retval' pointing to the allocated buffer by the
         optional event handler. If the user provided a buffer, retval
         points to it. */
      WRAPPER_REPLAY_READ_FROM_READ_LOG(getcwd, retval, size);
    }
    WRAPPER_REPLAY_END(getcwd);
  } else if (SYNC_IS_RECORD) {
    dmtcp::ThreadInfo::setOptionalEvent();
    retval = _real_getcwd(buf, size);
    dmtcp::ThreadInfo::unsetOptionalEvent();
    if (retval != NULL) {
      /* retval will be a pointer to whatever buffer was used. If the
         user provided a NULL buffer, _real_getcwd will allocate one
         and retval points to it. If the user provided a buffer,
         retval points to it. */
      JASSERT(size > 0).Text("Unimplemented.");
      WRAPPER_LOG_WRITE_INTO_READ_LOG(getcwd, retval, size);
    }
    WRAPPER_LOG_WRITE_ENTRY(getcwd);
  }
  return retval;
}
Exemple #4
0
extern "C" int getnameinfo(const struct sockaddr *sa, socklen_t salen,
                           char *host, socklen_t hostlen,
                           char *serv, socklen_t servlen, unsigned int flags)
{
  WRAPPER_HEADER(int, getnameinfo, _real_getnameinfo, sa, salen, host, hostlen,
                 serv, servlen, flags);
  if (SYNC_IS_REPLAY) {
    WRAPPER_REPLAY_START(getnameinfo);
    if (retval == 0 && host != NULL) {
      strncpy(host, GET_FIELD(my_entry, getnameinfo, ret_host), hostlen);
    }
    if (retval == 0 && host != NULL) {
      strncpy(serv, GET_FIELD(my_entry, getnameinfo, ret_serv), servlen);
    }
    WRAPPER_REPLAY_END(getnameinfo);
  } else if (SYNC_IS_RECORD) {
    isOptionalEvent = true;
    retval = _real_getnameinfo(sa, salen, host, hostlen, serv, servlen, flags);
    isOptionalEvent = false;

    if (retval == 0 && host != NULL) {
      strncpy(GET_FIELD(my_entry, getnameinfo, ret_host), host, hostlen);
    }
    if (retval == 0 && host != NULL) {
      strncpy(GET_FIELD(my_entry, getnameinfo, ret_serv), serv, servlen);
    }

    WRAPPER_LOG_WRITE_ENTRY(my_entry);
  }
  return retval;

}
Exemple #5
0
extern "C" int getgrgid_r(gid_t gid, struct group *grp,
                          char *buf, size_t buflen, struct group **result)
{
  WRAPPER_HEADER(int, getgrgid_r, _real_getgrgid_r, gid, grp, buf, buflen, result);
  if (SYNC_IS_REPLAY) {
    WRAPPER_REPLAY_START(getgrgid_r);
    if (retval == 0 &&
        GET_FIELD(my_entry, getgrgid_r, ret_result) != NULL) {
      *grp = GET_FIELD(my_entry, getgrgid_r, ret_grp);
      WRAPPER_REPLAY_READ_FROM_READ_LOG(getgrgid_r, buf, buflen);
    }
    *result = GET_FIELD(my_entry, getgrgid_r, ret_result);
    WRAPPER_REPLAY_END(getgrgid_r);
  } else if (SYNC_IS_RECORD) {
    isOptionalEvent = true;
    retval = _real_getgrgid_r(gid, grp, buf, buflen, result);
    isOptionalEvent = false;
    if (retval == 0 && result != NULL) {
      SET_FIELD2(my_entry, getgrgid_r, ret_grp, *grp);
      WRAPPER_LOG_WRITE_INTO_READ_LOG(getgrgid_r, buf, buflen);
    }
    SET_FIELD2(my_entry, getgrgid_r, ret_result, *result);
    WRAPPER_LOG_WRITE_ENTRY(my_entry);
  }
  return retval;
}
Exemple #6
0
extern "C" int pthread_join (pthread_t thread, void **value_ptr)
{
  /* Reap Existing Threads */
  //dmtcp::ThreadInfo::reapThreads();

  /* We change things up a bit here. Since we don't allow the user's
     pthread_join() to have an effect, we don't call the mtcp
     "delete_thread_on_pthread_join()" function here unless we decide not to
     synchronize this call to pthread_join().

     We DO need to call it from the thread reaper reapThread(), however, which
     is in pthreadwrappers.cpp. */
  //if (!dmtcp::ThreadInfo::isUserJoinable(thread)) {
    //return EINVAL;
  //}
  void *return_addr = GET_RETURN_ADDRESS();
  if (!shouldSynchronize(return_addr)) {
    int retval = _real_pthread_join(thread, value_ptr);
    if (retval == 0) {
      dmtcp::ThreadInfo::reapThread(thread);
    }
    return retval;
  }

  int retval = 0;
  log_entry_t my_entry = create_pthread_join_entry(my_clone_id,
      pthread_join_event, thread, value_ptr);
  if (SYNC_IS_REPLAY) {
    WRAPPER_REPLAY_START(pthread_join);
    int saved_retval = (long) RETVAL(my_entry, pthread_join);
    WRAPPER_REPLAY_END(pthread_join);
    retval = _real_pthread_join(thread, value_ptr);
    JASSERT(retval == saved_retval);
    if (value_ptr != NULL) {
      JASSERT(*value_ptr == GET_FIELD(my_entry, pthread_join, ret_value_ptr));
    }
  } else if (SYNC_IS_RECORD) {
    WRAPPER_LOG_RESERVE_SLOT(pthread_join);
    retval = _real_pthread_join(thread, value_ptr);
    if (value_ptr != NULL) {
      SET_FIELD2(my_entry, pthread_join, ret_value_ptr, *value_ptr);
    }
    WRAPPER_LOG_UPDATE_ENTRY(pthread_join);
  }
  return retval;
}
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;
}
Exemple #8
0
extern "C" int clock_gettime(clockid_t clk_id, struct timespec *tp)
{
  WRAPPER_HEADER(int, clock_gettime, _real_clock_gettime, clk_id, tp);
  if (SYNC_IS_REPLAY) {
    WRAPPER_REPLAY_START(clock_gettime);
    if (retval == 0 && tp != NULL) {
      *tp = GET_FIELD(my_entry, clock_gettime, ret_tp);
    }
    WRAPPER_REPLAY_END(clock_gettime);
  } else if (SYNC_IS_RECORD) {
    retval = _real_clock_gettime(clk_id, tp);
    if (retval == 0 && tp != NULL) {
      SET_FIELD2(my_entry, clock_gettime, ret_tp, *tp);
    }
    WRAPPER_LOG_WRITE_ENTRY(clock_gettime);
  }
  return retval;
}
Exemple #9
0
extern "C" int clock_getres(clockid_t clk_id, struct timespec *res)
{
  WRAPPER_HEADER(int, clock_getres, _real_clock_getres, clk_id, res);
  if (SYNC_IS_REPLAY) {
    WRAPPER_REPLAY_START(clock_getres);
    if (retval == 0 && res != NULL) {
      *res = GET_FIELD(my_entry, clock_getres, ret_res);
    }
    WRAPPER_REPLAY_END(clock_getres);
  } else if (SYNC_IS_RECORD) {
    retval = _real_clock_getres(clk_id, res);
    if (retval == 0 && res != NULL) {
      SET_FIELD2(my_entry, clock_getres, ret_res, *res);
    }
    WRAPPER_LOG_WRITE_ENTRY(clock_getres);
  }
  return retval;
}
Exemple #10
0
extern "C" time_t time(time_t *tloc)
{
  WRAPPER_HEADER(time_t, time, _real_time, tloc);
  if (SYNC_IS_REPLAY) {
    WRAPPER_REPLAY_START(time);
    if (retval != (time_t) -1 && tloc != NULL) {
      *tloc = GET_FIELD(my_entry, time, ret_tloc);
    }
    WRAPPER_REPLAY_END(time);
  } else if (SYNC_IS_RECORD) {
    retval = _real_time(tloc);
    if (tloc != NULL) {
      SET_FIELD2(my_entry, time, ret_tloc, *tloc);
    }
    WRAPPER_LOG_WRITE_ENTRY(time);
  }
  return retval;
}
Exemple #11
0
extern "C" FILE *fdopen(int fd, const char *mode)
{
  WRAPPER_HEADER(FILE*, fdopen, _real_fdopen, fd, mode);
  if (SYNC_IS_REPLAY) {
    WRAPPER_REPLAY_START_TYPED(FILE*, fdopen);
    if (retval != NULL) {
      *retval = GET_FIELD(my_entry, fdopen, fdopen_retval);
    }
    WRAPPER_REPLAY_END(fdopen);
  } else if (SYNC_IS_RECORD) {
    dmtcp::ThreadInfo::setOptionalEvent();
    retval = _real_fdopen(fd, mode);
    dmtcp::ThreadInfo::unsetOptionalEvent();
    if (retval != NULL) {
      SET_FIELD2(my_entry, fdopen, fdopen_retval, *retval);
    }
    WRAPPER_LOG_WRITE_ENTRY(fdopen);
  }
  return retval;
}
Exemple #12
0
extern "C" struct tm *localtime_r(const time_t *timep, struct tm *result)
{
  WRAPPER_HEADER(struct tm *, localtime_r, _real_localtime_r, timep, result);
  if (SYNC_IS_REPLAY) {
    WRAPPER_REPLAY_START_TYPED(struct tm *, localtime_r);
    if (retval != NULL) {
      *retval = GET_FIELD(my_entry, localtime_r, ret_result);
      if (result != NULL) {
        *result = GET_FIELD(my_entry, localtime_r, ret_result);
      }
    }
    WRAPPER_REPLAY_END(localtime_r);
  } else if (SYNC_IS_RECORD) {
    dmtcp::ThreadInfo::setOptionalEvent();
    retval = _real_localtime_r(timep, result);
    dmtcp::ThreadInfo::unsetOptionalEvent();
    if (retval != NULL) {
      SET_FIELD2(my_entry, localtime_r, ret_result, *retval);
    }
    WRAPPER_LOG_WRITE_ENTRY(localtime_r);
  }
  return retval;
}
Exemple #13
0
extern "C" int getpeername(int sockfd, struct sockaddr *addr,
                           socklen_t *addrlen)
{
  WRAPPER_EXECUTION_DISABLE_CKPT();
  WRAPPER_HEADER_CKPT_DISABLED(int, getpeername, _real_getpeername,
                               sockfd, addr, addrlen);
  if (SYNC_IS_REPLAY) {
    WRAPPER_REPLAY_START(getpeername);
    if (retval != -1) {
      *addr = GET_FIELD(my_entry, getpeername, ret_addr);
      *addrlen = GET_FIELD(my_entry, getpeername, ret_addrlen);
    }
    WRAPPER_REPLAY_END(getpeername);
  } else if (SYNC_IS_RECORD) {
    retval = _real_getpeername(sockfd, addr, addrlen);
    if (retval != -1) {
      SET_FIELD2(my_entry, getpeername, ret_addr, *addr);
      SET_FIELD2(my_entry, getpeername, ret_addrlen, *addrlen);
    }
    WRAPPER_LOG_WRITE_ENTRY(my_entry);
  }
  WRAPPER_EXECUTION_ENABLE_CKPT();
  return retval;
}
Exemple #14
0
extern "C" int gettimeofday(struct timeval *tv, struct timezone *tz)
{
  WRAPPER_HEADER(int, gettimeofday, _real_gettimeofday, tv, tz);
  if (SYNC_IS_REPLAY) {
    WRAPPER_REPLAY_START(gettimeofday);
    if (retval == 0 && tv != NULL) {
      *tv = GET_FIELD(my_entry, gettimeofday, ret_tv);
    }
    if (retval == 0 && tz != NULL) {
      *tz = GET_FIELD(my_entry, gettimeofday, ret_tz);
    }
    WRAPPER_REPLAY_END(gettimeofday);
  } else if (SYNC_IS_RECORD) {
    retval = _real_gettimeofday(tv, tz);
    if (retval == 0 && tv != NULL) {
      SET_FIELD2(my_entry, gettimeofday, ret_tv, *tv);
    }
    if (retval == 0 && tz != NULL) {
      SET_FIELD2(my_entry, gettimeofday, ret_tz, *tz);
    }
    WRAPPER_LOG_WRITE_ENTRY(gettimeofday);
  }
  return retval;
}
Exemple #15
0
extern "C" int getaddrinfo(const char *node, const char *service,
                           const struct addrinfo *hints, struct addrinfo **res)
{
  struct addrinfo_extended addrinfo_res[ADDRINFO_MAX_RES];
  struct addrinfo *rp;
  int numResults = 0;

  WRAPPER_HEADER(int, getaddrinfo, _real_getaddrinfo, node, service, hints,
                 res);
  if (SYNC_IS_REPLAY) {
    WRAPPER_REPLAY_START(getaddrinfo);
    if (retval == 0) {
      *res = GET_FIELD(my_entry, getaddrinfo, ret_res);
      numResults = GET_FIELD(my_entry, getaddrinfo, num_res);

      WRAPPER_REPLAY_READ_FROM_READ_LOG(getaddrinfo, (void*) addrinfo_res,
                                        (numResults *
                                         sizeof (struct addrinfo_extended)));
      for (int i = 0; i < numResults; i++) {
        struct addrinfo_extended *ext_info = &addrinfo_res[i];
        struct addrinfo *_addrinfo = &(addrinfo_res[i]._addrinfo);
        struct sockaddr *_sockaddr = &(addrinfo_res[i]._sockaddr);
        memcpy(ext_info->_addrinfo_p, _addrinfo, sizeof(struct addrinfo));
        memcpy(_addrinfo->ai_addr, _sockaddr, _addrinfo->ai_addrlen);
        if (_addrinfo->ai_canonname != NULL) {
          strncpy(_addrinfo->ai_canonname, ext_info->canonname,
                  sizeof(ext_info->canonname));
        }
      }
    }
    WRAPPER_REPLAY_END(getaddrinfo);
  } else if (SYNC_IS_RECORD) {
    isOptionalEvent = true;
    retval = _real_getaddrinfo(node, service, hints, res);
    isOptionalEvent = false;

    if (retval == 0) {
      SET_FIELD2(my_entry, getaddrinfo, ret_res, *res);
      for (rp = *res; rp != NULL; rp = rp->ai_next) {
        JASSERT(numResults < ADDRINFO_MAX_RES);
        struct addrinfo_extended *ext_info = &addrinfo_res[numResults];
        struct addrinfo *_addrinfo = &(addrinfo_res[numResults]._addrinfo);
        struct sockaddr *_sockaddr = &(addrinfo_res[numResults]._sockaddr);
        ext_info->_addrinfo_p = rp;
        memcpy(_addrinfo, rp, sizeof (struct addrinfo));
        memcpy(_sockaddr, rp->ai_addr, rp->ai_addrlen);
        if (rp->ai_canonname != NULL) {
          strncpy(ext_info->canonname, rp->ai_canonname,
                  sizeof(ext_info->canonname));
        }
        numResults++;
      }
      WRAPPER_LOG_WRITE_INTO_READ_LOG(getaddrinfo, (void*) addrinfo_res,
                                      (numResults *
                                       sizeof (struct addrinfo_extended)));
    }
    SET_FIELD2(my_entry, getaddrinfo, num_res, numResults);

    WRAPPER_LOG_WRITE_ENTRY(my_entry);
  }
  return retval;
}
Exemple #16
0
/* Performs the _real version with log and replay. Does NOT check
   shouldSynchronize() and shouldn't be called directly unless you know what
   you're doing. */
static int internal_pthread_create(pthread_t *thread,
    const pthread_attr_t *attr, void *(*start_routine)(void*), void *arg)
{
  int retval = 0, was_detached = 0;
  pthread_attr_t the_attr;
  size_t stack_size;
  void *stack_addr;
  struct create_arg *createArg =
    (struct create_arg*) JALLOC_HELPER_MALLOC(sizeof(*createArg));
  createArg->fn = start_routine;
  createArg->thread_arg = arg;
  if (attr != NULL) {
    pthread_attr_getstack(attr, &createArg->userStack, &stack_size);
    pthread_attr_getdetachstate(attr, &createArg->userDetachState);
  } else {
    createArg->userStack = NULL;
    createArg->userDetachState = PTHREAD_CREATE_JOINABLE;
  }

  log_entry_t my_entry = create_pthread_create_entry(my_clone_id,
                                                     pthread_create_event,
                                                     thread, attr,
                                                     start_routine, arg);
  if (SYNC_IS_REPLAY) {
    WRAPPER_REPLAY_START(pthread_create);
    stack_addr = (void *)GET_FIELD(my_entry, pthread_create, stack_addr);
    stack_size = GET_FIELD(my_entry, pthread_create, stack_size);
    dmtcp::ThreadInfo::prePthreadCreate();
    WRAPPER_REPLAY_END(pthread_create);

    // Register a new thread with ThreadInfo.
    pthread_t newPthreadId = GET_FIELD(my_entry, pthread_create, ret_thread);
    // Set up thread stacks to how they were at record time.
    pthread_attr_init(&the_attr);

    setupThreadStack(&the_attr, attr, stack_size);
    // Never let the user create a detached thread:
    disableDetachState(&the_attr);
    createArg->attr = the_attr;
    retval = _real_pthread_create(thread, &the_attr,
                                  start_wrapper, (void *)createArg);
    pthread_attr_destroy(&the_attr);

  } else if (SYNC_IS_RECORD) {
    WRAPPER_LOG_RESERVE_SLOT(pthread_create);
    dmtcp::ThreadInfo::prePthreadCreate();

    pthread_attr_init(&the_attr);
    // Possibly create a thread stack if the user has not provided one:
    setupThreadStack(&the_attr, attr, 0);
    // Never let the user create a detached thread:
    disableDetachState(&the_attr);

    createArg->attr = the_attr;
    // MTCP may call jalib::malloc to allocate space for thread struct.
    dmtcp::ThreadInfo::setOptionalEvent();
    retval = _real_pthread_create(thread, &the_attr,
                                  start_wrapper, (void *)createArg);
    dmtcp::ThreadInfo::unsetOptionalEvent();
    SET_RETVAL_ERRNO(my_entry, pthread_create, retval, errno);

    // Log whatever stack we ended up using:
    pthread_attr_getstack(&the_attr, &stack_addr, &stack_size);
    pthread_attr_destroy(&the_attr);
    SET_FIELD(my_entry, pthread_create, stack_addr);
    SET_FIELD(my_entry, pthread_create, stack_size);
    SET_FIELD2(my_entry, pthread_create, ret_thread, *thread);

    // Log annotation on the fly.
    WRAPPER_LOG_UPDATE_ENTRY(pthread_create);
  }

  if (retval != 0) {
    dmtcp::ThreadInfo::postPthreadCreate();
  }
  return retval;
}