Beispiel #1
0
static
int append_short_backtrace(struct strbuf *result, problem_data_t *problem_data, size_t max_text_size, bool print_item_name)
{
    const problem_item *item = problem_data_get_item_or_NULL(problem_data,
                                                             FILENAME_BACKTRACE);
    if (!item)
        return 0; /* "I did not print anything" */
    if (!(item->flags & CD_FLAG_TXT))
        return 0; /* "I did not print anything" */

    char *truncated = NULL;

    if (strlen(item->content) >= max_text_size)
    {
        struct sr_location location;
        sr_location_init(&location);

        /* sr_gdb_stacktrace_parse modifies the input parameter */
        char *content = item->content;
        struct sr_gdb_stacktrace *backtrace = sr_gdb_stacktrace_parse((const char **)&content, &location);

        if (!backtrace)
        {
            log(_("Can't parse backtrace"));
            return 0;
        }

        /* Get optimized thread stack trace for 10 top most frames */
        struct sr_gdb_thread *thread = sr_gdb_stacktrace_get_optimized_thread(backtrace, 10);

        sr_gdb_stacktrace_free(backtrace);

        if (!thread)
        {
            log(_("Can't find crash thread"));
            return 0;
        }

        /* Cannot be NULL, it dies on memory error */
        struct sr_strbuf *bt = sr_strbuf_new();

        sr_gdb_thread_append_to_str(thread, bt, true);

        sr_gdb_thread_free(thread);

        truncated = sr_strbuf_free_nobuf(bt);
    }

    append_text(result,
                /*item_name:*/ truncated ? "truncated_backtrace" : FILENAME_BACKTRACE,
                /*content:*/   truncated ? truncated             : item->content,
                print_item_name
    );
    free(truncated);
    return 1;
}
Beispiel #2
0
char *
sr_java_frame_to_json(struct sr_java_frame *frame)
{
    struct sr_strbuf *strbuf = sr_strbuf_new();

    /* Name. */
    if (frame->name)
    {
        sr_strbuf_append_str(strbuf, ",   \"name\": ");
        sr_json_append_escaped(strbuf, frame->name);
        sr_strbuf_append_str(strbuf, "\n");
    }

    /* File name. */
    if (frame->file_name)
    {
        sr_strbuf_append_str(strbuf, ",   \"file_name\": ");
        sr_json_append_escaped(strbuf, frame->file_name);
        sr_strbuf_append_str(strbuf, "\n");

        /* File line. */
        sr_strbuf_append_strf(strbuf,
                              ",   \"file_line\": %"PRIu32"\n",
                              frame->file_line);
    }

    /* Class path. */
    if (frame->class_path)
    {
        sr_strbuf_append_str(strbuf, ",   \"class_path\": ");
        sr_json_append_escaped(strbuf, frame->class_path);
        sr_strbuf_append_str(strbuf, "\n");
    }

    /* Is native? */
    sr_strbuf_append_strf(strbuf,
                          ",   \"is_native\": %s\n",
                          frame->is_native ? "true" : "false");

    /* Is exception? */
    sr_strbuf_append_strf(strbuf,
                          ",   \"is_exception\": %s\n",
                          frame->is_exception ? "true" : "false");

    /* Message. */
    if (frame->message)
    {
        sr_strbuf_append_str(strbuf, ",   \"message\": ");
        sr_json_append_escaped(strbuf, frame->message);
        sr_strbuf_append_str(strbuf, "\n");
    }

    strbuf->buf[0] = '{';
    sr_strbuf_append_str(strbuf, "}");
    return sr_strbuf_free_nobuf(strbuf);
}
Beispiel #3
0
char *
sr_ruby_frame_to_json(struct sr_ruby_frame *frame)
{
    struct sr_strbuf *strbuf = sr_strbuf_new();

    /* Source file name. */
    if (frame->file_name)
    {
        sr_strbuf_append_str(strbuf, ",   \"file_name\": ");
        sr_json_append_escaped(strbuf, frame->file_name);
        sr_strbuf_append_str(strbuf, "\n");
    }

    /* Source file line. */
    if (frame->file_line)
    {
        sr_strbuf_append_strf(strbuf,
                              ",   \"file_line\": %"PRIu32"\n",
                              frame->file_line);
    }

    /* Function name / special function. */
    if (frame->function_name)
    {
        if (frame->special_function)
            sr_strbuf_append_str(strbuf, ",   \"special_function\": ");
        else
            sr_strbuf_append_str(strbuf, ",   \"function_name\": ");

        sr_json_append_escaped(strbuf, frame->function_name);
        sr_strbuf_append_str(strbuf, "\n");
    }

    /* Block level. */
    if (frame->block_level > 0)
    {
        sr_strbuf_append_strf(strbuf,
                              ",   \"block_level\": %"PRIu32"\n",
                              frame->block_level);
    }

    /* Rescue level. */
    if (frame->rescue_level > 0)
    {
        sr_strbuf_append_strf(strbuf,
                              ",   \"rescue_level\": %"PRIu32"\n",
                              frame->rescue_level);
    }


    strbuf->buf[0] = '{';
    sr_strbuf_append_char(strbuf, '}');
    return sr_strbuf_free_nobuf(strbuf);
}
Beispiel #4
0
PyObject *
sr_py_distances_str(PyObject *self)
{
    struct sr_py_distances *this = (struct sr_py_distances *)self;
    struct sr_strbuf *buf = sr_strbuf_new();
    sr_strbuf_append_strf(buf, "%d-by-%d distance matrix",
                           this->distances->m, this->distances->n);
    char *str = sr_strbuf_free_nobuf(buf);
    PyObject *result = Py_BuildValue("s", str);
    free(str);
    return result;
}
Beispiel #5
0
PyObject *
sr_py_core_thread_str(PyObject *self)
{
    struct sr_py_core_thread *this = (struct sr_py_core_thread *)self;
    struct sr_strbuf *buf = sr_strbuf_new();
    sr_strbuf_append_strf(buf, "Thread with %zd frames", (ssize_t)(PyList_Size(this->frames)));

    char *str = sr_strbuf_free_nobuf(buf);
    PyObject *result = Py_BuildValue("s", str);
    free(str);
    return result;
}
Beispiel #6
0
char *
sr_disasm_instructions_to_text(char **instructions)
{
    struct sr_strbuf *strbuf = sr_strbuf_new();
    while (*instructions)
    {
        sr_strbuf_append_str(strbuf, *instructions);
        sr_strbuf_append_char(strbuf, '\n');
        ++instructions;
    }

    return sr_strbuf_free_nobuf(strbuf);
}
Beispiel #7
0
/* methods */
PyObject *
sr_py_base_frame_short_string(PyObject *self, PyObject *args)
{
    struct sr_frame *frame = ((struct sr_py_base_frame*)self)->frame;
    struct sr_strbuf *strbuf = sr_strbuf_new();

    sr_frame_append_to_str(frame, strbuf);
    char *str = sr_strbuf_free_nobuf(strbuf);

    PyObject *result = PyString_FromString(str);
    free(str);
    return result;
}
Beispiel #8
0
/* str */
PyObject *
sr_py_koops_frame_str(PyObject *self)
{
    struct sr_py_koops_frame *this = (struct sr_py_koops_frame*)self;
    struct sr_strbuf *buf = sr_strbuf_new();
    if (this->frame->special_stack)
        sr_strbuf_append_strf(buf, "[%s] ", this->frame->special_stack);

    if (this->frame->address != 0)
        sr_strbuf_append_strf(buf, "[0x%016"PRIx64"] ", this->frame->address);

    if (!this->frame->reliable)
        sr_strbuf_append_str(buf, "? ");

    if (this->frame->function_name)
        sr_strbuf_append_str(buf, this->frame->function_name);

    if (this->frame->function_offset)
        sr_strbuf_append_strf(buf, "+0x%"PRIx64, this->frame->function_offset);

    if (this->frame->function_length)
        sr_strbuf_append_strf(buf, "/0x%"PRIx64, this->frame->function_length);

    if (this->frame->module_name)
        sr_strbuf_append_strf(buf, " [%s]", this->frame->module_name);

    if (this->frame->from_function_name || this->frame->from_address)
        sr_strbuf_append_str(buf, " from ");

    if (this->frame->from_address != 0)
        sr_strbuf_append_strf(buf, "[0x%016"PRIx64"] ", this->frame->from_address);

    if (this->frame->from_function_name)
        sr_strbuf_append_str(buf, this->frame->from_function_name);

    if (this->frame->from_function_offset)
        sr_strbuf_append_strf(buf, "+0x%"PRIx64, this->frame->from_function_offset);

    if (this->frame->from_function_length)
        sr_strbuf_append_strf(buf, "/0x%"PRIx64, this->frame->from_function_length);

    if (this->frame->from_module_name)
        sr_strbuf_append_strf(buf, " [%s]", this->frame->from_module_name);

    char *str = sr_strbuf_free_nobuf(buf);
    PyObject *result = Py_BuildValue("s", str);
    free(str);
    return result;
}
Beispiel #9
0
char *
sr_python_frame_to_json(struct sr_python_frame *frame)
{
    struct sr_strbuf *strbuf = sr_strbuf_new();

    /* Source file name / special file. */
    if (frame->file_name)
    {
        if (frame->special_file)
            sr_strbuf_append_str(strbuf, ",   \"special_file\": ");
        else
            sr_strbuf_append_str(strbuf, ",   \"file_name\": ");

        sr_json_append_escaped(strbuf, frame->file_name);
        sr_strbuf_append_str(strbuf, "\n");
    }

    /* Source file line. */
    if (frame->file_line)
    {
        sr_strbuf_append_strf(strbuf,
                              ",   \"file_line\": %"PRIu32"\n",
                              frame->file_line);
    }

    /* Function name / special function. */
    if (frame->function_name)
    {
        if (frame->special_function)
            sr_strbuf_append_str(strbuf, ",   \"special_function\": ");
        else
            sr_strbuf_append_str(strbuf, ",   \"function_name\": ");

        sr_json_append_escaped(strbuf, frame->function_name);
        sr_strbuf_append_str(strbuf, "\n");
    }

    /* Line contents. */
    if (frame->line_contents)
    {
        sr_strbuf_append_str(strbuf, ",   \"line_contents\": ");
        sr_json_append_escaped(strbuf, frame->line_contents);
        sr_strbuf_append_str(strbuf, "\n");
    }

    strbuf->buf[0] = '{';
    sr_strbuf_append_char(strbuf, '}');
    return sr_strbuf_free_nobuf(strbuf);
}
Beispiel #10
0
char *
sr_core_stacktrace_to_json(struct sr_core_stacktrace *stacktrace)
{
    struct sr_strbuf *strbuf = sr_strbuf_new();
    sr_strbuf_append_strf(strbuf,
                          "{   \"signal\": %"PRIu16"\n",
                          stacktrace->signal);

    if (stacktrace->executable)
    {
        sr_strbuf_append_str(strbuf, ",   \"executable\": ");
        sr_json_append_escaped(strbuf, stacktrace->executable);
        sr_strbuf_append_str(strbuf, "\n");
    }

    if (stacktrace->only_crash_thread)
        sr_strbuf_append_str(strbuf, ",   \"only_crash_thread\": true\n");

    sr_strbuf_append_str(strbuf, ",   \"stacktrace\":\n");

    struct sr_core_thread *thread = stacktrace->threads;
    while (thread)
    {
        if (thread == stacktrace->threads)
            sr_strbuf_append_str(strbuf, "      [ ");
        else
            sr_strbuf_append_str(strbuf, "      , ");

        bool crash_thread = (thread == stacktrace->crash_thread);
        /* If we don't know the crash thread, just take the first one. */
        crash_thread |= (stacktrace->crash_thread == NULL
                         && thread == stacktrace->threads);

        char *thread_json = sr_core_thread_to_json(thread, crash_thread);
        char *indented_thread_json = sr_indent_except_first_line(thread_json, 8);

        sr_strbuf_append_str(strbuf, indented_thread_json);
        free(indented_thread_json);
        free(thread_json);
        thread = thread->next;
        if (thread)
            sr_strbuf_append_str(strbuf, "\n");
    }

    sr_strbuf_append_str(strbuf, " ]\n");
    sr_strbuf_append_char(strbuf, '}');
    return sr_strbuf_free_nobuf(strbuf);
}
Beispiel #11
0
char *
sr_disasm_binary_to_text(struct sr_disasm_state *state,
                         uint64_t start_offset,
                         uint64_t size,
                         char **error_message)
{
#if HAVE_LIBOPCODES
    asection *section = state->info.section;
    if (start_offset < section->vma
        || (start_offset + size) > section->vma + section->size)
    {
        *error_message = sr_asprintf(
            "Invalid function range: 0x%"PRIx64" - 0x%"PRIx64,
            start_offset,
            start_offset + size);

        return NULL;
    }

    char *code = sr_malloc(size);
    bool success = bfd_get_section_contents(state->bfd_file,
                                            state->info.section,
                                            code,
                                            start_offset - section->vma,
                                            size);

    if (!success)
    {
        *error_message = sr_strdup("Failed to get section contents.");
        return NULL;
    }

    struct sr_strbuf *strbuf = sr_strbuf_new();
    for (int i = 0; i < size; ++i)
    {
        sr_strbuf_append_strf(strbuf, "0x%02x ", (unsigned)code[i]);
        if ((i + 1) % 12 == 0)
            sr_strbuf_append_char(strbuf, '\n');
    }

    free(code);
    return sr_strbuf_free_nobuf(strbuf);
#else // HAVE_LIBOPCODES
    *error_message = sr_asprintf("satyr compiled without libopcodes");
    return NULL;
#endif // HAVE_LIBOPCODES
}
Beispiel #12
0
char *
sr_python_stacktrace_to_json(struct sr_python_stacktrace *stacktrace)
{
    struct sr_strbuf *strbuf = sr_strbuf_new();

    /* Exception class name. */
    if (stacktrace->exception_name)
    {
        sr_strbuf_append_str(strbuf, ",   \"exception_name\": ");
        sr_json_append_escaped(strbuf, stacktrace->exception_name);
        sr_strbuf_append_str(strbuf, "\n");
    }

    /* Frames. */
    if (stacktrace->frames)
    {
        struct sr_python_frame *frame = stacktrace->frames;
        sr_strbuf_append_str(strbuf, ",   \"stacktrace\":\n");
        while (frame)
        {
            if (frame == stacktrace->frames)
                sr_strbuf_append_str(strbuf, "      [ ");
            else
                sr_strbuf_append_str(strbuf, "      , ");

            char *frame_json = sr_python_frame_to_json(frame);
            char *indented_frame_json = sr_indent_except_first_line(frame_json, 8);
            sr_strbuf_append_str(strbuf, indented_frame_json);
            free(indented_frame_json);
            free(frame_json);
            frame = frame->next;
            if (frame)
                sr_strbuf_append_str(strbuf, "\n");
        }

        sr_strbuf_append_str(strbuf, " ]\n");
    }

    if (strbuf->len > 0)
        strbuf->buf[0] = '{';
    else
        sr_strbuf_append_char(strbuf, '{');

    sr_strbuf_append_char(strbuf, '}');
    return sr_strbuf_free_nobuf(strbuf);
}
Beispiel #13
0
char *
sr_elf_fde_to_json(struct sr_elf_fde *fde,
                   bool recursive)
{
    struct sr_strbuf *strbuf = sr_strbuf_new();

    if (recursive)
    {
        struct sr_elf_fde *loop = fde;
        while (loop)
        {
            if (loop == fde)
                sr_strbuf_append_str(strbuf, "[ ");
            else
                sr_strbuf_append_str(strbuf, ", ");

            char *fde_json = sr_elf_fde_to_json(loop, false);
            char *indented_fde_json = sr_indent_except_first_line(fde_json, 2);
            sr_strbuf_append_str(strbuf, indented_fde_json);
            free(indented_fde_json);
            free(fde_json);
            loop = loop->next;
            if (loop)
                sr_strbuf_append_str(strbuf, "\n");
        }

        sr_strbuf_append_str(strbuf, " ]");
    }
    else
    {
        /* Start address. */
        sr_strbuf_append_strf(strbuf,
                              "{   \"start_address\": %"PRIu64"\n",
                              fde->start_address);

        /* Length. */
        sr_strbuf_append_strf(strbuf,
                              ",   \"length\": %"PRIu64"\n",
                              fde->length);

        sr_strbuf_append_str(strbuf, "}");
    }

    return sr_strbuf_free_nobuf(strbuf);
}
Beispiel #14
0
/* str */
PyObject *
sr_py_java_frame_str(PyObject *self)
{
    struct sr_py_java_frame *this = (struct sr_py_java_frame*)self;
    struct sr_strbuf *buf = sr_strbuf_new();

    if (this->frame->is_exception)
    {
        sr_strbuf_append_str(buf, this->frame->name);
        if (this->frame->message)
            sr_strbuf_append_strf(buf, ": %s", this->frame->message);
    }
    else
    {
        sr_strbuf_append_str(buf, "\t");
        if (this->frame->name)
            sr_strbuf_append_strf(buf, "at %s", this->frame->name);

        if (this->frame->file_name)
            sr_strbuf_append_strf(buf, "(%s", this->frame->file_name);

        if (this->frame->file_line)
            sr_strbuf_append_strf(buf, ":%d", this->frame->file_line);

        if (this->frame->is_native)
            sr_strbuf_append_str(buf, "(Native Method");

        sr_strbuf_append_str(buf, ")");
    }

    /*
     * not present (parsed) at the moment
    if (this->frame->class_path)
        sr_strbuf_append_strf(buf, "class_path:%s", this->frame->class_path);
    */

    char *str = sr_strbuf_free_nobuf(buf);
    PyObject *result = Py_BuildValue("s", str);
    free(str);
    return result;
}
Beispiel #15
0
/* str */
PyObject *
sr_py_gdb_frame_str(PyObject *self)
{
    struct sr_py_gdb_frame *this = (struct sr_py_gdb_frame*)self;
    struct sr_strbuf *buf = sr_strbuf_new();
    sr_strbuf_append_strf(buf, "Frame #%u: ", this->frame->number);
    if (!this->frame->function_name)
        sr_strbuf_append_str(buf, "signal handler");
    else if (strncmp("??", this->frame->function_name, strlen("??")) == 0)
        sr_strbuf_append_str(buf, "unknown function");
    else
        sr_strbuf_append_strf(buf, "function %s", this->frame->function_name);
    if (this->frame->address != -1)
        sr_strbuf_append_strf(buf, " @ 0x%016"PRIx64, this->frame->address);
    if (this->frame->library_name)
        sr_strbuf_append_strf(buf, " (%s)", this->frame->library_name);
    char *str = sr_strbuf_free_nobuf(buf);
    PyObject *result = Py_BuildValue("s", str);
    free(str);
    return result;
}
Beispiel #16
0
static char *
taint_flags_to_json(struct sr_koops_stacktrace *stacktrace)
{
    struct sr_strbuf *strbuf = sr_strbuf_new();

    struct sr_taint_flag *f;
    for (f = sr_flags; f->letter; f++)
    {
        bool val = *(bool *)((void *)stacktrace + f->member_offset);
        if (val == true)
        {
            sr_strbuf_append_strf(strbuf, ", \"%s\"\n", f->name);
        }
    }

    if (strbuf->len == 0)
        return sr_strdup("[]");

    sr_strbuf_append_char(strbuf, ']');
    char *result = sr_strbuf_free_nobuf(strbuf);
    result[0] = '[';
    result[strlen(result) - 2] = ' '; /* erase the last newline */
    return result;
}
Beispiel #17
0
char *
sr_operating_system_to_json(struct sr_operating_system *operating_system)
{
    struct sr_strbuf *strbuf = sr_strbuf_new();

    if (operating_system->name)
    {
        sr_strbuf_append_str(strbuf, ",   \"name\": ");
        sr_json_append_escaped(strbuf, operating_system->name);
        sr_strbuf_append_str(strbuf, "\n");
    }

    if (operating_system->version)
    {
        sr_strbuf_append_str(strbuf, ",   \"version\": ");
        sr_json_append_escaped(strbuf, operating_system->version);
        sr_strbuf_append_str(strbuf, "\n");
    }

    if (operating_system->architecture)
    {
        sr_strbuf_append_str(strbuf, ",   \"architecture\": ");
        sr_json_append_escaped(strbuf, operating_system->architecture);
        sr_strbuf_append_str(strbuf, "\n");
    }

    if (operating_system->cpe)
    {
        sr_strbuf_append_str(strbuf, ",   \"cpe\": ");
        sr_json_append_escaped(strbuf, operating_system->cpe);
        sr_strbuf_append_str(strbuf, "\n");
    }

    if (operating_system->desktop)
    {
        sr_strbuf_append_str(strbuf, ",   \"desktop\": ");
        sr_json_append_escaped(strbuf, operating_system->desktop);
        sr_strbuf_append_str(strbuf, "\n");
    }

    if (operating_system->variant)
    {
        sr_strbuf_append_str(strbuf, ",   \"variant\": ");
        sr_json_append_escaped(strbuf, operating_system->variant);
        sr_strbuf_append_str(strbuf, "\n");
    }

    if (operating_system->uptime > 0)
    {
        sr_strbuf_append_strf(strbuf,
                              ",   \"uptime\": %"PRIu64"\n",
                              operating_system->uptime);
    }

    if (strbuf->len > 0)
        strbuf->buf[0] = '{';
    else
        sr_strbuf_append_char(strbuf, '{');

    sr_strbuf_append_char(strbuf, '}');
    return sr_strbuf_free_nobuf(strbuf);
}
Beispiel #18
0
char *
sr_koops_stacktrace_to_json(struct sr_koops_stacktrace *stacktrace)
{
    struct sr_strbuf *strbuf = sr_strbuf_new();

    /* Raw oops. */
    if (stacktrace->raw_oops)
    {
        sr_strbuf_append_str(strbuf, ",   \"raw_oops\": ");
        sr_json_append_escaped(strbuf, stacktrace->raw_oops);
        sr_strbuf_append_str(strbuf, "\n");
    }

    /* Kernel version. */
    if (stacktrace->version)
    {
        sr_strbuf_append_str(strbuf, ",   \"version\": ");
        sr_json_append_escaped(strbuf, stacktrace->version);
        sr_strbuf_append_str(strbuf, "\n");
    }

    /* Kernel taint flags. */
    char *taint_flags = taint_flags_to_json(stacktrace);
    char *indented_taint_flags = sr_indent_except_first_line(taint_flags, strlen(",   \"taint_flags\": "));
    free(taint_flags);
    sr_strbuf_append_strf(strbuf, ",   \"taint_flags\": %s\n", indented_taint_flags);
    free(indented_taint_flags);

    /* Modules. */
    if (stacktrace->modules)
    {
        sr_strbuf_append_strf(strbuf, ",   \"modules\":\n");
        sr_strbuf_append_str(strbuf, "      [ ");

        char **module = stacktrace->modules;
        while (*module)
        {
            if (module != stacktrace->modules)
                sr_strbuf_append_str(strbuf, "      , ");

            sr_json_append_escaped(strbuf, *module);
            ++module;
            if (*module)
                sr_strbuf_append_str(strbuf, "\n");
        }

        sr_strbuf_append_str(strbuf, " ]\n");
    }

    /* Frames. */
    if (stacktrace->frames)
    {
        struct sr_koops_frame *frame = stacktrace->frames;
        sr_strbuf_append_str(strbuf, ",   \"frames\":\n");
        while (frame)
        {
            if (frame == stacktrace->frames)
                sr_strbuf_append_str(strbuf, "      [ ");
            else
                sr_strbuf_append_str(strbuf, "      , ");

            char *frame_json = sr_koops_frame_to_json(frame);
            char *indented_frame_json = sr_indent_except_first_line(frame_json, 8);
            sr_strbuf_append_str(strbuf, indented_frame_json);
            free(indented_frame_json);
            free(frame_json);
            frame = frame->next;
            if (frame)
                sr_strbuf_append_str(strbuf, "\n");
        }

        sr_strbuf_append_str(strbuf, " ]\n");
    }

    if (strbuf->len > 0)
        strbuf->buf[0] = '{';
    else
        sr_strbuf_append_char(strbuf, '{');

    sr_strbuf_append_char(strbuf, '}');
    return sr_strbuf_free_nobuf(strbuf);
}