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; }
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); }
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); }
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; }
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; }
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); }
/* 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; }
/* 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; }
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); }
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); }
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 }
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); }
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); }
/* 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; }
/* 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; }
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; }
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); }
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); }