diff options
Diffstat (limited to 'kernel/trace/trace_fprobe.c')
-rw-r--r-- | kernel/trace/trace_fprobe.c | 21 |
1 files changed, 18 insertions, 3 deletions
diff --git a/kernel/trace/trace_fprobe.c b/kernel/trace/trace_fprobe.c index 2dd884609321..dfe2e546acdc 100644 --- a/kernel/trace/trace_fprobe.c +++ b/kernel/trace/trace_fprobe.c @@ -925,14 +925,16 @@ static int __trace_fprobe_create(int argc, const char *argv[]) * FETCHARG:TYPE : use TYPE instead of unsigned long. */ struct trace_fprobe *tf = NULL; - int i, len, ret = 0; + int i, len, new_argc = 0, ret = 0; bool is_return = false; char *symbol = NULL, *tmp = NULL; const char *event = NULL, *group = FPROBE_EVENT_SYSTEM; + const char **new_argv = NULL; int maxactive = 0; char buf[MAX_EVENT_NAME_LEN]; char gbuf[MAX_EVENT_NAME_LEN]; char sbuf[KSYM_NAME_LEN]; + char abuf[MAX_BTF_ARGS_LEN]; bool is_tracepoint = false; struct tracepoint *tpoint = NULL; struct traceprobe_parse_context ctx = { @@ -1040,9 +1042,22 @@ static int __trace_fprobe_create(int argc, const char *argv[]) } else ctx.funcname = symbol; + argc -= 2; argv += 2; + new_argv = traceprobe_expand_meta_args(argc, argv, &new_argc, + abuf, MAX_BTF_ARGS_LEN, &ctx); + if (IS_ERR(new_argv)) { + ret = PTR_ERR(new_argv); + new_argv = NULL; + goto out; + } + if (new_argv) { + argc = new_argc; + argv = new_argv; + } + /* setup a probe */ tf = alloc_trace_fprobe(group, event, symbol, tpoint, maxactive, - argc - 2, is_return); + argc, is_return); if (IS_ERR(tf)) { ret = PTR_ERR(tf); /* This must return -ENOMEM, else there is a bug */ @@ -1054,7 +1069,6 @@ static int __trace_fprobe_create(int argc, const char *argv[]) tf->mod = __module_text_address( (unsigned long)tf->tpoint->probestub); - argc -= 2; argv += 2; /* parse arguments */ for (i = 0; i < argc && i < MAX_TRACE_ARGS; i++) { trace_probe_log_set_index(i + 2); @@ -1083,6 +1097,7 @@ static int __trace_fprobe_create(int argc, const char *argv[]) out: trace_probe_log_clear(); + kfree(new_argv); kfree(symbol); return ret; |