Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 6b5201c2 authored by Greg Kroah-Hartman's avatar Greg Kroah-Hartman
Browse files
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
parents d4ec49d3 ba0e41ca
Loading
Loading
Loading
Loading
+25 −7
Original line number Diff line number Diff line
@@ -738,16 +738,30 @@ static void free_synth_field(struct synth_field *field)
	kfree(field);
}

static struct synth_field *parse_synth_field(char *field_type,
					     char *field_name)
static struct synth_field *parse_synth_field(int argc, char **argv,
					     int *consumed)
{
	struct synth_field *field;
	const char *prefix = NULL;
	char *field_type = argv[0], *field_name;
	int len, ret = 0;
	char *array;

	if (field_type[0] == ';')
		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);
	if (field_name[len - 1] == ';')
		field_name[len - 1] = '\0';
@@ -760,11 +774,15 @@ static struct synth_field *parse_synth_field(char *field_type,
	array = strchr(field_name, '[');
	if (array)
		len += strlen(array);
	if (prefix)
		len += strlen(prefix);
	field->type = kzalloc(len, GFP_KERNEL);
	if (!field->type) {
		ret = -ENOMEM;
		goto free;
	}
	if (prefix)
		strcat(field->type, prefix);
	strcat(field->type, field_type);
	if (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_event *event = NULL;
	bool delete_event = false;
	int i, n_fields = 0, ret = 0;
	int i, consumed = 0, n_fields = 0, ret = 0;
	char *name;

	mutex_lock(&synth_event_mutex);
@@ -1061,16 +1079,16 @@ static int create_synth_event(int argc, char **argv)
			goto err;
		}

		field = parse_synth_field(argv[i], argv[i + 1]);
		field = parse_synth_field(argc - i, &argv[i], &consumed);
		if (IS_ERR(field)) {
			ret = PTR_ERR(field);
			goto err;
		}
		fields[n_fields] = field;
		i++; n_fields++;
		fields[n_fields++] = field;
		i += consumed - 1;
	}

	if (i < argc) {
	if (i < argc && strcmp(argv[i], ";") != 0) {
		ret = -EINVAL;
		goto err;
	}
+80 −0
Original line number Diff line number Diff line
#!/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