Signed-off-by: Martin Milata mmilata@redhat.com --- include/frame.h | 6 ++++++ include/stacktrace.h | 12 ++++++++++++ include/thread.h | 12 ++++++++++++ lib/core_frame.c | 2 ++ lib/core_stacktrace.c | 5 +++++ lib/core_thread.c | 6 +++++- lib/gdb_frame.c | 2 ++ lib/gdb_stacktrace.c | 5 +++++ lib/gdb_thread.c | 6 +++++- lib/generic_frame.c | 9 +++++++++ lib/generic_frame.h | 2 ++ lib/generic_stacktrace.c | 15 +++++++++++++++ lib/generic_stacktrace.h | 11 +++++++++++ lib/generic_thread.c | 15 +++++++++++++++ lib/generic_thread.h | 18 +++++++++++------- lib/internal_utils.h | 19 ++++++++++++++----- lib/java_frame.c | 2 ++ lib/java_stacktrace.c | 5 +++++ lib/java_thread.c | 6 +++++- lib/koops_frame.c | 2 ++ lib/koops_stacktrace.c | 7 ++++++- lib/python_frame.c | 2 ++ lib/python_stacktrace.c | 7 ++++++- 23 files changed, 159 insertions(+), 17 deletions(-)
diff --git a/include/frame.h b/include/frame.h index 9eda374..706522a 100644 --- a/include/frame.h +++ b/include/frame.h @@ -52,6 +52,12 @@ struct sr_frame * sr_frame_next(struct sr_frame *frame);
/** + * Set the next pointer. + */ +void +sr_frame_set_next(struct sr_frame *cur, struct sr_frame *next); + +/** * Appends textual representation of the frame to buffer strbuf. */ void diff --git a/include/stacktrace.h b/include/stacktrace.h index c611e73..d16a1a9 100644 --- a/include/stacktrace.h +++ b/include/stacktrace.h @@ -63,6 +63,18 @@ struct sr_thread * sr_stacktrace_find_crash_thread(struct sr_stacktrace *stacktrace);
/** + * Returns pointer to the first thread. + */ +struct sr_thread * +sr_stacktrace_threads(struct sr_stacktrace *stacktrace); + +/** + * Set the threads linked list pointer. + */ +void +sr_stacktrace_set_threads(struct sr_stacktrace *stacktrace, struct sr_thread *threads); + +/** * Convert stacktrace to json and return it as text. */ char * diff --git a/include/thread.h b/include/thread.h index cb73577..1f39c2a 100644 --- a/include/thread.h +++ b/include/thread.h @@ -51,6 +51,12 @@ struct sr_frame * sr_thread_frames(struct sr_thread *thread);
/** + * Set the frame linked list pointer. + */ +void +sr_thread_set_frames(struct sr_thread *thread, struct sr_frame *frames); + +/** * Returns the number of frames in the thread. */ int @@ -69,6 +75,12 @@ sr_thread_cmp(struct sr_thread *t1, struct sr_thread *t2); struct sr_thread * sr_thread_next(struct sr_thread *thread);
+/** + * Set the next pointer. + */ +void +sr_thread_set_next(struct sr_thread *cur, struct sr_thread *next); + #ifdef __cplusplus } #endif diff --git a/lib/core_frame.c b/lib/core_frame.c index ac3f601..afdeb55 100644 --- a/lib/core_frame.c +++ b/lib/core_frame.c @@ -28,11 +28,13 @@ /* Method table */
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)
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, + .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, }; diff --git a/lib/core_stacktrace.c b/lib/core_stacktrace.c index 46bdcc7..172ade2 100644 --- a/lib/core_stacktrace.c +++ b/lib/core_stacktrace.c @@ -40,6 +40,9 @@
/* Method table */
+DEFINE_THREADS_FUNC(core_threads, struct sr_core_stacktrace) +DEFINE_SET_THREADS_FUNC(core_set_threads, struct sr_core_stacktrace) + struct stacktrace_methods core_stacktrace_methods = { /* core parser returns error_message directly */ @@ -50,6 +53,8 @@ struct stacktrace_methods core_stacktrace_methods = .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, + .threads = (threads_fn_t) core_threads, + .set_threads = (set_threads_fn_t) core_set_threads, .free = (free_fn_t) sr_core_stacktrace_free, };
diff --git a/lib/core_thread.c b/lib/core_thread.c index e97f806..dd41a78 100644 --- a/lib/core_thread.c +++ b/lib/core_thread.c @@ -28,15 +28,19 @@
/* Method table */
-DEFINE_THREAD_FUNC(core_frames, struct sr_core_thread) +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)
struct thread_methods core_thread_methods = { .frames = (frames_fn_t) core_frames, + .set_frames = (set_frames_fn_t) core_set_frames, .cmp = (thread_cmp_fn_t) sr_core_thread_cmp, .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, };
/* Public functions */ diff --git a/lib/gdb_frame.c b/lib/gdb_frame.c index f9e7f41..b04dbb7 100644 --- a/lib/gdb_frame.c +++ b/lib/gdb_frame.c @@ -31,6 +31,7 @@ /* Method table */
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)
static int frame_cmp_without_number(struct sr_gdb_frame *frame1, struct sr_gdb_frame *frame2) @@ -42,6 +43,7 @@ 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, + .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, }; diff --git a/lib/gdb_stacktrace.c b/lib/gdb_stacktrace.c index 1ef33dd..6e4dc29 100644 --- a/lib/gdb_stacktrace.c +++ b/lib/gdb_stacktrace.c @@ -41,6 +41,9 @@ gdb_return_null(struct sr_stacktrace *stacktrace) return NULL; }
+DEFINE_THREADS_FUNC(gdb_threads, struct sr_gdb_stacktrace) +DEFINE_SET_THREADS_FUNC(gdb_set_threads, struct sr_gdb_stacktrace) + struct stacktrace_methods gdb_stacktrace_methods = { .parse = (parse_fn_t) stacktrace_parse_wrapper, @@ -50,6 +53,8 @@ struct stacktrace_methods gdb_stacktrace_methods = .get_reason = (get_reason_fn_t) gdb_return_null, .find_crash_thread = (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, };
diff --git a/lib/gdb_thread.c b/lib/gdb_thread.c index e1af1f2..b957155 100644 --- a/lib/gdb_thread.c +++ b/lib/gdb_thread.c @@ -32,15 +32,19 @@
/* Method table */
-DEFINE_THREAD_FUNC(gdb_frames, struct sr_gdb_thread) +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)
struct thread_methods gdb_thread_methods = { .frames = (frames_fn_t) gdb_frames, + .set_frames = (set_frames_fn_t) gdb_set_frames, .cmp = (thread_cmp_fn_t) sr_gdb_thread_cmp, .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, };
/* Public functions */ diff --git a/lib/generic_frame.c b/lib/generic_frame.c index 83d399e..fd83bd4 100644 --- a/lib/generic_frame.c +++ b/lib/generic_frame.c @@ -18,6 +18,8 @@ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */
+#include <stdlib.h> + #include "report_type.h" #include "internal_utils.h" #include "generic_frame.h" @@ -44,6 +46,13 @@ sr_frame_next(struct sr_frame *frame) return DISPATCH(dtable, frame->type, next)(frame); }
+void +sr_frame_set_next(struct sr_frame *cur, struct sr_frame *next) +{ + assert(next == NULL || cur->type == next->type); + DISPATCH(dtable, cur->type, set_next)(cur, next); +} + int sr_frame_cmp(struct sr_frame *frame1, struct sr_frame *frame2) { diff --git a/lib/generic_frame.h b/lib/generic_frame.h index 138123c..e6fdaca 100644 --- a/lib/generic_frame.h +++ b/lib/generic_frame.h @@ -22,12 +22,14 @@
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 *);
struct frame_methods { append_to_str_fn_t append_to_str; next_frame_fn_t next; + set_next_frame_fn_t set_next; frame_cmp_fn_t cmp; frame_cmp_fn_t cmp_distance; }; diff --git a/lib/generic_stacktrace.c b/lib/generic_stacktrace.c index 9352001..d7f7ca4 100644 --- a/lib/generic_stacktrace.c +++ b/lib/generic_stacktrace.c @@ -18,6 +18,8 @@ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */
+#include <stdlib.h> + #include "internal_utils.h" #include "strbuf.h" #include "location.h" @@ -117,6 +119,19 @@ sr_stacktrace_find_crash_thread(struct sr_stacktrace *stacktrace) return DISPATCH(dtable, stacktrace->type, find_crash_thread)(stacktrace); }
+struct sr_thread * +sr_stacktrace_threads(struct sr_stacktrace *stacktrace) +{ + return DISPATCH(dtable, stacktrace->type, threads)(stacktrace); +} + +void +sr_stacktrace_set_threads(struct sr_stacktrace *stacktrace, struct sr_thread *threads) +{ + assert(threads == NULL || stacktrace->type == threads->type); + DISPATCH(dtable, stacktrace->type, set_threads)(stacktrace, threads); +} + void sr_stacktrace_free(struct sr_stacktrace *stacktrace) { diff --git a/lib/generic_stacktrace.h b/lib/generic_stacktrace.h index 7aa675d..2c1f56d 100644 --- a/lib/generic_stacktrace.h +++ b/lib/generic_stacktrace.h @@ -27,6 +27,8 @@ 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 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 *);
struct stacktrace_methods @@ -37,12 +39,21 @@ struct stacktrace_methods to_json_fn_t to_json; get_reason_fn_t get_reason; find_crash_thread_fn_t find_crash_thread; + threads_fn_t threads; + set_threads_fn_t set_threads; free_fn_t free; };
extern struct stacktrace_methods core_stacktrace_methods, python_stacktrace_methods, koops_stacktrace_methods, gdb_stacktrace_methods, java_stacktrace_methods;
+/* Macros to generate accessors for the "threads" member. */ +#define DEFINE_THREADS_FUNC(name, concrete_t) \ + DEFINE_GETTER(name, threads, struct sr_stacktrace, concrete_t, struct sr_thread) + +#define DEFINE_SET_THREADS_FUNC(name, concrete_t) \ + DEFINE_SETTER(name, threads, struct sr_stacktrace, concrete_t, struct sr_thread) + /* XXX generic functions */ 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 index 17fa778..24e590a 100644 --- a/lib/generic_thread.c +++ b/lib/generic_thread.c @@ -24,6 +24,7 @@ #include "generic_thread.h"
#include <stdio.h> +#include <stdlib.h>
//XXX /* Note that python and koops do not have multiple threads, thus the functions @@ -68,6 +69,13 @@ sr_thread_frames(struct sr_thread *thread) return DISPATCH(dtable, thread->type, frames)(thread); }
+void +sr_thread_set_frames(struct sr_thread *thread, struct sr_frame *frame) +{ + assert(frame == NULL || thread->type == frame->type); + DISPATCH(dtable, thread->type, set_frames)(thread, frame); +} + int sr_thread_frame_count(struct sr_thread *thread) { @@ -88,3 +96,10 @@ sr_thread_next(struct sr_thread *thread) { return DISPATCH(dtable, thread->type, next)(thread); } + +void +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); +} diff --git a/lib/generic_thread.h b/lib/generic_thread.h index c53f6fe..334994d 100644 --- a/lib/generic_thread.h +++ b/lib/generic_thread.h @@ -19,30 +19,34 @@ */
#include "thread.h" +#include "internal_utils.h"
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*);
struct thread_methods { frames_fn_t frames; + set_frames_fn_t set_frames; thread_cmp_fn_t cmp; frame_count_fn_t frame_count; next_thread_fn_t next; + set_next_thread_fn_t set_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; \ - } \ +/* Macros to generate accessors for the "frames" member. */ +#define DEFINE_FRAMES_FUNC(name, concrete_t) \ + DEFINE_GETTER(name, frames, struct sr_thread, concrete_t, struct sr_frame) + +#define DEFINE_SET_FRAMES_FUNC(name, concrete_t) \ + DEFINE_SETTER(name, frames, struct sr_thread, concrete_t, struct sr_frame)
int thread_frame_count(struct sr_thread *thread); diff --git a/lib/internal_utils.h b/lib/internal_utils.h index 459b5b8..a237064 100644 --- a/lib/internal_utils.h +++ b/lib/internal_utils.h @@ -24,10 +24,19 @@ (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; \ +#define DEFINE_GETTER(name, member, struct_abstract_t, struct_concrete_t, member_abstract_t) \ + static member_abstract_t * \ + name(struct_abstract_t *node) \ + { \ + return (member_abstract_t *)((struct_concrete_t *)node)->member; \ }
+#define DEFINE_SETTER(name, member, struct_abstract_t, struct_concrete_t, member_abstract_t) \ + static void \ + name(struct_abstract_t *node, member_abstract_t *val) \ + { \ + ((struct_concrete_t *)node)->member = (void*) val; \ + } + +#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) diff --git a/lib/java_frame.c b/lib/java_frame.c index dfe9f86..9477bc9 100644 --- a/lib/java_frame.c +++ b/lib/java_frame.c @@ -34,11 +34,13 @@ /* Method table */
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)
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, + .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, }; diff --git a/lib/java_stacktrace.c b/lib/java_stacktrace.c index b9f8ecb..0a7b583 100644 --- a/lib/java_stacktrace.c +++ b/lib/java_stacktrace.c @@ -31,6 +31,9 @@
/* Method table */
+DEFINE_THREADS_FUNC(java_threads, struct sr_java_stacktrace) +DEFINE_SET_THREADS_FUNC(java_set_threads, struct sr_java_stacktrace) + struct stacktrace_methods java_stacktrace_methods = { .parse = (parse_fn_t) stacktrace_parse_wrapper, @@ -40,6 +43,8 @@ struct stacktrace_methods java_stacktrace_methods = .get_reason = (get_reason_fn_t) sr_java_stacktrace_get_reason, .find_crash_thread = (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, };
diff --git a/lib/java_thread.c b/lib/java_thread.c index f149f76..70b01b3 100644 --- a/lib/java_thread.c +++ b/lib/java_thread.c @@ -32,15 +32,19 @@
/* Method table */
-DEFINE_THREAD_FUNC(java_frames, struct sr_java_thread) +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)
struct thread_methods java_thread_methods = { .frames = (frames_fn_t) java_frames, + .set_frames = (set_frames_fn_t) java_set_frames, .cmp = (thread_cmp_fn_t) sr_java_thread_cmp, .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, };
/* Public functions */ diff --git a/lib/koops_frame.c b/lib/koops_frame.c index 286bc94..2dfdad9 100644 --- a/lib/koops_frame.c +++ b/lib/koops_frame.c @@ -31,11 +31,13 @@ /* Method table */
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)
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, + .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, }; diff --git a/lib/koops_stacktrace.c b/lib/koops_stacktrace.c index f6c4ccb..121c330 100644 --- a/lib/koops_stacktrace.c +++ b/lib/koops_stacktrace.c @@ -56,14 +56,17 @@ struct sr_taint_flag sr_flags[] = {
/* Method tables */
-DEFINE_THREAD_FUNC(koops_frames, struct sr_koops_stacktrace) +DEFINE_FRAMES_FUNC(koops_frames, struct sr_koops_stacktrace) +DEFINE_SET_FRAMES_FUNC(koops_set_frames, struct sr_koops_stacktrace)
struct thread_methods koops_thread_methods = { .frames = (frames_fn_t) koops_frames, + .set_frames = (set_frames_fn_t) koops_set_frames, .cmp = (thread_cmp_fn_t) NULL, .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, };
struct stacktrace_methods koops_stacktrace_methods = @@ -74,6 +77,8 @@ struct stacktrace_methods koops_stacktrace_methods = .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, + .threads = (threads_fn_t) stacktrace_one_thread_only, + .set_threads = (set_threads_fn_t) NULL, .free = (free_fn_t) sr_koops_stacktrace_free, };
diff --git a/lib/python_frame.c b/lib/python_frame.c index e3ae238..077c391 100644 --- a/lib/python_frame.c +++ b/lib/python_frame.c @@ -30,11 +30,13 @@ /* Method table */
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)
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, + .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, }; diff --git a/lib/python_stacktrace.c b/lib/python_stacktrace.c index fbb0807..89a090c 100644 --- a/lib/python_stacktrace.c +++ b/lib/python_stacktrace.c @@ -34,14 +34,17 @@
/* Method tables */
-DEFINE_THREAD_FUNC(python_frames, struct sr_python_stacktrace) +DEFINE_FRAMES_FUNC(python_frames, struct sr_python_stacktrace) +DEFINE_SET_FRAMES_FUNC(python_set_frames, struct sr_python_stacktrace)
struct thread_methods python_thread_methods = { .frames = (frames_fn_t) python_frames, + .set_frames = (set_frames_fn_t) python_set_frames, .cmp = (thread_cmp_fn_t) NULL, .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, };
struct stacktrace_methods python_stacktrace_methods = @@ -52,6 +55,8 @@ struct stacktrace_methods python_stacktrace_methods = .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, + .threads = (threads_fn_t) stacktrace_one_thread_only, + .set_threads = (set_threads_fn_t) NULL, .free = (free_fn_t) sr_python_stacktrace_free, };