[SATYR PATCH 2/2] Move "method tables" to files where the methods are defined
Martin Milata
mmilata at redhat.com
Thu Jun 13 09:51:13 UTC 2013
- added new header internal_utils.h with private declarations that don't
fit into any other header
- stacktrace.c was split to generic_stacktrace.c and
generic_stacktrace.h, the same was done with thread.c and frame.c.
The generic_*.h headers contain the method table types and declaration
for platform-agnostic functions that should not be called directly by
the library user.
Signed-off-by: Martin Milata <mmilata at redhat.com>
---
include/utils.h | 11 ---
lib/Makefile.am | 12 ++-
lib/core_frame.c | 14 ++++
lib/core_stacktrace.c | 19 +++++
lib/core_thread.c | 17 ++++
lib/frame.c | 90 --------------------
lib/gdb_frame.c | 14 ++++
lib/gdb_stacktrace.c | 25 ++++++
lib/gdb_thread.c | 18 +++-
lib/generic_frame.c | 45 ++++++++++
lib/generic_frame.h | 33 ++++++++
lib/generic_stacktrace.c | 124 ++++++++++++++++++++++++++++
lib/generic_stacktrace.h | 57 +++++++++++++
lib/generic_thread.c | 90 ++++++++++++++++++++
lib/generic_thread.h | 51 ++++++++++++
lib/internal_utils.h | 33 ++++++++
lib/java_frame.c | 14 ++++
lib/java_stacktrace.c | 18 ++++
lib/java_thread.c | 17 ++++
lib/koops_frame.c | 14 ++++
lib/koops_stacktrace.c | 28 +++++++
lib/python_frame.c | 14 ++++
lib/python_stacktrace.c | 28 +++++++
lib/stacktrace.c | 210 -----------------------------------------------
lib/thread.c | 155 ----------------------------------
25 files changed, 680 insertions(+), 471 deletions(-)
delete mode 100644 lib/frame.c
create mode 100644 lib/generic_frame.c
create mode 100644 lib/generic_frame.h
create mode 100644 lib/generic_stacktrace.c
create mode 100644 lib/generic_stacktrace.h
create mode 100644 lib/generic_thread.c
create mode 100644 lib/generic_thread.h
create mode 100644 lib/internal_utils.h
delete mode 100644 lib/stacktrace.c
delete mode 100644 lib/thread.c
diff --git a/include/utils.h b/include/utils.h
index 9dff404..68e763b 100644
--- a/include/utils.h
+++ b/include/utils.h
@@ -46,17 +46,6 @@ extern "C" {
#define __sr_printf(x, y) __attribute__((format(printf, (x), (y))))
-#define SR_DISPATCH(type, method) \
- (assert((type > SR_REPORT_INVALID) && (type) < SR_REPORT_NUM && dtable[type].method), \
- dtable[type].method)
-
-#define SR_NEXT_FUNC(name, abstract_t, concrete_t) \
- static abstract_t * \
- name(abstract_t *node) \
- { \
- return (abstract_t *)((concrete_t *)node)->next; \
- } \
-
/**
* Debugging output to stdout while parsing.
* Default value is false.
diff --git a/lib/Makefile.am b/lib/Makefile.am
index c3ed3ea..277f53d 100644
--- a/lib/Makefile.am
+++ b/lib/Makefile.am
@@ -20,10 +20,17 @@ libsatyr_la_SOURCES = \
disasm.c \
distance.c \
elves.c \
+ generic_stacktrace.c \
+ generic_stacktrace.h \
+ generic_thread.c \
+ generic_thread.h \
+ generic_frame.c \
+ generic_frame.h \
gdb_stacktrace.c \
gdb_frame.c \
gdb_sharedlib.c \
gdb_thread.c \
+ internal_utils.h \
java_frame.c \
java_thread.c \
java_stacktrace.c \
@@ -41,10 +48,7 @@ libsatyr_la_SOURCES = \
sha1.c \
strbuf.c \
unstrip.c \
- utils.c \
- stacktrace.c \
- thread.c \
- frame.c
+ utils.c
libsatyr_la_CFLAGS = -Wall -std=gnu99 -D_GNU_SOURCE -I$(top_srcdir)/include $(GLIB_CFLAGS)
libsatyr_la_LDFLAGS = -version-info 1:0:0 $(GLIB_LIBS)
diff --git a/lib/core_frame.c b/lib/core_frame.c
index 37d2b8b..a2d1ef0 100644
--- a/lib/core_frame.c
+++ b/lib/core_frame.c
@@ -21,8 +21,22 @@
#include "utils.h"
#include "strbuf.h"
#include "json.h"
+#include "generic_frame.h"
+#include "internal_utils.h"
#include <string.h>
+/* Method table */
+
+DEFINE_NEXT_FUNC(core_next, struct sr_frame, struct sr_core_frame)
+
+struct frame_methods core_frame_methods =
+{
+ .append_to_str = (append_to_str_fn_t) sr_core_frame_append_to_str,
+ .next = (next_frame_fn_t) core_next,
+};
+
+/* Public functions */
+
struct sr_core_frame *
sr_core_frame_new()
{
diff --git a/lib/core_stacktrace.c b/lib/core_stacktrace.c
index c0978d4..46bdcc7 100644
--- a/lib/core_stacktrace.c
+++ b/lib/core_stacktrace.c
@@ -29,6 +29,8 @@
#include "strbuf.h"
#include "unstrip.h"
#include "json.h"
+#include "generic_stacktrace.h"
+#include "internal_utils.h"
#include <ctype.h>
#include <inttypes.h>
#include <stdint.h>
@@ -36,6 +38,23 @@
#include <string.h>
#include <assert.h>
+/* Method table */
+
+struct stacktrace_methods core_stacktrace_methods =
+{
+ /* core parser returns error_message directly */
+ .parse = (parse_fn_t) sr_core_stacktrace_from_json_text,
+ .parse_location = (parse_location_fn_t) NULL,
+ .to_short_text = (to_short_text_fn_t) stacktrace_to_short_text,
+ .to_json = (to_json_fn_t) sr_core_stacktrace_to_json,
+ .get_reason = (get_reason_fn_t) sr_core_stacktrace_get_reason,
+ .find_crash_thread =
+ (find_crash_thread_fn_t) sr_core_stacktrace_find_crash_thread,
+ .free = (free_fn_t) sr_core_stacktrace_free,
+};
+
+/* Public functions */
+
struct sr_core_stacktrace *
sr_core_stacktrace_new()
{
diff --git a/lib/core_thread.c b/lib/core_thread.c
index a48a3c3..3ebf1d9 100644
--- a/lib/core_thread.c
+++ b/lib/core_thread.c
@@ -22,8 +22,25 @@
#include "utils.h"
#include "strbuf.h"
#include "json.h"
+#include "generic_thread.h"
+#include "internal_utils.h"
#include <string.h>
+/* Method table */
+
+DEFINE_THREAD_FUNC(core_frames, struct sr_core_thread)
+DEFINE_NEXT_FUNC(core_next, struct sr_thread, struct sr_core_thread)
+
+struct thread_methods core_thread_methods =
+{
+ .frames = (frames_fn_t) core_frames,
+ .cmp = (cmp_fn_t) sr_core_thread_cmp,
+ .frame_count = (frame_count_fn_t) thread_frame_count,
+ .next = (next_thread_fn_t) core_next,
+};
+
+/* Public functions */
+
struct sr_core_thread *
sr_core_thread_new()
{
diff --git a/lib/frame.c b/lib/frame.c
deleted file mode 100644
index da4f070..0000000
--- a/lib/frame.c
+++ /dev/null
@@ -1,90 +0,0 @@
-/*
- stacktrace.h
-
- Copyright (C) 2013 Red Hat, Inc.
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License along
- with this program; if not, write to the Free Software Foundation, Inc.,
- 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-*/
-
-#include "report_type.h"
-#include "utils.h"
-#include "strbuf.h"
-#include "frame.h"
-
-#include "gdb/frame.h"
-#include "core/frame.h"
-#include "python/frame.h"
-#include "koops/frame.h"
-#include "java/frame.h"
-
-#include <stdio.h>
-
-SR_NEXT_FUNC(core_next, struct sr_frame, struct sr_core_frame)
-SR_NEXT_FUNC(python_next, struct sr_frame, struct sr_python_frame)
-SR_NEXT_FUNC(koops_next, struct sr_frame, struct sr_koops_frame)
-SR_NEXT_FUNC(java_next, struct sr_frame, struct sr_java_frame)
-SR_NEXT_FUNC(gdb_next, struct sr_frame, struct sr_gdb_frame)
-
-/* Initialize dispatch table. */
-
-typedef void (*append_to_str_fn_t)(struct sr_frame *, struct sr_strbuf *);
-typedef struct sr_frame* (*next_fn_t)(struct sr_frame *);
-
-struct methods
-{
- append_to_str_fn_t append_to_str;
- next_fn_t next;
-};
-
-static struct methods dtable[SR_REPORT_NUM] =
-{
- [SR_REPORT_CORE] =
- {
- .append_to_str = (append_to_str_fn_t) sr_core_frame_append_to_str,
- .next = (next_fn_t) core_next,
- },
- [SR_REPORT_PYTHON] =
- {
- .append_to_str = (append_to_str_fn_t) sr_python_frame_append_to_str,
- .next = (next_fn_t) python_next,
- },
- [SR_REPORT_KERNELOOPS] =
- {
- .append_to_str = (append_to_str_fn_t) sr_koops_frame_append_to_str,
- .next = (next_fn_t) koops_next,
- },
- [SR_REPORT_JAVA] =
- {
- .append_to_str = (append_to_str_fn_t) sr_java_frame_append_to_str,
- .next = (next_fn_t) java_next,
- },
- [SR_REPORT_GDB] =
- {
- .append_to_str = (append_to_str_fn_t) sr_gdb_frame_append_to_str,
- .next = (next_fn_t) gdb_next,
- },
-};
-
-void
-sr_frame_append_to_str(struct sr_frame *frame, struct sr_strbuf *strbuf)
-{
- SR_DISPATCH(frame->type, append_to_str)(frame, strbuf);
-}
-
-struct sr_frame *
-sr_frame_next(struct sr_frame *frame)
-{
- return SR_DISPATCH(frame->type, next)(frame);
-}
diff --git a/lib/gdb_frame.c b/lib/gdb_frame.c
index 630e9a2..e3b30fb 100644
--- a/lib/gdb_frame.c
+++ b/lib/gdb_frame.c
@@ -21,11 +21,25 @@
#include "utils.h"
#include "strbuf.h"
#include "location.h"
+#include "generic_frame.h"
+#include "internal_utils.h"
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <stdarg.h>
+/* Method table */
+
+DEFINE_NEXT_FUNC(gdb_next, struct sr_frame, struct sr_gdb_frame)
+
+struct frame_methods gdb_frame_methods =
+{
+ .append_to_str = (append_to_str_fn_t) sr_gdb_frame_append_to_str,
+ .next = (next_frame_fn_t) gdb_next,
+};
+
+/* Public functions */
+
struct sr_gdb_frame *
sr_gdb_frame_new()
{
diff --git a/lib/gdb_stacktrace.c b/lib/gdb_stacktrace.c
index 0fe2faa..1ef33dd 100644
--- a/lib/gdb_stacktrace.c
+++ b/lib/gdb_stacktrace.c
@@ -25,11 +25,36 @@
#include "strbuf.h"
#include "location.h"
#include "normalize.h"
+#include "generic_stacktrace.h"
+#include "internal_utils.h"
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <assert.h>
+/* Method table */
+
+/* for not used/implemented methods */
+static char *
+gdb_return_null(struct sr_stacktrace *stacktrace)
+{
+ return NULL;
+}
+
+struct stacktrace_methods gdb_stacktrace_methods =
+{
+ .parse = (parse_fn_t) stacktrace_parse_wrapper,
+ .parse_location = (parse_location_fn_t) sr_gdb_stacktrace_parse,
+ .to_short_text = (to_short_text_fn_t) sr_gdb_stacktrace_to_short_text,
+ .to_json = (to_json_fn_t) gdb_return_null,
+ .get_reason = (get_reason_fn_t) gdb_return_null,
+ .find_crash_thread =
+ (find_crash_thread_fn_t) sr_gdb_stacktrace_find_crash_thread,
+ .free = (free_fn_t) sr_gdb_stacktrace_free,
+};
+
+/* Public functions */
+
struct sr_gdb_stacktrace *
sr_gdb_stacktrace_new()
{
diff --git a/lib/gdb_thread.c b/lib/gdb_thread.c
index c01c32a..21acca3 100644
--- a/lib/gdb_thread.c
+++ b/lib/gdb_thread.c
@@ -24,11 +24,27 @@
#include "location.h"
#include "utils.h"
#include "strbuf.h"
-#include "thread.h"
+#include "generic_thread.h"
+#include "internal_utils.h"
#include <assert.h>
#include <stdlib.h>
#include <string.h>
+/* Method table */
+
+DEFINE_THREAD_FUNC(gdb_frames, struct sr_gdb_thread)
+DEFINE_NEXT_FUNC(gdb_next, struct sr_thread, struct sr_gdb_thread)
+
+struct thread_methods gdb_thread_methods =
+{
+ .frames = (frames_fn_t) gdb_frames,
+ .cmp = (cmp_fn_t) sr_gdb_thread_cmp,
+ .frame_count = (frame_count_fn_t) thread_frame_count,
+ .next = (next_thread_fn_t) gdb_next,
+};
+
+/* Public functions */
+
struct sr_gdb_thread *
sr_gdb_thread_new()
{
diff --git a/lib/generic_frame.c b/lib/generic_frame.c
new file mode 100644
index 0000000..9041037
--- /dev/null
+++ b/lib/generic_frame.c
@@ -0,0 +1,45 @@
+/*
+ generic_frame.c
+
+ Copyright (C) 2013 Red Hat, Inc.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License along
+ with this program; if not, write to the Free Software Foundation, Inc.,
+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+*/
+
+#include "report_type.h"
+#include "internal_utils.h"
+#include "generic_frame.h"
+
+/* Initialize dispatch table. */
+static struct frame_methods* dtable[SR_REPORT_NUM] =
+{
+ [SR_REPORT_CORE] = &core_frame_methods,
+ [SR_REPORT_PYTHON] = &python_frame_methods,
+ [SR_REPORT_KERNELOOPS] = &koops_frame_methods,
+ [SR_REPORT_JAVA] = &java_frame_methods,
+ [SR_REPORT_GDB] = &gdb_frame_methods,
+};
+
+void
+sr_frame_append_to_str(struct sr_frame *frame, struct sr_strbuf *strbuf)
+{
+ DISPATCH(dtable, frame->type, append_to_str)(frame, strbuf);
+}
+
+struct sr_frame *
+sr_frame_next(struct sr_frame *frame)
+{
+ return DISPATCH(dtable, frame->type, next)(frame);
+}
diff --git a/lib/generic_frame.h b/lib/generic_frame.h
new file mode 100644
index 0000000..5e28817
--- /dev/null
+++ b/lib/generic_frame.h
@@ -0,0 +1,33 @@
+/*
+ generic_frame.h
+
+ Copyright (C) 2013 Red Hat, Inc.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License along
+ with this program; if not, write to the Free Software Foundation, Inc.,
+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+*/
+
+#include "frame.h"
+
+typedef void (*append_to_str_fn_t)(struct sr_frame *, struct sr_strbuf *);
+typedef struct sr_frame* (*next_frame_fn_t)(struct sr_frame *);
+
+struct frame_methods
+{
+ append_to_str_fn_t append_to_str;
+ next_frame_fn_t next;
+};
+
+extern struct frame_methods core_frame_methods, python_frame_methods,
+ koops_frame_methods, gdb_frame_methods, java_frame_methods;
diff --git a/lib/generic_stacktrace.c b/lib/generic_stacktrace.c
new file mode 100644
index 0000000..9352001
--- /dev/null
+++ b/lib/generic_stacktrace.c
@@ -0,0 +1,124 @@
+/*
+ generic_stacktrace.c
+
+ Copyright (C) 2013 Red Hat, Inc.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License along
+ with this program; if not, write to the Free Software Foundation, Inc.,
+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+*/
+
+#include "internal_utils.h"
+#include "strbuf.h"
+#include "location.h"
+
+#include "frame.h"
+#include "thread.h"
+#include "generic_stacktrace.h"
+
+/* Initialize dispatch table. */
+static struct stacktrace_methods* dtable[SR_REPORT_NUM] =
+{
+ [SR_REPORT_CORE] = &core_stacktrace_methods,
+ [SR_REPORT_PYTHON] = &python_stacktrace_methods,
+ [SR_REPORT_KERNELOOPS] = &koops_stacktrace_methods,
+ [SR_REPORT_JAVA] = &java_stacktrace_methods,
+ [SR_REPORT_GDB] = &gdb_stacktrace_methods,
+};
+
+/* In case stacktrace type supports only one thread, return the stacktrace itself. */
+struct sr_thread *
+stacktrace_one_thread_only(struct sr_stacktrace *stacktrace)
+{
+ return (struct sr_thread *)stacktrace;
+}
+
+char *
+stacktrace_to_short_text(struct sr_stacktrace *stacktrace, int max_frames)
+{
+ struct sr_thread *thread = sr_stacktrace_find_crash_thread(stacktrace);
+ if (!thread)
+ return NULL;
+
+ struct sr_strbuf *strbuf = sr_strbuf_new();
+ struct sr_frame *frame;
+ int i = 0;
+
+ for (frame = sr_thread_frames(thread); frame; frame = sr_frame_next(frame))
+ {
+ i++;
+ sr_strbuf_append_strf(strbuf, "#%d ", i);
+ sr_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);
+}
+
+/* Uses the dispatch table but should not be exposed to library users directly. */
+struct sr_stacktrace *
+stacktrace_parse_wrapper(enum sr_report_type type, const char **input, char **error_message)
+{
+ struct sr_location location;
+ sr_location_init(&location);
+
+ struct sr_stacktrace *result = DISPATCH(dtable, type, parse_location)(input, &location);
+
+ if (!result)
+ {
+ *error_message = sr_location_to_string(&location);
+ return NULL;
+ }
+
+ return result;
+}
+
+/* Wrappers of polymorphic functions. */
+struct sr_stacktrace *
+sr_stacktrace_parse(enum sr_report_type type, const char **input, char **error_message)
+{
+ return DISPATCH(dtable, type, parse)(input, error_message);
+}
+
+char *
+sr_stacktrace_to_short_text(struct sr_stacktrace *stacktrace, int max_frames)
+{
+ return DISPATCH(dtable, stacktrace->type, to_short_text)(stacktrace, max_frames);
+}
+
+char *
+sr_stacktrace_to_json(struct sr_stacktrace *stacktrace)
+{
+ return DISPATCH(dtable, stacktrace->type, to_json)(stacktrace);
+}
+
+char *
+sr_stacktrace_get_reason(struct sr_stacktrace *stacktrace)
+{
+ return DISPATCH(dtable, stacktrace->type, get_reason)(stacktrace);
+}
+
+struct sr_thread *
+sr_stacktrace_find_crash_thread(struct sr_stacktrace *stacktrace)
+{
+ return DISPATCH(dtable, stacktrace->type, find_crash_thread)(stacktrace);
+}
+
+void
+sr_stacktrace_free(struct sr_stacktrace *stacktrace)
+{
+ DISPATCH(dtable, stacktrace->type, free)(stacktrace);
+}
diff --git a/lib/generic_stacktrace.h b/lib/generic_stacktrace.h
new file mode 100644
index 0000000..7aa675d
--- /dev/null
+++ b/lib/generic_stacktrace.h
@@ -0,0 +1,57 @@
+/*
+ generic_stacktrace.h
+
+ Copyright (C) 2013 Red Hat, Inc.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License along
+ with this program; if not, write to the Free Software Foundation, Inc.,
+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+*/
+
+#include "stacktrace.h"
+#include "thread.h"
+
+typedef struct sr_stacktrace* (*parse_fn_t)(const char **, char **);
+typedef struct sr_stacktrace* (*parse_location_fn_t)(const char **, struct sr_location *);
+typedef char* (*to_short_text_fn_t)(struct sr_stacktrace*, int);
+typedef char* (*to_json_fn_t)(struct sr_stacktrace *);
+typedef char* (*get_reason_fn_t)(struct sr_stacktrace *);
+typedef struct sr_thread* (*find_crash_thread_fn_t)(struct sr_stacktrace *);
+typedef void (*free_fn_t)(struct sr_stacktrace *);
+
+struct stacktrace_methods
+{
+ parse_fn_t parse;
+ parse_location_fn_t parse_location;
+ to_short_text_fn_t to_short_text;
+ to_json_fn_t to_json;
+ get_reason_fn_t get_reason;
+ find_crash_thread_fn_t find_crash_thread;
+ free_fn_t free;
+};
+
+extern struct stacktrace_methods core_stacktrace_methods, python_stacktrace_methods,
+ koops_stacktrace_methods, gdb_stacktrace_methods, java_stacktrace_methods;
+
+/* XXX generic functions */
+struct sr_stacktrace *
+stacktrace_parse_wrapper(enum sr_report_type type, const char **input, char **error_message);
+
+char *
+stacktrace_to_short_text(struct sr_stacktrace *stacktrace, int max_frames);
+
+struct sr_thread *
+stacktrace_one_thread_only(struct sr_stacktrace *stacktrace);
+
+struct sr_stacktrace *
+stacktrace_parse_wrapper(enum sr_report_type type, const char **input, char **error_message);
diff --git a/lib/generic_thread.c b/lib/generic_thread.c
new file mode 100644
index 0000000..17fa778
--- /dev/null
+++ b/lib/generic_thread.c
@@ -0,0 +1,90 @@
+/*
+ generic_thread.c
+
+ Copyright (C) 2013 Red Hat, Inc.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License along
+ with this program; if not, write to the Free Software Foundation, Inc.,
+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+*/
+
+#include "report_type.h"
+#include "internal_utils.h"
+#include "frame.h"
+#include "generic_thread.h"
+
+#include <stdio.h>
+
+//XXX
+/* Note that python and koops do not have multiple threads, thus the functions
+ * here operate directly on the stacktrace structures. */
+
+int
+thread_frame_count(struct sr_thread *thread)
+{
+ struct sr_frame *frame = sr_thread_frames(thread);
+ int count = 0;
+ while (frame)
+ {
+ frame = sr_frame_next(frame);
+ ++count;
+ }
+
+ return count;
+}
+
+struct sr_thread *
+thread_no_next_thread(struct sr_thread *thread)
+{
+ return NULL;
+}
+
+/* Initialize dispatch table. */
+
+/* Table that maps type-specific functions to the corresponding report types.
+ */
+static struct thread_methods* dtable[SR_REPORT_NUM] =
+{
+ [SR_REPORT_CORE] = &core_thread_methods,
+ [SR_REPORT_PYTHON] = &python_thread_methods,
+ [SR_REPORT_KERNELOOPS] = &koops_thread_methods,
+ [SR_REPORT_JAVA] = &java_thread_methods,
+ [SR_REPORT_GDB] = &gdb_thread_methods,
+};
+
+struct sr_frame *
+sr_thread_frames(struct sr_thread *thread)
+{
+ return DISPATCH(dtable, thread->type, frames)(thread);
+}
+
+int
+sr_thread_frame_count(struct sr_thread *thread)
+{
+ return DISPATCH(dtable, thread->type, frame_count)(thread);
+}
+
+int
+sr_thread_cmp(struct sr_thread *t1, struct sr_thread *t2)
+{
+ if (t1->type != t2->type)
+ return t1->type - t2->type;
+
+ return DISPATCH(dtable, t1->type, cmp)(t1, t2);
+}
+
+struct sr_thread *
+sr_thread_next(struct sr_thread *thread)
+{
+ return DISPATCH(dtable, thread->type, next)(thread);
+}
diff --git a/lib/generic_thread.h b/lib/generic_thread.h
new file mode 100644
index 0000000..e1e5f0a
--- /dev/null
+++ b/lib/generic_thread.h
@@ -0,0 +1,51 @@
+/*
+ generic_stacktrace.h
+
+ Copyright (C) 2013 Red Hat, Inc.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License along
+ with this program; if not, write to the Free Software Foundation, Inc.,
+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+*/
+
+#include "thread.h"
+
+typedef struct sr_frame* (*frames_fn_t)(struct sr_thread*);
+typedef int (*cmp_fn_t)(struct sr_thread*, struct sr_thread*);
+typedef int (*frame_count_fn_t)(struct sr_thread*);
+typedef struct sr_thread* (*next_thread_fn_t)(struct sr_thread*);
+
+struct thread_methods
+{
+ frames_fn_t frames;
+ cmp_fn_t cmp;
+ frame_count_fn_t frame_count;
+ next_thread_fn_t next;
+};
+
+extern struct thread_methods core_thread_methods, python_thread_methods,
+ koops_thread_methods, gdb_thread_methods, java_thread_methods;
+
+/* Macro to generate accessors for the "frames" member. */
+#define DEFINE_THREAD_FUNC(name, concrete_t) \
+ static struct sr_frame * \
+ name(struct sr_frame *node) \
+ { \
+ return (struct sr_frame *)((concrete_t *)node)->frames; \
+ } \
+
+int
+thread_frame_count(struct sr_thread *thread);
+
+struct sr_thread *
+thread_no_next_thread(struct sr_thread *thread);
diff --git a/lib/internal_utils.h b/lib/internal_utils.h
new file mode 100644
index 0000000..459b5b8
--- /dev/null
+++ b/lib/internal_utils.h
@@ -0,0 +1,33 @@
+/*
+ internal_utils.h
+
+ Copyright (C) 2013 Red Hat, Inc.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License along
+ with this program; if not, write to the Free Software Foundation, Inc.,
+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+*/
+
+#include <assert.h>
+
+#define DISPATCH(table, type, method) \
+ (assert((type > SR_REPORT_INVALID) && (type) < SR_REPORT_NUM && table[type]->method), \
+ table[type]->method)
+
+#define DEFINE_NEXT_FUNC(name, abstract_t, concrete_t) \
+ static abstract_t * \
+ name(abstract_t *node) \
+ { \
+ return (abstract_t *)((concrete_t *)node)->next; \
+ }
+
diff --git a/lib/java_frame.c b/lib/java_frame.c
index 9580138..fc8ae29 100644
--- a/lib/java_frame.c
+++ b/lib/java_frame.c
@@ -23,12 +23,26 @@
#include "location.h"
#include "utils.h"
#include "json.h"
+#include "generic_frame.h"
+#include "internal_utils.h"
#include <string.h>
#include <inttypes.h>
#define SR_JF_MARK_NATIVE_METHOD "Native Method"
#define SR_JF_MARK_UNKNOWN_SOURCE "Unknown Source"
+/* Method table */
+
+DEFINE_NEXT_FUNC(java_next, struct sr_frame, struct sr_java_frame)
+
+struct frame_methods java_frame_methods =
+{
+ .append_to_str = (append_to_str_fn_t) sr_java_frame_append_to_str,
+ .next = (next_frame_fn_t) java_next,
+};
+
+/* Public functions */
+
struct sr_java_frame *
sr_java_frame_new()
{
diff --git a/lib/java_stacktrace.c b/lib/java_stacktrace.c
index e05c0c6..b9f8ecb 100644
--- a/lib/java_stacktrace.c
+++ b/lib/java_stacktrace.c
@@ -23,10 +23,28 @@
#include "java/frame.h"
#include "utils.h"
#include "strbuf.h"
+#include "generic_stacktrace.h"
+#include "internal_utils.h"
#include <stdio.h>
#include <string.h>
#include <inttypes.h>
+/* Method table */
+
+struct stacktrace_methods java_stacktrace_methods =
+{
+ .parse = (parse_fn_t) stacktrace_parse_wrapper,
+ .parse_location = (parse_location_fn_t) sr_java_stacktrace_parse,
+ .to_short_text = (to_short_text_fn_t) stacktrace_to_short_text,
+ .to_json = (to_json_fn_t) sr_java_stacktrace_to_json,
+ .get_reason = (get_reason_fn_t) sr_java_stacktrace_get_reason,
+ .find_crash_thread =
+ (find_crash_thread_fn_t) sr_java_find_crash_thread,
+ .free = (free_fn_t) sr_java_stacktrace_free,
+};
+
+/* Public functions */
+
struct sr_java_stacktrace *
sr_java_stacktrace_new()
{
diff --git a/lib/java_thread.c b/lib/java_thread.c
index c578e74..ef5f73c 100644
--- a/lib/java_thread.c
+++ b/lib/java_thread.c
@@ -24,10 +24,27 @@
#include "utils.h"
#include "strbuf.h"
#include "json.h"
+#include "generic_thread.h"
+#include "internal_utils.h"
#include <assert.h>
#include <stdlib.h>
#include <string.h>
+/* Method table */
+
+DEFINE_THREAD_FUNC(java_frames, struct sr_java_thread)
+DEFINE_NEXT_FUNC(java_next, struct sr_thread, struct sr_java_thread)
+
+struct thread_methods java_thread_methods =
+{
+ .frames = (frames_fn_t) java_frames,
+ .cmp = (cmp_fn_t) sr_java_thread_cmp,
+ .frame_count = (frame_count_fn_t) thread_frame_count,
+ .next = (next_thread_fn_t) java_next,
+};
+
+/* Public functions */
+
struct sr_java_thread *
sr_java_thread_new()
{
diff --git a/lib/koops_frame.c b/lib/koops_frame.c
index 15d6473..76f5027 100644
--- a/lib/koops_frame.c
+++ b/lib/koops_frame.c
@@ -21,11 +21,25 @@
#include "utils.h"
#include "strbuf.h"
#include "json.h"
+#include "generic_frame.h"
+#include "internal_utils.h"
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <inttypes.h>
+/* Method table */
+
+DEFINE_NEXT_FUNC(koops_next, struct sr_frame, struct sr_koops_frame)
+
+struct frame_methods koops_frame_methods =
+{
+ .append_to_str = (append_to_str_fn_t) sr_koops_frame_append_to_str,
+ .next = (next_frame_fn_t) koops_next,
+};
+
+/* Public functions */
+
struct sr_koops_frame *
sr_koops_frame_new()
{
diff --git a/lib/koops_stacktrace.c b/lib/koops_stacktrace.c
index c9a249a..16d96a3 100644
--- a/lib/koops_stacktrace.c
+++ b/lib/koops_stacktrace.c
@@ -23,6 +23,9 @@
#include "json.h"
#include "strbuf.h"
#include "normalize.h"
+#include "generic_thread.h"
+#include "generic_stacktrace.h"
+#include "internal_utils.h"
#include <string.h>
#include <stddef.h>
@@ -51,6 +54,31 @@ struct sr_taint_flag sr_flags[] = {
#undef FLAG
#undef FLAG_OFFSET
+/* Method tables */
+
+DEFINE_THREAD_FUNC(koops_frames, struct sr_koops_stacktrace)
+
+struct thread_methods koops_thread_methods =
+{
+ .frames = (frames_fn_t) koops_frames,
+ .cmp = (cmp_fn_t) NULL,
+ .frame_count = (frame_count_fn_t) thread_frame_count,
+ .next = (next_thread_fn_t) thread_no_next_thread,
+};
+
+struct stacktrace_methods koops_stacktrace_methods =
+{
+ .parse = (parse_fn_t) stacktrace_parse_wrapper,
+ .parse_location = (parse_location_fn_t) sr_koops_stacktrace_parse,
+ .to_short_text = (to_short_text_fn_t) stacktrace_to_short_text,
+ .to_json = (to_json_fn_t) sr_koops_stacktrace_to_json,
+ .get_reason = (get_reason_fn_t) sr_koops_stacktrace_get_reason,
+ .find_crash_thread = (find_crash_thread_fn_t) stacktrace_one_thread_only,
+ .free = (free_fn_t) sr_koops_stacktrace_free,
+};
+
+/* Public functions */
+
struct sr_koops_stacktrace *
sr_koops_stacktrace_new()
{
diff --git a/lib/python_frame.c b/lib/python_frame.c
index 4f43ad4..86ecb4e 100644
--- a/lib/python_frame.c
+++ b/lib/python_frame.c
@@ -22,9 +22,23 @@
#include "location.h"
#include "strbuf.h"
#include "json.h"
+#include "generic_frame.h"
+#include "internal_utils.h"
#include <string.h>
#include <inttypes.h>
+/* Method table */
+
+DEFINE_NEXT_FUNC(python_next, struct sr_frame, struct sr_python_frame)
+
+struct frame_methods python_frame_methods =
+{
+ .append_to_str = (append_to_str_fn_t) sr_python_frame_append_to_str,
+ .next = (next_frame_fn_t) python_next,
+};
+
+/* Public functions */
+
struct sr_python_frame *
sr_python_frame_new()
{
diff --git a/lib/python_stacktrace.c b/lib/python_stacktrace.c
index bdc162b..278d175 100644
--- a/lib/python_stacktrace.c
+++ b/lib/python_stacktrace.c
@@ -25,10 +25,38 @@
#include "sha1.h"
#include "report_type.h"
#include "strbuf.h"
+#include "generic_stacktrace.h"
+#include "generic_thread.h"
+#include "internal_utils.h"
#include <stdio.h>
#include <string.h>
#include <inttypes.h>
+/* Method tables */
+
+DEFINE_THREAD_FUNC(python_frames, struct sr_python_stacktrace)
+
+struct thread_methods python_thread_methods =
+{
+ .frames = (frames_fn_t) python_frames,
+ .cmp = (cmp_fn_t) NULL,
+ .frame_count = (frame_count_fn_t) thread_frame_count,
+ .next = (next_thread_fn_t) thread_no_next_thread,
+};
+
+struct stacktrace_methods python_stacktrace_methods =
+{
+ .parse = (parse_fn_t) stacktrace_parse_wrapper,
+ .parse_location = (parse_location_fn_t) sr_python_stacktrace_parse,
+ .to_short_text = (to_short_text_fn_t) stacktrace_to_short_text,
+ .to_json = (to_json_fn_t) sr_python_stacktrace_to_json,
+ .get_reason = (get_reason_fn_t) sr_python_stacktrace_get_reason,
+ .find_crash_thread = (find_crash_thread_fn_t) stacktrace_one_thread_only,
+ .free = (free_fn_t) sr_python_stacktrace_free,
+};
+
+/* Public functions */
+
struct sr_python_stacktrace *
sr_python_stacktrace_new()
{
diff --git a/lib/stacktrace.c b/lib/stacktrace.c
deleted file mode 100644
index 0f22e58..0000000
--- a/lib/stacktrace.c
+++ /dev/null
@@ -1,210 +0,0 @@
-/*
- stacktrace.c
-
- Copyright (C) 2013 Red Hat, Inc.
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License along
- with this program; if not, write to the Free Software Foundation, Inc.,
- 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-*/
-
-#include "utils.h"
-#include "strbuf.h"
-#include "location.h"
-
-#include "frame.h"
-#include "stacktrace.h"
-#include "thread.h"
-
-#include "gdb/stacktrace.h"
-#include "core/stacktrace.h"
-#include "python/stacktrace.h"
-#include "koops/stacktrace.h"
-#include "java/stacktrace.h"
-
-#include <stdlib.h>
-
-static char *
-gdb_return_null(struct sr_stacktrace *stacktrace)
-{
- return NULL;
-}
-
-/* In case stacktrace type supports only one thread, return the stacktrace itself. */
-static struct sr_thread *
-one_thread_only(struct sr_stacktrace *stacktrace)
-{
- return (struct sr_thread *)stacktrace;
-}
-
-static char *
-generic_to_short_text(struct sr_stacktrace *stacktrace, int max_frames)
-{
- struct sr_thread *thread = sr_stacktrace_find_crash_thread(stacktrace);
- if (!thread)
- return NULL;
-
- struct sr_strbuf *strbuf = sr_strbuf_new();
- struct sr_frame *frame;
- int i = 0;
-
- for (frame = sr_thread_frames(thread); frame; frame = sr_frame_next(frame))
- {
- i++;
- sr_strbuf_append_strf(strbuf, "#%d ", i);
- sr_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);
-}
-
-/* Uses the dispatch table, but we don't want to expose it in the API. */
-static struct sr_stacktrace *
-generic_parse_wrapper(enum sr_report_type type, const char **input, char **error_message);
-
-/* Initialize dispatch table. */
-
-typedef struct sr_stacktrace* (*parse_fn_t)(const char **, char **);
-typedef struct sr_stacktrace* (*parse_location_fn_t)(const char **, struct sr_location *);
-typedef char* (*to_short_text_fn_t)(struct sr_stacktrace*, int);
-typedef char* (*to_json_fn_t)(struct sr_stacktrace *);
-typedef char* (*get_reason_fn_t)(struct sr_stacktrace *);
-typedef struct sr_thread* (*find_crash_thread_fn_t)(struct sr_stacktrace *);
-typedef void (*free_fn_t)(struct sr_stacktrace *);
-
-struct methods
-{
- parse_fn_t parse;
- parse_location_fn_t parse_location;
- to_short_text_fn_t to_short_text;
- to_json_fn_t to_json;
- get_reason_fn_t get_reason;
- find_crash_thread_fn_t find_crash_thread;
- free_fn_t free;
-};
-
-static struct methods dtable[SR_REPORT_NUM] =
-{
- [SR_REPORT_CORE] =
- {
- /* core parser returns error_message directly */
- .parse = (parse_fn_t) sr_core_stacktrace_from_json_text,
- .parse_location = (parse_location_fn_t) NULL,
- .to_short_text = (to_short_text_fn_t) generic_to_short_text,
- .to_json = (to_json_fn_t) sr_core_stacktrace_to_json,
- .get_reason = (get_reason_fn_t) sr_core_stacktrace_get_reason,
- .find_crash_thread =
- (find_crash_thread_fn_t) sr_core_stacktrace_find_crash_thread,
- .free = (free_fn_t) sr_core_stacktrace_free,
- },
- [SR_REPORT_PYTHON] =
- {
- /* for other types, we have to convert location to message first */
- .parse = (parse_fn_t) generic_parse_wrapper,
- .parse_location = (parse_location_fn_t) sr_python_stacktrace_parse,
- .to_short_text = (to_short_text_fn_t) generic_to_short_text,
- .to_json = (to_json_fn_t) sr_python_stacktrace_to_json,
- .get_reason = (get_reason_fn_t) sr_python_stacktrace_get_reason,
- .find_crash_thread = (find_crash_thread_fn_t) one_thread_only,
- .free = (free_fn_t) sr_python_stacktrace_free,
- },
- [SR_REPORT_KERNELOOPS] =
- {
- .parse = (parse_fn_t) generic_parse_wrapper,
- .parse_location = (parse_location_fn_t) sr_koops_stacktrace_parse,
- .to_short_text = (to_short_text_fn_t) generic_to_short_text,
- .to_json = (to_json_fn_t) sr_koops_stacktrace_to_json,
- .get_reason = (get_reason_fn_t) sr_koops_stacktrace_get_reason,
- .find_crash_thread = (find_crash_thread_fn_t) one_thread_only,
- .free = (free_fn_t) sr_koops_stacktrace_free,
- },
- [SR_REPORT_JAVA] =
- {
- .parse = (parse_fn_t) generic_parse_wrapper,
- .parse_location = (parse_location_fn_t) sr_java_stacktrace_parse,
- .to_short_text = (to_short_text_fn_t) generic_to_short_text,
- .to_json = (to_json_fn_t) sr_java_stacktrace_to_json,
- .get_reason = (get_reason_fn_t) sr_java_stacktrace_get_reason,
- .find_crash_thread =
- (find_crash_thread_fn_t) sr_java_find_crash_thread,
- .free = (free_fn_t) sr_java_stacktrace_free,
- },
- [SR_REPORT_GDB] =
- {
- .parse = (parse_fn_t) generic_parse_wrapper,
- .parse_location = (parse_location_fn_t) sr_gdb_stacktrace_parse,
- .to_short_text = (to_short_text_fn_t) sr_gdb_stacktrace_to_short_text,
- .to_json = (to_json_fn_t) gdb_return_null,
- .get_reason = (get_reason_fn_t) gdb_return_null,
- .find_crash_thread =
- (find_crash_thread_fn_t) sr_gdb_stacktrace_find_crash_thread,
- .free = (free_fn_t) sr_gdb_stacktrace_free,
- },
-};
-
-static struct sr_stacktrace *
-generic_parse_wrapper(enum sr_report_type type, const char **input, char **error_message)
-{
- struct sr_location location;
- sr_location_init(&location);
-
- struct sr_stacktrace *result = SR_DISPATCH(type, parse_location)(input, &location);
-
- if (!result)
- {
- *error_message = sr_location_to_string(&location);
- return NULL;
- }
-
- return result;
-}
-
-struct sr_stacktrace *
-sr_stacktrace_parse(enum sr_report_type type, const char **input, char **error_message)
-{
- return SR_DISPATCH(type, parse)(input, error_message);
-}
-
-char *
-sr_stacktrace_to_short_text(struct sr_stacktrace *stacktrace, int max_frames)
-{
- return SR_DISPATCH(stacktrace->type, to_short_text)(stacktrace, max_frames);
-}
-
-char *
-sr_stacktrace_to_json(struct sr_stacktrace *stacktrace)
-{
- return SR_DISPATCH(stacktrace->type, to_json)(stacktrace);
-}
-
-char *
-sr_stacktrace_get_reason(struct sr_stacktrace *stacktrace)
-{
- return SR_DISPATCH(stacktrace->type, get_reason)(stacktrace);
-}
-
-struct sr_thread *
-sr_stacktrace_find_crash_thread(struct sr_stacktrace *stacktrace)
-{
- return SR_DISPATCH(stacktrace->type, find_crash_thread)(stacktrace);
-}
-
-void
-sr_stacktrace_free(struct sr_stacktrace *stacktrace)
-{
- SR_DISPATCH(stacktrace->type, free)(stacktrace);
-}
diff --git a/lib/thread.c b/lib/thread.c
deleted file mode 100644
index c2cc2ca..0000000
--- a/lib/thread.c
+++ /dev/null
@@ -1,155 +0,0 @@
-/*
- stacktrace.h
-
- Copyright (C) 2013 Red Hat, Inc.
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License along
- with this program; if not, write to the Free Software Foundation, Inc.,
- 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-*/
-
-#include "report_type.h"
-#include "utils.h"
-#include "thread.h"
-#include "frame.h"
-
-#include "gdb/thread.h"
-#include "core/thread.h"
-#include "python/stacktrace.h"
-#include "koops/stacktrace.h"
-#include "java/thread.h"
-
-#include <stdio.h>
-
-/* Macro to generate accessors for the "frames" member. */
-#define SR_FRAMES_FUNC(name, concrete_t) \
- static struct sr_frame * \
- name(struct sr_frame *node) \
- { \
- return (struct sr_frame *)((concrete_t *)node)->frames; \
- } \
-
-/* Note that python and koops do not have multiple threads, thus the functions
- * here operate directly on the stacktrace structures. */
-SR_FRAMES_FUNC(core_frames, struct sr_core_thread)
-SR_FRAMES_FUNC(python_frames, struct sr_python_stacktrace)
-SR_FRAMES_FUNC(koops_frames, struct sr_koops_stacktrace)
-SR_FRAMES_FUNC(java_frames, struct sr_java_thread)
-SR_FRAMES_FUNC(gdb_frames, struct sr_gdb_thread)
-
-SR_NEXT_FUNC(core_next, struct sr_thread, struct sr_core_thread)
-SR_NEXT_FUNC(java_next, struct sr_thread, struct sr_java_thread)
-SR_NEXT_FUNC(gdb_next, struct sr_thread, struct sr_gdb_thread)
-
-static int
-generic_frame_count(struct sr_thread *thread)
-{
- struct sr_frame *frame = sr_thread_frames(thread);
- int count = 0;
- while (frame)
- {
- frame = sr_frame_next(frame);
- ++count;
- }
-
- return count;
-}
-
-static struct sr_thread *
-no_next_thread(struct sr_thread *thread)
-{
- return NULL;
-}
-
-/* Initialize dispatch table. */
-
-typedef struct sr_frame* (*frames_fn_t)(struct sr_thread*);
-typedef int (*cmp_fn_t)(struct sr_thread*, struct sr_thread*);
-typedef int (*frame_count_fn_t)(struct sr_thread*);
-typedef struct sr_thread* (*next_fn_t)(struct sr_thread*);
-
-struct methods
-{
- frames_fn_t frames;
- cmp_fn_t cmp;
- frame_count_fn_t frame_count;
- next_fn_t next;
-};
-
-/* Table that maps type-specific functions to the corresponding report types.
- */
-static struct methods dtable[SR_REPORT_NUM] =
-{
- [SR_REPORT_CORE] =
- {
- .frames = (frames_fn_t) core_frames,
- .cmp = (cmp_fn_t) sr_core_thread_cmp,
- .frame_count = (frame_count_fn_t) generic_frame_count,
- .next = (next_fn_t) core_next,
- },
- [SR_REPORT_PYTHON] =
- {
- .frames = (frames_fn_t) python_frames,
- .cmp = (cmp_fn_t) NULL,
- .frame_count = (frame_count_fn_t) generic_frame_count,
- .next = (next_fn_t) no_next_thread,
- },
- [SR_REPORT_KERNELOOPS] =
- {
- .frames = (frames_fn_t) koops_frames,
- .cmp = (cmp_fn_t) NULL,
- .frame_count = (frame_count_fn_t) generic_frame_count,
- .next = (next_fn_t) no_next_thread,
- },
- [SR_REPORT_JAVA] =
- {
- .frames = (frames_fn_t) java_frames,
- .cmp = (cmp_fn_t) sr_java_thread_cmp,
- .frame_count = (frame_count_fn_t) generic_frame_count,
- .next = (next_fn_t) java_next,
- },
- [SR_REPORT_GDB] =
- {
- .frames = (frames_fn_t) gdb_frames,
- .cmp = (cmp_fn_t) sr_gdb_thread_cmp,
- .frame_count = (frame_count_fn_t) generic_frame_count,
- .next = (next_fn_t) gdb_next,
- },
-};
-
-struct sr_frame *
-sr_thread_frames(struct sr_thread *thread)
-{
- return SR_DISPATCH(thread->type, frames)(thread);
-}
-
-int
-sr_thread_frame_count(struct sr_thread *thread)
-{
- return SR_DISPATCH(thread->type, frame_count)(thread);
-}
-
-int
-sr_thread_cmp(struct sr_thread *t1, struct sr_thread *t2)
-{
- if (t1->type != t2->type)
- return t1->type - t2->type;
-
- return SR_DISPATCH(t1->type, cmp)(t1, t2);
-}
-
-struct sr_thread *
-sr_thread_next(struct sr_thread *thread)
-{
- return SR_DISPATCH(thread->type, next)(thread);
-}
--
1.7.11.7
More information about the Crash-catcher
mailing list