Exemple #1
0
int backtrace (void **array, int size)
{
	struct layout *current;
	void *__unbounded top_frame;
	void *__unbounded top_stack;
	int cnt = 0;

	top_frame = FIRST_FRAME_POINTER;
	top_stack = CURRENT_STACK_FRAME;

	/* We skip the call to this function, it makes no sense to record it.  */
	current = BOUNDED_1 ((struct layout *) top_frame);
	while (cnt < size)
	{
		if ((void *) current INNER_THAN top_stack
				   || !((void *) current INNER_THAN stack_end))
			/* This means the address is out of range.  Note that for the
			toplevel we see a frame pointer with value NULL which clearly is
			out of range.  */
			break;

		array[cnt++] = current->return_address;

		current = ADVANCE_STACK_FRAME (current->next);
	}

	return cnt;
}
/* 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);
}