Devel-CoreDump

 view release on metacpan or  search on metacpan

src/elfcore.c  view on Meta::CPAN

        while (*ptr && *ptr != ' ')
          prstatus.pr_sigpend = 10*prstatus.pr_sigpend + *ptr++ - '0';
      }
      NO_INTR(sys_close(stat_fd));
    }
  }

  /* scope */ {
    int openmax  = sys_sysconf(_SC_OPEN_MAX);
    int pagesize = sys_sysconf(_SC_PAGESIZE);
    struct kernel_sigset_t old_signals, blocked_signals;

    const struct CoreDumpParameters *params =
      va_arg(ap, const struct CoreDumpParameters *);
    const char *file_name =
      va_arg(ap, const char *);
    size_t max_length =
      GetCoreDumpParameter(params, max_length);
    const char *PATH =
      va_arg(ap, const char *);
    const struct CoredumperCompressor *compressors =

src/elfcore.c  view on Meta::CPAN

        /* Block signals prior to forking. Technically, POSIX requires
         * us to call pthread_sigmask(), if this is a threaded
         * application. When using glibc, we are OK calling
         * sigprocmask(), though. We will end up blocking additional
         * signals that libpthread uses internally, but that
         * is actually exactly what we want.
         *
         * Also, POSIX claims that this should not actually be
         * necessarily, but reality says otherwise.
         */
        sys_sigfillset(&blocked_signals);
        sys_sigprocmask(SIG_BLOCK, &blocked_signals, &old_signals);

        /* Create a new core dump in child process; call sys_fork() in order to
         * avoid complications with pthread_atfork() handlers. In the child
         * process, we should only ever call system calls.
         */
        if ((rc = sys_fork()) == 0) {
          int  fds[2];

          /* Create a pipe for communicating between processes. If
           * necessary, add a compressor to the pipeline.

src/linuxthreads.c  view on Meta::CPAN

#include <linux/dirent.h>

#include "linux_syscall_support.h"
#include "thread_lister.h"

#ifndef CLONE_UNTRACED
#define CLONE_UNTRACED 0x00800000
#endif


/* Synchronous signals that should not be blocked while in the lister thread.
 */
static const int sync_signals[]  = { SIGABRT, SIGILL, SIGFPE, SIGSEGV, SIGBUS,
                                     SIGXCPU, SIGXFSZ };

/* itoa() is not a standard function, and we cannot safely call printf()
 * after suspending threads. So, we just implement our own copy. A
 * recursive approach is the easiest here.
 */
static char *local_itoa(char *buf, int i) {
  if (i < 0) {

src/linuxthreads.c  view on Meta::CPAN

/* This function gets the list of all linux threads of the current process
 * passes them to the 'callback' along with the 'parameter' pointer; at the
 * call back call time all the threads are paused via
 * PTRACE_ATTACH.
 * The callback is executed from a separate thread which shares only the
 * address space, the filesystem, and the filehandles with the caller. Most
 * notably, it does not share the same pid and ppid; and if it terminates,
 * the rest of the application is still there. 'callback' is supposed to do
 * or arrange for ResumeAllProcessThreads. This happens automatically, if
 * the thread raises a synchronous signal (e.g. SIGSEGV); asynchronous
 * signals are blocked. If the 'callback' decides to unblock them, it must
 * ensure that they cannot terminate the application, or that
 * ResumeAllProcessThreads will get called.
 * It is an error for the 'callback' to make any library calls that could
 * acquire locks. Most notably, this means that most system calls have to
 * avoid going through libc. Also, this means that it is not legal to call
 * exit() or abort().
 * We return -1 on error and the return value of 'callback' on success.
 */
int ListAllProcessThreads(void *parameter,
                          ListAllProcessThreadsCallBack callback, ...) {
  char                   altstack_mem[ALT_STACKSIZE];
  struct ListerParams    args;
  pid_t                  clone_pid;
  int                    dumpable = 1, sig;
  struct kernel_sigset_t sig_blocked, sig_old;

  va_start(args.ap, callback);

  /* If we are short on virtual memory, initializing the alternate stack
   * might trigger a SIGSEGV. Let's do this early, before it could get us
   * into more trouble (i.e. before signal handlers try to use the alternate
   * stack, and before we attach to other threads).
   */
  memset(altstack_mem, 0, sizeof(altstack_mem));

src/linuxthreads.c  view on Meta::CPAN


  /* Fill in argument block for dumper thread                                */
  args.result       = -1;
  args.err          = 0;
  args.altstack_mem = altstack_mem;
  args.parameter    = parameter;
  args.callback     = callback;

  /* Before cloning the thread lister, block all asynchronous signals, as we */
  /* are not prepared to handle them.                                        */
  sys_sigfillset(&sig_blocked);
  for (sig = 0; sig < sizeof(sync_signals)/sizeof(*sync_signals); sig++) {
    sys_sigdelset(&sig_blocked, sync_signals[sig]);
  }
  if (sys_sigprocmask(SIG_BLOCK, &sig_blocked, &sig_old)) {
    args.err = errno;
    args.result = -1;
    goto failed;
  }

  /* scope */ {
    /* After cloning, both the parent and the child share the same instance
     * of errno. We must make sure that at least one of these processes
     * (in our case, the parent) uses modified syscall macros that update
     * a local copy of errno, instead.

src/thread_lister.h  view on Meta::CPAN

/* This function gets the list of all linux threads of the current process
 * passes them to the 'callback' along with the 'parameter' pointer; at the
 * call back call time all the threads are paused via
 * PTRACE_ATTACH.
 * The callback is executed from a separate thread which shares only the
 * address space, the filesystem, and the filehandles with the caller. Most
 * notably, it does not share the same pid and ppid; and if it terminates,
 * the rest of the application is still there. 'callback' is supposed to do
 * or arrange for ResumeAllProcessThreads. This happens automatically, if
 * the thread raises a synchronous signal (e.g. SIGSEGV); asynchronous
 * signals are blocked. If the 'callback' decides to unblock them, it must
 * ensure that they cannot terminate the application, or that
 * ResumeAllProcessThreads will get called.
 * It is an error for the 'callback' to make any library calls that could
 * acquire locks. Most notably, this means that most system calls have to
 * avoid going through libc. Also, this means that it is not legal to call
 * exit() or abort().
 * We return -1 on error and the return value of 'callback' on success.
 */
int ListAllProcessThreads(void *parameter,
                          ListAllProcessThreadsCallBack callback, ...);



( run in 0.456 second using v1.01-cache-2.11-cpan-49f99fa48dc )