/* 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; }
/* destructor */ void sr_py_koops_frame_free(PyObject *object) { struct sr_py_koops_frame *this = (struct sr_py_koops_frame*)object; sr_koops_frame_free(this->frame); PyObject_Del(object); }
bool sr_koops_stacktrace_remove_frame(struct sr_koops_stacktrace *stacktrace, struct sr_koops_frame *frame) { struct sr_koops_frame *loop_frame = stacktrace->frames, *prev_frame = NULL; while (loop_frame) { if (loop_frame == frame) { if (prev_frame) prev_frame->next = loop_frame->next; else stacktrace->frames = loop_frame->next; sr_koops_frame_free(loop_frame); return true; } prev_frame = loop_frame; loop_frame = loop_frame->next; } return false; }
void sr_koops_stacktrace_free(struct sr_koops_stacktrace *stacktrace) { if (!stacktrace) return; while (stacktrace->frames) { struct sr_koops_frame *frame = stacktrace->frames; stacktrace->frames = frame->next; sr_koops_frame_free(frame); } free(stacktrace->version); free(stacktrace->raw_oops); free(stacktrace); }