]> granicus.if.org Git - strace/commitdiff
unwind-libdw: introduce indirect data structure for storing unwinding context
authorMasatake YAMATO <yamato@redhat.com>
Sun, 29 Apr 2018 21:45:39 +0000 (06:45 +0900)
committerDmitry V. Levin <ldv@altlinux.org>
Thu, 3 May 2018 22:01:30 +0000 (22:01 +0000)
unwind-libdw uses Dwfl as the data structure for storing unwinding
context.  It is raw data that come from libdw.

This commit introduces "struct ctx" file local data type for allowing
unwind-libdw to attach strace side data to the unwinding context.

* unwind-libdw.c (struct ctx): New struct definition.
(tcb_init, tcb_fin, tcb_walk, tcb_flush_cache): Use struct ctx instead
of Dwfl directly.

Signed-off-by: Masatake YAMATO <yamato@redhat.com>
unwind-libdw.c

index a2d4e294462176460fb7a418a0eea77e03ecee0c..b20ba20445ff637f7cafb2e4b8fe909c45309e88 100644 (file)
 #include "mmap_cache.h"
 #include <elfutils/libdwfl.h>
 
+struct ctx {
+       Dwfl *dwfl;
+};
+
 static void *
 tcb_init(struct tcb *tcp)
 {
@@ -68,14 +72,19 @@ tcb_init(struct tcb *tcp)
                return NULL;
        }
 
-       return dwfl;
+       struct ctx *ctx = xmalloc(sizeof(*ctx));
+       ctx->dwfl = dwfl;
+       return ctx;
 }
 
 static void
 tcb_fin(struct tcb *tcp)
 {
-       if (tcp->unwind_ctx)
-               dwfl_end(tcp->unwind_ctx);
+       struct ctx *ctx = tcp->unwind_ctx;
+       if (ctx) {
+               dwfl_end(ctx->dwfl);
+               free(ctx);
+       }
 }
 
 struct frame_user_data {
@@ -131,8 +140,8 @@ tcb_walk(struct tcb *tcp,
         unwind_error_action_fn error_action,
         void *data)
 {
-       Dwfl *dwfl = tcp->unwind_ctx;
-       if (!dwfl)
+       struct ctx *ctx = tcp->unwind_ctx;
+       if (!ctx)
                return;
 
        struct frame_user_data user_data = {
@@ -141,7 +150,7 @@ tcb_walk(struct tcb *tcp,
                .data = data,
                .stack_depth = 256,
        };
-       int r = dwfl_getthread_frames(dwfl, tcp->pid, frame_callback,
+       int r = dwfl_getthread_frames(ctx->dwfl, tcp->pid, frame_callback,
                                      &user_data);
        if (r)
                error_action(data,
@@ -152,11 +161,11 @@ tcb_walk(struct tcb *tcp,
 static void
 tcb_flush_cache(struct tcb *tcp)
 {
-       Dwfl *dwfl = tcp->unwind_ctx;
-       if (!dwfl)
+       struct ctx *ctx = tcp->unwind_ctx;
+       if (!ctx)
                return;
 
-       int r = dwfl_linux_proc_report(dwfl, tcp->pid);
+       int r = dwfl_linux_proc_report(ctx->dwfl, tcp->pid);
 
        if (r < 0)
                error_msg("dwfl_linux_proc_report returned an error"
@@ -164,7 +173,7 @@ tcb_flush_cache(struct tcb *tcp)
        else if (r > 0)
                error_msg("dwfl_linux_proc_report returned an error"
                          " for pid %d", tcp->pid);
-       else if (dwfl_report_end(dwfl, NULL, NULL) != 0)
+       else if (dwfl_report_end(ctx->dwfl, NULL, NULL) != 0)
                error_msg("dwfl_report_end returned an error"
                          " for pid %d: %s", tcp->pid, dwfl_errmsg(-1));
 }