Esempio n. 1
0
static
int append_short_backtrace(struct strbuf *result, problem_data_t *problem_data, size_t max_text_size, bool print_item_name)
{
    const problem_item *item = problem_data_get_item_or_NULL(problem_data,
                                                             FILENAME_BACKTRACE);
    if (!item)
        return 0; /* "I did not print anything" */
    if (!(item->flags & CD_FLAG_TXT))
        return 0; /* "I did not print anything" */

    char *truncated = NULL;

    if (strlen(item->content) >= max_text_size)
    {
        struct sr_location location;
        sr_location_init(&location);

        /* sr_gdb_stacktrace_parse modifies the input parameter */
        char *content = item->content;
        struct sr_gdb_stacktrace *backtrace = sr_gdb_stacktrace_parse((const char **)&content, &location);

        if (!backtrace)
        {
            log(_("Can't parse backtrace"));
            return 0;
        }

        /* Get optimized thread stack trace for 10 top most frames */
        struct sr_gdb_thread *thread = sr_gdb_stacktrace_get_optimized_thread(backtrace, 10);

        sr_gdb_stacktrace_free(backtrace);

        if (!thread)
        {
            log(_("Can't find crash thread"));
            return 0;
        }

        /* Cannot be NULL, it dies on memory error */
        struct sr_strbuf *bt = sr_strbuf_new();

        sr_gdb_thread_append_to_str(thread, bt, true);

        sr_gdb_thread_free(thread);

        truncated = sr_strbuf_free_nobuf(bt);
    }

    append_text(result,
                /*item_name:*/ truncated ? "truncated_backtrace" : FILENAME_BACKTRACE,
                /*content:*/   truncated ? truncated             : item->content,
                print_item_name
    );
    free(truncated);
    return 1;
}
Esempio n. 2
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;
}