コード例 #1
0
ファイル: thread.c プロジェクト: abrt/btparser
int thread_rebuild_python_list(ThreadObject *thread)
{
    struct btp_frame *newlinkedlist = btp_frame_dup(thread->thread->frames, true);
    if (thread_free_frame_python_list(thread) < 0)
    {
        struct btp_frame *next;
        while (newlinkedlist)
        {
            next = newlinkedlist->next;
            btp_frame_free(newlinkedlist);
            newlinkedlist = next;
        }
        return -1;
    }
    /* linked list */
    thread->thread->frames = newlinkedlist;
    /* python list */
    thread->frames = frame_linked_list_to_python_list(thread->thread);
    if (!thread->frames)
    {
        struct btp_frame *next;
        while (newlinkedlist)
        {
            next = newlinkedlist->next;
            btp_frame_free(newlinkedlist);
            newlinkedlist = next;
        }
        return -1;
    }

    return 0;
}
コード例 #2
0
ファイル: thread.c プロジェクト: rplnt/abrt
void
btp_thread_remove_frames_below_n(struct btp_thread *thread,
                                 int n)
{
    assert(n >= 0);

    /* Skip some frames to get the required stack depth. */
    int i = n;
    struct btp_frame *frame = thread->frames, *last_frame = NULL;
    while (frame && i)
    {
        last_frame = frame;
        frame = frame->next;
        --i;
    }

    /* Delete the remaining frames. */
    if (last_frame)
        last_frame->next = NULL;
    else
        thread->frames = NULL;

    while (frame)
    {
        struct btp_frame *delete_frame = frame;
        frame = frame->next;
        btp_frame_free(delete_frame);
    }
}
コード例 #3
0
ファイル: thread.c プロジェクト: rplnt/abrt
bool
btp_thread_remove_frames_above(struct btp_thread *thread,
                               struct btp_frame *frame)
{
    /* Check that the frame is present in the thread. */
    struct btp_frame *loop_frame = thread->frames;
    while (loop_frame)
    {
        if (loop_frame == frame)
            break;
        loop_frame = loop_frame->next;
    }

    if (!loop_frame)
        return false;

    /* Delete all the frames up to the frame. */
    while (thread->frames != frame)
    {
        loop_frame = thread->frames->next;
        btp_frame_free(thread->frames);
        thread->frames = loop_frame;
    }

    return true;
}
コード例 #4
0
ファイル: backtrace.c プロジェクト: abrt/btparser
void
btp_backtrace_free(struct btp_backtrace *backtrace)
{
    if (!backtrace)
        return;

    while (backtrace->threads)
    {
        struct btp_thread *rm = backtrace->threads;
        backtrace->threads = rm->next;
        btp_thread_free(rm);
    }

    while (backtrace->libs)
    {
        struct btp_sharedlib *rm = backtrace->libs;
        backtrace->libs = rm->next;
        btp_sharedlib_free(rm);
    }

    if (backtrace->crash)
        btp_frame_free(backtrace->crash);

    free(backtrace);
}
コード例 #5
0
ファイル: thread.c プロジェクト: rplnt/abrt
void
btp_thread_free(struct btp_thread *thread)
{
    if (!thread)
        return;

    while (thread->frames)
    {
        struct btp_frame *rm = thread->frames;
        thread->frames = rm->next;
        btp_frame_free(rm);
    }

    free(thread);
}
コード例 #6
0
ファイル: thread.c プロジェクト: rplnt/abrt
bool
btp_thread_remove_frame(struct btp_thread *thread,
                        struct btp_frame *frame)
{
    struct btp_frame *loop_frame = thread->frames, *prev_frame = NULL;
    while (loop_frame)
    {
        if (loop_frame == frame)
        {
            if (prev_frame)
                prev_frame->next = loop_frame->next;
            else
                thread->frames = loop_frame->next;

            btp_frame_free(loop_frame);
            return true;
        }
        prev_frame = loop_frame;
        loop_frame = loop_frame->next;
    }
    return false;
}
コード例 #7
0
int main(int argc, char **argv)
{
    abrt_init(argv);

    /* Can't keep these strings/structs static: _() doesn't support that */
    const char *program_usage_string = _(
        "\b [options] -d DIR\n"
        "\n"
        "Analyzes C/C++ backtrace, generates duplication hash, backtrace rating, and identifies crash function in dump directory DIR"
    );
    enum {
        OPT_v = 1 << 0,
        OPT_d = 1 << 1
    };
    /* Keep enum above and order of options below in sync! */
    struct options program_options[] = {
        OPT__VERBOSE(&g_verbose),
        OPT_STRING('d', NULL, &dump_dir_name, "DIR", _("Dump directory")),
        OPT_END()
    };
    /*unsigned opts =*/ parse_opts(argc, argv, program_options, program_usage_string);

    export_abrt_envvars(0);

    struct dump_dir *dd = dd_opendir(dump_dir_name, /*flags:*/ 0);
    if (!dd)
        return 1;

    char *component = dd_load_text(dd, FILENAME_COMPONENT);

    /* Read backtrace */
    char *backtrace_str = dd_load_text_ext(dd, FILENAME_BACKTRACE,
                                           DD_LOAD_TEXT_RETURN_NULL_ON_FAILURE);
    if (!backtrace_str)
    {
        dd_close(dd);
        return 1;
    }

    /* Compute backtrace hash */
    struct btp_location location;
    btp_location_init(&location);
    char *backtrace_str_ptr = backtrace_str;
    struct btp_backtrace *backtrace = btp_backtrace_parse(&backtrace_str_ptr, &location);
    free(backtrace_str);

    /* Store backtrace hash */
    if (!backtrace)
    {
        /*
         * The parser failed. Compute the duphash from the executable
         * instead of a backtrace.
         * and component only.  This is not supposed to happen often.
         */
        log(_("Backtrace parsing failed for %s"), dump_dir_name);
        log("%d:%d: %s", location.line, location.column, location.message);
        struct strbuf *emptybt = strbuf_new();

        char *executable = dd_load_text(dd, FILENAME_EXECUTABLE);
        strbuf_prepend_str(emptybt, executable);
        free(executable);

        strbuf_prepend_str(emptybt, component);

        VERB3 log("Generating duphash: %s", emptybt->buf);
        char hash_str[SHA1_RESULT_LEN*2 + 1];
        create_hash(hash_str, emptybt->buf);

        dd_save_text(dd, FILENAME_DUPHASH, hash_str);
        /*
         * Other parts of ABRT assume that if no rating is available,
         * it is ok to allow reporting of the bug. To be sure no bad
         * backtrace is reported, rate the backtrace with the lowest
         * rating.
         */
        dd_save_text(dd, FILENAME_RATING, "0");

        strbuf_free(emptybt);
        free(component);
        dd_close(dd);

        /* Report success even if the parser failed, as the backtrace
         * has been created and rated. The failure is caused by a flaw
         * in the parser, not in the backtrace.
         */
        return 0;
    }

    /* Compute duplication hash. */
    char *str_hash_core = btp_backtrace_get_duplication_hash(backtrace);
    struct strbuf *str_hash = strbuf_new();
    strbuf_append_str(str_hash, component);
    strbuf_append_str(str_hash, str_hash_core);

    VERB3 log("Generating duphash: %s", str_hash->buf);
    char hash_str[SHA1_RESULT_LEN*2 + 1];
    create_hash(hash_str, str_hash->buf);

    dd_save_text(dd, FILENAME_DUPHASH, hash_str);
    strbuf_free(str_hash);
    free(str_hash_core);

    /* Compute the backtrace rating. */
    float quality = btp_backtrace_quality_complex(backtrace);
    const char *rating;
    if (quality < 0.6f)
        rating = "0";
    else if (quality < 0.7f)
        rating = "1";
    else if (quality < 0.8f)
        rating = "2";
    else if (quality < 0.9f)
        rating = "3";
    else
        rating = "4";
    dd_save_text(dd, FILENAME_RATING, rating);

    /* Get the function name from the crash frame. */
    struct btp_frame *crash_frame = btp_backtrace_get_crash_frame(backtrace);
    if (crash_frame)
    {
        if (crash_frame->function_name &&
            0 != strcmp(crash_frame->function_name, "??"))
        {
            dd_save_text(dd, FILENAME_CRASH_FUNCTION, crash_frame->function_name);
        }
        btp_frame_free(crash_frame);
    }
    btp_backtrace_free(backtrace);
    dd_close(dd);
    free(component);
    return 0;
}
コード例 #8
0
ファイル: frame.c プロジェクト: abrt/btparser
/* destructor */
void p_btp_frame_free(PyObject *object)
{
    FrameObject *this = (FrameObject *)object;
    btp_frame_free(this->frame);
    PyObject_Del(object);
}