//===-- FDInterposing.cpp ---------------------------------------*- C++ -*-===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
// This file helps with catching double close calls on unix integer file
// descriptors by interposing functions for all file descriptor create and
// close operations. A stack backtrace for every create and close function is
// maintained, and every create and close operation is logged. When a double
// file descriptor close is encountered, it will be logged.
//
// To enable the interposing in a darwin program, set the DYLD_INSERT_LIBRARIES
// environment variable as follows:
// For sh:
//  DYLD_INSERT_LIBRARIES=/path/to/FDInterposing.dylib /path/to/executable
// For tcsh:
//  (setenv DYLD_INSERT_LIBRARIES=/path/to/FDInterposing.dylib ;
//  /path/to/executable)
//
// Other environment variables that can alter the default actions of this
// interposing shared library include:
//
// "FileDescriptorStackLoggingNoCompact"
//
//      With this environment variable set, all file descriptor create and
//      delete operations will be permanantly maintained in the event map.
//      The default action is to compact the create/delete events by removing
//      any previous file descriptor create events that are matched with a
//      corresponding file descriptor delete event when the next valid file
//      descriptor create event is detected.
//
// "FileDescriptorMinimalLogging"
//
//      By default every file descriptor create and delete operation is logged
//      (to STDOUT by default, see the "FileDescriptorLogFile"). This can be
//      suppressed to only show errors and warnings by setting this environment
//      variable (the value in not important).
//
// "FileDescriptorLogFile=<path>"
//
//      By default logging goes to STDOUT_FILENO, but this can be changed by
//      setting FileDescriptorLogFile. The value is a path to a file that
//      will be opened and used for logging.
//===----------------------------------------------------------------------===//

#include <assert.h>
#include <dirent.h>
#include <errno.h>
#include <execinfo.h>
#include <fcntl.h>
#include <libgen.h>
#include <mach-o/dyld-interposing.h>
#include <mach-o/dyld.h>
#include <map>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <string>
#include <sys/event.h>
#include <sys/mman.h>
#include <sys/socket.h>
#include <sys/time.h>
#include <sys/types.h>
#include <tr1/memory>
#include <unistd.h>
#include <vector>

/// \def DISALLOW_COPY_AND_ASSIGN(TypeName)
///     Macro definition for easily disallowing copy constructor and
///     assignment operators in C++ classes.
#define DISALLOW_COPY_AND_ASSIGN(TypeName)                                     \
  TypeName(const TypeName &);                                                  \
  const TypeName &operator=(const TypeName &)

extern "C" {
int accept$NOCANCEL(int, struct sockaddr *__restrict, socklen_t *__restrict);
int close$NOCANCEL(int);
int open$NOCANCEL(const char *, int, ...);
int __open_extended(const char *, int, uid_t, gid_t, int,
                    struct kauth_filesec *);
}

namespace fd_interposing {

// String class so we can get formatted strings without having to worry
// about the memory storage since it will allocate the memory it needs.
class String {
public:
  String() : m_str(NULL) {}

  String(const char *format, ...) : m_str(NULL) {
    va_list args;
    va_start(args, format);
    vprintf(format, args);
    va_end(args);
  }

  ~String() { reset(); }

  void reset(char *s = NULL) {
    if (m_str)
      ::free(m_str);
    m_str = s;
  }

  const char *c_str() const { return m_str; }

  void printf(const char *format, ...) {
    va_list args;
    va_start(args, format);
    vprintf(format, args);
    va_end(args);
  }
  void vprintf(const char *format, va_list args) {
    reset();
    ::vasprintf(&m_str, format, args);
  }

  void log(int log_fd) {
    if (m_str && log_fd >= 0) {
      const int len = strlen(m_str);
      if (len > 0) {
        write(log_fd, m_str, len);
        const char last_char = m_str[len - 1];
        if (!(last_char == '\n' || last_char == '\r'))
          write(log_fd, "\n", 1);
      }
    }
  }

protected:
  char *m_str;

private:
  DISALLOW_COPY_AND_ASSIGN(String);
};

// Type definitions
typedef std::vector<void *> Frames;
class FDEvent;
typedef std::vector<void *> Frames;
typedef std::tr1::shared_ptr<FDEvent> FDEventSP;
typedef std::tr1::shared_ptr<String> StringSP;

// FDEvent
//
// A class that describes a file desciptor event.
//
// File descriptor events fall into one of two categories: create events
// and delete events.
class FDEvent {
public:
  FDEvent(int fd, int err, const StringSP &string_sp, bool is_create,
          const Frames &frames)
      : m_string_sp(string_sp), m_frames(frames.begin(), frames.end()),
        m_fd(fd), m_err(err), m_is_create(is_create) {}

  ~FDEvent() {}

  bool IsCreateEvent() const { return m_is_create; }

  bool IsDeleteEvent() const { return !m_is_create; }

  Frames &GetFrames() { return m_frames; }

  const Frames &GetFrames() const { return m_frames; }

  int GetFD() const { return m_fd; }

  int GetError() const { return m_err; }

  void Dump(int log_fd) const;

  void SetCreateEvent(FDEventSP &create_event_sp) {
    m_create_event_sp = create_event_sp;
  }

private:
  // A shared pointer to a String that describes this event in
  // detail (all args and return and error values)
  StringSP m_string_sp;
  // The frames for the stack backtrace for this event
  Frames m_frames;
  // If this is a file descriptor delete event, this might contain
  // the correspoding file descriptor create event
  FDEventSP m_create_event_sp;
  // The file descriptor for this event
  int m_fd;
  // The error code (if any) for this event
  int m_err;
  // True if this event is a file descriptor create event, false
  // if it is a file descriptor delete event
  bool m_is_create;
};

// Templatized class that will save errno only if the "value" it is
// constructed with is equal to INVALID. When the class goes out of
// scope, it will restore errno if it was saved.
template <int INVALID> class Errno {
public:
  // Save errno only if we are supposed to
  Errno(int value)
      : m_saved_errno((value == INVALID) ? errno : 0),
        m_restore(value == INVALID) {}

  // Restore errno only if we are supposed to
  ~Errno() {
    if (m_restore)
      errno = m_saved_errno;
  }

  // Accessor for the saved value of errno
  int get_errno() const { return m_saved_errno; }

protected:
  const int m_saved_errno;
  const bool m_restore;
};

typedef Errno<-1> InvalidFDErrno;
typedef Errno<-1> NegativeErrorErrno;
typedef std::vector<FDEventSP> FDEventArray;
typedef std::map<int, FDEventArray> FDEventMap;

// Globals
// Global event map that contains all file descriptor events. As file
// descriptor create and close events come in, they will get filled
// into this map (protected by g_mutex). When a file descriptor close
// event is detected, the open event will be removed and placed into
// the close event so if something tries to double close a file
// descriptor we can show the previous close event and the file
// desctiptor event that created it. When a new file descriptor create
// event comes in, we will remove the previous one for that file
// desctiptor unless the environment variable
// "FileDescriptorStackLoggingNoCompact"
// is set. The file desctiptor history can be accessed using the
// get_fd_history() function.
static FDEventMap g_fd_event_map;
// A mutex to protect access to our data structures in g_fd_event_map
// and also our logging messages
static pthread_mutex_t g_mutex = PTHREAD_MUTEX_INITIALIZER;
// Log all file descriptor create and close events by default. Only log
// warnings and erros if the "FileDescriptorMinimalLogging" environment
// variable is set.
static int g_log_all_calls = 1;
// We compact the file descriptor events by default. Set the environment
// varible "FileDescriptorStackLoggingNoCompact" to keep a full history.
static int g_compact = 1;
// The current process ID
static int g_pid = -1;
static bool g_enabled = true;
// Mutex class that will lock a mutex when it is constructed, and unlock
// it when is goes out of scope
class Locker {
public:
  Locker(pthread_mutex_t *mutex_ptr) : m_mutex_ptr(mutex_ptr) {
    ::pthread_mutex_lock(m_mutex_ptr);
  }

  // This allows clients to test try and acquire the mutex...
  Locker(pthread_mutex_t *mutex_ptr, bool &lock_acquired) : m_mutex_ptr(NULL) {
    lock_acquired = ::pthread_mutex_trylock(mutex_ptr) == 0;
    if (lock_acquired)
      m_mutex_ptr = mutex_ptr;
  }

  ~Locker() {
    if (m_mutex_ptr)
      ::pthread_mutex_unlock(m_mutex_ptr);
  }

protected:
  pthread_mutex_t *m_mutex_ptr;
};

static void log(const char *format, ...) __attribute__((format(printf, 1, 2)));

static void log(int log_fd, const FDEvent *event, const char *format, ...)
    __attribute__((format(printf, 3, 4)));

static void backtrace_log(const char *format, ...)
    __attribute__((format(printf, 1, 2)));

static void backtrace_error(const char *format, ...)
    __attribute__((format(printf, 1, 2)));

static void log_to_fd(int log_fd, const char *format, ...)
    __attribute__((format(printf, 2, 3)));

static inline size_t get_backtrace(Frames &frame_buffer,
                                   size_t frames_to_remove) {
  void *frames[2048];
  int count = ::backtrace(&frames[0], sizeof(frames) / sizeof(void *));
  if (count > frames_to_remove)
    frame_buffer.assign(&frames[frames_to_remove], &frames[count]);
  else
    frame_buffer.assign(&frames[0], &frames[count]);
  while (frame_buffer.back() < (void *)1024)
    frame_buffer.pop_back();
  return frame_buffer.size();
}

static int g_log_fd = STDOUT_FILENO;
static int g_initialized = 0;

const char *get_process_fullpath(bool force = false) {
  static char g_process_fullpath[PATH_MAX] = {0};
  if (force || g_process_fullpath[0] == '\0') {
    // If DST is NULL, then return the number of bytes needed.
    uint32_t len = sizeof(g_process_fullpath);
    if (_NSGetExecutablePath(g_process_fullpath, &len) != 0)
      strncpy(g_process_fullpath, "<error>", sizeof(g_process_fullpath));
  }
  return g_process_fullpath;
}

// Returns the current process ID, or -1 if inserposing not enabled for
// this process
static int get_interposed_pid() {
  if (!g_enabled)
    return -1;

  const pid_t pid = getpid();
  if (g_pid != pid) {
    if (g_pid == -1) {
      g_pid = pid;
      log("Interposing file descriptor create and delete functions for %s "
          "(pid=%i)\n",
          get_process_fullpath(true), pid);
    } else {
      log("pid=%i: disabling interposing file descriptor create and delete "
          "functions for child process %s (pid=%i)\n",
          g_pid, get_process_fullpath(true), pid);
      g_enabled = false;
      return -1;
    }
    // Log when our process changes
  }
  return g_pid;
}

static int get_logging_fd() {
  if (!g_enabled)
    return -1;

  if (!g_initialized) {
    g_initialized = 1;

    const pid_t pid = get_interposed_pid();

    if (g_enabled) {
      // Keep all stack info around for all fd create and delete calls.
      // Otherwise we will remove the fd create call when a corresponding
      // fd delete call is received
      if (getenv("FileDescriptorStackLoggingNoCompact"))
        g_compact = 0;

      if (getenv("FileDescriptorMinimalLogging"))
        g_log_all_calls = 0;

      const char *log_path = getenv("FileDescriptorLogFile");
      if (log_path)
        g_log_fd = ::creat(log_path, 0660);
      else
        g_log_fd = STDOUT_FILENO;

      // Only let this interposing happen on the first time this matches
      // and stop this from happening so any child processes don't also
      // log their file descriptors
      ::unsetenv("DYLD_INSERT_LIBRARIES");
    } else {
      log("pid=%i: logging disabled\n", getpid());
    }
  }
  return g_log_fd;
}

void log_to_fd(int log_fd, const char *format, va_list args) {
  if (format && format[0] && log_fd >= 0) {
    char buffer[PATH_MAX];
    const int count = ::vsnprintf(buffer, sizeof(buffer), format, args);
    if (count > 0)
      write(log_fd, buffer, count);
  }
}

void log_to_fd(int log_fd, const char *format, ...) {
  if (format && format[0]) {
    va_list args;
    va_start(args, format);
    log_to_fd(log_fd, format, args);
    va_end(args);
  }
}

void log(const char *format, va_list args) {
  log_to_fd(get_logging_fd(), format, args);
}

void log(const char *format, ...) {
  if (format && format[0]) {
    va_list args;
    va_start(args, format);
    log(format, args);
    va_end(args);
  }
}

void log(int log_fd, const FDEvent *event, const char *format, ...) {
  if (format && format[0]) {
    va_list args;
    va_start(args, format);
    log_to_fd(log_fd, format, args);
    va_end(args);
  }
  if (event)
    event->Dump(log_fd);
}

void FDEvent::Dump(int log_fd) const {
  if (log_fd >= 0) {
    log_to_fd(log_fd, "%s\n", m_string_sp->c_str());
    if (!m_frames.empty())
      ::backtrace_symbols_fd(m_frames.data(), m_frames.size(), log_fd);

    if (m_create_event_sp) {
      log_to_fd(log_fd, "\nfd=%i was created with this event:\n", m_fd);
      m_create_event_sp->Dump(log_fd);
      log_to_fd(log_fd, "\n");
    }
  }
}

void backtrace_log(const char *format, ...) {
  const int log_fd = get_logging_fd();
  if (log_fd >= 0) {
    if (format && format[0]) {
      va_list args;
      va_start(args, format);
      log(format, args);
      va_end(args);
    }

    Frames frames;
    if (get_backtrace(frames, 2))
      ::backtrace_symbols_fd(frames.data(), frames.size(), log_fd);
  }
}

void backtrace_error(const char *format, ...) {
  const int pid = get_interposed_pid();
  if (pid >= 0) {
    const int log_fd = get_logging_fd();
    if (log_fd >= 0) {
      log("\nerror: %s (pid=%i): ", get_process_fullpath(), pid);

      if (format && format[0]) {
        va_list args;
        va_start(args, format);
        log(format, args);
        va_end(args);
      }

      Frames frames;
      if (get_backtrace(frames, 2))
        ::backtrace_symbols_fd(frames.data(), frames.size(), log_fd);
    }
  }
}

void save_backtrace(int fd, int err, const StringSP &string_sp,
                    bool is_create) {
  Frames frames;
  get_backtrace(frames, 2);

  FDEventSP fd_event_sp(new FDEvent(fd, err, string_sp, is_create, frames));

  FDEventMap::iterator pos = g_fd_event_map.find(fd);

  if (pos != g_fd_event_map.end()) {
    // We have history for this fd...

    FDEventArray &event_array = g_fd_event_map[fd];
    if (fd_event_sp->IsCreateEvent()) {
      // The current fd event is a function that creates
      // a descriptor, check in case last event was
      // a create event.
      if (event_array.back()->IsCreateEvent()) {
        const int log_fd = get_logging_fd();
        // Two fd create functions in a row, we missed
        // a function that closes a fd...
        log(log_fd, fd_event_sp.get(), "\nwarning: unmatched file descriptor "
                                       "create event fd=%i (we missed a file "
                                       "descriptor close event):\n",
            fd);
      } else if (g_compact) {
        // We are compacting so we remove previous create event
        // when we get the correspinding delete event
        event_array.pop_back();
      }
    } else {
      // The current fd event is a function that deletes
      // a descriptor, check in case last event for this
      // fd was a delete event (double close!)
      if (event_array.back()->IsDeleteEvent()) {
        const int log_fd = get_logging_fd();
        // Two fd delete functions in a row, we must
        // have missed some function that opened a descriptor
        log(log_fd, fd_event_sp.get(), "\nwarning: unmatched file descriptor "
                                       "close event for fd=%d (we missed the "
                                       "file descriptor create event):\n",
            fd);
      } else if (g_compact) {
        // Since this is a close event, we want to remember the open event
        // that this close if for...
        fd_event_sp->SetCreateEvent(event_array.back());
        // We are compacting so we remove previous create event
        // when we get the correspinding delete event
        event_array.pop_back();
      }
    }

    event_array.push_back(fd_event_sp);
  } else {
    g_fd_event_map[fd].push_back(fd_event_sp);
  }
}

// socket() interpose function
extern "C" int socket$__interposed__(int domain, int type, int protocol) {
  const int pid = get_interposed_pid();
  if (pid >= 0) {
    Locker locker(&g_mutex);
    const int fd = ::socket(domain, type, protocol);
    InvalidFDErrno fd_errno(fd);
    StringSP description_sp(new String);
    if (fd == -1)
      description_sp->printf("pid=%i: socket (domain = %i, type = %i, protocol "
                             "= %i) => fd=%i  errno = %i",
                             pid, domain, type, protocol, fd,
                             fd_errno.get_errno());
    else
      description_sp->printf(
          "pid=%i: socket (domain = %i, type = %i, protocol = %i) => fd=%i",
          pid, domain, type, protocol, fd);
    if (g_log_all_calls)
      description_sp->log(get_logging_fd());
    if (fd >= 0)
      save_backtrace(fd, fd_errno.get_errno(), description_sp, true);
    return fd;
  } else {
    return ::socket(domain, type, protocol);
  }
}

// socketpair() interpose function
extern "C" int socketpair$__interposed__(int domain, int type, int protocol,
                                         int fds[2]) {
  const int pid = get_interposed_pid();
  if (pid >= 0) {
    Locker locker(&g_mutex);
    fds[0] = -1;
    fds[1] = -1;
    const int err = socketpair(domain, type, protocol, fds);
    NegativeErrorErrno err_errno(err);
    StringSP description_sp(
        new String("pid=%i: socketpair (domain=%i, type=%i, protocol=%i, "
                   "{fd=%i, fd=%i}) -> err=%i",
                   pid, domain, type, protocol, fds[0], fds[1], err));
    if (g_log_all_calls)
      description_sp->log(get_logging_fd());
    if (fds[0] >= 0)
      save_backtrace(fds[0], err_errno.get_errno(), description_sp, true);
    if (fds[1] >= 0)
      save_backtrace(fds[1], err_errno.get_errno(), description_sp, true);
    return err;
  } else {
    return socketpair(domain, type, protocol, fds);
  }
}

// open() interpose function
extern "C" int open$__interposed__(const char *path, int oflag, int mode) {
  const int pid = get_interposed_pid();
  if (pid >= 0) {
    Locker locker(&g_mutex);
    int fd = -2;
    StringSP description_sp(new String);
    if (oflag & O_CREAT) {
      fd = ::open(path, oflag, mode);
      description_sp->printf(
          "pid=%i: open (path = '%s', oflag = %i, mode = %i) -> fd=%i", pid,
          path, oflag, mode, fd);
    } else {
      fd = ::open(path, oflag);
      description_sp->printf("pid=%i: open (path = '%s', oflag = %i) -> fd=%i",
                             pid, path, oflag, fd);
    }

    InvalidFDErrno fd_errno(fd);
    if (g_log_all_calls)
      description_sp->log(get_logging_fd());
    if (fd >= 0)
      save_backtrace(fd, fd_errno.get_errno(), description_sp, true);
    return fd;
  } else {
    return ::open(path, oflag, mode);
  }
}

// open$NOCANCEL() interpose function
extern "C" int open$NOCANCEL$__interposed__(const char *path, int oflag,
                                            int mode) {
  const int pid = get_interposed_pid();
  if (pid >= 0) {
    Locker locker(&g_mutex);
    const int fd = ::open$NOCANCEL(path, oflag, mode);
    InvalidFDErrno fd_errno(fd);
    StringSP description_sp(new String(
        "pid=%i: open$NOCANCEL (path = '%s', oflag = %i, mode = %i) -> fd=%i",
        pid, path, oflag, mode, fd));
    if (g_log_all_calls)
      description_sp->log(get_logging_fd());
    if (fd >= 0)
      save_backtrace(fd, fd_errno.get_errno(), description_sp, true);
    return fd;
  } else {
    return ::open$NOCANCEL(path, oflag, mode);
  }
}

// __open_extended() interpose function
extern "C" int __open_extended$__interposed__(const char *path, int oflag,
                                              uid_t uid, gid_t gid, int mode,
                                              struct kauth_filesec *fsacl) {
  const int pid = get_interposed_pid();
  if (pid >= 0) {
    Locker locker(&g_mutex);
    const int fd = ::__open_extended(path, oflag, uid, gid, mode, fsacl);
    InvalidFDErrno fd_errno(fd);
    StringSP description_sp(
        new String("pid=%i: __open_extended (path='%s', oflag=%i, uid=%i, "
                   "gid=%i, mode=%i, fsacl=%p) -> fd=%i",
                   pid, path, oflag, uid, gid, mode, fsacl, fd));
    if (g_log_all_calls)
      description_sp->log(get_logging_fd());
    if (fd >= 0)
      save_backtrace(fd, fd_errno.get_errno(), description_sp, true);
    return fd;
  } else {
    return ::__open_extended(path, oflag, uid, gid, mode, fsacl);
  }
}

// kqueue() interpose function
extern "C" int kqueue$__interposed__(void) {
  const int pid = get_interposed_pid();
  if (pid >= 0) {
    Locker locker(&g_mutex);
    const int fd = ::kqueue();
    InvalidFDErrno fd_errno(fd);
    StringSP description_sp(new String("pid=%i: kqueue () -> fd=%i", pid, fd));
    if (g_log_all_calls)
      description_sp->log(get_logging_fd());
    if (fd >= 0)
      save_backtrace(fd, fd_errno.get_errno(), description_sp, true);
    return fd;
  } else {
    return ::kqueue();
  }
}

// shm_open() interpose function
extern "C" int shm_open$__interposed__(const char *path, int oflag, int mode) {
  const int pid = get_interposed_pid();
  if (pid >= 0) {
    Locker locker(&g_mutex);
    const int fd = ::shm_open(path, oflag, mode);
    InvalidFDErrno fd_errno(fd);
    StringSP description_sp(new String(
        "pid=%i: shm_open (path = '%s', oflag = %i, mode = %i) -> fd=%i", pid,
        path, oflag, mode, fd));
    if (g_log_all_calls)
      description_sp->log(get_logging_fd());
    if (fd >= 0)
      save_backtrace(fd, fd_errno.get_errno(), description_sp, true);
    return fd;
  } else {
    return ::shm_open(path, oflag, mode);
  }
}

// accept() interpose function
extern "C" int accept$__interposed__(int socket, struct sockaddr *address,
                                     socklen_t *address_len) {
  const int pid = get_interposed_pid();
  if (pid >= 0) {
    Locker locker(&g_mutex);
    const int fd = ::accept(socket, address, address_len);
    InvalidFDErrno fd_errno(fd);
    StringSP description_sp(new String(
        "pid=%i: accept (socket=%i, ...) -> fd=%i", pid, socket, fd));
    if (g_log_all_calls)
      description_sp->log(get_logging_fd());
    if (fd >= 0)
      save_backtrace(fd, fd_errno.get_errno(), description_sp, true);
    return fd;
  } else {
    return ::accept(socket, address, address_len);
  }
}

// accept$NOCANCEL() interpose function
extern "C" int accept$NOCANCEL$__interposed__(int socket,
                                              struct sockaddr *address,
                                              socklen_t *address_len) {
  const int pid = get_interposed_pid();
  if (pid >= 0) {
    Locker locker(&g_mutex);
    const int fd = ::accept$NOCANCEL(socket, address, address_len);
    InvalidFDErrno fd_errno(fd);
    StringSP description_sp(new String(
        "pid=%i: accept$NOCANCEL (socket=%i, ...) -> fd=%i", pid, socket, fd));
    if (g_log_all_calls)
      description_sp->log(get_logging_fd());
    if (fd >= 0)
      save_backtrace(fd, fd_errno.get_errno(), description_sp, true);
    return fd;
  } else {
    return ::accept$NOCANCEL(socket, address, address_len);
  }
}

// dup() interpose function
extern "C" int dup$__interposed__(int fd2) {
  const int pid = get_interposed_pid();
  if (pid >= 0) {
    Locker locker(&g_mutex);
    const int fd = ::dup(fd2);
    InvalidFDErrno fd_errno(fd);
    StringSP description_sp(
        new String("pid=%i: dup (fd2=%i) -> fd=%i", pid, fd2, fd));
    if (g_log_all_calls)
      description_sp->log(get_logging_fd());
    if (fd >= 0)
      save_backtrace(fd, fd_errno.get_errno(), description_sp, true);
    return fd;
  } else {
    return ::dup(fd2);
  }
}

// dup2() interpose function
extern "C" int dup2$__interposed__(int fd1, int fd2) {
  const int pid = get_interposed_pid();
  if (pid >= 0) {
    Locker locker(&g_mutex);
    // If "fd2" is already opened, it will be closed during the
    // dup2 call below, so we need to see if we have fd2 in our
    // open map and treat it as a close(fd2)
    FDEventMap::iterator pos = g_fd_event_map.find(fd2);
    StringSP dup2_close_description_sp(
        new String("pid=%i: dup2 (fd1=%i, fd2=%i) -> will close (fd=%i)", pid,
                   fd1, fd2, fd2));
    if (pos != g_fd_event_map.end() && pos->second.back()->IsCreateEvent())
      save_backtrace(fd2, 0, dup2_close_description_sp, false);

    const int fd = ::dup2(fd1, fd2);
    InvalidFDErrno fd_errno(fd);
    StringSP description_sp(new String("pid=%i: dup2 (fd1=%i, fd2=%i) -> fd=%i",
                                       pid, fd1, fd2, fd));
    if (g_log_all_calls)
      description_sp->log(get_logging_fd());

    if (fd >= 0)
      save_backtrace(fd, fd_errno.get_errno(), description_sp, true);
    return fd;
  } else {
    return ::dup2(fd1, fd2);
  }
}

// close() interpose function
extern "C" int close$__interposed__(int fd) {
  const int pid = get_interposed_pid();
  if (pid >= 0) {
    Locker locker(&g_mutex);
    const int err = close(fd);
    NegativeErrorErrno err_errno(err);
    StringSP description_sp(new String);
    if (err == -1)
      description_sp->printf("pid=%i: close (fd=%i) => %i errno = %i (%s))",
                             pid, fd, err, err_errno.get_errno(),
                             strerror(err_errno.get_errno()));
    else
      description_sp->printf("pid=%i: close (fd=%i) => %i", pid, fd, err);
    if (g_log_all_calls)
      description_sp->log(get_logging_fd());

    if (err == 0) {
      if (fd >= 0)
        save_backtrace(fd, err, description_sp, false);
    } else if (err == -1) {
      if (err_errno.get_errno() == EBADF && fd != -1) {
        backtrace_error("close (fd=%d) resulted in EBADF:\n", fd);

        FDEventMap::iterator pos = g_fd_event_map.find(fd);
        if (pos != g_fd_event_map.end()) {
          log(get_logging_fd(), pos->second.back().get(),
              "\nfd=%d was previously %s with this event:\n", fd,
              pos->second.back()->IsCreateEvent() ? "opened" : "closed");
        }
      }
    }
    return err;
  } else {
    return close(fd);
  }
}

// close$NOCANCEL() interpose function
extern "C" int close$NOCANCEL$__interposed__(int fd) {
  const int pid = get_interposed_pid();
  if (pid >= 0) {
    Locker locker(&g_mutex);
    const int err = close$NOCANCEL(fd);
    NegativeErrorErrno err_errno(err);
    StringSP description_sp(new String);
    if (err == -1)
      description_sp->printf(
          "pid=%i: close$NOCANCEL (fd=%i) => %i errno = %i (%s))", pid, fd, err,
          err_errno.get_errno(), strerror(err_errno.get_errno()));
    else
      description_sp->printf("pid=%i: close$NOCANCEL (fd=%i) => %i", pid, fd,
                             err);
    if (g_log_all_calls)
      description_sp->log(get_logging_fd());

    if (err == 0) {
      if (fd >= 0)
        save_backtrace(fd, err, description_sp, false);
    } else if (err == -1) {
      if (err_errno.get_errno() == EBADF && fd != -1) {
        backtrace_error("close$NOCANCEL (fd=%d) resulted in EBADF\n:", fd);

        FDEventMap::iterator pos = g_fd_event_map.find(fd);
        if (pos != g_fd_event_map.end()) {
          log(get_logging_fd(), pos->second.back().get(),
              "\nfd=%d was previously %s with this event:\n", fd,
              pos->second.back()->IsCreateEvent() ? "opened" : "closed");
        }
      }
    }
    return err;
  } else {
    return close$NOCANCEL(fd);
  }
}

// pipe() interpose function
extern "C" int pipe$__interposed__(int fds[2]) {
  const int pid = get_interposed_pid();
  if (pid >= 0) {
    Locker locker(&g_mutex);
    fds[0] = -1;
    fds[1] = -1;
    const int err = pipe(fds);
    const int saved_errno = errno;
    StringSP description_sp(new String(
        "pid=%i: pipe ({fd=%i, fd=%i}) -> err=%i", pid, fds[0], fds[1], err));
    if (g_log_all_calls)
      description_sp->log(get_logging_fd());
    if (fds[0] >= 0)
      save_backtrace(fds[0], saved_errno, description_sp, true);
    if (fds[1] >= 0)
      save_backtrace(fds[1], saved_errno, description_sp, true);
    errno = saved_errno;
    return err;
  } else {
    return pipe(fds);
  }
}

// get_fd_history()
//
// This function allows runtime access to the file descriptor history.
//
// @param[in] log_fd
//      The file descriptor to log to
//
// @param[in] fd
//      The file descriptor whose history should be dumped
extern "C" void get_fd_history(int log_fd, int fd) {
  // "create" below needs to be outside of the mutex locker scope
  if (log_fd >= 0) {
    bool got_lock = false;
    Locker locker(&g_mutex, got_lock);
    if (got_lock) {
      FDEventMap::iterator pos = g_fd_event_map.find(fd);
      log_to_fd(log_fd, "Dumping file descriptor history for fd=%i:\n", fd);
      if (pos != g_fd_event_map.end()) {
        FDEventArray &event_array = g_fd_event_map[fd];
        const size_t num_events = event_array.size();
        for (size_t i = 0; i < num_events; ++i)
          event_array[i]->Dump(log_fd);
      } else {
        log_to_fd(log_fd, "error: no file descriptor events found for fd=%i\n",
                  fd);
      }
    } else {
      log_to_fd(log_fd, "error: fd event mutex is locked...\n");
    }
  }
}

// Interposing
// FD creation routines
DYLD_INTERPOSE(accept$__interposed__, accept);
DYLD_INTERPOSE(accept$NOCANCEL$__interposed__, accept$NOCANCEL);
DYLD_INTERPOSE(dup$__interposed__, dup);
DYLD_INTERPOSE(dup2$__interposed__, dup2);
DYLD_INTERPOSE(kqueue$__interposed__, kqueue);
DYLD_INTERPOSE(open$__interposed__, open);
DYLD_INTERPOSE(open$NOCANCEL$__interposed__, open$NOCANCEL);
DYLD_INTERPOSE(__open_extended$__interposed__, __open_extended);
DYLD_INTERPOSE(pipe$__interposed__, pipe);
DYLD_INTERPOSE(shm_open$__interposed__, shm_open);
DYLD_INTERPOSE(socket$__interposed__, socket);
DYLD_INTERPOSE(socketpair$__interposed__, socketpair);

// FD deleting routines
DYLD_INTERPOSE(close$__interposed__, close);
DYLD_INTERPOSE(close$NOCANCEL$__interposed__, close$NOCANCEL);

} // namespace fd_interposing
