Exemple #1
0
int
outOfStack(void *stack, stack_overflow_action how)
{ GET_LD
  Stack s = stack;
  const char *msg = "unhandled stack overflow";

  if ( LD->outofstack )
  { Sdprintf("[Thread %d]: failed to recover from %s-overflow\n",
	     PL_thread_self(), s->name);
    print_backtrace_named(msg);
    save_backtrace("crash");
    print_backtrace_named("crash");
    fatalError("Sorry, cannot continue");

    return FALSE;				/* NOTREACHED */
  }

  save_backtrace(msg);

  LD->trim_stack_requested = TRUE;
  LD->exception.processing = TRUE;
  LD->outofstack = stack;

  switch(how)
  { case STACK_OVERFLOW_THROW:
    case STACK_OVERFLOW_RAISE:
    { fid_t fid;

      blockGC(0 PASS_LD);

      if ( (fid=PL_open_foreign_frame()) )
      { PL_clearsig(SIG_GC);
	s->gced_size = 0;			/* after handling, all is new */
	if ( !PL_unify_term(LD->exception.tmp,
			    PL_FUNCTOR, FUNCTOR_error2,
			      PL_FUNCTOR, FUNCTOR_resource_error1,
			        PL_ATOM, ATOM_stack,
			      PL_CHARS, s->name) )
	  fatalError("Out of stack inside out-of-stack handler");

	if ( how == STACK_OVERFLOW_THROW )
	{ PL_close_foreign_frame(fid);
	  unblockGC(0 PASS_LD);
	  PL_throw(LD->exception.tmp);
	  warning("Out of %s stack while not in Prolog!?", s->name);
	  assert(0);
	} else
	{ PL_raise_exception(LD->exception.tmp);
	}

	PL_close_foreign_frame(fid);
      }

      unblockGC(0 PASS_LD);
      fail;
    }
  }
  assert(0);
  fail;
}
//----------------------------------------------------------------------
// 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);
  }
}
//----------------------------------------------------------------------
// 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);
  }
}
//----------------------------------------------------------------------
// 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);
  }
}
//----------------------------------------------------------------------
// 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);
  }
}
void add_node(unsigned long long size)
{
	struct node *new_node = (struct node*)malloc(sizeof(struct node));
	save_backtrace();
	new_node->data = (char*)malloc(size);
	save_backtrace();
	new_node->size = size;
	new_node->next = list;

#ifdef DIRTY_ENABLED
	for (unsigned long long i = 0; i < size; i += pgsz) {
		new_node->data[i] = 42;
	}
#endif

	if ((counter++) % 2) {
		free(new_node->data);
		new_node->data = NULL;
	}

	list = new_node;
}
//----------------------------------------------------------------------
// 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);
  }
}
//----------------------------------------------------------------------
// 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();
  }
}
//----------------------------------------------------------------------
// 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);
  }
}
//----------------------------------------------------------------------
// __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);
  }
}
//----------------------------------------------------------------------
// 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);
  }
}
Exemple #12
0
int
outOfStack(void *stack, stack_overflow_action how)
{ GET_LD
  Stack s = stack;
  const char *msg = "out-of-stack";

  if ( LD->outofstack )
  { Sdprintf("[Thread %d]: failed to recover from %s-overflow\n",
	     PL_thread_self(), s->name);
    print_backtrace_named(msg);
    save_backtrace("crash");
    print_backtrace_named("crash");
    fatalError("Sorry, cannot continue");

    return FALSE;				/* NOTREACHED */
  }

  save_backtrace(msg);

  if ( s->spare != s->def_spare )
  { Sdprintf("[Thread %d]: %s-overflow: spare=%ld\n"
	     "Last resource exception:\n",
	     PL_thread_self(), s->name, (long)s->spare);
    print_backtrace_named("exception");
  }

  LD->trim_stack_requested = TRUE;
  LD->exception.processing = TRUE;
  LD->outofstack = stack;

  switch(how)
  { case STACK_OVERFLOW_THROW:
    case STACK_OVERFLOW_RAISE:
    { if ( gTop+5 < gMax )
      { Word p = gTop;

	p[0] = FUNCTOR_error2;			/* see (*) above */
	p[1] = consPtr(&p[3], TAG_COMPOUND|STG_GLOBAL);
	p[2] = PL_new_atom(s->name);
	p[3] = FUNCTOR_resource_error1;
	p[4] = ATOM_stack;
	gTop += 5;
	PL_unregister_atom(p[2]);

	*valTermRef(LD->exception.bin) = consPtr(p, TAG_COMPOUND|STG_GLOBAL);
	freezeGlobal(PASS_LD1);
      } else
      { Sdprintf("Out of %s-stack.  No room for exception term.  Aborting.\n", s->name);
	*valTermRef(LD->exception.bin) = ATOM_aborted;
      }
      exception_term = exception_bin;

      if ( how == STACK_OVERFLOW_THROW &&
	   LD->exception.throw_environment )
      {						/* see PL_throw() */
	longjmp(LD->exception.throw_environment->exception_jmp_env, 1);
      }

      return FALSE;
    }
    default:
      assert(0);
      fail;
  }
}