/* 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; }
/* constructor */ PyObject * sr_py_koops_frame_new(PyTypeObject *object, PyObject *args, PyObject *kwds) { struct sr_py_koops_frame *fo = (struct sr_py_koops_frame*) PyObject_New(struct sr_py_koops_frame, &sr_py_koops_frame_type); if (!fo) return PyErr_NoMemory(); const char *str = NULL; if (!PyArg_ParseTuple(args, "|s", &str)) return NULL; if (str) { fo->frame = sr_koops_frame_parse(&str); } else fo->frame = sr_koops_frame_new(); return (PyObject*)fo; }
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; }