Exemplo n.º 1
0
/* constructor */
PyObject *p_btp_frame_new(PyTypeObject *object, PyObject *args, PyObject *kwds)
{
    FrameObject *fo = (FrameObject *)PyObject_New(FrameObject, &FrameTypeObject);
    if (!fo)
        return PyErr_NoMemory();

    const char *str = NULL;
    if (!PyArg_ParseTuple(args, "|s", &str))
        return NULL;

    if (str)
    {
        struct btp_location location;
        btp_location_init(&location);
        fo->frame = btp_frame_parse(&str, &location);

        if (!fo->frame)
        {
            PyErr_SetString(PyExc_ValueError, location.message);
            return NULL;
        }
    }
    else
        fo->frame = btp_frame_new();

    return (PyObject *)fo;
}
Exemplo n.º 2
0
Arquivo: thread.c Projeto: rplnt/abrt
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;
}
Exemplo n.º 3
0
bool
btp_backtrace_parse_header(const char **input,
                           struct btp_frame **frame,
                           struct btp_location *location)
{
    int first_thread_line, first_thread_column;
    const char *first_thread = btp_strstr_location(*input,
                                                   "\nThread ",
                                                   &first_thread_line,
                                                   &first_thread_column);

    /* Skip the newline. */
    if (first_thread)
    {
        ++first_thread;
        first_thread_line += 1;
        first_thread_column = 0;
    }

    int first_frame_line, first_frame_column;
    const char *first_frame = btp_strstr_location(*input,
                                                  "\n#",
                                                  &first_frame_line,
                                                  &first_frame_column);

    /* Skip the newline. */
    if (first_frame)
    {
        ++first_frame;
        first_frame_line += 1;
        first_frame_column = 0;
    }

    if (first_thread)
    {
        if (first_frame && first_frame < first_thread)
        {
            /* Common case. The crash frame is present in the input
             * before the list of threads begins.
             */
            *input = first_frame;
            btp_location_add(location, first_frame_line, first_frame_column);
        }
        else
        {
	    /* Uncommon case (caused by some kernel bug) where the
             * frame is missing from the header.  The backtrace
             * contains just threads.  We silently skip the header and
             * return true.
             */
  	    *input = first_thread;
            btp_location_add(location,
                             first_thread_line,
                             first_thread_column);
            *frame = NULL;
	    return true;
        }
    }
    else if (first_frame)
    {
        /* Degenerate case when the backtrace contains no thread, but
         * the frame is there.
         */
        *input = first_frame;
        btp_location_add(location, first_frame_line, first_frame_column);
    }
    else
    {
        /* Degenerate case where the input is empty or completely
         * meaningless. Report a failure.
         */
        location->message = "No frame and no thread found.";
        return false;
    }

    /* Parse the frame header. */
    *frame = btp_frame_parse(input, location);
    return *frame;
}