Beispiel #1
0
/* This function is called when a segmentation fault is caught.  The system
   is in an unstable state now.  This means especially that malloc() might
   not work anymore.  */
static void
catch_segfault (int signal, SIGCONTEXT ctx)
{
    int fd, cnt, i;
    void **arr;
    struct sigaction sa;
    uintptr_t pc;

    /* This is the name of the file we are writing to.  If none is given
       or we cannot write to this file write to stderr.  */
    fd = 2;
    if (fname != NULL)
    {
        fd = open (fname, O_TRUNC | O_WRONLY | O_CREAT, 0666);
        if (fd == -1)
            fd = 2;
    }

    WRITE_STRING ("*** ");
    write_strsignal (fd, signal);
    WRITE_STRING ("\n");

#ifdef REGISTER_DUMP
    REGISTER_DUMP;
#endif

#if __OPTION_EGLIBC_BACKTRACE
    WRITE_STRING ("\nBacktrace:\n");

    /* Get the backtrace.  */
    arr = alloca (256 * sizeof (void *));
    cnt = backtrace (arr, 256);

    /* Now try to locate the PC from signal context in the backtrace.
       Normally it will be found at arr[2], but it might appear later
       if there were some signal handler wrappers.  Allow a few bytes
       difference to cope with as many arches as possible.  */
    pc = (uintptr_t) GET_PC (ctx);
    for (i = 0; i < cnt; ++i)
        if ((uintptr_t) arr[i] >= pc - 16 && (uintptr_t) arr[i] <= pc + 16)
            break;

    /* If we haven't found it, better dump full backtrace even including
       the signal handler frames instead of not dumping anything.  */
    if (i == cnt)
        i = 0;

    /* Now generate nicely formatted output.  */
    __backtrace_symbols_fd (arr + i, cnt - i, fd);
#endif

#ifdef HAVE_PROC_SELF
    /* Now the link map.  */
    int mapfd = open ("/proc/self/maps", O_RDONLY);
    if (mapfd != -1)
    {
        write (fd, "\nMemory map:\n\n", 14);

        char buf[256];
        ssize_t n;

        while ((n = TEMP_FAILURE_RETRY (read (mapfd, buf, sizeof (buf)))) > 0)
            TEMP_FAILURE_RETRY (write (fd, buf, n));

        close (mapfd);
    }
#endif

    /* Pass on the signal (so that a core file is produced).  */
    sa.sa_handler = SIG_DFL;
    sigemptyset (&sa.sa_mask);
    sa.sa_flags = 0;
    sigaction (signal, &sa, NULL);
    raise (signal);
}
Beispiel #2
0
/* This function is called when a segmentation fault is caught.  The system
   is in an instable state now.  This means especially that malloc() might
   not work anymore.  */
static void
catch_segfault (int signal, SIGCONTEXT ctx)
{
    struct layout *current;
    void *__unbounded top_frame;
    void *__unbounded top_stack;
    int fd;
    void **arr;
    size_t cnt;
    struct sigaction sa;

    /* This is the name of the file we are writing to.  If none is given
       or we cannot write to this file write to stderr.  */
    fd = 2;
    if (fname != NULL)
    {
        fd = open (fname, O_TRUNC | O_WRONLY | O_CREAT, 0666);
        if (fd == -1)
            fd = 2;
    }

    WRITE_STRING ("*** ");
    write_strsignal (fd, signal);
    WRITE_STRING ("\n");

#ifdef REGISTER_DUMP
    REGISTER_DUMP;
#endif

    WRITE_STRING ("\nBacktrace:\n");

    top_frame = GET_FRAME (ctx);
    top_stack = GET_STACK (ctx);

    /* First count how many entries we'll have.  */
    cnt = 1;
    current = BOUNDED_1 ((struct layout *) top_frame);
    while (!((void *) current INNER_THAN top_stack
             || !((void *) current INNER_THAN __libc_stack_end)))
    {
        ++cnt;

        current = ADVANCE_STACK_FRAME (current->next);
    }

    arr = alloca (cnt * sizeof (void *));

    /* First handle the program counter from the structure.  */
    arr[0] = GET_PC (ctx);

    current = BOUNDED_1 ((struct layout *) top_frame);
    cnt = 1;
    while (!((void *) current INNER_THAN top_stack
             || !((void *) current INNER_THAN __libc_stack_end)))
    {
        arr[cnt++] = current->return_address;

        current = ADVANCE_STACK_FRAME (current->next);
    }

    /* If the last return address was NULL, assume that it doesn't count.  */
    if (arr[cnt-1] == NULL)
        cnt--;

    /* Now generate nicely formatted output.  */
    __backtrace_symbols_fd (arr, cnt, fd);

    /* Pass on the signal (so that a core file is produced).  */
    sa.sa_handler = SIG_DFL;
    sigemptyset (&sa.sa_mask);
    sa.sa_flags = 0;
    sigaction (signal, &sa, NULL);
    raise (signal);
}