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); } }
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; } }