Masami found some issues with the creation of synthetic events.

The first two patches fix handling of unsigned type, and handling
 of a space before an ending semi-colon.
 
 The third patch adds a selftest to test the processing of synthetic events.
 -----BEGIN PGP SIGNATURE-----
 
 iIoEABYIADIWIQRRSw7ePDh/lE+zeZMp5XQQmuv6qgUCW8pMwxQccm9zdGVkdEBn
 b29kbWlzLm9yZwAKCRAp5XQQmuv6qn2jAQCV4leBtN9EAax4B9Mmy4e5oYGE0SDF
 Qq0f/Zb1SLYbTwD/Wdo+mqOAc9EFYkrxRjvgufgqM4bOUufW4fOQnqqPnwI=
 =GS2b
 -----END PGP SIGNATURE-----

Merge tag 'trace-v4.19-rc8-2' of git://git.kernel.org/pub/scm/linux/kernel/git/rostedt/linux-trace

Steven writes:
  "tracing: A few small fixes to synthetic events

   Masami found some issues with the creation of synthetic events.  The
   first two patches fix handling of unsigned type, and handling of a
   space before an ending semi-colon.

   The third patch adds a selftest to test the processing of synthetic
   events."

* tag 'trace-v4.19-rc8-2' of git://git.kernel.org/pub/scm/linux/kernel/git/rostedt/linux-trace:
  selftests: ftrace: Add synthetic event syntax testcase
  tracing: Fix synthetic event to allow semicolon at end
  tracing: Fix synthetic event to accept unsigned modifier
This commit is contained in:
Greg Kroah-Hartman 2018-10-20 09:20:48 +02:00
commit 6b5201c21d
2 changed files with 105 additions and 7 deletions

View File

@ -738,16 +738,30 @@ static void free_synth_field(struct synth_field *field)
kfree(field); kfree(field);
} }
static struct synth_field *parse_synth_field(char *field_type, static struct synth_field *parse_synth_field(int argc, char **argv,
char *field_name) int *consumed)
{ {
struct synth_field *field; struct synth_field *field;
const char *prefix = NULL;
char *field_type = argv[0], *field_name;
int len, ret = 0; int len, ret = 0;
char *array; char *array;
if (field_type[0] == ';') if (field_type[0] == ';')
field_type++; field_type++;
if (!strcmp(field_type, "unsigned")) {
if (argc < 3)
return ERR_PTR(-EINVAL);
prefix = "unsigned ";
field_type = argv[1];
field_name = argv[2];
*consumed = 3;
} else {
field_name = argv[1];
*consumed = 2;
}
len = strlen(field_name); len = strlen(field_name);
if (field_name[len - 1] == ';') if (field_name[len - 1] == ';')
field_name[len - 1] = '\0'; field_name[len - 1] = '\0';
@ -760,11 +774,15 @@ static struct synth_field *parse_synth_field(char *field_type,
array = strchr(field_name, '['); array = strchr(field_name, '[');
if (array) if (array)
len += strlen(array); len += strlen(array);
if (prefix)
len += strlen(prefix);
field->type = kzalloc(len, GFP_KERNEL); field->type = kzalloc(len, GFP_KERNEL);
if (!field->type) { if (!field->type) {
ret = -ENOMEM; ret = -ENOMEM;
goto free; goto free;
} }
if (prefix)
strcat(field->type, prefix);
strcat(field->type, field_type); strcat(field->type, field_type);
if (array) { if (array) {
strcat(field->type, array); strcat(field->type, array);
@ -1009,7 +1027,7 @@ static int create_synth_event(int argc, char **argv)
struct synth_field *field, *fields[SYNTH_FIELDS_MAX]; struct synth_field *field, *fields[SYNTH_FIELDS_MAX];
struct synth_event *event = NULL; struct synth_event *event = NULL;
bool delete_event = false; bool delete_event = false;
int i, n_fields = 0, ret = 0; int i, consumed = 0, n_fields = 0, ret = 0;
char *name; char *name;
mutex_lock(&synth_event_mutex); mutex_lock(&synth_event_mutex);
@ -1061,16 +1079,16 @@ static int create_synth_event(int argc, char **argv)
goto err; goto err;
} }
field = parse_synth_field(argv[i], argv[i + 1]); field = parse_synth_field(argc - i, &argv[i], &consumed);
if (IS_ERR(field)) { if (IS_ERR(field)) {
ret = PTR_ERR(field); ret = PTR_ERR(field);
goto err; goto err;
} }
fields[n_fields] = field; fields[n_fields++] = field;
i++; n_fields++; i += consumed - 1;
} }
if (i < argc) { if (i < argc && strcmp(argv[i], ";") != 0) {
ret = -EINVAL; ret = -EINVAL;
goto err; goto err;
} }

View File

@ -0,0 +1,80 @@
#!/bin/sh
# SPDX-License-Identifier: GPL-2.0
# description: event trigger - test synthetic_events syntax parser
do_reset() {
reset_trigger
echo > set_event
clear_trace
}
fail() { #msg
do_reset
echo $1
exit_fail
}
if [ ! -f set_event ]; then
echo "event tracing is not supported"
exit_unsupported
fi
if [ ! -f synthetic_events ]; then
echo "synthetic event is not supported"
exit_unsupported
fi
reset_tracer
do_reset
echo "Test synthetic_events syntax parser"
echo > synthetic_events
# synthetic event must have a field
! echo "myevent" >> synthetic_events
echo "myevent u64 var1" >> synthetic_events
# synthetic event must be found in synthetic_events
grep "myevent[[:space:]]u64 var1" synthetic_events
# it is not possible to add same name event
! echo "myevent u64 var2" >> synthetic_events
# Non-append open will cleanup all events and add new one
echo "myevent u64 var2" > synthetic_events
# multiple fields with different spaces
echo "myevent u64 var1; u64 var2;" > synthetic_events
grep "myevent[[:space:]]u64 var1; u64 var2" synthetic_events
echo "myevent u64 var1 ; u64 var2 ;" > synthetic_events
grep "myevent[[:space:]]u64 var1; u64 var2" synthetic_events
echo "myevent u64 var1 ;u64 var2" > synthetic_events
grep "myevent[[:space:]]u64 var1; u64 var2" synthetic_events
# test field types
echo "myevent u32 var" > synthetic_events
echo "myevent u16 var" > synthetic_events
echo "myevent u8 var" > synthetic_events
echo "myevent s64 var" > synthetic_events
echo "myevent s32 var" > synthetic_events
echo "myevent s16 var" > synthetic_events
echo "myevent s8 var" > synthetic_events
echo "myevent char var" > synthetic_events
echo "myevent int var" > synthetic_events
echo "myevent long var" > synthetic_events
echo "myevent pid_t var" > synthetic_events
echo "myevent unsigned char var" > synthetic_events
echo "myevent unsigned int var" > synthetic_events
echo "myevent unsigned long var" > synthetic_events
grep "myevent[[:space:]]unsigned long var" synthetic_events
# test string type
echo "myevent char var[10]" > synthetic_events
grep "myevent[[:space:]]char\[10\] var" synthetic_events
do_reset
exit 0