Commit 95c104c3 authored by Linyu Yuan's avatar Linyu Yuan Committed by Steven Rostedt (Google)

tracing: Auto generate event name when creating a group of events

Currently when creating a specific group of trace events,
take kprobe event as example, the user must use the following format:
p:GRP/EVENT [MOD:]KSYM[+OFFS]|KADDR [FETCHARGS],
which means user must enter EVENT name, one example is:

  echo 'p:usb_gadget/config_usb_cfg_link config_usb_cfg_link $arg1' >> kprobe_events

It is not simple if there are too many entries because the event name is
the same as symbol name.

This change allows user to specify no EVENT name, format changed as:

   p:GRP/ [MOD:]KSYM[+OFFS]|KADDR [FETCHARGS]

It will generate event name automatically and one example is:

  echo 'p:usb_gadget/ config_usb_cfg_link $arg1' >> kprobe_events.

Link: https://lore.kernel.org/all/1656296348-16111-4-git-send-email-quic_linyyuan@quicinc.com/Acked-by: default avatarMasami Hiramatsu (Google) <mhiramat@kernel.org>
Reviewed-by: default avatarTom Zanussi <zanussi@kernel.org>
Signed-off-by: default avatarLinyu Yuan <quic_linyyuan@quicinc.com>
Signed-off-by: default avatarSteven Rostedt (Google) <rostedt@goodmis.org>
parent f360ea56
...@@ -28,10 +28,10 @@ Synopsis of kprobe_events ...@@ -28,10 +28,10 @@ Synopsis of kprobe_events
------------------------- -------------------------
:: ::
p[:[GRP/]EVENT] [MOD:]SYM[+offs]|MEMADDR [FETCHARGS] : Set a probe p[:[GRP/][EVENT]] [MOD:]SYM[+offs]|MEMADDR [FETCHARGS] : Set a probe
r[MAXACTIVE][:[GRP/]EVENT] [MOD:]SYM[+0] [FETCHARGS] : Set a return probe r[MAXACTIVE][:[GRP/][EVENT]] [MOD:]SYM[+0] [FETCHARGS] : Set a return probe
p:[GRP/]EVENT] [MOD:]SYM[+0]%return [FETCHARGS] : Set a return probe p[:[GRP/][EVENT]] [MOD:]SYM[+0]%return [FETCHARGS] : Set a return probe
-:[GRP/]EVENT : Clear a probe -:[GRP/][EVENT] : Clear a probe
GRP : Group name. If omitted, use "kprobes" for it. GRP : Group name. If omitted, use "kprobes" for it.
EVENT : Event name. If omitted, the event name is generated EVENT : Event name. If omitted, the event name is generated
......
...@@ -26,10 +26,10 @@ Synopsis of uprobe_tracer ...@@ -26,10 +26,10 @@ Synopsis of uprobe_tracer
------------------------- -------------------------
:: ::
p[:[GRP/]EVENT] PATH:OFFSET [FETCHARGS] : Set a uprobe p[:[GRP/][EVENT]] PATH:OFFSET [FETCHARGS] : Set a uprobe
r[:[GRP/]EVENT] PATH:OFFSET [FETCHARGS] : Set a return uprobe (uretprobe) r[:[GRP/][EVENT]] PATH:OFFSET [FETCHARGS] : Set a return uprobe (uretprobe)
p[:[GRP/]EVENT] PATH:OFFSET%return [FETCHARGS] : Set a return uprobe (uretprobe) p[:[GRP/][EVENT]] PATH:OFFSET%return [FETCHARGS] : Set a return uprobe (uretprobe)
-:[GRP/]EVENT : Clear uprobe or uretprobe event -:[GRP/][EVENT] : Clear uprobe or uretprobe event
GRP : Group name. If omitted, "uprobes" is the default value. GRP : Group name. If omitted, "uprobes" is the default value.
EVENT : Event name. If omitted, the event name is generated based EVENT : Event name. If omitted, the event name is generated based
......
...@@ -5569,13 +5569,13 @@ static const char readme_msg[] = ...@@ -5569,13 +5569,13 @@ static const char readme_msg[] =
#endif #endif
#if defined(CONFIG_KPROBE_EVENTS) || defined(CONFIG_UPROBE_EVENTS) #if defined(CONFIG_KPROBE_EVENTS) || defined(CONFIG_UPROBE_EVENTS)
"\t accepts: event-definitions (one definition per line)\n" "\t accepts: event-definitions (one definition per line)\n"
"\t Format: p[:[<group>/]<event>] <place> [<args>]\n" "\t Format: p[:[<group>/][<event>]] <place> [<args>]\n"
"\t r[maxactive][:[<group>/]<event>] <place> [<args>]\n" "\t r[maxactive][:[<group>/][<event>]] <place> [<args>]\n"
#ifdef CONFIG_HIST_TRIGGERS #ifdef CONFIG_HIST_TRIGGERS
"\t s:[synthetic/]<event> <field> [<field>]\n" "\t s:[synthetic/]<event> <field> [<field>]\n"
#endif #endif
"\t e[:[<group>/]<event>] <attached-group>.<attached-event> [<args>]\n" "\t e[:[<group>/][<event>]] <attached-group>.<attached-event> [<args>]\n"
"\t -:[<group>/]<event>\n" "\t -:[<group>/][<event>]\n"
#ifdef CONFIG_KPROBE_EVENTS #ifdef CONFIG_KPROBE_EVENTS
"\t place: [<module>:]<symbol>[+<offset>]|<memaddr>\n" "\t place: [<module>:]<symbol>[+<offset>]|<memaddr>\n"
"place (kretprobe): [<module>:]<symbol>[+<offset>]%return|<memaddr>\n" "place (kretprobe): [<module>:]<symbol>[+<offset>]%return|<memaddr>\n"
......
...@@ -101,7 +101,7 @@ int dyn_event_release(const char *raw_command, struct dyn_event_operations *type ...@@ -101,7 +101,7 @@ int dyn_event_release(const char *raw_command, struct dyn_event_operations *type
event = p + 1; event = p + 1;
*p = '\0'; *p = '\0';
} }
if (event[0] == '\0') { if (!system && event[0] == '\0') {
ret = -EINVAL; ret = -EINVAL;
goto out; goto out;
} }
......
...@@ -125,6 +125,7 @@ static bool eprobe_dyn_event_match(const char *system, const char *event, ...@@ -125,6 +125,7 @@ static bool eprobe_dyn_event_match(const char *system, const char *event,
* We match the following: * We match the following:
* event only - match all eprobes with event name * event only - match all eprobes with event name
* system and event only - match all system/event probes * system and event only - match all system/event probes
* system only - match all system probes
* *
* The below has the above satisfied with more arguments: * The below has the above satisfied with more arguments:
* *
...@@ -143,7 +144,7 @@ static bool eprobe_dyn_event_match(const char *system, const char *event, ...@@ -143,7 +144,7 @@ static bool eprobe_dyn_event_match(const char *system, const char *event,
return false; return false;
/* Must match the event name */ /* Must match the event name */
if (strcmp(trace_probe_name(&ep->tp), event) != 0) if (event[0] != '\0' && strcmp(trace_probe_name(&ep->tp), event) != 0)
return false; return false;
/* No arguments match all */ /* No arguments match all */
...@@ -848,7 +849,7 @@ static int __trace_eprobe_create(int argc, const char *argv[]) ...@@ -848,7 +849,7 @@ static int __trace_eprobe_create(int argc, const char *argv[])
{ {
/* /*
* Argument syntax: * Argument syntax:
* e[:[GRP/]ENAME] SYSTEM.EVENT [FETCHARGS] * e[:[GRP/][ENAME]] SYSTEM.EVENT [FETCHARGS]
* Fetch args: * Fetch args:
* <name>=$<field>[:TYPE] * <name>=$<field>[:TYPE]
*/ */
...@@ -858,6 +859,7 @@ static int __trace_eprobe_create(int argc, const char *argv[]) ...@@ -858,6 +859,7 @@ static int __trace_eprobe_create(int argc, const char *argv[])
struct trace_eprobe *ep = NULL; struct trace_eprobe *ep = NULL;
char buf1[MAX_EVENT_NAME_LEN]; char buf1[MAX_EVENT_NAME_LEN];
char buf2[MAX_EVENT_NAME_LEN]; char buf2[MAX_EVENT_NAME_LEN];
char gbuf[MAX_EVENT_NAME_LEN];
int ret = 0; int ret = 0;
int i; int i;
...@@ -869,25 +871,24 @@ static int __trace_eprobe_create(int argc, const char *argv[]) ...@@ -869,25 +871,24 @@ static int __trace_eprobe_create(int argc, const char *argv[])
event = strchr(&argv[0][1], ':'); event = strchr(&argv[0][1], ':');
if (event) { if (event) {
event++; event++;
ret = traceprobe_parse_event_name(&event, &group, buf1, ret = traceprobe_parse_event_name(&event, &group, gbuf,
event - argv[0]); event - argv[0]);
if (ret) if (ret)
goto parse_error; goto parse_error;
} else {
strscpy(buf1, argv[1], MAX_EVENT_NAME_LEN);
sanitize_event_name(buf1);
event = buf1;
} }
if (!is_good_name(event) || !is_good_name(group))
goto parse_error;
trace_probe_log_set_index(1); trace_probe_log_set_index(1);
sys_event = argv[1]; sys_event = argv[1];
ret = traceprobe_parse_event_name(&sys_event, &sys_name, buf2, ret = traceprobe_parse_event_name(&sys_event, &sys_name, buf2, 0);
sys_event - argv[1]); if (!sys_event || !sys_name)
if (ret || !sys_name)
goto parse_error; goto parse_error;
if (!event) {
strscpy(buf1, argv[1], MAX_EVENT_NAME_LEN);
sanitize_event_name(buf1);
event = buf1;
}
mutex_lock(&event_mutex); mutex_lock(&event_mutex);
event_call = find_and_get_event(sys_name, sys_event); event_call = find_and_get_event(sys_name, sys_event);
ep = alloc_event_probe(group, event, event_call, argc - 2); ep = alloc_event_probe(group, event, event_call, argc - 2);
......
...@@ -163,7 +163,8 @@ static bool trace_kprobe_match(const char *system, const char *event, ...@@ -163,7 +163,8 @@ static bool trace_kprobe_match(const char *system, const char *event,
{ {
struct trace_kprobe *tk = to_trace_kprobe(ev); struct trace_kprobe *tk = to_trace_kprobe(ev);
return strcmp(trace_probe_name(&tk->tp), event) == 0 && return (event[0] == '\0' ||
strcmp(trace_probe_name(&tk->tp), event) == 0) &&
(!system || strcmp(trace_probe_group_name(&tk->tp), system) == 0) && (!system || strcmp(trace_probe_group_name(&tk->tp), system) == 0) &&
trace_kprobe_match_command_head(tk, argc, argv); trace_kprobe_match_command_head(tk, argc, argv);
} }
...@@ -708,11 +709,11 @@ static int __trace_kprobe_create(int argc, const char *argv[]) ...@@ -708,11 +709,11 @@ static int __trace_kprobe_create(int argc, const char *argv[])
/* /*
* Argument syntax: * Argument syntax:
* - Add kprobe: * - Add kprobe:
* p[:[GRP/]EVENT] [MOD:]KSYM[+OFFS]|KADDR [FETCHARGS] * p[:[GRP/][EVENT]] [MOD:]KSYM[+OFFS]|KADDR [FETCHARGS]
* - Add kretprobe: * - Add kretprobe:
* r[MAXACTIVE][:[GRP/]EVENT] [MOD:]KSYM[+0] [FETCHARGS] * r[MAXACTIVE][:[GRP/][EVENT]] [MOD:]KSYM[+0] [FETCHARGS]
* Or * Or
* p:[GRP/]EVENT] [MOD:]KSYM[+0]%return [FETCHARGS] * p[:[GRP/][EVENT]] [MOD:]KSYM[+0]%return [FETCHARGS]
* *
* Fetch args: * Fetch args:
* $retval : fetch return value * $retval : fetch return value
...@@ -739,6 +740,7 @@ static int __trace_kprobe_create(int argc, const char *argv[]) ...@@ -739,6 +740,7 @@ static int __trace_kprobe_create(int argc, const char *argv[])
long offset = 0; long offset = 0;
void *addr = NULL; void *addr = NULL;
char buf[MAX_EVENT_NAME_LEN]; char buf[MAX_EVENT_NAME_LEN];
char gbuf[MAX_EVENT_NAME_LEN];
unsigned int flags = TPARG_FL_KERNEL; unsigned int flags = TPARG_FL_KERNEL;
switch (argv[0][0]) { switch (argv[0][0]) {
...@@ -833,11 +835,13 @@ static int __trace_kprobe_create(int argc, const char *argv[]) ...@@ -833,11 +835,13 @@ static int __trace_kprobe_create(int argc, const char *argv[])
trace_probe_log_set_index(0); trace_probe_log_set_index(0);
if (event) { if (event) {
ret = traceprobe_parse_event_name(&event, &group, buf, ret = traceprobe_parse_event_name(&event, &group, gbuf,
event - argv[0]); event - argv[0]);
if (ret) if (ret)
goto parse_error; goto parse_error;
} else { }
if (!event) {
/* Make a new event name */ /* Make a new event name */
if (symbol) if (symbol)
snprintf(buf, MAX_EVENT_NAME_LEN, "%c_%s_%ld", snprintf(buf, MAX_EVENT_NAME_LEN, "%c_%s_%ld",
......
...@@ -257,6 +257,10 @@ int traceprobe_parse_event_name(const char **pevent, const char **pgroup, ...@@ -257,6 +257,10 @@ int traceprobe_parse_event_name(const char **pevent, const char **pgroup,
} }
len = strlen(event); len = strlen(event);
if (len == 0) { if (len == 0) {
if (slash) {
*pevent = NULL;
return 0;
}
trace_probe_log_err(offset, NO_EVENT_NAME); trace_probe_log_err(offset, NO_EVENT_NAME);
return -EINVAL; return -EINVAL;
} else if (len > MAX_EVENT_NAME_LEN) { } else if (len > MAX_EVENT_NAME_LEN) {
......
...@@ -312,7 +312,8 @@ static bool trace_uprobe_match(const char *system, const char *event, ...@@ -312,7 +312,8 @@ static bool trace_uprobe_match(const char *system, const char *event,
{ {
struct trace_uprobe *tu = to_trace_uprobe(ev); struct trace_uprobe *tu = to_trace_uprobe(ev);
return strcmp(trace_probe_name(&tu->tp), event) == 0 && return (event[0] == '\0' ||
strcmp(trace_probe_name(&tu->tp), event) == 0) &&
(!system || strcmp(trace_probe_group_name(&tu->tp), system) == 0) && (!system || strcmp(trace_probe_group_name(&tu->tp), system) == 0) &&
trace_uprobe_match_command_head(tu, argc, argv); trace_uprobe_match_command_head(tu, argc, argv);
} }
...@@ -532,7 +533,7 @@ static int register_trace_uprobe(struct trace_uprobe *tu) ...@@ -532,7 +533,7 @@ static int register_trace_uprobe(struct trace_uprobe *tu)
/* /*
* Argument syntax: * Argument syntax:
* - Add uprobe: p|r[:[GRP/]EVENT] PATH:OFFSET[%return][(REF)] [FETCHARGS] * - Add uprobe: p|r[:[GRP/][EVENT]] PATH:OFFSET[%return][(REF)] [FETCHARGS]
*/ */
static int __trace_uprobe_create(int argc, const char **argv) static int __trace_uprobe_create(int argc, const char **argv)
{ {
...@@ -540,6 +541,7 @@ static int __trace_uprobe_create(int argc, const char **argv) ...@@ -540,6 +541,7 @@ static int __trace_uprobe_create(int argc, const char **argv)
const char *event = NULL, *group = UPROBE_EVENT_SYSTEM; const char *event = NULL, *group = UPROBE_EVENT_SYSTEM;
char *arg, *filename, *rctr, *rctr_end, *tmp; char *arg, *filename, *rctr, *rctr_end, *tmp;
char buf[MAX_EVENT_NAME_LEN]; char buf[MAX_EVENT_NAME_LEN];
char gbuf[MAX_EVENT_NAME_LEN];
enum probe_print_type ptype; enum probe_print_type ptype;
struct path path; struct path path;
unsigned long offset, ref_ctr_offset; unsigned long offset, ref_ctr_offset;
...@@ -644,11 +646,13 @@ static int __trace_uprobe_create(int argc, const char **argv) ...@@ -644,11 +646,13 @@ static int __trace_uprobe_create(int argc, const char **argv)
/* setup a probe */ /* setup a probe */
trace_probe_log_set_index(0); trace_probe_log_set_index(0);
if (event) { if (event) {
ret = traceprobe_parse_event_name(&event, &group, buf, ret = traceprobe_parse_event_name(&event, &group, gbuf,
event - argv[0]); event - argv[0]);
if (ret) if (ret)
goto fail_address_parse; goto fail_address_parse;
} else { }
if (!event) {
char *tail; char *tail;
char *ptr; char *ptr;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment