예제 #1
0
파일: libc_fatal.c 프로젝트: gf-chen/glibc
static void
backtrace_and_maps (int do_abort, bool written, int fd)
{
  if (do_abort > 1 && written)
    {
      void *addrs[64];
#define naddrs (sizeof (addrs) / sizeof (addrs[0]))
      int n = __backtrace (addrs, naddrs);
      if (n > 2)
        {
#define strnsize(str) str, strlen (str)
#define writestr(str) write_not_cancel (fd, str)
          writestr (strnsize ("======= Backtrace: =========\n"));
          __backtrace_symbols_fd (addrs + 1, n - 1, fd);

          writestr (strnsize ("======= Memory map: ========\n"));
          int fd2 = open_not_cancel_2 ("/proc/self/maps", O_RDONLY);
          char buf[1024];
          ssize_t n2;
          while ((n2 = read_not_cancel (fd2, buf, sizeof (buf))) > 0)
            if (write_not_cancel (fd, buf, n2) != n2)
              break;
          close_not_cancel_no_status (fd2);
        }
    }
}
예제 #2
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);
}
예제 #3
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);
}