Exemple #1
0
/* constructor */
PyObject *
sr_py_distances_part_new(PyTypeObject *object, PyObject *args, PyObject *kwds)
{
    int m, n, m_begin, n_begin;
    unsigned long long len;
    enum sr_distance_type dist_type;
    unsigned long long checksum;
    PyObject *dist_list;

    if (!PyArg_ParseTuple(args, "iiiiKiKO", &m, &n, &m_begin, &n_begin, &len, &dist_type,
                          &checksum, &dist_list))
        return NULL;

    struct sr_distances_part *part = sr_distances_part_new(m, n, dist_type, m_begin, n_begin,
                                                           (size_t)len);
    part->checksum = (uint32_t)checksum;

    if (PyList_Check(dist_list))
    {
        part->distances = sr_malloc_array(sizeof(float), part->len);
        int i;
        for (i = 0; i < PyList_Size(dist_list); i++)
        {
            PyObject *item = PyList_GetItem(dist_list, i);
            if (!item)
                goto error;

            double d = PyFloat_AsDouble(item);
            if (PyErr_Occurred())
                goto error;

            part->distances[i] = (float)d;
        }
    }
    else if (dist_list != Py_None)
    {
        PyErr_SetString(PyExc_TypeError, "distances must be list of floats or None");
        goto error;
    }

    struct sr_py_distances_part *py_part =
        PyObject_New(struct sr_py_distances_part, &sr_py_distances_part_type);
    py_part->distances_part = part;

    return (PyObject *)py_part;
error:
    sr_distances_part_free(part, false);
    return NULL;
}
Exemple #2
0
struct sr_distances *
sr_distances_new(int m, int n)
{
    struct sr_distances *distances = sr_malloc(sizeof(struct sr_distances));

    /* The number of rows has to be smaller than columns. */
    if (m >= n)
        m = n - 1;

    assert(m > 0 && n > 1 && m < n);

    distances->m = m;
    distances->n = n;
    distances->distances = sr_malloc_array(
                               get_distance_position(distances, m - 1, n - 1) + 1,
                               sizeof(*distances->distances)
                           );

    return distances;
}
Exemple #3
0
float
distance_levenshtein(struct sr_thread *thread1,
                     struct sr_thread *thread2,
                     bool transposition)
{
    assert(thread1->type == thread2->type);

    int frame_count1 = sr_thread_frame_count(thread1);
    int frame_count2 = sr_thread_frame_count(thread2);

    int max_frame_count = frame_count2;
    if (max_frame_count < frame_count1)
        max_frame_count = frame_count1;

    /* Avoid division by zero in case we get two empty threads */
    if (max_frame_count == 0)
        return 0.0;

    int m = frame_count1 + 1;
    int n = frame_count2 + 1;

    // store only two last rows and columns instead of whole 2D array
    SR_ASSERT(n <= SIZE_MAX - 1);
    SR_ASSERT(m <= SIZE_MAX - (n + 1));
    int *dist = sr_malloc_array(sizeof(int), m + n + 1);
    int *dist1 = sr_malloc_array(sizeof(int), m + n + 1);

    // first row and column having distance equal to their position
    for (int i = m; i > 0; --i)
        dist[m - i] = i;

    for (int i = 0; i <= n; ++i)
        dist[m + i] = i;

    struct sr_frame *curr_frame2 = sr_thread_frames(thread2);
    struct sr_frame *prev_frame = NULL;
    struct sr_frame *prev_frame2 = NULL;

    for (int j = 1; curr_frame2; ++j)
    {
        struct sr_frame *curr_frame = sr_thread_frames(thread1);
        for (int i = 1; curr_frame; ++i)
        {
            int l = m + j - i;

            int dist2 = dist1[l];
            dist1[l] = dist[l];

            int cost;

            /*similar characters have distance equal to the previous
              one diagonally, "??" functions aren't taken as
              similar */
            if (0 == sr_frame_cmp_distance(curr_frame, curr_frame2))
                cost = 0;
            else
            {
                // different ones takes the lowest value of all
                // previous distances
                cost = 1;
                dist[l] += 1;
                if (dist[l] > dist[l - 1] + 1)
                    dist[l] = dist[l - 1] + 1;

                if (dist[l] > dist[l + 1] + 1)
                    dist[l] = dist[l + 1] + 1;
            }

            /*checking for transposition of two characters in both ways
              taking into account that "??" functions are not similar*/
            if (transposition &&
                (i >= 2 && j >= 2 && dist[l] > dist2 + cost &&
                 0 == sr_frame_cmp_distance(curr_frame, prev_frame2) &&
                 0 == sr_frame_cmp_distance(prev_frame, curr_frame2)))
            {
                dist[l] = dist2 + cost;
            }

            prev_frame = curr_frame;
            curr_frame = sr_frame_next(curr_frame);
        }

        prev_frame2 = curr_frame2;
        curr_frame2 = sr_frame_next(curr_frame2);
    }

    int result = dist[n];
    free(dist);
    free(dist1);

    return (float)result / max_frame_count;
}
Exemple #4
0
struct sr_koops_stacktrace *
sr_koops_stacktrace_from_json(struct sr_json_value *root, char **error_message)
{
    if (!JSON_CHECK_TYPE(root, SR_JSON_OBJECT, "stacktrace"))
        return NULL;

    struct sr_koops_stacktrace *result = sr_koops_stacktrace_new();

    /* Kernel version. */
    if (!JSON_READ_STRING(root, "version", &result->version))
        goto fail;

    /* Raw oops text. */
    if (!JSON_READ_STRING(root, "raw_oops", &result->raw_oops))
        goto fail;

    /* Kernel taint flags. */
    struct sr_json_value *taint_flags = json_element(root, "taint_flags");
    if (taint_flags)
    {
        if (!JSON_CHECK_TYPE(taint_flags, SR_JSON_ARRAY, "taint_flags"))
            goto fail;

        struct sr_json_value *flag_json;
        FOR_JSON_ARRAY(taint_flags, flag_json)
        {
            if (!JSON_CHECK_TYPE(flag_json, SR_JSON_STRING, "taint flag"))
                goto fail;

            for (struct sr_taint_flag *f = sr_flags; f->name; f++)
            {
                if (0 == strcmp(f->name, flag_json->u.string.ptr))
                {
                    *(bool *)((void *)result + f->member_offset) = true;
                    break;
                }
            }
            /* XXX should we do something if nothing is set? */
        }
    }

    /* Modules. */
    struct sr_json_value *modules = json_element(root, "modules");
    if (modules)
    {
        if (!JSON_CHECK_TYPE(modules, SR_JSON_ARRAY, "modules"))
            goto fail;

        unsigned i = 0;
        size_t allocated = 128;
        result->modules = sr_malloc_array(allocated, sizeof(char*));

        struct sr_json_value *mod_json;
        FOR_JSON_ARRAY(modules, mod_json)
        {
            if (!JSON_CHECK_TYPE(mod_json, SR_JSON_STRING, "module"))
                goto fail;

            /* need to keep the last element for NULL terminator */
            if (i+1 == allocated)
            {
                allocated *= 2;
                result->modules = sr_realloc(result->modules, allocated);
            }
            result->modules[i] = sr_strdup(mod_json->u.string.ptr);
            i++;
        }

        result->modules[i] = NULL;
    }

    /* Frames. */
    struct sr_json_value *frames = json_element(root, "frames");
    if (frames)
    {
        if (!JSON_CHECK_TYPE(frames, SR_JSON_ARRAY, "frames"))
            goto fail;

        struct sr_json_value *frame_json;
        FOR_JSON_ARRAY(frames, frame_json)
        {
            struct sr_koops_frame *frame = sr_koops_frame_from_json(frame_json,
                error_message);

            if (!frame)
                goto fail;

            result->frames = sr_koops_frame_append(result->frames, frame);
        }
    }

    return result;

fail:
    sr_koops_stacktrace_free(result);
    return NULL;
}