Beispiel #1
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;

}
Beispiel #2
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;
}
Beispiel #3
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;
}
Beispiel #4
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;
}
Beispiel #6
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;
}
Beispiel #7
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;
}
Beispiel #8
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;
}
Beispiel #9
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;
}
Beispiel #10
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;
}
Beispiel #11
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;
}
Beispiel #12
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;
}