Ejemplo n.º 1
0
/* methods */
PyObject *
sr_py_base_thread_distance(PyObject *self, PyObject *args, PyObject *kwds)
{
    PyObject *other;
    int dist_type = SR_DISTANCE_LEVENSHTEIN;
    static const char *kwlist[] = { "other", "dist_type", NULL };

    if (!PyArg_ParseTupleAndKeywords(args, kwds, "O!|i", (char **)kwlist,
                                     &sr_py_base_thread_type, &other, &dist_type))
        return NULL;

    struct sr_py_base_thread *t1 = (struct sr_py_base_thread *)self;
    struct sr_py_base_thread *t2 = (struct sr_py_base_thread *)other;

    if (frames_prepare_linked_list(t1) < 0)
        return NULL;

    if (frames_prepare_linked_list(t2) < 0)
        return NULL;

    if (Py_TYPE(self) != Py_TYPE(other))
    {
        PyErr_SetString(PyExc_TypeError, "Both threads must have the same type");
        return NULL;
    }

    if (dist_type < 0 || dist_type >= SR_DISTANCE_NUM)
    {
        PyErr_SetString(PyExc_ValueError, "Invalid distance type");
        return NULL;
    }

    float dist = sr_distance(dist_type, t1->thread, t2->thread);
    return PyFloat_FromDouble((double)dist);
}
Ejemplo n.º 2
0
static int core_backtrace_is_duplicate(struct sr_stacktrace *bt1,
                                       const char *bt2_text)
{
    struct sr_thread *thread1 = sr_stacktrace_find_crash_thread(bt1);

    if (thread1 == NULL)
    {
        log_notice("New stacktrace has no crash thread, disabling core stacktrace deduplicate");
        dup_corebt_fini();
        return 0;
    }

    int result;
    char *error_message;
    struct sr_stacktrace *bt2 = sr_stacktrace_parse(sr_abrt_type_from_type(type),
                                                    bt2_text, &error_message);
    if (bt2 == NULL)
    {
        log_notice("Failed to parse backtrace, considering it not duplicate: %s", error_message);
        free(error_message);
        return 0;
    }

    struct sr_thread *thread2 = sr_stacktrace_find_crash_thread(bt2);

    if (thread2 == NULL)
    {
        log_notice("Failed to get crash thread, considering it not duplicate");
        result = 0;
        goto end;
    }

    int length2 = sr_thread_frame_count(thread2);

    if (length2 <= 0)
    {
        log_notice("Core backtrace has zero frames, considering it not duplicate");
        result = 0;
        goto end;
    }

    float distance = sr_distance(SR_DISTANCE_DAMERAU_LEVENSHTEIN, thread1, thread2);
    log_info("Distance between backtraces: %f", distance);
    result = (distance <= BACKTRACE_DUP_THRESHOLD);

end:
    sr_stacktrace_free(bt2);

    return result;
}
Ejemplo n.º 3
0
struct sr_distances *
sr_threads_compare(struct sr_thread **threads,
                   int m,
                   int n,
                   enum sr_distance_type dist_type)
{
    struct sr_distances *distances;
    int i, j;
    float dist;

    distances = sr_distances_new(m, n);

    if (n <= 0)
        return distances;

    /* Check that all threads are of the same type */
    enum sr_report_type type, prev_type = threads[0]->type;
    for (i = 0; i < n; i++)
    {
        type = threads[i]->type;
        assert(prev_type == type);
        prev_type = type;
    }

    for (i = 0; i < m; i++)
    {
        for (j = i + 1; j < n; j++)
        {
            /* XXX: GDB crashes have a special normalization step for
             * clustering. If there's something similar for other types, we can
             * generalize it -- meanwhile there's a separate case for GDB here
             */
            if (type == SR_REPORT_GDB)
            {
                struct sr_gdb_thread *thread1 = (struct sr_gdb_thread*)threads[i],
                                     *thread2 = (struct sr_gdb_thread*)threads[j];
                int ok = 0, all = 0;

                sr_gdb_thread_quality_counts(thread1, &ok, &all);
                sr_gdb_thread_quality_counts(thread2, &ok, &all);

                if (ok != all)
                {
                    /* There are some unknown function names, try to pair them, but
                     * the threads need to be copied first. */
                    thread1 = sr_gdb_thread_dup(thread1, false);
                    thread2 = sr_gdb_thread_dup(thread2, false);
                    sr_normalize_gdb_paired_unknown_function_names(thread1, thread2);
                }

                dist = sr_distance(dist_type, (struct sr_thread*)thread1,
                                   (struct sr_thread*)thread2);

                if (ok != all)
                {
                    sr_gdb_thread_free(thread1);
                    sr_gdb_thread_free(thread2);
                }
            }
            else
                dist = sr_distance(dist_type, threads[i], threads[j]);

            distances->distances[get_distance_position(distances, i, j)] = dist;
        }
    }

    return distances;
}
Ejemplo n.º 4
0
static int core_backtrace_is_duplicate(struct sr_stacktrace *bt1,
                                       const char *bt2_text)
{
    struct sr_thread *thread1 = sr_stacktrace_find_crash_thread(bt1);

    if (thread1 == NULL)
    {
        log_notice("New stacktrace has no crash thread, disabling core stacktrace deduplicate");
        dup_corebt_fini();
        return 0;
    }

    int result;
    char *error_message;
    struct sr_stacktrace *bt2 = sr_stacktrace_parse(sr_abrt_type_from_analyzer(analyzer),
                                                    bt2_text, &error_message);
    if (bt2 == NULL)
    {
        log_notice("Failed to parse backtrace, considering it not duplicate: %s", error_message);
        free(error_message);
        return 0;
    }

    struct sr_thread *thread2 = sr_stacktrace_find_crash_thread(bt2);

    if (thread2 == NULL)
    {
        log_notice("Failed to get crash thread, considering it not duplicate");
        result = 0;
        goto end;
    }

    int length2 = sr_thread_frame_count(thread2);

    if (length2 <= 0)
    {
        log_notice("Core backtrace has zero frames, considering it not duplicate");
        result = 0;
        goto end;
    }

    /* This is an ugly workaround for https://github.com/abrt/btparser/issues/6 */
    /*
    int length1 = sr_core_thread_get_frame_count(thread1);

    if (length1 <= 2 || length2 <= 2)
    {
        log_notice("Backtraces too short, falling back on full comparison");
        result = (sr_core_thread_cmp(thread1, thread2) == 0);
        goto end;
    }
    */

    float distance = sr_distance(SR_DISTANCE_DAMERAU_LEVENSHTEIN, thread1, thread2);
    log_info("Distance between backtraces: %f", distance);
    result = (distance <= BACKTRACE_DUP_THRESHOLD);

end:
    sr_stacktrace_free(bt2);

    return result;
}