Skip to content

Commit d00bbea

Browse files
mhiramatrostedt
authored andcommitted
tracing: Integrate similar probe argument parsers
Integrate similar argument parsers for kprobes and uprobes events into traceprobe_parse_probe_arg(). Link: http://lkml.kernel.org/r/154140850016.17322.9836787731210512176.stgit@devbox Reviewed-by: Tom Zanussi <tom.zanussi@linux.intel.com> Tested-by: Tom Zanussi <tom.zanussi@linux.intel.com> Signed-off-by: Masami Hiramatsu <mhiramat@kernel.org> Signed-off-by: Steven Rostedt (VMware) <rostedt@goodmis.org>
1 parent faacb36 commit d00bbea

File tree

4 files changed

+50
-96
lines changed

4 files changed

+50
-96
lines changed

kernel/trace/trace_kprobe.c

Lines changed: 2 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -548,7 +548,6 @@ static int create_trace_kprobe(int argc, char **argv)
548548
bool is_return = false, is_delete = false;
549549
char *symbol = NULL, *event = NULL, *group = NULL;
550550
int maxactive = 0;
551-
char *arg;
552551
long offset = 0;
553552
void *addr = NULL;
554553
char buf[MAX_EVENT_NAME_LEN];
@@ -676,53 +675,10 @@ static int create_trace_kprobe(int argc, char **argv)
676675
}
677676

678677
/* parse arguments */
679-
ret = 0;
680678
for (i = 0; i < argc && i < MAX_TRACE_ARGS; i++) {
681-
struct probe_arg *parg = &tk->tp.args[i];
682-
683-
/* Increment count for freeing args in error case */
684-
tk->tp.nr_args++;
685-
686-
/* Parse argument name */
687-
arg = strchr(argv[i], '=');
688-
if (arg) {
689-
*arg++ = '\0';
690-
parg->name = kstrdup(argv[i], GFP_KERNEL);
691-
} else {
692-
arg = argv[i];
693-
/* If argument name is omitted, set "argN" */
694-
snprintf(buf, MAX_EVENT_NAME_LEN, "arg%d", i + 1);
695-
parg->name = kstrdup(buf, GFP_KERNEL);
696-
}
697-
698-
if (!parg->name) {
699-
pr_info("Failed to allocate argument[%d] name.\n", i);
700-
ret = -ENOMEM;
701-
goto error;
702-
}
703-
704-
if (!is_good_name(parg->name)) {
705-
pr_info("Invalid argument[%d] name: %s\n",
706-
i, parg->name);
707-
ret = -EINVAL;
708-
goto error;
709-
}
710-
711-
if (traceprobe_conflict_field_name(parg->name,
712-
tk->tp.args, i)) {
713-
pr_info("Argument[%d] name '%s' conflicts with "
714-
"another field.\n", i, argv[i]);
715-
ret = -EINVAL;
716-
goto error;
717-
}
718-
719-
/* Parse fetch argument */
720-
ret = traceprobe_parse_probe_arg(arg, &tk->tp.size, parg,
721-
flags);
722-
if (ret) {
723-
pr_info("Parse error at argument[%d]. (%d)\n", i, ret);
679+
ret = traceprobe_parse_probe_arg(&tk->tp, i, argv[i], flags);
680+
if (ret)
724681
goto error;
725-
}
726682
}
727683

728684
ret = register_trace_kprobe(tk);

kernel/trace/trace_probe.c

Lines changed: 44 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -348,7 +348,7 @@ static int __parse_bitfield_probe_arg(const char *bf,
348348
}
349349

350350
/* String length checking wrapper */
351-
int traceprobe_parse_probe_arg(char *arg, ssize_t *size,
351+
static int traceprobe_parse_probe_arg_body(char *arg, ssize_t *size,
352352
struct probe_arg *parg, unsigned int flags)
353353
{
354354
struct fetch_insn *code, *scode, *tmp = NULL;
@@ -491,8 +491,8 @@ int traceprobe_parse_probe_arg(char *arg, ssize_t *size,
491491
}
492492

493493
/* Return 1 if name is reserved or already used by another argument */
494-
int traceprobe_conflict_field_name(const char *name,
495-
struct probe_arg *args, int narg)
494+
static int traceprobe_conflict_field_name(const char *name,
495+
struct probe_arg *args, int narg)
496496
{
497497
int i;
498498

@@ -507,6 +507,47 @@ int traceprobe_conflict_field_name(const char *name,
507507
return 0;
508508
}
509509

510+
int traceprobe_parse_probe_arg(struct trace_probe *tp, int i, char *arg,
511+
unsigned int flags)
512+
{
513+
struct probe_arg *parg = &tp->args[i];
514+
char *body;
515+
int ret;
516+
517+
/* Increment count for freeing args in error case */
518+
tp->nr_args++;
519+
520+
body = strchr(arg, '=');
521+
if (body) {
522+
parg->name = kmemdup_nul(arg, body - arg, GFP_KERNEL);
523+
body++;
524+
} else {
525+
/* If argument name is omitted, set "argN" */
526+
parg->name = kasprintf(GFP_KERNEL, "arg%d", i + 1);
527+
body = arg;
528+
}
529+
if (!parg->name)
530+
return -ENOMEM;
531+
532+
if (!is_good_name(parg->name)) {
533+
pr_info("Invalid argument[%d] name: %s\n",
534+
i, parg->name);
535+
return -EINVAL;
536+
}
537+
538+
if (traceprobe_conflict_field_name(parg->name, tp->args, i)) {
539+
pr_info("Argument[%d]: '%s' conflicts with another field.\n",
540+
i, parg->name);
541+
return -EINVAL;
542+
}
543+
544+
/* Parse fetch argument */
545+
ret = traceprobe_parse_probe_arg_body(body, &tp->size, parg, flags);
546+
if (ret)
547+
pr_info("Parse error at argument[%d]. (%d)\n", i, ret);
548+
return ret;
549+
}
550+
510551
void traceprobe_free_probe_arg(struct probe_arg *arg)
511552
{
512553
struct fetch_insn *code = arg->code;

kernel/trace/trace_probe.h

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -272,11 +272,8 @@ find_event_file_link(struct trace_probe *tp, struct trace_event_file *file)
272272
#define TPARG_FL_FENTRY BIT(2)
273273
#define TPARG_FL_MASK GENMASK(2, 0)
274274

275-
extern int traceprobe_parse_probe_arg(char *arg, ssize_t *size,
276-
struct probe_arg *parg, unsigned int flags);
277-
278-
extern int traceprobe_conflict_field_name(const char *name,
279-
struct probe_arg *args, int narg);
275+
extern int traceprobe_parse_probe_arg(struct trace_probe *tp, int i,
276+
char *arg, unsigned int flags);
280277

281278
extern int traceprobe_update_arg(struct probe_arg *arg);
282279
extern void traceprobe_free_probe_arg(struct probe_arg *arg);

kernel/trace/trace_uprobe.c

Lines changed: 2 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -517,51 +517,11 @@ static int create_trace_uprobe(int argc, char **argv)
517517
}
518518

519519
/* parse arguments */
520-
ret = 0;
521520
for (i = 0; i < argc && i < MAX_TRACE_ARGS; i++) {
522-
struct probe_arg *parg = &tu->tp.args[i];
523-
524-
/* Increment count for freeing args in error case */
525-
tu->tp.nr_args++;
526-
527-
/* Parse argument name */
528-
arg = strchr(argv[i], '=');
529-
if (arg) {
530-
*arg++ = '\0';
531-
parg->name = kstrdup(argv[i], GFP_KERNEL);
532-
} else {
533-
arg = argv[i];
534-
/* If argument name is omitted, set "argN" */
535-
snprintf(buf, MAX_EVENT_NAME_LEN, "arg%d", i + 1);
536-
parg->name = kstrdup(buf, GFP_KERNEL);
537-
}
538-
539-
if (!parg->name) {
540-
pr_info("Failed to allocate argument[%d] name.\n", i);
541-
ret = -ENOMEM;
542-
goto error;
543-
}
544-
545-
if (!is_good_name(parg->name)) {
546-
pr_info("Invalid argument[%d] name: %s\n", i, parg->name);
547-
ret = -EINVAL;
548-
goto error;
549-
}
550-
551-
if (traceprobe_conflict_field_name(parg->name, tu->tp.args, i)) {
552-
pr_info("Argument[%d] name '%s' conflicts with "
553-
"another field.\n", i, argv[i]);
554-
ret = -EINVAL;
555-
goto error;
556-
}
557-
558-
/* Parse fetch argument */
559-
ret = traceprobe_parse_probe_arg(arg, &tu->tp.size, parg,
521+
ret = traceprobe_parse_probe_arg(&tu->tp, i, argv[i],
560522
is_return ? TPARG_FL_RETURN : 0);
561-
if (ret) {
562-
pr_info("Parse error at argument[%d]. (%d)\n", i, ret);
523+
if (ret)
563524
goto error;
564-
}
565525
}
566526

567527
ret = register_trace_uprobe(tu);

0 commit comments

Comments
 (0)