Ejemplo n.º 1
0
/* a special line with instruction pointer may be present in the format
 * RIP: 0010:[<ffffffff811c6ed5>]  [<ffffffff811c6ed5>] __block_write_full_page+0xa5/0x350
 * (for x86_64), or
 * EIP: [<f8e40765>] wdev_priv.part.8+0x3/0x5 [wl] SS:ESP 0068:f180dbf8
 * (for i386, where it is AFTER the trace)
 */
static struct sr_koops_frame*
parse_IP(const char **input)
{
    struct sr_koops_frame *frame;
    const char *local_input = *input;
    sr_skip_char_span(&local_input, " \t");

    if (sr_skip_string(&local_input, "RIP:"))
    {
        if (!sr_skip_char_span(&local_input, " \t"))
            return NULL;

        /* The address is there twice, skip the first one */
        if (!sr_skip_char_cspan(&local_input, " \t"))
            return NULL;

        if (!sr_skip_char_span(&local_input, " \t"))
            return NULL;

        frame = sr_koops_frame_parse(&local_input);
        if (!frame)
            return NULL;
    }
    else if(sr_skip_string(&local_input, "EIP:"))
    {
        if (!sr_skip_char_span(&local_input, " \t"))
            return NULL;

        frame = sr_koops_frame_new();

        if (!sr_koops_parse_address(&local_input, &frame->address))
        {
            sr_koops_frame_free(frame);
            return NULL;
        }

        sr_skip_char_span(&local_input, " \t");

        /* Question mark means unreliable */
        frame->reliable = sr_skip_char(&local_input, '?') != true;

        sr_skip_char_span(&local_input, " \t");

        if (!sr_koops_parse_function(&local_input,
                                     &frame->function_name,
                                     &frame->function_offset,
                                     &frame->function_length,
                                     &frame->module_name))
        {
            sr_koops_frame_free(frame);
            return NULL;
        }
    }
    else
        return NULL;

    sr_skip_char_cspan(&local_input, "\n");
    *input = local_input;
    return frame;
}
Ejemplo n.º 2
0
struct sr_python_stacktrace *
sr_python_stacktrace_parse(const char **input,
                           struct sr_location *location)
{
    const char *local_input = *input;

    /* Parse the header. */
    if (sr_skip_char(&local_input, '\n'))
        location->column += 1;

    const char *HEADER = "Traceback (most recent call last):\n";
    local_input = sr_strstr_location(local_input,
                                     HEADER,
                                     &location->line,
                                     &location->column);

    if (!local_input)
    {
        /* SyntaxError stack trace of an exception thrown in the executed file
         * conforms to the following template:
         * invalid syntax ($file, line $number)
         *
         *    File "$file", line $number
         *       $code
         *         ^
         * SyntaxError: invalid syntax
         *
         * for exceptions thrown from imported files, the stack trace has the
         * regular form, except the last frame has no function name and is
         * followed by the pointer line (^).
         */
        HEADER = "invalid syntax (",
        local_input = sr_strstr_location(*input,
                                     HEADER,
                                     &location->line,
                                     &location->column);

        if (!local_input)
        {
            location->message = "Traceback header not found.";
            return NULL;
        }

        local_input = sr_strstr_location(local_input,
                           "  File \"",
                           &location->line,
                           &location->column);

        if (!local_input)
        {
            location->message = "Frame with invalid line not found.";
            return NULL;
        }
    }
    else
    {
        local_input += strlen(HEADER);
        location->line += 2;
        location->column = 0;
    }

    struct sr_python_stacktrace *stacktrace = sr_python_stacktrace_new();

    /* Read the frames. */
    struct sr_python_frame *frame;
    struct sr_location frame_location;
    sr_location_init(&frame_location);
    while ((frame = sr_python_frame_parse(&local_input, &frame_location)))
    {
        /*
         * Python stacktraces are in reverse order than other types - we
         * reverse it here by prepending each frame to the list instead of
         * appending it.
         */
        frame->next = stacktrace->frames;
        stacktrace->frames = frame;

        sr_location_add(location,
                        frame_location.line,
                        frame_location.column);
    }

    if (!stacktrace->frames)
    {
        location->message = frame_location.message;
        sr_python_stacktrace_free(stacktrace);
        return NULL;
    }

    bool invalid_syntax_pointer = true;
    const char *tmp_input = local_input;
    while (*tmp_input != '\n' && *tmp_input != '\0')
    {
        if (*tmp_input != ' ' && *tmp_input != '^')
        {
            invalid_syntax_pointer = false;
            break;
        }
        ++tmp_input;
    }

    if (invalid_syntax_pointer)
    {
        /* Skip line "   ^" pointing to the invalid code */
        sr_skip_char_cspan(&local_input, "\n");
        ++local_input;
        ++location->line;
        location->column = 1;
    }

    /* Parse exception name. */
    if (!sr_parse_char_cspan(&local_input, ":\n", &stacktrace->exception_name))
    {

        location->message = "Unable to find the ':\\n' characters "
                            "identifying the end of exception name.";
        sr_python_stacktrace_free(stacktrace);
        return NULL;

    }

    *input = local_input;
    return stacktrace;
}
Ejemplo n.º 3
0
struct sr_java_frame *
sr_java_frame_parse(const char **input,
                     struct sr_location *location)
{
    const char *mark = *input;
    int lines, columns;
    /*      at SimpleTest.throwNullPointerException(SimpleTest.java:36) [file:/usr/lib/java/foo.class] */
    const char *cursor = sr_strstr_location(mark, "at", &lines, &columns);

    if (!cursor)
    {
        location->message = "Frame expected";
        return NULL;
    }

    /*  SimpleTest.throwNullPointerException(SimpleTest.java:36) [file:/usr/lib/java/foo.class] */
    cursor = mark = cursor + 2;
    sr_location_add(location, lines, columns + 2);

    /* SimpleTest.throwNullPointerException(SimpleTest.java:36) [file:/usr/lib/java/foo.class] */
    cursor = sr_skip_whitespace(cursor);
    sr_location_add(location, 0, cursor - mark);
    mark = cursor;

    sr_location_add(location, 0, sr_skip_char_cspan(&cursor, "(\n"));

    struct sr_java_frame *frame = sr_java_frame_new();

    if (cursor != mark)
        frame->name = sr_strndup(mark, cursor - mark);

    /* (SimpleTest.java:36) [file:/usr/lib/java/foo.class] */
    if (*cursor == '(')
    {
        ++cursor;
        sr_location_add(location, 0, 1);
        mark = cursor;

        sr_location_add(location, 0, sr_skip_char_cspan(&cursor, ":)\n"));

        if (mark != cursor)
        {
            if (sr_java_frame_parse_is_native_method(mark))
                frame->is_native = true;
            else if (!sr_java_frame_parse_is_unknown_source(mark))
            {
                /* DO NOT set file_name if input says that source isn't known */
                frame->file_name = sr_strndup(mark, cursor - mark);
                frame->file_name = anonymize_path(frame->file_name);
            }
        }

        if (*cursor == ':')
        {
            ++cursor;
            sr_location_add(location, 0, 1);
            mark = cursor;

            sr_parse_uint32(&cursor, &(frame->file_line));

            sr_location_add(location, 0, cursor - mark);
        }
    }

    /* [file:/usr/lib/java/foo.class] */
    mark = sr_java_frame_parse_frame_url(frame, cursor, location);
    cursor = strchrnul(mark, '\n');

    if (*cursor == '\n')
    {
        *input = cursor + 1;
        sr_location_add(location, 2, 0);
    }
    else
    {
        *input = cursor;
        /* don't take \0 Byte into account */
        sr_location_add(location, 0, (cursor - mark) - 1);
    }

    return frame;
}
Ejemplo n.º 4
0
/* [jar:http://locahost/usr/lib/java/foo.jar!/Foo.class] */
static
const char *sr_java_frame_parse_frame_url(struct sr_java_frame *frame, const char *mark,
                                            struct sr_location *location)
{
    const char *cursor = mark;

    sr_location_add(location, 0, sr_skip_char_cspan(&cursor, "[\n"));

    if (*cursor != '[')
        return cursor;

    ++cursor;
    sr_location_add(location, 0, 1);
    mark = cursor;

    sr_location_add(location, 0, sr_skip_char_cspan(&cursor, ":\n"));

    if (*cursor == ':')
    {
        const char *path_stop = "]\n";
        if (strncmp("jar:", mark, strlen("jar:")) == 0)
        {   /* From jar:file:/usr/lib/java/foo.jar!/Foo.class] */
            /*                                               ^ */
            ++cursor;
            sr_location_add(location, 0, 1);
            mark = cursor;
            sr_location_add(location, 0, sr_skip_char_cspan(&cursor, ":\n"));
            path_stop = "!\n";
            /* To   file:/usr/lib/java/foo.jar!/Foo.class] */
            /*                                ^            */

            if (*cursor != ':')
                return cursor;
        }

        if (strncmp("file:", mark, strlen("file:")) != 0)
        {   /* move cursor back in case of http: ... */
            sr_location_add(location, 0, -(cursor - mark));
            cursor = mark;
        }
        else
        {
            ++cursor;
            sr_location_add(location, 0, 1);
            mark = cursor;
        }

        sr_location_add(location, 0, sr_skip_char_cspan(&cursor, path_stop));

        if (mark != cursor)
        {
            frame->class_path = sr_strndup(mark, cursor - mark);
            frame->class_path = anonymize_path(frame->class_path);
        }
    }

    if (*cursor != ']' && *cursor != '\n')
        sr_location_add(location, 0, sr_skip_char_cspan(&cursor, "]\n"));

    return cursor;
}
Ejemplo n.º 5
0
struct sr_java_frame *
sr_java_frame_parse_exception(const char **input,
                              struct sr_location *location)
{
    /* java.lang.NullPointerException: foo */
    const char *cursor = sr_skip_whitespace(*input);
    sr_location_add(location, 0, cursor - *input);
    const char *mark = cursor;

    sr_location_add(location, 0, sr_skip_char_cspan(&cursor, ": \t\n"));

    if (mark == cursor)
    {
        location->message = "Expected exception name";
        return NULL;
    }

    struct sr_java_frame *exception = sr_java_frame_new_exception();
    exception->name = sr_strndup(mark, cursor - mark);

    /* : foo */
    if (*cursor == ':')
    {
        ++cursor;
        sr_location_add(location, 0, 1);
        mark = cursor;

        /* foo */
        cursor = sr_skip_whitespace(mark);
        sr_location_add(location, 0, cursor - mark);
        mark = cursor;

        sr_location_add(location, 0, sr_skip_char_cspan(&cursor, "\n"));

        if (mark != cursor)
            exception->message = sr_strndup(mark, cursor - mark);
    }
    else
    {
        /* just to be sure, that we skip white space behind exception name */
        sr_location_add(location, 0, sr_skip_char_cspan(&cursor, "\n"));
    }

    if (*cursor == '\n')
    {
        ++cursor;
        /* this adds one line */
        sr_location_add(location, 2, 0);
    }
    /* else *cursor == '\0' */

    mark = cursor;

    struct sr_java_frame *frame = NULL;
    /* iterate line by line
       best effort - continue on error */
    while (*cursor != '\0')
    {
        cursor = sr_skip_whitespace(mark);
        sr_location_add(location, 0, cursor - mark);

        /* Each inner exception has '...' at its end */
        if (strncmp("... ", cursor, strlen("... ")) == 0)
            goto current_exception_done;

        /* Suppressed exceptions follow after the end of current exception */
        if (strncmp("Suppressed: ", cursor, strlen("Suppressed: ")) == 0)
            goto current_exception_done;

        /* The top most exception does not have '...' at its end */
        if (strncmp("Caused by: ", cursor, strlen("Caused by: ")) == 0)
            goto parse_inner_exception;

        struct sr_java_frame *parsed = sr_java_frame_parse(&cursor, location);

        if (parsed == NULL)
        {
            sr_java_frame_free(exception);
            return NULL;
        }

        mark = cursor;

        if (exception->next == NULL)
            exception->next = parsed;
        else
        {
            assert(frame);
            frame->next = parsed;
        }

        frame = parsed;
    }
    /* We are done with the top most exception without inner exceptions */
    /* because of no 'Caused by:' and no '...' */
    goto exception_parsing_successful;

current_exception_done:
    sr_skip_to_next_line_location(&cursor, &location->line, &location->column);

    mark = cursor;
    cursor = sr_skip_whitespace(mark);
    sr_location_add(location, 0, cursor - mark);

    if (strncmp("Suppressed: ", cursor, strlen("Suppressed: ")) == 0)
    {
        /* Skip all lines related to the suppressed exception. We can do
         * this by skipping all lines that begin with a whitespace - the
         * main exception chain always begins without preceding whitespace.
         */
        sr_skip_to_next_line_location(&cursor, &location->line, &location->column);

        while (cursor && isspace(*cursor))
            sr_skip_to_next_line_location(&cursor, &location->line, &location->column);
    }

    if (strncmp("Caused by: ", cursor, strlen("Caused by: ")) == 0)
    {
parse_inner_exception:
        cursor += strlen("Caused by: ");
        sr_location_add(location, 0, strlen("Caused by: "));

        struct sr_java_frame *inner = sr_java_frame_parse_exception(&cursor, location);
        if (inner == NULL)
        {
            sr_java_frame_free(exception);
            return NULL;
        }

        struct sr_java_frame *last_inner = sr_java_frame_get_last(inner);
        last_inner->next = exception;
        exception = inner;
    }

exception_parsing_successful:
    *input = cursor;

    return exception;
}
Ejemplo n.º 6
0
struct sr_koops_stacktrace *
sr_koops_stacktrace_parse(const char **input,
                          struct sr_location *location)
{
    const char *local_input = *input;

    struct sr_koops_stacktrace *stacktrace = sr_koops_stacktrace_new();
    struct sr_koops_frame *frame;
    bool parsed_ip = false;
    char *alt_stack = NULL;

    /* Include the raw kerneloops text */
    stacktrace->raw_oops = sr_strdup(*input);

    /* Looks for the "Tainted: " line in the whole input */
    parse_taint_flags(local_input, stacktrace);

    while (*local_input)
    {
        sr_skip_char_span(&local_input, " \t");

        /* Skip timestamp if it's present. */
        sr_koops_skip_timestamp(&local_input);
        sr_skip_char_span(&local_input, " \t");

        /* Not sure what it means on s390x but i think it's at the end of the
         * stack
         */
        if (sr_skip_string(&local_input, "Last Breaking-Event-Address:\n"))
        {
            while (*local_input)
                local_input++;
            break;
        }

        if (!stacktrace->modules &&
            (stacktrace->modules = sr_koops_stacktrace_parse_modules(&local_input)))
            goto next_line;

        if (!parsed_ip &&
            (frame = parse_IP(&local_input)))
        {
            /* this is the very first frame (even though for i386 it's at the
             * end), we need to prepend it */
            stacktrace->frames = sr_koops_frame_prepend(stacktrace->frames, frame);
            parsed_ip = true;
            goto next_line;
        }

        /* <IRQ>, <NMI>, ... */
        if (parse_alt_stack_end(&local_input))
        {
            free(alt_stack);
            alt_stack = NULL;
        }

        /* <EOI>, <<EOE>> */
        char *new_alt_stack = parse_alt_stack_start(&local_input);
        if (new_alt_stack)
        {
            alt_stack = new_alt_stack;
        }

        if((frame = sr_koops_frame_parse(&local_input)))
        {
            if (alt_stack)
                frame->special_stack = sr_strdup(alt_stack);

            stacktrace->frames = sr_koops_frame_append(stacktrace->frames, frame);
            goto next_line;
        }

        sr_skip_char_cspan(&local_input, "\n");

next_line:
        sr_skip_char(&local_input, '\n');
    }

    *input = local_input;
    return stacktrace;
}