[SATYR PATCH 2/3] Implement bthashes
Martin Milata
mmilata at redhat.com
Wed Jun 26 14:13:52 UTC 2013
BTHASH is computed from (almost) everything that is contained in a
stacktrace and therefore should be unique (as much as a hash can be).
Related to #66.
Signed-off-by: Martin Milata <mmilata at redhat.com>
---
include/stacktrace.h | 22 ++++++++++++++++++++++
lib/core_frame.c | 23 +++++++++++++++++++++++
lib/core_stacktrace.c | 15 +++++++++++++++
lib/core_thread.c | 3 +++
lib/gdb_frame.c | 24 ++++++++++++++++++++++++
lib/gdb_stacktrace.c | 21 +++++++++++++++++++++
lib/gdb_thread.c | 14 ++++++++++++++
lib/generic_frame.c | 9 +++++++++
lib/generic_frame.h | 9 +++++++++
lib/generic_stacktrace.c | 43 +++++++++++++++++++++++++++++++++++++++++++
lib/generic_stacktrace.h | 4 ++++
lib/generic_thread.c | 16 ++++++++++++++++
lib/generic_thread.h | 14 ++++++++++++++
lib/internal_utils.h | 3 +++
lib/java_frame.c | 22 ++++++++++++++++++++++
lib/java_stacktrace.c | 9 +++++++++
lib/java_thread.c | 13 +++++++++++++
lib/koops_frame.c | 27 +++++++++++++++++++++++++++
lib/koops_stacktrace.c | 34 ++++++++++++++++++++++++++++++++++
lib/python_frame.c | 21 +++++++++++++++++++++
lib/python_stacktrace.c | 16 ++++++++++++++++
21 files changed, 362 insertions(+)
diff --git a/include/stacktrace.h b/include/stacktrace.h
index d16a1a9..d23b32a 100644
--- a/include/stacktrace.h
+++ b/include/stacktrace.h
@@ -42,6 +42,19 @@ struct sr_stacktrace
enum sr_report_type type;
};
+/* Flags that influence how the bthash is computed.
+ */
+enum sr_bthash_flags
+{
+ /* Default hashing process.
+ */
+ SR_BTHASH_NORMAL = 1 << 0,
+
+ /* Return the plaintext that would be hashed. Useful mainly for debugging.
+ */
+ SR_BTHASH_NOHASH = 1 << 1,
+};
+
/**
* Parses the stacktrace pointed to by input. You need to provide the correct
* stacktrace type in the first parameter.
@@ -87,6 +100,15 @@ char *
sr_stacktrace_get_reason(struct sr_stacktrace *stacktrace);
/**
+ * Returns hash of a backtrace. This is a hash in the usual sense that the same
+ * stacktraces always have the same hash while two distinct stacktraces have
+ * negligible probability of having the same hash. The string is allocated by
+ * malloc().
+ */
+char *
+sr_stacktrace_get_bthash(struct sr_stacktrace *stacktrace, enum sr_bthash_flags flags);
+
+/**
* Releases all the memory associated with the stacktrace pointer.
*/
void
diff --git a/lib/core_frame.c b/lib/core_frame.c
index 074de56..2833b8a 100644
--- a/lib/core_frame.c
+++ b/lib/core_frame.c
@@ -22,11 +22,16 @@
#include "strbuf.h"
#include "json.h"
#include "generic_frame.h"
+#include "stacktrace.h"
#include "internal_utils.h"
#include <string.h>
/* Method table */
+static void
+core_append_bthash_text(struct sr_core_frame *frame, enum sr_bthash_flags flags,
+ struct sr_strbuf *strbuf);
+
DEFINE_NEXT_FUNC(core_next, struct sr_frame, struct sr_core_frame)
DEFINE_SET_NEXT_FUNC(core_set_next, struct sr_frame, struct sr_core_frame)
@@ -37,6 +42,8 @@ struct frame_methods core_frame_methods =
.set_next = (set_next_frame_fn_t) core_set_next,
.cmp = (frame_cmp_fn_t) sr_core_frame_cmp,
.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,
};
/* Public functions */
@@ -404,3 +411,19 @@ sr_core_frame_append_to_str(struct sr_core_frame *frame,
sr_strbuf_append_strf(dest, " in %s", frame->file_name);
}
}
+
+static void
+core_append_bthash_text(struct sr_core_frame *frame, enum sr_bthash_flags flags,
+ struct sr_strbuf *strbuf)
+{
+ if (frame->address)
+ sr_strbuf_append_strf(strbuf, "0x%"PRIx64", ", frame->address);
+ else
+ sr_strbuf_append_str(strbuf, "<unknown>, ");
+
+ sr_strbuf_append_strf(strbuf, "%s+0x%"PRIx64", %s, %s\n",
+ OR_UNKNOWN(frame->build_id),
+ frame->build_id_offset,
+ OR_UNKNOWN(frame->file_name),
+ OR_UNKNOWN(frame->fingerprint));
+}
diff --git a/lib/core_stacktrace.c b/lib/core_stacktrace.c
index 172ade2..2b5997c 100644
--- a/lib/core_stacktrace.c
+++ b/lib/core_stacktrace.c
@@ -40,6 +40,10 @@
/* Method table */
+static void
+core_append_bthash_text(struct sr_core_stacktrace *stacktrace, enum sr_bthash_flags flags,
+ struct sr_strbuf *strbuf);
+
DEFINE_THREADS_FUNC(core_threads, struct sr_core_stacktrace)
DEFINE_SET_THREADS_FUNC(core_set_threads, struct sr_core_stacktrace)
@@ -56,6 +60,8 @@ struct stacktrace_methods core_stacktrace_methods =
.threads = (threads_fn_t) core_threads,
.set_threads = (set_threads_fn_t) core_set_threads,
.free = (free_fn_t) sr_core_stacktrace_free,
+ .stacktrace_append_bthash_text =
+ (stacktrace_append_bthash_text_fn_t) core_append_bthash_text,
};
/* Public functions */
@@ -393,3 +399,12 @@ sr_core_stacktrace_get_reason(struct sr_core_stacktrace *stacktrace)
return sr_asprintf("Program %s was terminated by signal %"PRIu16, prog, stacktrace->signal);
}
+
+static void
+core_append_bthash_text(struct sr_core_stacktrace *stacktrace, enum sr_bthash_flags flags,
+ struct sr_strbuf *strbuf)
+{
+ sr_strbuf_append_strf(strbuf, "Executable: %s\n", OR_UNKNOWN(stacktrace->executable));
+ sr_strbuf_append_strf(strbuf, "Signal: %"PRIu16"\n", stacktrace->signal);
+ sr_strbuf_append_char(strbuf, '\n');
+}
diff --git a/lib/core_thread.c b/lib/core_thread.c
index dd41a78..5844ce9 100644
--- a/lib/core_thread.c
+++ b/lib/core_thread.c
@@ -23,6 +23,7 @@
#include "strbuf.h"
#include "json.h"
#include "generic_thread.h"
+#include "stacktrace.h"
#include "internal_utils.h"
#include <string.h>
@@ -41,6 +42,8 @@ struct thread_methods core_thread_methods =
.frame_count = (frame_count_fn_t) thread_frame_count,
.next = (next_thread_fn_t) core_next,
.set_next = (set_next_thread_fn_t) core_set_next,
+ .thread_append_bthash_text =
+ (thread_append_bthash_text_fn_t) thread_no_bthash_text,
};
/* Public functions */
diff --git a/lib/gdb_frame.c b/lib/gdb_frame.c
index b04dbb7..46acd4d 100644
--- a/lib/gdb_frame.c
+++ b/lib/gdb_frame.c
@@ -22,14 +22,20 @@
#include "strbuf.h"
#include "location.h"
#include "generic_frame.h"
+#include "stacktrace.h"
#include "internal_utils.h"
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <stdarg.h>
+#include <inttypes.h>
/* Method table */
+static void
+gdb_append_bthash_text(struct sr_gdb_frame *frame, enum sr_bthash_flags flags,
+ struct sr_strbuf *strbuf);
+
DEFINE_NEXT_FUNC(gdb_next, struct sr_frame, struct sr_gdb_frame)
DEFINE_SET_NEXT_FUNC(gdb_set_next, struct sr_frame, struct sr_gdb_frame)
@@ -46,6 +52,8 @@ struct frame_methods gdb_frame_methods =
.set_next = (set_next_frame_fn_t) gdb_set_next,
.cmp = (frame_cmp_fn_t) frame_cmp_without_number,
.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,
};
/* Public functions */
@@ -1114,3 +1122,19 @@ sr_gdb_frame_remove_func_prefix(struct sr_gdb_frame *frame,
memmove(frame->function_name, frame->function_name + num,
func_len - num + 1);
}
+
+static void
+gdb_append_bthash_text(struct sr_gdb_frame *frame, enum sr_bthash_flags flags,
+ struct sr_strbuf *strbuf)
+{
+ sr_strbuf_append_strf(strbuf,
+ "%s, %s, %" PRIu32 ", %s, %" PRIu32 ", %d, 0x%" PRIx64 ", %s\n",
+ OR_UNKNOWN(frame->function_name),
+ OR_UNKNOWN(frame->function_type),
+ frame->number,
+ OR_UNKNOWN(frame->source_file),
+ frame->source_line,
+ frame->signal_handler_called,
+ frame->address,
+ OR_UNKNOWN(frame->library_name));
+}
diff --git a/lib/gdb_stacktrace.c b/lib/gdb_stacktrace.c
index b77898b..6ccebab 100644
--- a/lib/gdb_stacktrace.c
+++ b/lib/gdb_stacktrace.c
@@ -34,6 +34,10 @@
/* Method table */
+static void
+gdb_append_bthash_text(struct sr_gdb_stacktrace *stacktrace, enum sr_bthash_flags flags,
+ struct sr_strbuf *strbuf);
+
/* for not used/implemented methods */
static char *
gdb_return_null(struct sr_stacktrace *stacktrace)
@@ -57,6 +61,8 @@ struct stacktrace_methods gdb_stacktrace_methods =
.threads = (threads_fn_t) gdb_threads,
.set_threads = (set_threads_fn_t) gdb_set_threads,
.free = (free_fn_t) sr_gdb_stacktrace_free,
+ .stacktrace_append_bthash_text =
+ (stacktrace_append_bthash_text_fn_t) gdb_append_bthash_text,
};
/* Public functions */
@@ -528,3 +534,18 @@ sr_gdb_stacktrace_to_short_text(struct sr_gdb_stacktrace *stacktrace,
sr_gdb_thread_free(optimized_thread);
return sr_strbuf_free_nobuf(strbuf);
}
+
+static void
+gdb_append_bthash_text(struct sr_gdb_stacktrace *stacktrace, enum sr_bthash_flags flags,
+ struct sr_strbuf *strbuf)
+{
+ for (struct sr_gdb_sharedlib *lib = stacktrace->libs;
+ lib;
+ lib = lib->next)
+ {
+ sr_strbuf_append_strf(strbuf, "%"PRIx64"-%"PRIx64", %s\n", lib->from, lib->to,
+ OR_UNKNOWN(lib->soname));
+ }
+
+ sr_strbuf_append_char(strbuf, '\n');
+}
diff --git a/lib/gdb_thread.c b/lib/gdb_thread.c
index b957155..45da010 100644
--- a/lib/gdb_thread.c
+++ b/lib/gdb_thread.c
@@ -25,6 +25,7 @@
#include "utils.h"
#include "strbuf.h"
#include "generic_thread.h"
+#include "stacktrace.h"
#include "internal_utils.h"
#include <assert.h>
#include <stdlib.h>
@@ -32,6 +33,10 @@
/* Method table */
+static void
+gdb_append_bthash_text(struct sr_gdb_thread *thread, enum sr_bthash_flags flags,
+ struct sr_strbuf *strbuf);
+
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)
@@ -45,6 +50,8 @@ struct thread_methods gdb_thread_methods =
.frame_count = (frame_count_fn_t) thread_frame_count,
.next = (next_thread_fn_t) gdb_next,
.set_next = (set_next_thread_fn_t) gdb_set_next,
+ .thread_append_bthash_text =
+ (thread_append_bthash_text_fn_t) gdb_append_bthash_text,
};
/* Public functions */
@@ -550,3 +557,10 @@ sr_gdb_thread_get_optimized(struct sr_gdb_thread *thread,
return thread;
}
+
+static void
+gdb_append_bthash_text(struct sr_gdb_thread *thread, enum sr_bthash_flags flags,
+ struct sr_strbuf *strbuf)
+{
+ sr_strbuf_append_strf(strbuf, "Thread %"PRIu32"\n", thread->number);
+}
diff --git a/lib/generic_frame.c b/lib/generic_frame.c
index fd83bd4..04a8407 100644
--- a/lib/generic_frame.c
+++ b/lib/generic_frame.c
@@ -23,6 +23,7 @@
#include "report_type.h"
#include "internal_utils.h"
#include "generic_frame.h"
+#include "stacktrace.h"
/* Initialize dispatch table. */
static struct frame_methods* dtable[SR_REPORT_NUM] =
@@ -70,3 +71,11 @@ sr_frame_cmp_distance(struct sr_frame *frame1, struct sr_frame *frame2)
return DISPATCH(dtable, frame1->type, cmp_distance)(frame1, frame2);
}
+
+void
+frame_append_bthash_text(struct sr_frame *frame, enum sr_bthash_flags flags,
+ struct sr_strbuf *strbuf)
+{
+ DISPATCH(dtable, frame->type, frame_append_bthash_text)
+ (frame, flags, strbuf);
+}
diff --git a/lib/generic_frame.h b/lib/generic_frame.h
index e6fdaca..584112e 100644
--- a/lib/generic_frame.h
+++ b/lib/generic_frame.h
@@ -20,10 +20,14 @@
#include "frame.h"
+enum sr_bthash_flags;
+
typedef void (*append_to_str_fn_t)(struct sr_frame *, struct sr_strbuf *);
typedef struct sr_frame* (*next_frame_fn_t)(struct sr_frame *);
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*);
struct frame_methods
{
@@ -32,7 +36,12 @@ struct frame_methods
set_next_frame_fn_t set_next;
frame_cmp_fn_t cmp;
frame_cmp_fn_t cmp_distance;
+ frame_append_bthash_text_fn_t frame_append_bthash_text;
};
extern struct frame_methods core_frame_methods, python_frame_methods,
koops_frame_methods, gdb_frame_methods, java_frame_methods;
+
+void
+frame_append_bthash_text(struct sr_frame *frame, enum sr_bthash_flags flags,
+ struct sr_strbuf *strbuf);
diff --git a/lib/generic_stacktrace.c b/lib/generic_stacktrace.c
index d7f7ca4..bba7f5f 100644
--- a/lib/generic_stacktrace.c
+++ b/lib/generic_stacktrace.c
@@ -23,10 +23,13 @@
#include "internal_utils.h"
#include "strbuf.h"
#include "location.h"
+#include "sha1.h"
#include "frame.h"
#include "thread.h"
#include "generic_stacktrace.h"
+#include "generic_thread.h"
+#include "generic_frame.h"
/* Initialize dispatch table. */
static struct stacktrace_methods* dtable[SR_REPORT_NUM] =
@@ -137,3 +140,43 @@ sr_stacktrace_free(struct sr_stacktrace *stacktrace)
{
DISPATCH(dtable, stacktrace->type, free)(stacktrace);
}
+
+char *
+sr_stacktrace_get_bthash(struct sr_stacktrace *stacktrace, enum sr_bthash_flags flags)
+{
+ char *ret;
+ struct sr_strbuf *strbuf = sr_strbuf_new();
+
+ /* Append data contained in the stacktrace structure. */
+ DISPATCH(dtable, stacktrace->type, stacktrace_append_bthash_text)
+ (stacktrace, flags, strbuf);
+
+ for (struct sr_thread *thread = sr_stacktrace_threads(stacktrace);
+ thread;
+ thread = sr_thread_next(thread))
+ {
+ /* Data containted in the thread structure (if any). */
+ thread_append_bthash_text(thread, flags, strbuf);
+
+ for (struct sr_frame *frame = sr_thread_frames(thread);
+ frame;
+ frame = sr_frame_next(frame))
+ {
+ frame_append_bthash_text(frame, flags, strbuf);
+ }
+
+ /* Blank line in between threads. */
+ if (sr_thread_next(thread))
+ sr_strbuf_append_char(strbuf, '\n');
+ }
+
+ if (flags & SR_BTHASH_NOHASH)
+ ret = sr_strbuf_free_nobuf(strbuf);
+ else
+ {
+ ret = sr_sha1_hash_string(strbuf->buf);
+ sr_strbuf_free(strbuf);
+ }
+
+ return ret;
+}
diff --git a/lib/generic_stacktrace.h b/lib/generic_stacktrace.h
index bb6ba9f..5615998 100644
--- a/lib/generic_stacktrace.h
+++ b/lib/generic_stacktrace.h
@@ -20,6 +20,7 @@
#include "stacktrace.h"
#include "thread.h"
+#include "strbuf.h"
typedef struct sr_stacktrace* (*parse_fn_t)(const char **, char **);
typedef struct sr_stacktrace* (*parse_location_fn_t)(const char **, struct sr_location *);
@@ -30,6 +31,8 @@ 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_append_bthash_text_fn_t)(struct sr_stacktrace *, enum sr_bthash_flags,
+ struct sr_strbuf *);
struct stacktrace_methods
{
@@ -42,6 +45,7 @@ struct stacktrace_methods
threads_fn_t threads;
set_threads_fn_t set_threads;
free_fn_t free;
+ stacktrace_append_bthash_text_fn_t stacktrace_append_bthash_text;
};
extern struct stacktrace_methods core_stacktrace_methods, python_stacktrace_methods,
diff --git a/lib/generic_thread.c b/lib/generic_thread.c
index 24e590a..b0b3861 100644
--- a/lib/generic_thread.c
+++ b/lib/generic_thread.c
@@ -21,6 +21,7 @@
#include "report_type.h"
#include "internal_utils.h"
#include "frame.h"
+#include "stacktrace.h"
#include "generic_thread.h"
#include <stdio.h>
@@ -50,6 +51,13 @@ thread_no_next_thread(struct sr_thread *thread)
return NULL;
}
+void
+thread_no_bthash_text(struct sr_thread *thread, enum sr_bthash_flags flags,
+ struct sr_strbuf *strbuf)
+{
+ /* nop */
+}
+
/* Initialize dispatch table. */
/* Table that maps type-specific functions to the corresponding report types.
@@ -103,3 +111,11 @@ sr_thread_set_next(struct sr_thread *cur, struct sr_thread *next)
assert(next == NULL || cur->type == next->type);
DISPATCH(dtable, cur->type, set_next)(cur, next);
}
+
+void
+thread_append_bthash_text(struct sr_thread *thread, enum sr_bthash_flags flags,
+ struct sr_strbuf *strbuf)
+{
+ DISPATCH(dtable, thread->type, thread_append_bthash_text)
+ (thread, flags, strbuf);
+}
diff --git a/lib/generic_thread.h b/lib/generic_thread.h
index 334994d..6022fb5 100644
--- a/lib/generic_thread.h
+++ b/lib/generic_thread.h
@@ -21,12 +21,16 @@
#include "thread.h"
#include "internal_utils.h"
+enum sr_bthash_flags;
+
typedef struct sr_frame* (*frames_fn_t)(struct sr_thread*);
typedef void (*set_frames_fn_t)(struct sr_thread*, struct sr_frame*);
typedef int (*thread_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*);
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*);
struct thread_methods
{
@@ -36,6 +40,7 @@ struct thread_methods
frame_count_fn_t frame_count;
next_thread_fn_t next;
set_next_thread_fn_t set_next;
+ thread_append_bthash_text_fn_t thread_append_bthash_text;
};
extern struct thread_methods core_thread_methods, python_thread_methods,
@@ -53,3 +58,12 @@ thread_frame_count(struct sr_thread *thread);
struct sr_thread *
thread_no_next_thread(struct sr_thread *thread);
+
+void
+thread_no_bthash_text(struct sr_thread *thread, enum sr_bthash_flags flags,
+ struct sr_strbuf *strbuf);
+
+/* Uses dispatch table but not intended for public use. */
+void
+thread_append_bthash_text(struct sr_thread *thread, enum sr_bthash_flags flags,
+ struct sr_strbuf *strbuf);
diff --git a/lib/internal_utils.h b/lib/internal_utils.h
index a237064..2236f58 100644
--- a/lib/internal_utils.h
+++ b/lib/internal_utils.h
@@ -40,3 +40,6 @@
#define DEFINE_NEXT_FUNC(name, abstract_t, concrete_t) DEFINE_GETTER(name, next, abstract_t, concrete_t, abstract_t)
#define DEFINE_SET_NEXT_FUNC(name, abstract_t, concrete_t) DEFINE_SETTER(name, next, abstract_t, concrete_t, abstract_t)
+
+/* beware the side effects */
+#define OR_UNKNOWN(s) ((s) ? (s) : "<unknown>")
diff --git a/lib/java_frame.c b/lib/java_frame.c
index 9477bc9..71881ca 100644
--- a/lib/java_frame.c
+++ b/lib/java_frame.c
@@ -24,6 +24,7 @@
#include "utils.h"
#include "json.h"
#include "generic_frame.h"
+#include "stacktrace.h"
#include "internal_utils.h"
#include <string.h>
#include <inttypes.h>
@@ -33,6 +34,10 @@
/* Method table */
+static void
+java_append_bthash_text(struct sr_java_frame *frame, enum sr_bthash_flags flags,
+ struct sr_strbuf *strbuf);
+
DEFINE_NEXT_FUNC(java_next, struct sr_frame, struct sr_java_frame)
DEFINE_SET_NEXT_FUNC(java_set_next, struct sr_frame, struct sr_java_frame)
@@ -43,6 +48,8 @@ struct frame_methods java_frame_methods =
.set_next = (set_next_frame_fn_t) java_set_next,
.cmp = (frame_cmp_fn_t) sr_java_frame_cmp,
.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,
};
/* Public functions */
@@ -571,3 +578,18 @@ sr_java_frame_to_json(struct sr_java_frame *frame)
sr_strbuf_append_str(strbuf, "}");
return sr_strbuf_free_nobuf(strbuf);
}
+
+static void
+java_append_bthash_text(struct sr_java_frame *frame, enum sr_bthash_flags flags,
+ struct sr_strbuf *strbuf)
+{
+ sr_strbuf_append_strf(strbuf,
+ "%s, %s, %"PRIu32", %s, %d, %d, %s\n",
+ OR_UNKNOWN(frame->name),
+ OR_UNKNOWN(frame->file_name),
+ frame->file_line,
+ OR_UNKNOWN(frame->class_path),
+ frame->is_native,
+ frame->is_exception,
+ OR_UNKNOWN(frame->message));
+}
diff --git a/lib/java_stacktrace.c b/lib/java_stacktrace.c
index b3231e7..d0b9152 100644
--- a/lib/java_stacktrace.c
+++ b/lib/java_stacktrace.c
@@ -31,6 +31,13 @@
/* Method table */
+static void
+java_append_bthash_text(struct sr_java_stacktrace *stacktrace, enum sr_bthash_flags flags,
+ struct sr_strbuf *strbuf)
+{
+ /* nop */
+}
+
DEFINE_THREADS_FUNC(java_threads, struct sr_java_stacktrace)
DEFINE_SET_THREADS_FUNC(java_set_threads, struct sr_java_stacktrace)
DEFINE_PARSE_WRAPPER_FUNC(java_parse, SR_REPORT_JAVA)
@@ -47,6 +54,8 @@ struct stacktrace_methods java_stacktrace_methods =
.threads = (threads_fn_t) java_threads,
.set_threads = (set_threads_fn_t) java_set_threads,
.free = (free_fn_t) sr_java_stacktrace_free,
+ .stacktrace_append_bthash_text =
+ (stacktrace_append_bthash_text_fn_t) java_append_bthash_text,
};
/* Public functions */
diff --git a/lib/java_thread.c b/lib/java_thread.c
index 70b01b3..c3a697a 100644
--- a/lib/java_thread.c
+++ b/lib/java_thread.c
@@ -25,6 +25,7 @@
#include "strbuf.h"
#include "json.h"
#include "generic_thread.h"
+#include "stacktrace.h"
#include "internal_utils.h"
#include <assert.h>
#include <stdlib.h>
@@ -32,6 +33,10 @@
/* Method table */
+static void
+java_append_bthash_text(struct sr_java_thread *thread, enum sr_bthash_flags flags,
+ struct sr_strbuf *strbuf);
+
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)
@@ -45,6 +50,8 @@ struct thread_methods java_thread_methods =
.frame_count = (frame_count_fn_t) thread_frame_count,
.next = (next_thread_fn_t) java_next,
.set_next = (set_next_thread_fn_t) java_set_next,
+ .thread_append_bthash_text =
+ (thread_append_bthash_text_fn_t) java_append_bthash_text,
};
/* Public functions */
@@ -394,3 +401,9 @@ sr_java_thread_to_json(struct sr_java_thread *thread)
return sr_strbuf_free_nobuf(strbuf);
}
+static void
+java_append_bthash_text(struct sr_java_thread *thread, enum sr_bthash_flags flags,
+ struct sr_strbuf *strbuf)
+{
+ sr_strbuf_append_strf(strbuf, "Thread %s\n", OR_UNKNOWN(thread->name));
+}
diff --git a/lib/koops_frame.c b/lib/koops_frame.c
index 2dfdad9..7ae3ece 100644
--- a/lib/koops_frame.c
+++ b/lib/koops_frame.c
@@ -22,6 +22,7 @@
#include "strbuf.h"
#include "json.h"
#include "generic_frame.h"
+#include "stacktrace.h"
#include "internal_utils.h"
#include <stdlib.h>
#include <stdio.h>
@@ -30,6 +31,10 @@
/* Method table */
+static void
+koops_append_bthash_text(struct sr_koops_frame *frame, enum sr_bthash_flags flags,
+ struct sr_strbuf *strbuf);
+
DEFINE_NEXT_FUNC(koops_next, struct sr_frame, struct sr_koops_frame)
DEFINE_SET_NEXT_FUNC(koops_set_next, struct sr_frame, struct sr_koops_frame)
@@ -40,6 +45,8 @@ struct frame_methods koops_frame_methods =
.set_next = (set_next_frame_fn_t) koops_set_next,
.cmp = (frame_cmp_fn_t) sr_koops_frame_cmp,
.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,
};
/* Public functions */
@@ -513,3 +520,23 @@ sr_koops_frame_append_to_str(struct sr_koops_frame *frame,
if (frame->module_name)
sr_strbuf_append_strf(str, " in %s", frame->module_name);
}
+
+static void
+koops_append_bthash_text(struct sr_koops_frame *frame, enum sr_bthash_flags flags,
+ struct sr_strbuf *strbuf)
+{
+ sr_strbuf_append_strf(strbuf,
+ "0x%"PRIx64", %d, %s, 0x%"PRIx64", 0x%"PRIx64", %s, "
+ "0x%"PRIx64", %s, 0x%"PRIx64", 0x%"PRIx64", %s\n",
+ frame->address,
+ frame->reliable,
+ OR_UNKNOWN(frame->function_name),
+ frame->function_offset,
+ frame->function_length,
+ OR_UNKNOWN(frame->module_name),
+ frame->from_address,
+ OR_UNKNOWN(frame->from_function_name),
+ frame->from_function_offset,
+ frame->from_function_length,
+ OR_UNKNOWN(frame->from_module_name));
+}
diff --git a/lib/koops_stacktrace.c b/lib/koops_stacktrace.c
index 5ac3fdf..95ae344 100644
--- a/lib/koops_stacktrace.c
+++ b/lib/koops_stacktrace.c
@@ -56,6 +56,10 @@ struct sr_taint_flag sr_flags[] = {
/* Method tables */
+static void
+koops_append_bthash_text(struct sr_koops_stacktrace *stacktrace,
+ enum sr_bthash_flags flags, struct sr_strbuf *strbuf);
+
DEFINE_FRAMES_FUNC(koops_frames, struct sr_koops_stacktrace)
DEFINE_SET_FRAMES_FUNC(koops_set_frames, struct sr_koops_stacktrace)
DEFINE_PARSE_WRAPPER_FUNC(koops_parse, SR_REPORT_KERNELOOPS)
@@ -68,6 +72,7 @@ struct thread_methods koops_thread_methods =
.frame_count = (frame_count_fn_t) thread_frame_count,
.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,
};
struct stacktrace_methods koops_stacktrace_methods =
@@ -81,6 +86,8 @@ struct stacktrace_methods koops_stacktrace_methods =
.threads = (threads_fn_t) stacktrace_one_thread_only,
.set_threads = (set_threads_fn_t) NULL,
.free = (free_fn_t) sr_koops_stacktrace_free,
+ .stacktrace_append_bthash_text =
+ (stacktrace_append_bthash_text_fn_t) koops_append_bthash_text,
};
/* Public functions */
@@ -525,3 +532,30 @@ sr_koops_stacktrace_get_reason(struct sr_koops_stacktrace *stacktrace)
return result;
}
+
+static void
+koops_append_bthash_text(struct sr_koops_stacktrace *stacktrace,
+ enum sr_bthash_flags flags, struct sr_strbuf *strbuf)
+{
+ sr_strbuf_append_strf(strbuf, "Version: %s\n", OR_UNKNOWN(stacktrace->version));
+
+ sr_strbuf_append_str(strbuf, "Flags: ");
+ for (struct sr_taint_flag *f = sr_flags; f->letter; f++)
+ {
+ bool val = *(bool *)((void *)stacktrace + f->member_offset);
+ if (val == false)
+ continue;
+ }
+ sr_strbuf_append_char(strbuf, '\n');
+
+ sr_strbuf_append_str(strbuf, "Modules: ");
+ for (char **mod = stacktrace->modules; mod && *mod; mod++)
+ {
+ sr_strbuf_append_str(strbuf, *mod);
+ if (*(mod+1))
+ sr_strbuf_append_str(strbuf, ", ");
+ }
+ sr_strbuf_append_char(strbuf, '\n');
+
+ sr_strbuf_append_char(strbuf, '\n');
+}
diff --git a/lib/python_frame.c b/lib/python_frame.c
index 077c391..8ac4b90 100644
--- a/lib/python_frame.c
+++ b/lib/python_frame.c
@@ -23,12 +23,17 @@
#include "strbuf.h"
#include "json.h"
#include "generic_frame.h"
+#include "stacktrace.h"
#include "internal_utils.h"
#include <string.h>
#include <inttypes.h>
/* Method table */
+static void
+python_append_bthash_text(struct sr_python_frame *frame, enum sr_bthash_flags flags,
+ struct sr_strbuf *strbuf);
+
DEFINE_NEXT_FUNC(python_next, struct sr_frame, struct sr_python_frame)
DEFINE_SET_NEXT_FUNC(python_set_next, struct sr_frame, struct sr_python_frame)
@@ -39,6 +44,8 @@ struct frame_methods python_frame_methods =
.set_next = (set_next_frame_fn_t) python_set_next,
.cmp = (frame_cmp_fn_t) sr_python_frame_cmp,
.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,
};
/* Public functions */
@@ -344,3 +351,17 @@ sr_python_frame_append_to_str(struct sr_python_frame *frame,
}
}
}
+
+static void
+python_append_bthash_text(struct sr_python_frame *frame, enum sr_bthash_flags flags,
+ struct sr_strbuf *strbuf)
+{
+ sr_strbuf_append_strf(strbuf,
+ "%s, %d, %"PRIu32", %s, %d, %s\n",
+ OR_UNKNOWN(frame->file_name),
+ frame->special_file,
+ frame->file_line,
+ OR_UNKNOWN(frame->function_name),
+ frame->special_function,
+ OR_UNKNOWN(frame->line_contents));
+}
diff --git a/lib/python_stacktrace.c b/lib/python_stacktrace.c
index 3c1d030..300bd0b 100644
--- a/lib/python_stacktrace.c
+++ b/lib/python_stacktrace.c
@@ -34,6 +34,10 @@
/* Method tables */
+static void
+python_append_bthash_text(struct sr_python_stacktrace *stacktrace, enum sr_bthash_flags flags,
+ struct sr_strbuf *strbuf);
+
DEFINE_FRAMES_FUNC(python_frames, struct sr_python_stacktrace)
DEFINE_SET_FRAMES_FUNC(python_set_frames, struct sr_python_stacktrace)
DEFINE_PARSE_WRAPPER_FUNC(python_parse, SR_REPORT_PYTHON)
@@ -46,6 +50,8 @@ struct thread_methods python_thread_methods =
.frame_count = (frame_count_fn_t) thread_frame_count,
.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,
};
struct stacktrace_methods python_stacktrace_methods =
@@ -59,6 +65,8 @@ struct stacktrace_methods python_stacktrace_methods =
.threads = (threads_fn_t) stacktrace_one_thread_only,
.set_threads = (set_threads_fn_t) NULL,
.free = (free_fn_t) sr_python_stacktrace_free,
+ .stacktrace_append_bthash_text =
+ (stacktrace_append_bthash_text_fn_t) python_append_bthash_text,
};
/* Public functions */
@@ -236,3 +244,11 @@ sr_python_stacktrace_get_reason(struct sr_python_stacktrace *stacktrace)
return sr_asprintf("%s in %s:%"PRIu32, exc, file, line);
}
+
+static void
+python_append_bthash_text(struct sr_python_stacktrace *stacktrace, enum sr_bthash_flags flags,
+ struct sr_strbuf *strbuf)
+{
+ sr_strbuf_append_strf(strbuf, "Exception: %s\n", OR_UNKNOWN(stacktrace->exception_name));
+ sr_strbuf_append_char(strbuf, '\n');
+}
--
1.7.11.7
More information about the Crash-catcher
mailing list