Esempio n. 1
0
struct sr_core_stacktrace *
sr_core_stacktrace_from_json(struct sr_json_value *root,
                             char **error_message)
{
    if (!JSON_CHECK_TYPE(root, SR_JSON_OBJECT, "stacktrace"))
        return NULL;

    struct sr_core_stacktrace *result = sr_core_stacktrace_new();

    bool success =
        JSON_READ_UINT16(root, "signal", &result->signal) &&
        JSON_READ_STRING(root, "executable", &result->executable) &&
        JSON_READ_BOOL(root, "only_crash_thread", &result->only_crash_thread);

    if (!success)
        goto fail;

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

        struct sr_json_value *json_thread;
        FOR_JSON_ARRAY(stacktrace, json_thread)
        {
            struct sr_core_thread *thread = sr_core_thread_from_json(json_thread,
                    error_message);

            if (!thread)
                goto fail;

            struct sr_json_value *crash_thread = json_element(json_thread, "crash_thread");
            if (crash_thread)
            {
                if (!JSON_CHECK_TYPE(crash_thread, SR_JSON_BOOLEAN, "crash_thread"))
                {
                    sr_core_thread_free(thread);
                    goto fail;
                }

                if (crash_thread->u.boolean)
                    result->crash_thread = thread;
            }

            result->threads = sr_core_thread_append(result->threads, thread);
        }
    }

    return result;

fail:
    sr_core_stacktrace_free(result);
    return NULL;
}
Esempio n. 2
0
/* destructor */
void
sr_py_core_thread_free(PyObject *object)
{
    struct sr_py_core_thread *this = (struct sr_py_core_thread *)object;
    /* the list will decref all of its elements */
    Py_DECREF(this->frames);
    this->thread->frames = NULL;
    sr_core_thread_free(this->thread);
    PyObject_Del(object);
}
Esempio n. 3
0
static int
unwind_thread(Dwfl_Thread *thread, void *data)
{
    struct thread_callback_arg *thread_arg = data;
    char **error_msg = &thread_arg->error_msg;

    struct sr_core_thread *result = sr_core_thread_new();
    if (!result)
    {
        set_error("Failed to initialize stacktrace memory");
        return DWARF_CB_ABORT;
    }
    result->id = (int64_t)dwfl_thread_tid(thread);

    struct frame_callback_arg frame_arg =
    {
        .thread = result,
        .error_msg = NULL
    };

    int ret = dwfl_thread_getframes(thread, frame_callback, &frame_arg);
    if (ret == -1)
    {
        warn("dwfl_thread_getframes failed for thread id %d: %s",
             (int)result->id, dwfl_errmsg(-1));
    }
    else if (ret == DWARF_CB_ABORT)
    {
        *error_msg = frame_arg.error_msg;
        goto abort;
    }
    else if (ret != 0 && ret != CB_STOP_UNWIND)
    {
        *error_msg = sr_strdup("Unknown error in dwfl_thread_getframes");
        goto abort;
    }

    if (!error_msg && !frame_arg.thread->frames)
    {
        set_error("No frames found for thread id %d", (int)result->id);
        goto abort;
    }

    thread_arg->stacktrace->threads =
        sr_core_thread_append(thread_arg->stacktrace->threads, result);
    return DWARF_CB_OK;

abort:
    sr_core_thread_free(result);
    return DWARF_CB_ABORT;
}
Esempio n. 4
0
void
sr_core_stacktrace_free(struct sr_core_stacktrace *stacktrace)
{
    if (!stacktrace)
        return;

    while (stacktrace->threads)
    {
        struct sr_core_thread *thread = stacktrace->threads;
        stacktrace->threads = thread->next;
        sr_core_thread_free(thread);
    }

    free(stacktrace);
}