Exemplo n.º 1
0
struct sr_core_stacktrace *
sr_core_stacktrace_from_gdb(const char *gdb_output, const char *core_file,
                            const char *exe_file, char **error_msg)
{
    /* I'm not going to rewrite it now since the function is not being used. */
    assert(error_msg);
    /* Initialize error_msg to 'no error'. */
    *error_msg = NULL;

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

    struct sr_gdb_stacktrace *gdb_stacktrace;
    struct sr_location location;
    sr_location_init(&location);

    gdb_stacktrace = sr_gdb_stacktrace_parse(&gdb_output, &location);
    if (!gdb_stacktrace)
    {
        *error_msg = sr_location_to_string(&location);
        core_handle_free(ch);
        return NULL;
    }

    struct sr_core_stacktrace *core_stacktrace = sr_core_stacktrace_new();

    for (struct sr_gdb_thread *gdb_thread = gdb_stacktrace->threads;
         gdb_thread;
         gdb_thread = gdb_thread->next)
    {
        struct sr_core_thread *core_thread = sr_core_thread_new();

        for (struct sr_gdb_frame *gdb_frame = gdb_thread->frames;
             gdb_frame;
             gdb_frame = gdb_frame->next)
        {
            if (gdb_frame->signal_handler_called)
                continue;

            struct sr_core_frame *core_frame = resolve_frame(ch->dwfl,
                    gdb_frame->address, false);

            core_thread->frames = sr_core_frame_append(core_thread->frames,
                    core_frame);
        }

        if (sr_gdb_stacktrace_find_crash_thread(gdb_stacktrace) == gdb_thread)
        {
            core_stacktrace->crash_thread = core_thread;
        }

        core_stacktrace->threads = sr_core_thread_append(
                core_stacktrace->threads, core_thread);
    }

    core_stacktrace->signal = get_signal_number(ch->eh, core_file);
    core_stacktrace->executable = realpath(exe_file, NULL);

    core_handle_free(ch);
    sr_gdb_stacktrace_free(gdb_stacktrace);
    return core_stacktrace;
}
Exemplo n.º 2
0
struct sr_core_stacktrace *
sr_parse_coredump_maps(const char *core_file,
                       const char *exe_file,
                       const char *maps_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, maps_file, error_msg);
    if (!ch)
        goto fail;

    if (dwfl_core_file_attach(ch->dwfl, ch->eh) < 0)
    {
        set_error_dwfl("dwfl_core_file_attach");
        goto fail;
    }

    stacktrace = sr_core_stacktrace_new();
    if (!stacktrace)
    {
        set_error("Failed to initialize stacktrace memory");
        goto fail;
    }

    struct thread_callback_arg thread_arg =
    {
        .stacktrace = stacktrace,
        .error_msg = NULL
    };

    int ret = dwfl_getthreads(ch->dwfl, unwind_thread, &thread_arg);
    if (ret != 0)
    {
        if (ret == -1)
            set_error_dwfl("dwfl_getthreads");
        else if (ret == DWARF_CB_ABORT)
        {
            set_error("%s", thread_arg.error_msg);
            free(thread_arg.error_msg);
        }
        else
            set_error("Unknown error in dwfl_getthreads");

        sr_core_stacktrace_free(stacktrace);
        stacktrace = NULL;
        goto fail;
    }

    stacktrace->executable = sr_strdup(exe_file);
    stacktrace->signal = get_signal_number(ch->eh, core_file);
    /* FIXME: is this the best we can do? */
    stacktrace->crash_thread = stacktrace->threads;

fail:
    core_handle_free(ch);
    return stacktrace;
}