[SATYR PATCH 3/5] Short text representation for koops traces

Martin Milata mmilata at redhat.com
Fri May 24 15:55:21 UTC 2013


Signed-off-by: Martin Milata <mmilata at redhat.com>
---
 lib/koops_frame.c            | 12 ++++++++++++
 lib/koops_frame.h            |  9 +++++++++
 lib/koops_stacktrace.c       | 22 ++++++++++++++++++++++
 lib/koops_stacktrace.h       |  8 ++++++++
 python/py_koops_stacktrace.c | 27 +++++++++++++++++++++++++++
 python/py_koops_stacktrace.h |  1 +
 tests/python/koops.py        | 11 +++++++++++
 7 files changed, 90 insertions(+)

diff --git a/lib/koops_frame.c b/lib/koops_frame.c
index 0cfa614..8fed0bc 100644
--- a/lib/koops_frame.c
+++ b/lib/koops_frame.c
@@ -482,3 +482,15 @@ sr_koops_frame_to_json(struct sr_koops_frame *frame)
     sr_strbuf_append_str(strbuf, "}");
     return sr_strbuf_free_nobuf(strbuf);
 }
+
+void
+sr_koops_frame_append_to_str(struct sr_koops_frame *frame,
+                             struct sr_strbuf *str)
+{
+    sr_strbuf_append_strf(str, "%s%s",
+                          (frame->reliable ? "" : "? "),
+                          (frame->function_name ? frame->function_name : "??"));
+
+    if (frame->module_name)
+        sr_strbuf_append_strf(str, " in %s", frame->module_name);
+}
diff --git a/lib/koops_frame.h b/lib/koops_frame.h
index aeccd42..733dbcf 100644
--- a/lib/koops_frame.h
+++ b/lib/koops_frame.h
@@ -33,6 +33,8 @@ extern "C" {
 #include <stdbool.h>
 #include <stdint.h>
 
+struct sr_strbuf;
+
 /**
  * @brief Kernel oops stack frame.
  */
@@ -214,6 +216,13 @@ sr_koops_parse_function(const char **input,
 char *
 sr_koops_frame_to_json(struct sr_koops_frame *frame);
 
+/**
+ * Appends textual representation of the frame to the string buffer dest.
+ */
+void
+sr_koops_frame_append_to_str(struct sr_koops_frame *frame,
+                             struct sr_strbuf *dest);
+
 #ifdef __cplusplus
 }
 #endif
diff --git a/lib/koops_stacktrace.c b/lib/koops_stacktrace.c
index 89e3d34..5403b5a 100644
--- a/lib/koops_stacktrace.c
+++ b/lib/koops_stacktrace.c
@@ -514,3 +514,25 @@ sr_koops_stacktrace_get_reason(struct sr_koops_stacktrace *stacktrace)
 
     return result;
 }
+
+char *
+sr_koops_stacktrace_to_short_text(struct sr_koops_stacktrace *stacktrace,
+                                  int max_frames)
+{
+    struct sr_strbuf *strbuf = sr_strbuf_new();
+    struct sr_koops_frame *frame;
+    int i = 0;
+
+    for (frame = stacktrace->frames; frame; frame = frame->next)
+    {
+        i++;
+        sr_strbuf_append_strf(strbuf, "#%d ", i);
+        sr_koops_frame_append_to_str(frame, strbuf);
+        sr_strbuf_append_char(strbuf, '\n');
+
+        if (max_frames && i >= max_frames)
+            break;
+    }
+
+    return sr_strbuf_free_nobuf(strbuf);
+}
diff --git a/lib/koops_stacktrace.h b/lib/koops_stacktrace.h
index 54bd0cc..4fa1d00 100644
--- a/lib/koops_stacktrace.h
+++ b/lib/koops_stacktrace.h
@@ -161,6 +161,14 @@ sr_koops_stacktrace_get_reason(struct sr_koops_stacktrace *stacktrace);
 char *
 sr_koops_stacktrace_to_json(struct sr_koops_stacktrace *stacktrace);
 
+/**
+ * Returns brief textual representation of the stacktrace, or NULL in case of
+ * failure. Caller has to free it using free().
+ */
+char *
+sr_koops_stacktrace_to_short_text(struct sr_koops_stacktrace *stacktrace,
+                                  int max_frames);
+
 #ifdef __cplusplus
 }
 #endif
diff --git a/python/py_koops_stacktrace.c b/python/py_koops_stacktrace.c
index cd74fd9..461415c 100644
--- a/python/py_koops_stacktrace.c
+++ b/python/py_koops_stacktrace.c
@@ -19,6 +19,10 @@
 #define b_normalize_doc "Usage: stacktrace.normalize()\n" \
                         "Normalizes the stacktrace."
 
+#define b_to_short_text "Usage: stacktrace.to_short_text([max_frames])\n" \
+                        "Returns short text representation of the stacktrace. If max_frames is\n" \
+                        "specified, the result includes only that much topmost frames.\n"
+
 #define b_frames_doc "A list containing frames"
 #define b_modules_doc "Modules loaded at the time of the event (list of strings)"
 
@@ -29,6 +33,7 @@ koops_stacktrace_methods[] =
     /* methods */
     { "dup",                  sr_py_koops_stacktrace_dup,                  METH_NOARGS,  b_dup_doc                   },
     { "normalize",            sr_py_koops_stacktrace_normalize,            METH_NOARGS,  b_normalize_doc             },
+    { "to_short_text",        sr_py_koops_stacktrace_to_short_text,        METH_VARARGS, b_to_short_text             },
     { NULL },
 };
 
@@ -326,3 +331,25 @@ sr_py_koops_stacktrace_normalize(PyObject *self, PyObject *args)
 
     Py_RETURN_NONE;
 }
+
+PyObject *
+sr_py_koops_stacktrace_to_short_text(PyObject *self, PyObject *args)
+{
+    int max_frames = 0;
+    if (!PyArg_ParseTuple(args, "|i", &max_frames))
+        return NULL;
+
+    struct sr_py_koops_stacktrace *this = (struct sr_py_koops_stacktrace*)self;
+    if (koops_stacktrace_prepare_linked_list(this) < 0)
+        return NULL;
+
+    char *text =
+        sr_koops_stacktrace_to_short_text(this->stacktrace, max_frames);
+    if (!text)
+        return NULL;
+
+    PyObject *result = PyString_FromString(text);
+
+    free(text);
+    return result;
+}
diff --git a/python/py_koops_stacktrace.h b/python/py_koops_stacktrace.h
index b36b555..28d7cba 100644
--- a/python/py_koops_stacktrace.h
+++ b/python/py_koops_stacktrace.h
@@ -59,6 +59,7 @@ int sr_py_koops_stacktrace_set_modules(PyObject *self, PyObject *rhs, void *data
 /* methods */
 PyObject *sr_py_koops_stacktrace_dup(PyObject *self, PyObject *args);
 PyObject *sr_py_koops_stacktrace_normalize(PyObject *self, PyObject *args);
+PyObject *sr_py_koops_stacktrace_to_short_text(PyObject *self, PyObject *args);
 
 
 #ifdef __cplusplus
diff --git a/tests/python/koops.py b/tests/python/koops.py
index b343979..4f4cafa 100755
--- a/tests/python/koops.py
+++ b/tests/python/koops.py
@@ -12,6 +12,14 @@ except ImportError:
 path = '../kerneloopses/rhbz-827868'
 frames_expected = 32
 mods_expected = 119
+expected_short_text = '''#1 warn_slowpath_common
+#2 warn_slowpath_null
+#3 __alloc_pages_nodemask
+#4 ? ip_copy_metadata
+#5 ? ip_forward_options
+#6 alloc_pages_current
+#7 __get_free_pages
+'''
 
 if not os.path.isfile(path):
     path = '../' + path
@@ -53,6 +61,9 @@ class TestKerneloops(BindingsTestCase):
         out = str(self.koops)
         self.assertTrue(('Kerneloops with %d frames' % frames_expected) in out)
 
+    def test_to_short_text(self):
+        self.assertEqual(self.koops.to_short_text(7), expected_short_text)
+
 class TestKoopsFrame(BindingsTestCase):
     def setUp(self):
         self.frame = satyr.Kerneloops(contents).frames[0]
-- 
1.7.11.7



More information about the Crash-catcher mailing list