[SATYR PATCH 5/9] Add additional methods to thread
Martin Milata
mmilata at redhat.com
Wed Jun 26 20:14:09 UTC 2013
Signed-off-by: Martin Milata <mmilata at redhat.com>
---
include/frame.h | 3 ++
include/thread.h | 37 ++++++++++++++++++++++
lib/core_frame.c | 1 +
lib/core_stacktrace.c | 2 +-
lib/core_thread.c | 6 ++++
lib/gdb_frame.c | 1 +
lib/gdb_stacktrace.c | 2 +-
lib/gdb_thread.c | 6 ++++
lib/generic_frame.c | 8 +++++
lib/generic_frame.h | 2 ++
lib/generic_stacktrace.c | 5 ++-
lib/generic_stacktrace.h | 4 +--
lib/generic_thread.c | 82 ++++++++++++++++++++++++++++++++++++++++++++++++
lib/generic_thread.h | 22 +++++++++++++
lib/java_frame.c | 1 +
lib/java_stacktrace.c | 2 +-
lib/java_thread.c | 6 ++++
lib/koops_frame.c | 1 +
lib/koops_stacktrace.c | 7 ++++-
lib/python_frame.c | 1 +
lib/python_stacktrace.c | 7 ++++-
21 files changed, 198 insertions(+), 8 deletions(-)
diff --git a/include/frame.h b/include/frame.h
index 706522a..db8ea98 100644
--- a/include/frame.h
+++ b/include/frame.h
@@ -77,6 +77,9 @@ sr_frame_cmp(struct sr_frame *t1, struct sr_frame *t2);
int
sr_frame_cmp_distance(struct sr_frame *t1, struct sr_frame *t2);
+void
+sr_frame_free(struct sr_frame *frame);
+
#ifdef __cplusplus
}
#endif
diff --git a/include/thread.h b/include/thread.h
index 1f39c2a..56bf1b5 100644
--- a/include/thread.h
+++ b/include/thread.h
@@ -37,6 +37,8 @@
extern "C" {
#endif
+#include <stdbool.h>
+
#include "report_type.h"
struct sr_thread
@@ -81,6 +83,41 @@ sr_thread_next(struct sr_thread *thread);
void
sr_thread_set_next(struct sr_thread *cur, struct sr_thread *next);
+/**
+ * Releases the memory held by the thread. The thread siblings are not
+ * released.
+ * @param thread
+ * If thread is NULL, no operation is performed.
+ */
+void
+sr_thread_free(struct sr_thread *thread);
+
+/**
+ * Removes the frame from the thread and then deletes it.
+ * @returns
+ * True if the frame was found in the thread and removed and deleted.
+ * False if the frame was not found in the thread.
+ */
+bool
+sr_thread_remove_frame(struct sr_thread *thread, struct sr_frame *frame);
+
+/**
+ * Removes all the frames from the thread that are above certain
+ * frame.
+ * @returns
+ * True if the frame was found, and all the frames that were above the
+ * frame in the thread were removed from the thread and then deleted.
+ * False if the frame was not found in the thread.
+ */
+bool
+sr_thread_remove_frames_above(struct sr_thread *thread, struct sr_frame *frame);
+
+/**
+ * Return a copy of the thread (without its siblings).
+ */
+struct sr_thread *
+sr_thread_dup(struct sr_thread *thread);
+
#ifdef __cplusplus
}
#endif
diff --git a/lib/core_frame.c b/lib/core_frame.c
index 2833b8a..4ae8e8c 100644
--- a/lib/core_frame.c
+++ b/lib/core_frame.c
@@ -44,6 +44,7 @@ struct frame_methods core_frame_methods =
.cmp_distance = (frame_cmp_fn_t) sr_core_frame_cmp_distance,
.frame_append_bthash_text =
(frame_append_bthash_text_fn_t) core_append_bthash_text,
+ .frame_free = (frame_free_fn_t) sr_core_frame_free,
};
/* Public functions */
diff --git a/lib/core_stacktrace.c b/lib/core_stacktrace.c
index 2b5997c..ff34221 100644
--- a/lib/core_stacktrace.c
+++ b/lib/core_stacktrace.c
@@ -59,7 +59,7 @@ struct stacktrace_methods core_stacktrace_methods =
(find_crash_thread_fn_t) sr_core_stacktrace_find_crash_thread,
.threads = (threads_fn_t) core_threads,
.set_threads = (set_threads_fn_t) core_set_threads,
- .free = (free_fn_t) sr_core_stacktrace_free,
+ .stacktrace_free = (stacktrace_free_fn_t) sr_core_stacktrace_free,
.stacktrace_append_bthash_text =
(stacktrace_append_bthash_text_fn_t) core_append_bthash_text,
};
diff --git a/lib/core_thread.c b/lib/core_thread.c
index 5844ce9..d6e62b2 100644
--- a/lib/core_thread.c
+++ b/lib/core_thread.c
@@ -33,6 +33,7 @@ DEFINE_FRAMES_FUNC(core_frames, struct sr_core_thread)
DEFINE_SET_FRAMES_FUNC(core_set_frames, struct sr_core_thread)
DEFINE_NEXT_FUNC(core_next, struct sr_thread, struct sr_core_thread)
DEFINE_SET_NEXT_FUNC(core_set_next, struct sr_thread, struct sr_core_thread)
+DEFINE_DUP_WRAPPER_FUNC(core_dup, struct sr_core_thread, sr_core_thread_dup)
struct thread_methods core_thread_methods =
{
@@ -44,6 +45,11 @@ struct thread_methods core_thread_methods =
.set_next = (set_next_thread_fn_t) core_set_next,
.thread_append_bthash_text =
(thread_append_bthash_text_fn_t) thread_no_bthash_text,
+ .thread_free = (thread_free_fn_t) sr_core_thread_free,
+ .remove_frame = (remove_frame_fn_t) thread_remove_frame,
+ .remove_frames_above =
+ (remove_frames_above_fn_t) thread_remove_frames_above,
+ .thread_dup = (thread_dup_fn_t) core_dup,
};
/* Public functions */
diff --git a/lib/gdb_frame.c b/lib/gdb_frame.c
index 46acd4d..6deb1a3 100644
--- a/lib/gdb_frame.c
+++ b/lib/gdb_frame.c
@@ -54,6 +54,7 @@ struct frame_methods gdb_frame_methods =
.cmp_distance = (frame_cmp_fn_t) sr_gdb_frame_cmp_distance,
.frame_append_bthash_text =
(frame_append_bthash_text_fn_t) gdb_append_bthash_text,
+ .frame_free = (frame_free_fn_t) sr_gdb_frame_free,
};
/* Public functions */
diff --git a/lib/gdb_stacktrace.c b/lib/gdb_stacktrace.c
index 6ccebab..9950c69 100644
--- a/lib/gdb_stacktrace.c
+++ b/lib/gdb_stacktrace.c
@@ -60,7 +60,7 @@ struct stacktrace_methods gdb_stacktrace_methods =
(find_crash_thread_fn_t) sr_gdb_stacktrace_find_crash_thread,
.threads = (threads_fn_t) gdb_threads,
.set_threads = (set_threads_fn_t) gdb_set_threads,
- .free = (free_fn_t) sr_gdb_stacktrace_free,
+ .stacktrace_free = (stacktrace_free_fn_t) sr_gdb_stacktrace_free,
.stacktrace_append_bthash_text =
(stacktrace_append_bthash_text_fn_t) gdb_append_bthash_text,
};
diff --git a/lib/gdb_thread.c b/lib/gdb_thread.c
index 45da010..dc34320 100644
--- a/lib/gdb_thread.c
+++ b/lib/gdb_thread.c
@@ -41,6 +41,7 @@ DEFINE_FRAMES_FUNC(gdb_frames, struct sr_gdb_thread)
DEFINE_SET_FRAMES_FUNC(gdb_set_frames, struct sr_gdb_thread)
DEFINE_NEXT_FUNC(gdb_next, struct sr_thread, struct sr_gdb_thread)
DEFINE_SET_NEXT_FUNC(gdb_set_next, struct sr_thread, struct sr_gdb_thread)
+DEFINE_DUP_WRAPPER_FUNC(gdb_dup, struct sr_gdb_thread, sr_gdb_thread_dup)
struct thread_methods gdb_thread_methods =
{
@@ -52,6 +53,11 @@ struct thread_methods gdb_thread_methods =
.set_next = (set_next_thread_fn_t) gdb_set_next,
.thread_append_bthash_text =
(thread_append_bthash_text_fn_t) gdb_append_bthash_text,
+ .thread_free = (thread_free_fn_t) sr_gdb_thread_free,
+ .remove_frame = (remove_frame_fn_t) thread_remove_frame,
+ .remove_frames_above =
+ (remove_frames_above_fn_t) thread_remove_frames_above,
+ .thread_dup = (thread_dup_fn_t) gdb_dup,
};
/* Public functions */
diff --git a/lib/generic_frame.c b/lib/generic_frame.c
index 04a8407..b3a5f3c 100644
--- a/lib/generic_frame.c
+++ b/lib/generic_frame.c
@@ -79,3 +79,11 @@ frame_append_bthash_text(struct sr_frame *frame, enum sr_bthash_flags flags,
DISPATCH(dtable, frame->type, frame_append_bthash_text)
(frame, flags, strbuf);
}
+
+void sr_frame_free(struct sr_frame *frame)
+{
+ if (!frame)
+ return;
+
+ DISPATCH(dtable, frame->type, frame_free)(frame);
+}
diff --git a/lib/generic_frame.h b/lib/generic_frame.h
index 69f1fa8..7a02bbe 100644
--- a/lib/generic_frame.h
+++ b/lib/generic_frame.h
@@ -30,6 +30,7 @@ typedef void (*set_next_frame_fn_t)(struct sr_frame *, struct sr_frame *);
typedef int (*frame_cmp_fn_t)(struct sr_frame *, struct sr_frame *);
typedef void (*frame_append_bthash_text_fn_t)(struct sr_frame*, enum sr_bthash_flags,
struct sr_strbuf*);
+typedef void (*frame_free_fn_t)(struct sr_frame*);
struct frame_methods
{
@@ -39,6 +40,7 @@ struct frame_methods
frame_cmp_fn_t cmp;
frame_cmp_fn_t cmp_distance;
frame_append_bthash_text_fn_t frame_append_bthash_text;
+ frame_free_fn_t frame_free;
};
extern struct frame_methods core_frame_methods, python_frame_methods,
diff --git a/lib/generic_stacktrace.c b/lib/generic_stacktrace.c
index bba7f5f..de393e4 100644
--- a/lib/generic_stacktrace.c
+++ b/lib/generic_stacktrace.c
@@ -138,7 +138,10 @@ sr_stacktrace_set_threads(struct sr_stacktrace *stacktrace, struct sr_thread *th
void
sr_stacktrace_free(struct sr_stacktrace *stacktrace)
{
- DISPATCH(dtable, stacktrace->type, free)(stacktrace);
+ if (!stacktrace)
+ return;
+
+ DISPATCH(dtable, stacktrace->type, stacktrace_free)(stacktrace);
}
char *
diff --git a/lib/generic_stacktrace.h b/lib/generic_stacktrace.h
index 829b680..f08bdfc 100644
--- a/lib/generic_stacktrace.h
+++ b/lib/generic_stacktrace.h
@@ -32,7 +32,7 @@ typedef char* (*get_reason_fn_t)(struct sr_stacktrace *);
typedef struct sr_thread* (*find_crash_thread_fn_t)(struct sr_stacktrace *);
typedef struct sr_thread* (*threads_fn_t)(struct sr_stacktrace *);
typedef void (*set_threads_fn_t)(struct sr_stacktrace *, struct sr_thread *);
-typedef void (*free_fn_t)(struct sr_stacktrace *);
+typedef void (*stacktrace_free_fn_t)(struct sr_stacktrace *);
typedef void (*stacktrace_append_bthash_text_fn_t)(struct sr_stacktrace *, enum sr_bthash_flags,
struct sr_strbuf *);
@@ -46,7 +46,7 @@ struct stacktrace_methods
find_crash_thread_fn_t find_crash_thread;
threads_fn_t threads;
set_threads_fn_t set_threads;
- free_fn_t free;
+ stacktrace_free_fn_t stacktrace_free;
stacktrace_append_bthash_text_fn_t stacktrace_append_bthash_text;
};
diff --git a/lib/generic_thread.c b/lib/generic_thread.c
index b0b3861..c9ff98a 100644
--- a/lib/generic_thread.c
+++ b/lib/generic_thread.c
@@ -45,6 +45,59 @@ thread_frame_count(struct sr_thread *thread)
return count;
}
+bool
+thread_remove_frame(struct sr_thread *thread, struct sr_frame *frame)
+{
+ struct sr_frame *loop_frame = sr_thread_frames(thread),
+ *prev_frame = NULL;
+
+ while (loop_frame)
+ {
+ if (loop_frame == frame)
+ {
+ if (prev_frame)
+ sr_frame_set_next(prev_frame, sr_frame_next(loop_frame));
+ else
+ sr_thread_set_frames(thread, sr_frame_next(loop_frame));
+
+ sr_frame_free(loop_frame);
+ return true;
+ }
+
+ prev_frame = loop_frame;
+ loop_frame = sr_frame_next(loop_frame);
+ }
+
+ return false;
+}
+
+bool
+thread_remove_frames_above(struct sr_thread *thread, struct sr_frame *frame)
+{
+ /* Check that the frame is present in the thread. */
+ struct sr_frame *loop_frame = sr_thread_frames(thread);
+ while (loop_frame)
+ {
+ if (loop_frame == frame)
+ break;
+
+ loop_frame = sr_frame_next(loop_frame);
+ }
+
+ if (!loop_frame)
+ return false;
+
+ /* Delete all the frames up to the frame. */
+ while (sr_thread_frames(thread) != frame)
+ {
+ loop_frame = sr_frame_next(sr_thread_frames(thread));
+ sr_frame_free(sr_thread_frames(thread));
+ sr_thread_set_frames(thread, loop_frame);
+ }
+
+ return true;
+}
+
struct sr_thread *
thread_no_next_thread(struct sr_thread *thread)
{
@@ -119,3 +172,32 @@ thread_append_bthash_text(struct sr_thread *thread, enum sr_bthash_flags flags,
DISPATCH(dtable, thread->type, thread_append_bthash_text)
(thread, flags, strbuf);
}
+
+void
+sr_thread_free(struct sr_thread *thread)
+{
+ if (!thread)
+ return;
+
+ DISPATCH(dtable, thread->type, thread_free)(thread);
+}
+
+bool
+sr_thread_remove_frame(struct sr_thread *thread, struct sr_frame *frame)
+{
+ assert(thread->type == frame->type);
+ return DISPATCH(dtable, thread->type, remove_frame)(thread, frame);
+}
+
+bool
+sr_thread_remove_frames_above(struct sr_thread *thread, struct sr_frame *frame)
+{
+ assert(thread->type == frame->type);
+ return DISPATCH(dtable, thread->type, remove_frames_above)(thread, frame);
+}
+
+struct sr_thread*
+sr_thread_dup(struct sr_thread *thread)
+{
+ return DISPATCH(dtable, thread->type, thread_dup)(thread);
+}
diff --git a/lib/generic_thread.h b/lib/generic_thread.h
index d3232d6..3914212 100644
--- a/lib/generic_thread.h
+++ b/lib/generic_thread.h
@@ -33,6 +33,10 @@ typedef struct sr_thread* (*next_thread_fn_t)(struct sr_thread*);
typedef void (*set_next_thread_fn_t)(struct sr_thread*, struct sr_thread*);
typedef void (*thread_append_bthash_text_fn_t)(struct sr_thread*, enum sr_bthash_flags,
struct sr_strbuf*);
+typedef void (*thread_free_fn_t)(struct sr_thread*);
+typedef bool (*remove_frame_fn_t)(struct sr_thread*, struct sr_frame*);
+typedef bool (*remove_frames_above_fn_t)(struct sr_thread*, struct sr_frame*);
+typedef struct sr_thread* (*thread_dup_fn_t)(struct sr_thread*);
struct thread_methods
{
@@ -43,6 +47,10 @@ struct thread_methods
next_thread_fn_t next;
set_next_thread_fn_t set_next;
thread_append_bthash_text_fn_t thread_append_bthash_text;
+ thread_free_fn_t thread_free;
+ remove_frame_fn_t remove_frame;
+ remove_frames_above_fn_t remove_frames_above;
+ thread_dup_fn_t thread_dup;
};
extern struct thread_methods core_thread_methods, python_thread_methods,
@@ -55,9 +63,23 @@ extern struct thread_methods core_thread_methods, python_thread_methods,
#define DEFINE_SET_FRAMES_FUNC(name, concrete_t) \
DEFINE_SETTER(name, frames, struct sr_thread, concrete_t, struct sr_frame)
+/* _dup wrapper for thread fucntions that accept 'sibling' argument */
+#define DEFINE_DUP_WRAPPER_FUNC(name, concrete_t, wrappee) \
+ static concrete_t * \
+ name(concrete_t *thread) \
+ { \
+ return wrappee(thread, false); \
+ }
+
int
thread_frame_count(struct sr_thread *thread);
+bool
+thread_remove_frame(struct sr_thread *thread, struct sr_frame *frame);
+
+bool
+thread_remove_frames_above(struct sr_thread *thread, struct sr_frame *frame);
+
struct sr_thread *
thread_no_next_thread(struct sr_thread *thread);
diff --git a/lib/java_frame.c b/lib/java_frame.c
index 71881ca..4e61332 100644
--- a/lib/java_frame.c
+++ b/lib/java_frame.c
@@ -50,6 +50,7 @@ struct frame_methods java_frame_methods =
.cmp_distance = (frame_cmp_fn_t) sr_java_frame_cmp_distance,
.frame_append_bthash_text =
(frame_append_bthash_text_fn_t) java_append_bthash_text,
+ .frame_free = (frame_free_fn_t) sr_java_frame_free,
};
/* Public functions */
diff --git a/lib/java_stacktrace.c b/lib/java_stacktrace.c
index d0b9152..f8ef874 100644
--- a/lib/java_stacktrace.c
+++ b/lib/java_stacktrace.c
@@ -53,7 +53,7 @@ struct stacktrace_methods java_stacktrace_methods =
(find_crash_thread_fn_t) sr_java_find_crash_thread,
.threads = (threads_fn_t) java_threads,
.set_threads = (set_threads_fn_t) java_set_threads,
- .free = (free_fn_t) sr_java_stacktrace_free,
+ .stacktrace_free = (stacktrace_free_fn_t) sr_java_stacktrace_free,
.stacktrace_append_bthash_text =
(stacktrace_append_bthash_text_fn_t) java_append_bthash_text,
};
diff --git a/lib/java_thread.c b/lib/java_thread.c
index c3a697a..644ac34 100644
--- a/lib/java_thread.c
+++ b/lib/java_thread.c
@@ -41,6 +41,7 @@ DEFINE_FRAMES_FUNC(java_frames, struct sr_java_thread)
DEFINE_SET_FRAMES_FUNC(java_set_frames, struct sr_java_thread)
DEFINE_NEXT_FUNC(java_next, struct sr_thread, struct sr_java_thread)
DEFINE_SET_NEXT_FUNC(java_set_next, struct sr_thread, struct sr_java_thread)
+DEFINE_DUP_WRAPPER_FUNC(java_dup, struct sr_java_thread, sr_java_thread_dup)
struct thread_methods java_thread_methods =
{
@@ -52,6 +53,11 @@ struct thread_methods java_thread_methods =
.set_next = (set_next_thread_fn_t) java_set_next,
.thread_append_bthash_text =
(thread_append_bthash_text_fn_t) java_append_bthash_text,
+ .thread_free = (thread_free_fn_t) sr_java_thread_free,
+ .remove_frame = (remove_frame_fn_t) thread_remove_frame,
+ .remove_frames_above =
+ (remove_frames_above_fn_t) thread_remove_frames_above,
+ .thread_dup = (thread_dup_fn_t) java_dup,
};
/* Public functions */
diff --git a/lib/koops_frame.c b/lib/koops_frame.c
index 7ae3ece..aecd591 100644
--- a/lib/koops_frame.c
+++ b/lib/koops_frame.c
@@ -47,6 +47,7 @@ struct frame_methods koops_frame_methods =
.cmp_distance = (frame_cmp_fn_t) sr_koops_frame_cmp_distance,
.frame_append_bthash_text =
(frame_append_bthash_text_fn_t) koops_append_bthash_text,
+ .frame_free = (frame_free_fn_t) sr_koops_frame_free,
};
/* Public functions */
diff --git a/lib/koops_stacktrace.c b/lib/koops_stacktrace.c
index 0533034..ab62598 100644
--- a/lib/koops_stacktrace.c
+++ b/lib/koops_stacktrace.c
@@ -73,6 +73,11 @@ struct thread_methods koops_thread_methods =
.next = (next_thread_fn_t) thread_no_next_thread,
.set_next = (set_next_thread_fn_t) NULL,
.thread_append_bthash_text = (thread_append_bthash_text_fn_t) thread_no_bthash_text,
+ .thread_free = (thread_free_fn_t) sr_koops_stacktrace_free,
+ .remove_frame = (remove_frame_fn_t) thread_remove_frame,
+ .remove_frames_above =
+ (remove_frames_above_fn_t) thread_remove_frames_above,
+ .thread_dup = (thread_dup_fn_t) sr_koops_stacktrace_dup,
};
struct stacktrace_methods koops_stacktrace_methods =
@@ -85,7 +90,7 @@ struct stacktrace_methods koops_stacktrace_methods =
.find_crash_thread = (find_crash_thread_fn_t) stacktrace_one_thread_only,
.threads = (threads_fn_t) stacktrace_one_thread_only,
.set_threads = (set_threads_fn_t) NULL,
- .free = (free_fn_t) sr_koops_stacktrace_free,
+ .stacktrace_free = (stacktrace_free_fn_t) sr_koops_stacktrace_free,
.stacktrace_append_bthash_text =
(stacktrace_append_bthash_text_fn_t) koops_append_bthash_text,
};
diff --git a/lib/python_frame.c b/lib/python_frame.c
index 8ac4b90..4a6a209 100644
--- a/lib/python_frame.c
+++ b/lib/python_frame.c
@@ -46,6 +46,7 @@ struct frame_methods python_frame_methods =
.cmp_distance = (frame_cmp_fn_t) sr_python_frame_cmp_distance,
.frame_append_bthash_text =
(frame_append_bthash_text_fn_t) python_append_bthash_text,
+ .frame_free = (frame_free_fn_t) sr_python_frame_free,
};
/* Public functions */
diff --git a/lib/python_stacktrace.c b/lib/python_stacktrace.c
index 300bd0b..15bb41c 100644
--- a/lib/python_stacktrace.c
+++ b/lib/python_stacktrace.c
@@ -52,6 +52,11 @@ struct thread_methods python_thread_methods =
.set_next = (set_next_thread_fn_t) NULL,
.thread_append_bthash_text =
(thread_append_bthash_text_fn_t) thread_no_bthash_text,
+ .thread_free = (thread_free_fn_t) sr_python_stacktrace_free,
+ .remove_frame = (remove_frame_fn_t) thread_remove_frame,
+ .remove_frames_above =
+ (remove_frames_above_fn_t) thread_remove_frames_above,
+ .thread_dup = (thread_dup_fn_t) sr_python_stacktrace_dup,
};
struct stacktrace_methods python_stacktrace_methods =
@@ -64,7 +69,7 @@ struct stacktrace_methods python_stacktrace_methods =
.find_crash_thread = (find_crash_thread_fn_t) stacktrace_one_thread_only,
.threads = (threads_fn_t) stacktrace_one_thread_only,
.set_threads = (set_threads_fn_t) NULL,
- .free = (free_fn_t) sr_python_stacktrace_free,
+ .stacktrace_free = (stacktrace_free_fn_t) sr_python_stacktrace_free,
.stacktrace_append_bthash_text =
(stacktrace_append_bthash_text_fn_t) python_append_bthash_text,
};
--
1.7.11.7
More information about the Crash-catcher
mailing list