Commit 3cd65616 authored by Arnaldo Carvalho de Melo's avatar Arnaldo Carvalho de Melo
Browse files

perf examples bpf: Remove augmented_syscalls.c, the raw_syscalls one should be used instead



The attempt at using BPF to copy syscall pointer arguments to show them
like strace does started with sys_{enter,exit}_SYSCALL_NAME tracepoints,
in tools/perf/examples/bpf/augmented_syscalls.c, but then achieving this
result using raw_syscalls:{enter,exit} and BPF tail calls was deemed
more flexible.

The 'perf trace' codebase was adapted to using it while trying to
continue supporting the old style per-syscall tracepoints, which at some
point became too unwieldly and now isn't working properly.

So lets scale back and concentrate on the augmented_raw_syscalls.c
model on the way to using BPF skeletons.

For the same reason remove the etcsnoop.c example, that used the
old style per-tp syscalls just for the 'open' and 'openat' syscalls,
looking at the pathnames starting with "/etc/", we should be able
to do this later using filters, after we move to BPF skels.

The augmented_raw_syscalls.c one continues to work, now with libbpf 1.0,
after Ian work on using the libbpf map style:

  # perf trace -e ~acme/git/perf/tools/perf/examples/bpf/augmented_raw_syscalls.c,open* --max-events 4
     0.000 ping/194815 openat(dfd: CWD, filename: "/etc/hosts", flags: RDONLY|CLOEXEC) = 5
    20.225 systemd-oomd/972 openat(dfd: CWD, filename: "/proc/meminfo", flags: RDONLY|CLOEXEC) = 12
    20.285 abrt-dump-jour/1371 openat(dfd: CWD, filename: "/var/log/journal/d6a97235307247e09f13f326fb607e3c/system.journal", flags: RDONLY|CLOEXEC|NONBLOCK) = 21
    20.301 abrt-dump-jour/1370 openat(dfd: CWD, filename: "/var/log/journal/d6a97235307247e09f13f326fb607e3c/system.journal", flags: RDONLY|CLOEXEC|NONBLOCK) = 21
  #

This is using this:

  # cat ~/.perfconfig
  [trace]
	show_zeros = yes
	show_duration = no
	no_inherit = yes
	args_alignment = 40

Cc: Adrian Hunter <adrian.hunter@intel.com>
Cc: Ian Rogers <irogers@google.com>
Cc: Jiri Olsa <jolsa@kernel.org>
Cc: Namhyung Kim <namhyung@kernel.org>
Signed-off-by: default avatarArnaldo Carvalho de Melo <acme@redhat.com>
parent cfddf0d4
Loading
Loading
Loading
Loading
+0 −169
Original line number Diff line number Diff line
// SPDX-License-Identifier: GPL-2.0
/*
 * Augment syscalls with the contents of the pointer arguments.
 *
 * Test it with:
 *
 * perf trace -e tools/perf/examples/bpf/augmented_syscalls.c cat /etc/passwd > /dev/null
 *
 * It'll catch some openat syscalls related to the dynamic linked and
 * the last one should be the one for '/etc/passwd'.
 *
 * This matches what is marshalled into the raw_syscall:sys_enter payload
 * expected by the 'perf trace' beautifiers, and can be used by them, that will
 * check if perf_sample->raw_data is more than what is expected for each
 * syscalls:sys_{enter,exit}_SYSCALL tracepoint, uing the extra data as the
 * contents of pointer arguments.
 */

#include <stdio.h>
#include <linux/socket.h>

/* bpf-output associated map */
bpf_map(__augmented_syscalls__, PERF_EVENT_ARRAY, int, u32, __NR_CPUS__);

struct syscall_exit_args {
	unsigned long long common_tp_fields;
	long		   syscall_nr;
	long		   ret;
};

struct augmented_filename {
	unsigned int	size;
	int		reserved;
	char		value[256];
};

#define augmented_filename_syscall(syscall)							\
struct augmented_enter_##syscall##_args {			 				\
	struct syscall_enter_##syscall##_args	args;				 		\
	struct augmented_filename		filename;				 	\
};												\
int syscall_enter(syscall)(struct syscall_enter_##syscall##_args *args)				\
{												\
	struct augmented_enter_##syscall##_args augmented_args = { .filename.reserved = 0, }; 	\
	unsigned int len = sizeof(augmented_args);						\
	probe_read(&augmented_args.args, sizeof(augmented_args.args), args);			\
	augmented_args.filename.size = probe_read_str(&augmented_args.filename.value, 		\
						      sizeof(augmented_args.filename.value), 	\
						      args->filename_ptr); 			\
	if (augmented_args.filename.size < sizeof(augmented_args.filename.value)) {		\
		len -= sizeof(augmented_args.filename.value) - augmented_args.filename.size;	\
		len &= sizeof(augmented_args.filename.value) - 1;				\
	}											\
	/* If perf_event_output fails, return non-zero so that it gets recorded unaugmented */	\
	return perf_event_output(args, &__augmented_syscalls__, BPF_F_CURRENT_CPU, 		\
				 &augmented_args, len);						\
}												\
int syscall_exit(syscall)(struct syscall_exit_args *args)					\
{												\
       return 1; /* 0 as soon as we start copying data returned by the kernel, e.g. 'read' */	\
}

struct syscall_enter_openat_args {
	unsigned long long common_tp_fields;
	long		   syscall_nr;
	long		   dfd;
	char		   *filename_ptr;
	long		   flags;
	long		   mode;
};

augmented_filename_syscall(openat);

struct syscall_enter_open_args {
	unsigned long long common_tp_fields;
	long		   syscall_nr;
	char		   *filename_ptr;
	long		   flags;
	long		   mode;
};

augmented_filename_syscall(open);

struct syscall_enter_inotify_add_watch_args {
	unsigned long long common_tp_fields;
	long		   syscall_nr;
	long		   fd;
	char		   *filename_ptr;
	long		   mask;
};

augmented_filename_syscall(inotify_add_watch);

struct statbuf;

struct syscall_enter_newstat_args {
	unsigned long long common_tp_fields;
	long		   syscall_nr;
	char		   *filename_ptr;
	struct stat	   *statbuf;
};

augmented_filename_syscall(newstat);

#ifndef _K_SS_MAXSIZE
#define _K_SS_MAXSIZE 128
#endif

#define augmented_sockaddr_syscall(syscall)						\
struct augmented_enter_##syscall##_args {			 				\
	struct syscall_enter_##syscall##_args	args;				 		\
	struct sockaddr_storage			addr;						\
};												\
int syscall_enter(syscall)(struct syscall_enter_##syscall##_args *args)				\
{												\
	struct augmented_enter_##syscall##_args augmented_args;				 	\
	unsigned long addrlen = sizeof(augmented_args.addr);					\
	probe_read(&augmented_args.args, sizeof(augmented_args.args), args);			\
/* FIXME_CLANG_OPTIMIZATION_THAT_ACCESSES_USER_CONTROLLED_ADDRLEN_DESPITE_THIS_CHECK */		\
/*	if (addrlen > augmented_args.args.addrlen)				     */		\
/*		addrlen = augmented_args.args.addrlen;				     */		\
/*										     */		\
	probe_read(&augmented_args.addr, addrlen, args->addr_ptr); 				\
	/* If perf_event_output fails, return non-zero so that it gets recorded unaugmented */	\
	return perf_event_output(args, &__augmented_syscalls__, BPF_F_CURRENT_CPU, 		\
				 &augmented_args, 						\
				sizeof(augmented_args) - sizeof(augmented_args.addr) + addrlen);\
}												\
int syscall_exit(syscall)(struct syscall_exit_args *args)					\
{												\
       return 1; /* 0 as soon as we start copying data returned by the kernel, e.g. 'read' */	\
}

struct sockaddr;

struct syscall_enter_bind_args {
	unsigned long long common_tp_fields;
	long		   syscall_nr;
	long		   fd;
	struct sockaddr	   *addr_ptr;
	unsigned long	   addrlen;
};

augmented_sockaddr_syscall(bind);

struct syscall_enter_connect_args {
	unsigned long long common_tp_fields;
	long		   syscall_nr;
	long		   fd;
	struct sockaddr	   *addr_ptr;
	unsigned long	   addrlen;
};

augmented_sockaddr_syscall(connect);

struct syscall_enter_sendto_args {
	unsigned long long common_tp_fields;
	long		   syscall_nr;
	long		   fd;
	void		   *buff;
	long		   len;
	unsigned long	   flags;
	struct sockaddr	   *addr_ptr;
	long		   addr_len;
};

augmented_sockaddr_syscall(sendto);

license(GPL);
+0 −76
Original line number Diff line number Diff line
// SPDX-License-Identifier: GPL-2.0
/*
 * Augment the filename syscalls with the contents of the filename pointer argument
 * filtering only those that do not start with /etc/.
 *
 * Test it with:
 *
 * perf trace -e tools/perf/examples/bpf/augmented_syscalls.c cat /etc/passwd > /dev/null
 *
 * It'll catch some openat syscalls related to the dynamic linked and
 * the last one should be the one for '/etc/passwd'.
 *
 * This matches what is marshalled into the raw_syscall:sys_enter payload
 * expected by the 'perf trace' beautifiers, and can be used by them unmodified,
 * which will be done as that feature is implemented in the next csets, for now
 * it will appear in a dump done by the default tracepoint handler in 'perf trace',
 * that uses bpf_output__fprintf() to just dump those contents, as done with
 * the bpf-output event associated with the __bpf_output__ map declared in
 * tools/perf/include/bpf/stdio.h.
 */

#include <stdio.h>

/* bpf-output associated map */
bpf_map(__augmented_syscalls__, PERF_EVENT_ARRAY, int, u32, __NR_CPUS__);

struct augmented_filename {
	int	size;
	int	reserved;
	char	value[64];
};

#define augmented_filename_syscall_enter(syscall) 						\
struct augmented_enter_##syscall##_args {			 				\
	struct syscall_enter_##syscall##_args	args;				 		\
	struct augmented_filename		filename;				 	\
};												\
int syscall_enter(syscall)(struct syscall_enter_##syscall##_args *args)				\
{												\
	char etc[6] = "/etc/";									\
	struct augmented_enter_##syscall##_args augmented_args = { .filename.reserved = 0, }; 	\
	probe_read(&augmented_args.args, sizeof(augmented_args.args), args);			\
	augmented_args.filename.size = probe_read_str(&augmented_args.filename.value, 		\
						      sizeof(augmented_args.filename.value), 	\
						      args->filename_ptr); 			\
	if (__builtin_memcmp(augmented_args.filename.value, etc, 4) != 0)			\
		return 0;									\
	/* If perf_event_output fails, return non-zero so that it gets recorded unaugmented */	\
	return perf_event_output(args, &__augmented_syscalls__, BPF_F_CURRENT_CPU, 		\
				 &augmented_args,						\
				 (sizeof(augmented_args) - sizeof(augmented_args.filename.value) + \
				 augmented_args.filename.size));				\
}

struct syscall_enter_openat_args {
	unsigned long long common_tp_fields;
	long		   syscall_nr;
	long		   dfd;
	char		   *filename_ptr;
	long		   flags;
	long		   mode;
};

augmented_filename_syscall_enter(openat);

struct syscall_enter_open_args {
	unsigned long long common_tp_fields;
	long		   syscall_nr;
	char		   *filename_ptr;
	long		   flags;
	long		   mode;
};

augmented_filename_syscall_enter(open);

license(GPL);