perf probe: Add perf_probe_event__copy()

Add perf_probe_event__copy() to copy perf_probe_event data structure and
sub data structures under given source perf_probe_event.

Signed-off-by: Masami Hiramatsu <mhiramat@kernel.org>
Cc: Ananth N Mavinakayanahalli <ananth@linux.vnet.ibm.com>
Cc: Brendan Gregg <brendan.d.gregg@gmail.com>
Cc: Hemant Kumar <hemant@linux.vnet.ibm.com>
Cc: Namhyung Kim <namhyung@kernel.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Link: http://lkml.kernel.org/r/20160608092940.3116.18034.stgit@devbox
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
This commit is contained in:
Masami Hiramatsu 2016-06-08 18:29:40 +09:00 committed by Arnaldo Carvalho de Melo
parent 4698b8b757
commit 0542bb9c8d
2 changed files with 76 additions and 3 deletions

View File

@ -2030,6 +2030,79 @@ void clear_perf_probe_event(struct perf_probe_event *pev)
memset(pev, 0, sizeof(*pev)); memset(pev, 0, sizeof(*pev));
} }
#define strdup_or_goto(str, label) \
({ char *__p = NULL; if (str && !(__p = strdup(str))) goto label; __p; })
static int perf_probe_point__copy(struct perf_probe_point *dst,
struct perf_probe_point *src)
{
dst->file = strdup_or_goto(src->file, out_err);
dst->function = strdup_or_goto(src->function, out_err);
dst->lazy_line = strdup_or_goto(src->lazy_line, out_err);
dst->line = src->line;
dst->retprobe = src->retprobe;
dst->offset = src->offset;
return 0;
out_err:
clear_perf_probe_point(dst);
return -ENOMEM;
}
static int perf_probe_arg__copy(struct perf_probe_arg *dst,
struct perf_probe_arg *src)
{
struct perf_probe_arg_field *field, **ppfield;
dst->name = strdup_or_goto(src->name, out_err);
dst->var = strdup_or_goto(src->var, out_err);
dst->type = strdup_or_goto(src->type, out_err);
field = src->field;
ppfield = &(dst->field);
while (field) {
*ppfield = zalloc(sizeof(*field));
if (!*ppfield)
goto out_err;
(*ppfield)->name = strdup_or_goto(field->name, out_err);
(*ppfield)->index = field->index;
(*ppfield)->ref = field->ref;
field = field->next;
ppfield = &((*ppfield)->next);
}
return 0;
out_err:
return -ENOMEM;
}
int perf_probe_event__copy(struct perf_probe_event *dst,
struct perf_probe_event *src)
{
int i;
dst->event = strdup_or_goto(src->event, out_err);
dst->group = strdup_or_goto(src->group, out_err);
dst->target = strdup_or_goto(src->target, out_err);
dst->uprobes = src->uprobes;
if (perf_probe_point__copy(&dst->point, &src->point) < 0)
goto out_err;
dst->args = zalloc(sizeof(struct perf_probe_arg) * src->nargs);
if (!dst->args)
goto out_err;
dst->nargs = src->nargs;
for (i = 0; i < src->nargs; i++)
if (perf_probe_arg__copy(&dst->args[i], &src->args[i]) < 0)
goto out_err;
return 0;
out_err:
clear_perf_probe_event(dst);
return -ENOMEM;
}
void clear_probe_trace_event(struct probe_trace_event *tev) void clear_probe_trace_event(struct probe_trace_event *tev)
{ {
struct probe_trace_arg_ref *ref, *next; struct probe_trace_arg_ref *ref, *next;
@ -2505,9 +2578,6 @@ static int find_probe_functions(struct map *map, char *name,
return found; return found;
} }
#define strdup_or_goto(str, label) \
({ char *__p = strdup(str); if (!__p) goto label; __p; })
void __weak arch__fix_tev_from_maps(struct perf_probe_event *pev __maybe_unused, void __weak arch__fix_tev_from_maps(struct perf_probe_event *pev __maybe_unused,
struct probe_trace_event *tev __maybe_unused, struct probe_trace_event *tev __maybe_unused,
struct map *map __maybe_unused, struct map *map __maybe_unused,

View File

@ -122,6 +122,9 @@ char *synthesize_perf_probe_command(struct perf_probe_event *pev);
char *synthesize_probe_trace_command(struct probe_trace_event *tev); char *synthesize_probe_trace_command(struct probe_trace_event *tev);
char *synthesize_perf_probe_arg(struct perf_probe_arg *pa); char *synthesize_perf_probe_arg(struct perf_probe_arg *pa);
int perf_probe_event__copy(struct perf_probe_event *dst,
struct perf_probe_event *src);
/* Check the perf_probe_event needs debuginfo */ /* Check the perf_probe_event needs debuginfo */
bool perf_probe_event_need_dwarf(struct perf_probe_event *pev); bool perf_probe_event_need_dwarf(struct perf_probe_event *pev);