Exemple #1
0
struct btp_thread *
btp_thread_dup(struct btp_thread *thread, bool siblings)
{
    struct btp_thread *result = btp_thread_new();
    memcpy(result, thread, sizeof(struct btp_thread));

    /* Handle siblings. */
    if (siblings)
    {
        if (result->next)
            result->next = btp_thread_dup(result->next, true);
    }
    else
        result->next = NULL; /* Do not copy that. */

    result->frames = btp_frame_dup(result->frames, true);

    return result;
}
Exemple #2
0
/* constructor */
PyObject *p_btp_thread_new(PyTypeObject *object, PyObject *args, PyObject *kwds)
{
    ThreadObject *to = (ThreadObject *)PyObject_New(ThreadObject, &ThreadTypeObject);
    if (!to)
        return PyErr_NoMemory();

    const char *str = NULL;
    int only_funs = 0;
    if (!PyArg_ParseTuple(args, "|si", &str, &only_funs))
        return NULL;

    if (str)
    {
        if (!only_funs)
        {
            struct btp_location location;
            btp_location_init(&location);
            to->thread = btp_thread_parse(&str, &location);
            if (!to->thread)
            {
                PyErr_SetString(PyExc_ValueError, location.message);
                return NULL;
            }
        }
        else
        {
            to->thread = btp_thread_parse_funs(str);
        }
        to->frames = frame_linked_list_to_python_list(to->thread);
        if (!to->frames)
            return NULL;
    }
    else
    {
        to->frames = PyList_New(0);
        to->thread = btp_thread_new();
    }

    return (PyObject *)to;
}
Exemple #3
0
struct btp_thread *
btp_thread_parse(char **input,
                 struct btp_location *location)
{
    char *local_input = *input;

    /* Read the Thread keyword, which is mandatory. */
    int chars = btp_skip_string(&local_input, "Thread");
    location->column += chars;
    if (0 == chars)
    {
        location->message = "\"Thread\" header expected";
        return NULL;
    }

    /* Skip spaces, at least one space is mandatory. */
    int spaces = btp_skip_char_sequence(&local_input, ' ');
    location->column += spaces;
    if (0 == spaces)
    {
        location->message = "Space expected after the \"Thread\" keyword.";
        return NULL;
    }

    /* Read thread number. */
    struct btp_thread *imthread = btp_thread_new();
    int digits = btp_parse_unsigned_integer(&local_input, &imthread->number);
    location->column += digits;
    if (0 == digits)
    {
        location->message = "Thread number expected.";
        btp_thread_free(imthread);
        return NULL;
    }

    /* Skip spaces after the thread number and before parentheses. */
    spaces = btp_skip_char_sequence(&local_input, ' ');
    location->column += spaces;
    if (0 == spaces)
    {
        location->message = "Space expected after the thread number.";
        btp_thread_free(imthread);
        return NULL;
    }

    /* Read the LWP section in parentheses, optional. */
    location->column += btp_thread_skip_lwp(&local_input);

    /* Read the Thread keyword in parentheses, optional. */
    chars = btp_skip_string(&local_input, "(Thread ");
    location->column += chars;
    if (0 != chars)
    {
        /* Read the thread identification number. It can be either in
         * decimal or hexadecimal form.
         * Examples:
         * "Thread 10 (Thread 2476):"
         * "Thread 8 (Thread 0xb07fdb70 (LWP 6357)):"
         */
        digits = btp_skip_hexadecimal_number(&local_input);
        if (0 == digits)
            digits = btp_skip_unsigned_integer(&local_input);
        location->column += digits;
        if (0 == digits)
        {
            location->message = "The thread identification number expected.";
            btp_thread_free(imthread);
            return NULL;
        }

        /* Handle the optional " (LWP [0-9]+)" section. */
        location->column += btp_skip_char_sequence(&local_input, ' ');
        location->column += btp_thread_skip_lwp(&local_input);

        /* Read the end of the parenthesis. */
        if (!btp_skip_char(&local_input, ')'))
        {
            location->message = "Closing parenthesis for Thread expected.";
            btp_thread_free(imthread);
            return NULL;
        }
    }

    /* Read the end of the header line. */
    chars = btp_skip_string(&local_input, ":\n");
    if (0 == chars)
    {
        location->message = "Expected a colon followed by a newline ':\\n'.";
        btp_thread_free(imthread);
        return NULL;
    }
    /* Add the newline from the last btp_skip_string. */
    btp_location_add(location, 2, 0);

    /* Read the frames. */
    struct btp_frame *frame, *prevframe = NULL;
    struct btp_location frame_location;
    btp_location_init(&frame_location);
    while ((frame = btp_frame_parse(&local_input, &frame_location)))
    {
        if (prevframe)
        {
            btp_frame_add_sibling(prevframe, frame);
            prevframe = frame;
        }
        else
            imthread->frames = prevframe = frame;

        btp_location_add(location,
                         frame_location.line,
                         frame_location.column);
    }
    if (!imthread->frames)
    {
        location->message = frame_location.message;
        btp_thread_free(imthread);
        return NULL;
    }

    *input = local_input;
    return imthread;
}