예제 #1
0
파일: stack.c 프로젝트: mmilata/seecore
struct thread* unwind_stacks(Dwfl *dwfl, const char *core_file,
                             struct exec_map *em,
                             struct expr_context *ctx)
{
    unw_addr_space_t as;
    struct UCD_info *ui;
    struct thread *head = NULL, *tail = NULL;

    as = unw_create_addr_space(&_UCD_accessors, 0);
    fail_if(!as, "unw_create_addr_space");

    ui = _UCD_create(core_file);
    fail_if(!ui, "_UCD_create");

    for (; em != NULL; em = em->next)
    {
        if (_UCD_add_backing_file_at_vaddr(ui, em->vaddr, em->file) < 0)
        {
            fail("_UCD_add_backing_file_at_vaddr");
        }
    }

    int tnum;
    int nthreads = _UCD_get_num_threads(ui);
    for (tnum = 0; tnum < nthreads; tnum++)
    {
        struct thread *thread = xalloc(sizeof(struct thread));
        thread->frames = unwind_thread(dwfl, as, ui, tnum, ctx);
        list_append(head, tail, thread);
    }

    return head;
}
예제 #2
0
static int
get_signal_number_libunwind(struct UCD_info *ui)
{
    int tnum, nthreads = _UCD_get_num_threads(ui);
    for (tnum = 0; tnum < nthreads; ++tnum)
    {
        _UCD_select_thread(ui, tnum);
        int signo = _UCD_get_cursig(ui);

        /* Return first nonzero signal, gdb/bfd seem to work this way. */
        if (signo)
            return signo;
    }

    return 0;
}
예제 #3
0
struct sr_core_stacktrace *
sr_parse_coredump(const char *core_file,
                   const char *exe_file,
                   char **error_msg)
{
    struct sr_core_stacktrace *stacktrace = NULL;

    /* Initialize error_msg to 'no error'. */
    if (error_msg)
        *error_msg = NULL;

    struct core_handle *ch = open_coredump(core_file, exe_file, error_msg);
    if (*error_msg)
        return NULL;

    unw_addr_space_t as;
    struct UCD_info *ui;
    as = unw_create_addr_space(&_UCD_accessors, 0);
    if (!as)
    {
        set_error("Failed to create address space");
        goto fail_destroy_handle;
    }

    ui = _UCD_create(core_file);
    if (!ui)
    {
        set_error("Failed to set up core dump accessors for '%s'", core_file);
        goto fail_destroy_as;
    }

    struct exe_mapping_data *s;
    for (s = ch->segments; s != NULL; s = s->next)
    {
        if (_UCD_add_backing_file_at_vaddr(ui, s->start, s->filename) < 0)
        {
            /* Sometimes produces:
             * >_UCD_add_backing_file_at_segment:
             * Error reading from '/usr/lib/modules/3.6.9-2.fc17.x86_64/vdso/vdso.so'
             * Ignore errors for now & fail later.
             */
            warn("Can't add backing file '%s' at addr 0x%jx", s->filename,
                 (uintmax_t)s->start);
            /* goto fail_destroy_ui; */
        }
    }

    stacktrace = sr_core_stacktrace_new();

    int tnum, nthreads = _UCD_get_num_threads(ui);
    for (tnum = 0; tnum < nthreads; ++tnum)
    {
        struct sr_core_thread *trace = unwind_thread(ui, as, ch->dwfl, tnum, error_msg);
        if (trace)
        {
            stacktrace->threads = sr_core_thread_append(stacktrace->threads, trace);
        }
        else
        {
            sr_core_stacktrace_free(stacktrace);
            stacktrace = NULL;
            break;
        }
    }

    stacktrace->executable = realpath(exe_file, NULL);
    stacktrace->signal = get_signal_number_libunwind(ui);
    /* FIXME: is this the best we can do? */
    stacktrace->crash_thread = stacktrace->threads;

    _UCD_destroy(ui);
fail_destroy_as:
    unw_destroy_addr_space(as);
fail_destroy_handle:
    core_handle_free(ch);

    return stacktrace;
}