* [PATCH 0/5] perf tools: Add dlfilter test @ 2021-08-10 11:48 Adrian Hunter 2021-08-10 11:48 ` [PATCH 1/5] perf script: Fix unnecessary machine_resolve() Adrian Hunter ` (4 more replies) 0 siblings, 5 replies; 13+ messages in thread From: Adrian Hunter @ 2021-08-10 11:48 UTC (permalink / raw) To: Arnaldo Carvalho de Melo; +Cc: Jiri Olsa, linux-kernel Hi Here are some minor fixes / improvements to dlfilters and a new perf test for the dlfilter C API. Adrian Hunter (5): perf script: Fix unnecessary machine_resolve() perf script: Fix --list-dlfilters documentation perf tools: Amend dlfilter documentation wrt library dependencies perf tools: Move perf_dlfilters.h in the source tree perf tools: Add dlfilter test tools/perf/Documentation/perf-dlfilter.txt | 8 + tools/perf/Documentation/perf-script.txt | 2 +- tools/perf/Makefile.perf | 17 +- tools/perf/builtin-script.c | 2 +- tools/perf/dlfilters/dlfilter-test-api-v0.c | 336 ++++++++++++++++++ tools/perf/{util => include/perf}/perf_dlfilter.h | 0 tools/perf/tests/Build | 1 + tools/perf/tests/builtin-test.c | 4 + tools/perf/tests/dlfilter-test.c | 409 ++++++++++++++++++++++ tools/perf/tests/tests.h | 1 + tools/perf/util/dlfilter.c | 6 +- tools/perf/util/dlfilter.h | 2 + 12 files changed, 781 insertions(+), 7 deletions(-) create mode 100644 tools/perf/dlfilters/dlfilter-test-api-v0.c rename tools/perf/{util => include/perf}/perf_dlfilter.h (100%) create mode 100644 tools/perf/tests/dlfilter-test.c Regards Adrian ^ permalink raw reply [flat|nested] 13+ messages in thread
* [PATCH 1/5] perf script: Fix unnecessary machine_resolve() 2021-08-10 11:48 [PATCH 0/5] perf tools: Add dlfilter test Adrian Hunter @ 2021-08-10 11:48 ` Adrian Hunter 2021-08-10 18:25 ` Arnaldo Carvalho de Melo 2021-08-10 11:48 ` [PATCH 2/5] perf script: Fix --list-dlfilters documentation Adrian Hunter ` (3 subsequent siblings) 4 siblings, 1 reply; 13+ messages in thread From: Adrian Hunter @ 2021-08-10 11:48 UTC (permalink / raw) To: Arnaldo Carvalho de Melo; +Cc: Jiri Olsa, linux-kernel machine_resolve() may have already been called. Test for that to avoid calling it again unnecessarily. Signed-off-by: Adrian Hunter <adrian.hunter@intel.com> --- tools/perf/builtin-script.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/perf/builtin-script.c b/tools/perf/builtin-script.c index e2e165b53499..f469354155f1 100644 --- a/tools/perf/builtin-script.c +++ b/tools/perf/builtin-script.c @@ -2212,7 +2212,7 @@ static int process_sample_event(struct perf_tool *tool, if (filter_cpu(sample)) goto out_put; - if (machine__resolve(machine, &al, sample) < 0) { + if (!al.thread && machine__resolve(machine, &al, sample) < 0) { pr_err("problem processing %d event, skipping it.\n", event->header.type); ret = -1; -- 2.17.1 ^ permalink raw reply related [flat|nested] 13+ messages in thread
* Re: [PATCH 1/5] perf script: Fix unnecessary machine_resolve() 2021-08-10 11:48 ` [PATCH 1/5] perf script: Fix unnecessary machine_resolve() Adrian Hunter @ 2021-08-10 18:25 ` Arnaldo Carvalho de Melo 2021-08-11 10:18 ` Adrian Hunter 0 siblings, 1 reply; 13+ messages in thread From: Arnaldo Carvalho de Melo @ 2021-08-10 18:25 UTC (permalink / raw) To: Adrian Hunter; +Cc: Jiri Olsa, linux-kernel Em Tue, Aug 10, 2021 at 02:48:09PM +0300, Adrian Hunter escreveu: > machine_resolve() may have already been called. Test for that to avoid > calling it again unnecessarily. By some dlfilter function, right... Perhaps it would be better for machine__resolve() itself to check that? Probably we'll need a 'force' arg, or have __machine__resolve() that does exactly what machine__resolve() does today and then tools wanting to force it to avoid using whatever is 'cached'? - Arnaldo > Signed-off-by: Adrian Hunter <adrian.hunter@intel.com> > --- > tools/perf/builtin-script.c | 2 +- > 1 file changed, 1 insertion(+), 1 deletion(-) > > diff --git a/tools/perf/builtin-script.c b/tools/perf/builtin-script.c > index e2e165b53499..f469354155f1 100644 > --- a/tools/perf/builtin-script.c > +++ b/tools/perf/builtin-script.c > @@ -2212,7 +2212,7 @@ static int process_sample_event(struct perf_tool *tool, > if (filter_cpu(sample)) > goto out_put; > > - if (machine__resolve(machine, &al, sample) < 0) { > + if (!al.thread && machine__resolve(machine, &al, sample) < 0) { > pr_err("problem processing %d event, skipping it.\n", > event->header.type); > ret = -1; > -- > 2.17.1 > -- - Arnaldo ^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [PATCH 1/5] perf script: Fix unnecessary machine_resolve() 2021-08-10 18:25 ` Arnaldo Carvalho de Melo @ 2021-08-11 10:18 ` Adrian Hunter 0 siblings, 0 replies; 13+ messages in thread From: Adrian Hunter @ 2021-08-11 10:18 UTC (permalink / raw) To: Arnaldo Carvalho de Melo; +Cc: Jiri Olsa, linux-kernel On 10/08/21 9:25 pm, Arnaldo Carvalho de Melo wrote: > Em Tue, Aug 10, 2021 at 02:48:09PM +0300, Adrian Hunter escreveu: >> machine_resolve() may have already been called. Test for that to avoid >> calling it again unnecessarily. > > By some dlfilter function, right... > > Perhaps it would be better for machine__resolve() itself to check that? > > Probably we'll need a 'force' arg, or have __machine__resolve() that > does exactly what machine__resolve() does today and then tools wanting > to force it to avoid using whatever is 'cached'? Yes, or perhaps introduce machine__resolve_once() and thread__resolve_once() ? > > - Arnaldo > >> Signed-off-by: Adrian Hunter <adrian.hunter@intel.com> >> --- >> tools/perf/builtin-script.c | 2 +- >> 1 file changed, 1 insertion(+), 1 deletion(-) >> >> diff --git a/tools/perf/builtin-script.c b/tools/perf/builtin-script.c >> index e2e165b53499..f469354155f1 100644 >> --- a/tools/perf/builtin-script.c >> +++ b/tools/perf/builtin-script.c >> @@ -2212,7 +2212,7 @@ static int process_sample_event(struct perf_tool *tool, >> if (filter_cpu(sample)) >> goto out_put; >> >> - if (machine__resolve(machine, &al, sample) < 0) { >> + if (!al.thread && machine__resolve(machine, &al, sample) < 0) { >> pr_err("problem processing %d event, skipping it.\n", >> event->header.type); >> ret = -1; >> -- >> 2.17.1 >> > ^ permalink raw reply [flat|nested] 13+ messages in thread
* [PATCH 2/5] perf script: Fix --list-dlfilters documentation 2021-08-10 11:48 [PATCH 0/5] perf tools: Add dlfilter test Adrian Hunter 2021-08-10 11:48 ` [PATCH 1/5] perf script: Fix unnecessary machine_resolve() Adrian Hunter @ 2021-08-10 11:48 ` Adrian Hunter 2021-08-10 18:28 ` Arnaldo Carvalho de Melo 2021-08-10 11:48 ` [PATCH 3/5] perf tools: Amend dlfilter documentation wrt library dependencies Adrian Hunter ` (2 subsequent siblings) 4 siblings, 1 reply; 13+ messages in thread From: Adrian Hunter @ 2021-08-10 11:48 UTC (permalink / raw) To: Arnaldo Carvalho de Melo; +Cc: Jiri Olsa, linux-kernel The option --list-dlfilters does use a string value. Signed-off-by: Adrian Hunter <adrian.hunter@intel.com> --- tools/perf/Documentation/perf-script.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/perf/Documentation/perf-script.txt b/tools/perf/Documentation/perf-script.txt index aa3a0b2c29a2..c80515243560 100644 --- a/tools/perf/Documentation/perf-script.txt +++ b/tools/perf/Documentation/perf-script.txt @@ -106,7 +106,7 @@ OPTIONS Pass 'arg' as an argument to the dlfilter. --dlarg may be repeated to add more arguments. ---list-dlfilters=:: +--list-dlfilters:: Display a list of available dlfilters. Use with option -v (must come before option --list-dlfilters) to show long descriptions. -- 2.17.1 ^ permalink raw reply related [flat|nested] 13+ messages in thread
* Re: [PATCH 2/5] perf script: Fix --list-dlfilters documentation 2021-08-10 11:48 ` [PATCH 2/5] perf script: Fix --list-dlfilters documentation Adrian Hunter @ 2021-08-10 18:28 ` Arnaldo Carvalho de Melo 0 siblings, 0 replies; 13+ messages in thread From: Arnaldo Carvalho de Melo @ 2021-08-10 18:28 UTC (permalink / raw) To: Adrian Hunter; +Cc: Jiri Olsa, linux-kernel Em Tue, Aug 10, 2021 at 02:48:10PM +0300, Adrian Hunter escreveu: > The option --list-dlfilters does use a string value. Added: Fixes: 638e2b9984ee1b8d ("perf script: Add option to list dlfilters") - Arnaldo > Signed-off-by: Adrian Hunter <adrian.hunter@intel.com> > --- > tools/perf/Documentation/perf-script.txt | 2 +- > 1 file changed, 1 insertion(+), 1 deletion(-) > > diff --git a/tools/perf/Documentation/perf-script.txt b/tools/perf/Documentation/perf-script.txt > index aa3a0b2c29a2..c80515243560 100644 > --- a/tools/perf/Documentation/perf-script.txt > +++ b/tools/perf/Documentation/perf-script.txt > @@ -106,7 +106,7 @@ OPTIONS > Pass 'arg' as an argument to the dlfilter. --dlarg may be repeated > to add more arguments. > > ---list-dlfilters=:: > +--list-dlfilters:: > Display a list of available dlfilters. Use with option -v (must come > before option --list-dlfilters) to show long descriptions. > > -- > 2.17.1 > -- - Arnaldo ^ permalink raw reply [flat|nested] 13+ messages in thread
* [PATCH 3/5] perf tools: Amend dlfilter documentation wrt library dependencies 2021-08-10 11:48 [PATCH 0/5] perf tools: Add dlfilter test Adrian Hunter 2021-08-10 11:48 ` [PATCH 1/5] perf script: Fix unnecessary machine_resolve() Adrian Hunter 2021-08-10 11:48 ` [PATCH 2/5] perf script: Fix --list-dlfilters documentation Adrian Hunter @ 2021-08-10 11:48 ` Adrian Hunter 2021-08-10 11:48 ` [PATCH 4/5] perf tools: Move perf_dlfilters.h in the source tree Adrian Hunter 2021-08-10 11:48 ` [PATCH 5/5] perf tools: Add dlfilter test Adrian Hunter 4 siblings, 0 replies; 13+ messages in thread From: Adrian Hunter @ 2021-08-10 11:48 UTC (permalink / raw) To: Arnaldo Carvalho de Melo; +Cc: Jiri Olsa, linux-kernel Like all locally-built programs, dlfilters may need to be re-built if shared libraries they use change. Also there may be unexpected results if the dfilter uses different versions of the shared libraries that perf uses. Note those things in the documentation. Signed-off-by: Adrian Hunter <adrian.hunter@intel.com> --- tools/perf/Documentation/perf-dlfilter.txt | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/tools/perf/Documentation/perf-dlfilter.txt b/tools/perf/Documentation/perf-dlfilter.txt index 02842cb4cf90..322510d3ec0c 100644 --- a/tools/perf/Documentation/perf-dlfilter.txt +++ b/tools/perf/Documentation/perf-dlfilter.txt @@ -246,6 +246,14 @@ To use the filter with perf script: perf script --dlfilter dlfilter-example.so +NOTES +----- + +The dlfilter .so file will be dependent on shared libraries. If those change, +it may be necessary to rebuild the .so. Also there may be unexpected results +if the .so uses different versions of the shared libraries that perf uses. +Versions can be checked using the ldd command. + SEE ALSO -------- linkperf:perf-script[1] -- 2.17.1 ^ permalink raw reply related [flat|nested] 13+ messages in thread
* [PATCH 4/5] perf tools: Move perf_dlfilters.h in the source tree 2021-08-10 11:48 [PATCH 0/5] perf tools: Add dlfilter test Adrian Hunter ` (2 preceding siblings ...) 2021-08-10 11:48 ` [PATCH 3/5] perf tools: Amend dlfilter documentation wrt library dependencies Adrian Hunter @ 2021-08-10 11:48 ` Adrian Hunter 2021-08-10 11:48 ` [PATCH 5/5] perf tools: Add dlfilter test Adrian Hunter 4 siblings, 0 replies; 13+ messages in thread From: Adrian Hunter @ 2021-08-10 11:48 UTC (permalink / raw) To: Arnaldo Carvalho de Melo; +Cc: Jiri Olsa, linux-kernel Move perf_dlfilters.h in the source tree so that it will be found when building dlfilters as part of the perf build. Signed-off-by: Adrian Hunter <adrian.hunter@intel.com> --- tools/perf/Makefile.perf | 2 +- tools/perf/{util => include/perf}/perf_dlfilter.h | 0 tools/perf/util/dlfilter.c | 2 +- 3 files changed, 2 insertions(+), 2 deletions(-) rename tools/perf/{util => include/perf}/perf_dlfilter.h (100%) diff --git a/tools/perf/Makefile.perf b/tools/perf/Makefile.perf index 77e7f18c0bd0..6dafde69d5e3 100644 --- a/tools/perf/Makefile.perf +++ b/tools/perf/Makefile.perf @@ -925,7 +925,7 @@ install-tools: all install-gtk $(INSTALL) $(OUTPUT)perf '$(DESTDIR_SQ)$(bindir_SQ)'; \ $(LN) '$(DESTDIR_SQ)$(bindir_SQ)/perf' '$(DESTDIR_SQ)$(bindir_SQ)/trace'; \ $(INSTALL) -d -m 755 '$(DESTDIR_SQ)$(includedir_SQ)/perf'; \ - $(INSTALL) util/perf_dlfilter.h -t '$(DESTDIR_SQ)$(includedir_SQ)/perf' + $(INSTALL) -m 644 include/perf/perf_dlfilter.h -t '$(DESTDIR_SQ)$(includedir_SQ)/perf' ifndef NO_PERF_READ_VDSO32 $(call QUIET_INSTALL, perf-read-vdso32) \ $(INSTALL) $(OUTPUT)perf-read-vdso32 '$(DESTDIR_SQ)$(bindir_SQ)'; diff --git a/tools/perf/util/perf_dlfilter.h b/tools/perf/include/perf/perf_dlfilter.h similarity index 100% rename from tools/perf/util/perf_dlfilter.h rename to tools/perf/include/perf/perf_dlfilter.h diff --git a/tools/perf/util/dlfilter.c b/tools/perf/util/dlfilter.c index ca33fbc5efde..7d11ce76157c 100644 --- a/tools/perf/util/dlfilter.c +++ b/tools/perf/util/dlfilter.c @@ -21,7 +21,7 @@ #include "symbol.h" #include "srcline.h" #include "dlfilter.h" -#include "perf_dlfilter.h" +#include "../include/perf/perf_dlfilter.h" static void al_to_d_al(struct addr_location *al, struct perf_dlfilter_al *d_al) { -- 2.17.1 ^ permalink raw reply related [flat|nested] 13+ messages in thread
* [PATCH 5/5] perf tools: Add dlfilter test 2021-08-10 11:48 [PATCH 0/5] perf tools: Add dlfilter test Adrian Hunter ` (3 preceding siblings ...) 2021-08-10 11:48 ` [PATCH 4/5] perf tools: Move perf_dlfilters.h in the source tree Adrian Hunter @ 2021-08-10 11:48 ` Adrian Hunter 2021-08-10 18:32 ` Arnaldo Carvalho de Melo 4 siblings, 1 reply; 13+ messages in thread From: Adrian Hunter @ 2021-08-10 11:48 UTC (permalink / raw) To: Arnaldo Carvalho de Melo; +Cc: Jiri Olsa, linux-kernel Add a perf test to test the dlfilter C API. A perf.data file is synthesized and then processed by perf script with a dlfilter named dlfilter-test-api-v0.so. Also a C file is compiled to provide a dso to match the synthesized perf.data file. Signed-off-by: Adrian Hunter <adrian.hunter@intel.com> --- tools/perf/Makefile.perf | 15 +- tools/perf/dlfilters/dlfilter-test-api-v0.c | 336 ++++++++++++++++ tools/perf/tests/Build | 1 + tools/perf/tests/builtin-test.c | 4 + tools/perf/tests/dlfilter-test.c | 409 ++++++++++++++++++++ tools/perf/tests/tests.h | 1 + tools/perf/util/dlfilter.c | 4 +- tools/perf/util/dlfilter.h | 2 + 8 files changed, 769 insertions(+), 3 deletions(-) create mode 100644 tools/perf/dlfilters/dlfilter-test-api-v0.c create mode 100644 tools/perf/tests/dlfilter-test.c diff --git a/tools/perf/Makefile.perf b/tools/perf/Makefile.perf index 6dafde69d5e3..24623599113d 100644 --- a/tools/perf/Makefile.perf +++ b/tools/perf/Makefile.perf @@ -360,8 +360,11 @@ ifndef NO_JVMTI PROGRAMS += $(OUTPUT)$(LIBJVMTI) endif +DLFILTERS := dlfilter-test-api-v0.so +DLFILTERS := $(patsubst %,$(OUTPUT)dlfilters/%,$(DLFILTERS)) + # what 'all' will build and 'install' will install, in perfexecdir -ALL_PROGRAMS = $(PROGRAMS) $(SCRIPTS) +ALL_PROGRAMS = $(PROGRAMS) $(SCRIPTS) $(DLFILTERS) # what 'all' will build but not install in perfexecdir OTHER_PROGRAMS = $(OUTPUT)perf @@ -780,6 +783,13 @@ $(OUTPUT)perf-read-vdsox32: perf-read-vdso.c util/find-map.c $(QUIET_CC)$(CC) -mx32 $(filter -static,$(LDFLAGS)) -Wall -Werror -o $@ perf-read-vdso.c endif +$(OUTPUT)dlfilters/%.o: dlfilters/%.c include/perf/perf_dlfilter.h + $(Q)$(MKDIR) -p $(OUTPUT)dlfilters + $(QUIET_CC)$(CC) -c -Iinclude -o $@ -fpic $< + +$(OUTPUT)dlfilters/%.so: $(OUTPUT)dlfilters/%.o + $(QUIET_LINK)$(CC) -shared -o $@ $< + ifndef NO_JVMTI LIBJVMTI_IN := $(OUTPUT)jvmti/jvmti-in.o @@ -978,6 +988,9 @@ ifndef NO_LIBPYTHON $(INSTALL) scripts/python/*.py -m 644 -t '$(DESTDIR_SQ)$(perfexec_instdir_SQ)/scripts/python'; \ $(INSTALL) scripts/python/bin/* -t '$(DESTDIR_SQ)$(perfexec_instdir_SQ)/scripts/python/bin' endif + $(call QUIET_INSTALL, dlfilters) \ + $(INSTALL) -d -m 755 '$(DESTDIR_SQ)$(perfexec_instdir_SQ)/dlfilters'; \ + $(INSTALL) $(DLFILTERS) '$(DESTDIR_SQ)$(perfexec_instdir_SQ)/dlfilters'; $(call QUIET_INSTALL, perf_completion-script) \ $(INSTALL) -d -m 755 '$(DESTDIR_SQ)$(sysconfdir_SQ)/bash_completion.d'; \ $(INSTALL) perf-completion.sh '$(DESTDIR_SQ)$(sysconfdir_SQ)/bash_completion.d/perf' diff --git a/tools/perf/dlfilters/dlfilter-test-api-v0.c b/tools/perf/dlfilters/dlfilter-test-api-v0.c new file mode 100644 index 000000000000..401656badef8 --- /dev/null +++ b/tools/perf/dlfilters/dlfilter-test-api-v0.c @@ -0,0 +1,336 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * dlfilter-test-api-v0.c: test original (v0) API for perf --dlfilter shared object + * Copyright (c) 2021, Intel Corporation. + */ +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <stdbool.h> + +/* + * Copy original (v0) API instead of including current API + */ +#include <linux/perf_event.h> +#include <linux/types.h> + +/* Definitions for perf_dlfilter_sample flags */ +enum { + PERF_DLFILTER_FLAG_BRANCH = 1ULL << 0, + PERF_DLFILTER_FLAG_CALL = 1ULL << 1, + PERF_DLFILTER_FLAG_RETURN = 1ULL << 2, + PERF_DLFILTER_FLAG_CONDITIONAL = 1ULL << 3, + PERF_DLFILTER_FLAG_SYSCALLRET = 1ULL << 4, + PERF_DLFILTER_FLAG_ASYNC = 1ULL << 5, + PERF_DLFILTER_FLAG_INTERRUPT = 1ULL << 6, + PERF_DLFILTER_FLAG_TX_ABORT = 1ULL << 7, + PERF_DLFILTER_FLAG_TRACE_BEGIN = 1ULL << 8, + PERF_DLFILTER_FLAG_TRACE_END = 1ULL << 9, + PERF_DLFILTER_FLAG_IN_TX = 1ULL << 10, + PERF_DLFILTER_FLAG_VMENTRY = 1ULL << 11, + PERF_DLFILTER_FLAG_VMEXIT = 1ULL << 12, +}; + +/* + * perf sample event information (as per perf script and <linux/perf_event.h>) + */ +struct perf_dlfilter_sample { + __u32 size; /* Size of this structure (for compatibility checking) */ + __u16 ins_lat; /* Refer PERF_SAMPLE_WEIGHT_TYPE in <linux/perf_event.h> */ + __u16 p_stage_cyc; /* Refer PERF_SAMPLE_WEIGHT_TYPE in <linux/perf_event.h> */ + __u64 ip; + __s32 pid; + __s32 tid; + __u64 time; + __u64 addr; + __u64 id; + __u64 stream_id; + __u64 period; + __u64 weight; /* Refer PERF_SAMPLE_WEIGHT_TYPE in <linux/perf_event.h> */ + __u64 transaction; /* Refer PERF_SAMPLE_TRANSACTION in <linux/perf_event.h> */ + __u64 insn_cnt; /* For instructions-per-cycle (IPC) */ + __u64 cyc_cnt; /* For instructions-per-cycle (IPC) */ + __s32 cpu; + __u32 flags; /* Refer PERF_DLFILTER_FLAG_* above */ + __u64 data_src; /* Refer PERF_SAMPLE_DATA_SRC in <linux/perf_event.h> */ + __u64 phys_addr; /* Refer PERF_SAMPLE_PHYS_ADDR in <linux/perf_event.h> */ + __u64 data_page_size; /* Refer PERF_SAMPLE_DATA_PAGE_SIZE in <linux/perf_event.h> */ + __u64 code_page_size; /* Refer PERF_SAMPLE_CODE_PAGE_SIZE in <linux/perf_event.h> */ + __u64 cgroup; /* Refer PERF_SAMPLE_CGROUP in <linux/perf_event.h> */ + __u8 cpumode; /* Refer CPUMODE_MASK etc in <linux/perf_event.h> */ + __u8 addr_correlates_sym; /* True => resolve_addr() can be called */ + __u16 misc; /* Refer perf_event_header in <linux/perf_event.h> */ + __u32 raw_size; /* Refer PERF_SAMPLE_RAW in <linux/perf_event.h> */ + const void *raw_data; /* Refer PERF_SAMPLE_RAW in <linux/perf_event.h> */ + __u64 brstack_nr; /* Number of brstack entries */ + const struct perf_branch_entry *brstack; /* Refer <linux/perf_event.h> */ + __u64 raw_callchain_nr; /* Number of raw_callchain entries */ + const __u64 *raw_callchain; /* Refer <linux/perf_event.h> */ + const char *event; +}; + +/* + * Address location (as per perf script) + */ +struct perf_dlfilter_al { + __u32 size; /* Size of this structure (for compatibility checking) */ + __u32 symoff; + const char *sym; + __u64 addr; /* Mapped address (from dso) */ + __u64 sym_start; + __u64 sym_end; + const char *dso; + __u8 sym_binding; /* STB_LOCAL, STB_GLOBAL or STB_WEAK, refer <elf.h> */ + __u8 is_64_bit; /* Only valid if dso is not NULL */ + __u8 is_kernel_ip; /* True if in kernel space */ + __u32 buildid_size; + __u8 *buildid; + /* Below members are only populated by resolve_ip() */ + __u8 filtered; /* True if this sample event will be filtered out */ + const char *comm; +}; + +struct perf_dlfilter_fns { + /* Return information about ip */ + const struct perf_dlfilter_al *(*resolve_ip)(void *ctx); + /* Return information about addr (if addr_correlates_sym) */ + const struct perf_dlfilter_al *(*resolve_addr)(void *ctx); + /* Return arguments from --dlarg option */ + char **(*args)(void *ctx, int *dlargc); + /* + * Return information about address (al->size must be set before + * calling). Returns 0 on success, -1 otherwise. + */ + __s32 (*resolve_address)(void *ctx, __u64 address, struct perf_dlfilter_al *al); + /* Return instruction bytes and length */ + const __u8 *(*insn)(void *ctx, __u32 *length); + /* Return source file name and line number */ + const char *(*srcline)(void *ctx, __u32 *line_number); + /* Return perf_event_attr, refer <linux/perf_event.h> */ + struct perf_event_attr *(*attr)(void *ctx); + /* Read object code, return numbers of bytes read */ + __s32 (*object_code)(void *ctx, __u64 ip, void *buf, __u32 len); + /* Reserved */ + void *(*reserved[120])(void *); +}; + +const struct perf_dlfilter_fns perf_dlfilter_fns; + +static int verbose; + +#define pr_debug(fmt, ...) do { \ + if (verbose) \ + fprintf(stderr, fmt, ##__VA_ARGS__); \ + } while (0) + +static int test_fail(const char *msg) +{ + pr_debug("%s\n", msg); + return -1; +} + +#define CHECK(x) do { \ + if (!(x)) \ + return test_fail("Check '" #x "' failed\n"); \ + } while (0) + +struct filter_data { + __u64 ip; + __u64 addr; + int do_early; + int early_filter_cnt; + int filter_cnt; +}; + +static struct filter_data *filt_dat; + +int start(void **data, void *ctx) +{ + int dlargc; + char **dlargv; + struct filter_data *d; + static bool called; + + verbose = 1; + + CHECK(!filt_dat && !called); + called = true; + + d = calloc(1, sizeof(*d)); + if (!d) + test_fail("Failed to allocate memory"); + filt_dat = d; + *data = d; + + dlargv = perf_dlfilter_fns.args(ctx, &dlargc); + + CHECK(dlargc == 6); + CHECK(!strcmp(dlargv[0], "first")); + verbose = strtol(dlargv[1], NULL, 0); + d->ip = strtoull(dlargv[2], NULL, 0); + d->addr = strtoull(dlargv[3], NULL, 0); + d->do_early = strtol(dlargv[4], NULL, 0); + CHECK(!strcmp(dlargv[5], "last")); + + pr_debug("%s API\n", __func__); + + return 0; +} + +#define CHECK_SAMPLE(x) do { \ + if (sample->x != expected.x) \ + return test_fail("'" #x "' not expected value\n"); \ + } while (0) + +static int check_sample(struct filter_data *d, const struct perf_dlfilter_sample *sample) +{ + struct perf_dlfilter_sample expected = { + .ip = d->ip, + .pid = 12345, + .tid = 12346, + .time = 1234567890, + .addr = d->addr, + .id = 99, + .stream_id = 101, + .period = 543212345, + .cpu = 31, + .cpumode = PERF_RECORD_MISC_USER, + .addr_correlates_sym = 1, + .misc = PERF_RECORD_MISC_USER, + }; + + CHECK(sample->size >= sizeof(struct perf_dlfilter_sample)); + + CHECK_SAMPLE(ip); + CHECK_SAMPLE(pid); + CHECK_SAMPLE(tid); + CHECK_SAMPLE(time); + CHECK_SAMPLE(addr); + CHECK_SAMPLE(id); + CHECK_SAMPLE(stream_id); + CHECK_SAMPLE(period); + CHECK_SAMPLE(cpu); + CHECK_SAMPLE(cpumode); + CHECK_SAMPLE(addr_correlates_sym); + CHECK_SAMPLE(misc); + + CHECK(!sample->raw_data); + CHECK_SAMPLE(brstack_nr); + CHECK(!sample->brstack); + CHECK_SAMPLE(raw_callchain_nr); + CHECK(!sample->raw_callchain); + +#define EVENT_NAME "branches:" + CHECK(!strncmp(sample->event, EVENT_NAME, strlen(EVENT_NAME))); + + return 0; +} + +static int check_al(void *ctx) +{ + const struct perf_dlfilter_al *al; + + al = perf_dlfilter_fns.resolve_ip(ctx); + if (!al) + return test_fail("resolve_ip() failed"); + + CHECK(al->sym && !strcmp("foo", al->sym)); + CHECK(!al->symoff); + + return 0; +} + +static int check_addr_al(void *ctx) +{ + const struct perf_dlfilter_al *addr_al; + + addr_al = perf_dlfilter_fns.resolve_addr(ctx); + if (!addr_al) + return test_fail("resolve_addr() failed"); + + CHECK(addr_al->sym && !strcmp("bar", addr_al->sym)); + CHECK(!addr_al->symoff); + + return 0; +} + +static int check_attr(void *ctx) +{ + struct perf_event_attr *attr = perf_dlfilter_fns.attr(ctx); + + CHECK(attr); + CHECK(attr->type == PERF_TYPE_HARDWARE); + CHECK(attr->config == PERF_COUNT_HW_BRANCH_INSTRUCTIONS); + + return 0; +} + +static int do_checks(void *data, const struct perf_dlfilter_sample *sample, void *ctx, bool early) +{ + struct filter_data *d = data; + + CHECK(data && filt_dat == data); + + if (early) { + CHECK(!d->early_filter_cnt); + d->early_filter_cnt += 1; + } else { + CHECK(!d->filter_cnt); + CHECK(d->early_filter_cnt); + CHECK(d->do_early != 2); + d->filter_cnt += 1; + } + + if (check_sample(data, sample)) + return -1; + + if (check_attr(ctx)) + return -1; + + if (early && !d->do_early) + return 0; + + if (check_al(ctx) || check_addr_al(ctx)) + return -1; + + if (early) + return d->do_early == 2; + + return 1; +} + +int filter_event_early(void *data, const struct perf_dlfilter_sample *sample, void *ctx) +{ + pr_debug("%s API\n", __func__); + + return do_checks(data, sample, ctx, true); +} + +int filter_event(void *data, const struct perf_dlfilter_sample *sample, void *ctx) +{ + struct filter_data *d = data; + + pr_debug("%s API\n", __func__); + + return do_checks(data, sample, ctx, false); +} + +int stop(void *data, void *ctx) +{ + static bool called; + + pr_debug("%s API\n", __func__); + + CHECK(data && filt_dat == data && !called); + called = true; + + free(data); + filt_dat = NULL; + return 0; +} + +const char *filter_description(const char **long_description) +{ + *long_description = "Filter used by the 'dlfilter C API' perf test"; + return "dlfilter to test v0 C API"; +} diff --git a/tools/perf/tests/Build b/tools/perf/tests/Build index 650aec19d490..803ca426f8e6 100644 --- a/tools/perf/tests/Build +++ b/tools/perf/tests/Build @@ -64,6 +64,7 @@ perf-y += parse-metric.o perf-y += pe-file-parsing.o perf-y += expand-cgroup.o perf-y += perf-time-to-tsc.o +perf-y += dlfilter-test.o $(OUTPUT)tests/llvm-src-base.c: tests/bpf-script-example.c tests/Build $(call rule_mkdir) diff --git a/tools/perf/tests/builtin-test.c b/tools/perf/tests/builtin-test.c index 5e6242576236..fb5846db02e1 100644 --- a/tools/perf/tests/builtin-test.c +++ b/tools/perf/tests/builtin-test.c @@ -360,6 +360,10 @@ static struct test generic_tests[] = { .func = test__perf_time_to_tsc, .is_supported = test__tsc_is_supported, }, + { + .desc = "dlfilter C API", + .func = test__dlfilter, + }, { .func = NULL, }, diff --git a/tools/perf/tests/dlfilter-test.c b/tools/perf/tests/dlfilter-test.c new file mode 100644 index 000000000000..7fadf6e12f99 --- /dev/null +++ b/tools/perf/tests/dlfilter-test.c @@ -0,0 +1,409 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Test dlfilter C API. A perf.data file is synthesized and then processed + * by perf script with a dlfilter named dlfilter-test-api-v0.so. Also a C file + * is compiled to provide a dso to match the synthesized perf.data file. + */ + +#include <linux/compiler.h> +#include <linux/kernel.h> +#include <linux/string.h> +#include <linux/perf_event.h> +#include <internal/lib.h> +#include <subcmd/exec-cmd.h> +#include <sys/types.h> +#include <sys/stat.h> +#include <fcntl.h> +#include <stdlib.h> +#include <unistd.h> +#include <inttypes.h> +#include <libgen.h> +#include <string.h> +#include <errno.h> +#include "debug.h" +#include "tool.h" +#include "event.h" +#include "header.h" +#include "machine.h" +#include "dso.h" +#include "map.h" +#include "symbol.h" +#include "synthetic-events.h" +#include "util.h" +#include "archinsn.h" +#include "dlfilter.h" +#include "tests.h" + +#define MAP_START 0x400000 + +struct test_data { + struct perf_tool tool; + struct machine *machine; + int fd; + u64 foo; + u64 bar; + u64 ip; + u64 addr; + char perf[PATH_MAX]; + char perf_data_file_name[PATH_MAX]; + char c_file_name[PATH_MAX]; + char prog_file_name[PATH_MAX]; + char dlfilters[PATH_MAX]; +}; + +static int test_result(const char *msg, int ret) +{ + pr_debug("%s\n", msg); + return ret; +} + +static int process(struct perf_tool *tool, union perf_event *event, + struct perf_sample *sample __maybe_unused, + struct machine *machine __maybe_unused) +{ + struct test_data *td = container_of(tool, struct test_data, tool); + int fd = td->fd; + + if (writen(fd, event, event->header.size) != event->header.size) + return -1; + + return 0; +} + +#define MAXCMD 4096 +#define REDIRECT_TO_DEV_NULL " >/dev/null 2>&1" + +static __printf(1, 2) int system_cmd(const char *fmt, ...) +{ + char cmd[MAXCMD + sizeof(REDIRECT_TO_DEV_NULL)]; + int ret; + + va_list args; + + va_start(args, fmt); + ret = vsnprintf(cmd, MAXCMD, fmt, args); + va_end(args); + + if (ret <= 0 || ret >= MAXCMD) + return -1; + + if (!verbose) + strcat(cmd, REDIRECT_TO_DEV_NULL); + + pr_debug("Command: %s\n", cmd); + ret = system(cmd); + if (ret) + pr_debug("Failed with return value %d\n", ret); + + return ret; +} + +static bool have_gcc(void) +{ + pr_debug("Checking for gcc\n"); + return !system_cmd("gcc --version"); +} + +static int write_attr(struct test_data *td, u64 sample_type, u64 *id) +{ + struct perf_event_attr attr = { + .size = sizeof(attr), + .type = PERF_TYPE_HARDWARE, + .config = PERF_COUNT_HW_BRANCH_INSTRUCTIONS, + .sample_type = sample_type, + .sample_period = 1, + }; + + return perf_event__synthesize_attr(&td->tool, &attr, 1, id, process); +} + +static int write_comm(int fd, pid_t pid, pid_t tid, const char *comm_str) +{ + struct perf_record_comm comm; + ssize_t sz = sizeof(comm); + + comm.header.type = PERF_RECORD_COMM; + comm.header.misc = PERF_RECORD_MISC_USER; + comm.header.size = sz; + + comm.pid = pid; + comm.tid = tid; + strncpy(comm.comm, comm_str, 16); + + if (writen(fd, &comm, sz) != sz) { + pr_debug("%s failed\n", __func__); + return -1; + } + + return 0; +} + +static int write_mmap(int fd, pid_t pid, pid_t tid, u64 start, u64 len, u64 pgoff, + const char *filename) +{ + char buf[PERF_SAMPLE_MAX_SIZE]; + struct perf_record_mmap *mmap = (struct perf_record_mmap *)buf; + size_t fsz = roundup(strlen(filename) + 1, 8); + ssize_t sz = sizeof(*mmap) - sizeof(mmap->filename) + fsz; + + mmap->header.type = PERF_RECORD_MMAP; + mmap->header.misc = PERF_RECORD_MISC_USER; + mmap->header.size = sz; + + mmap->pid = pid; + mmap->tid = tid; + mmap->start = start; + mmap->len = len; + mmap->pgoff = pgoff; + strncpy(mmap->filename, filename, sizeof(mmap->filename)); + + if (writen(fd, mmap, sz) != sz) { + pr_debug("%s failed\n", __func__); + return -1; + } + + return 0; +} + +static int write_sample(struct test_data *td, u64 sample_type, u64 id, pid_t pid, pid_t tid) +{ + char buf[PERF_SAMPLE_MAX_SIZE]; + union perf_event *event = (union perf_event *)buf; + struct perf_sample sample = { + .ip = td->ip, + .addr = td->addr, + .id = id, + .time = 1234567890, + .cpu = 31, + .pid = pid, + .tid = tid, + .period = 543212345, + .stream_id = 101, + }; + int err; + + event->header.type = PERF_RECORD_SAMPLE; + event->header.misc = PERF_RECORD_MISC_USER; + event->header.size = perf_event__sample_event_size(&sample, sample_type, 0); + err = perf_event__synthesize_sample(event, sample_type, 0, &sample); + if (err) + return test_result("perf_event__synthesize_sample() failed", TEST_FAIL); + + err = process(&td->tool, event, &sample, td->machine); + if (err) + return test_result("Failed to write sample", TEST_FAIL); + + return TEST_OK; +} + +static void close_fd(int fd) +{ + if (fd >= 0) + close(fd); +} + +static const char *prog = "int bar(){};int foo(){bar();};int main(){foo();return 0;}"; + +static int write_prog(char *file_name) +{ + int fd = creat(file_name, 0644); + ssize_t n = strlen(prog); + bool err = fd < 0 || writen(fd, prog, n) != n; + + close_fd(fd); + return err ? -1 : 0; +} + +static int get_dlfilters_path(char *buf, size_t sz) +{ + char perf[PATH_MAX]; + char path[PATH_MAX]; + char *perf_path; + char *exec_path; + + perf_exe(perf, sizeof(perf)); + perf_path = dirname(perf); + snprintf(path, sizeof(path), "%s/dlfilters/dlfilter-test-api-v0.so", perf_path); + if (access(path, R_OK)) { + exec_path = get_argv_exec_path(); + if (!exec_path) + return -1; + snprintf(path, sizeof(path), "%s/dlfilters/dlfilter-test-api-v0.so", exec_path); + free(exec_path); + if (access(path, R_OK)) + return -1; + } + strlcpy(buf, dirname(path), sz); + return 0; +} + +static int check_filter_desc(struct test_data *td) +{ + char *long_desc; + char *desc; + + if (get_filter_desc(td->dlfilters, "dlfilter-test-api-v0.so", &desc, &long_desc) && + long_desc && !strcmp(long_desc, "Filter used by the 'dlfilter C API' perf test") && + desc && !strcmp(desc, "dlfilter to test v0 C API")) + return 0; + + return -1; +} + +static int get_ip_addr(struct test_data *td) +{ + struct map *map; + struct symbol *sym; + + map = dso__new_map(td->prog_file_name); + if (!map) + return -1; + + sym = map__find_symbol_by_name(map, "foo"); + if (sym) + td->foo = sym->start; + + sym = map__find_symbol_by_name(map, "bar"); + if (sym) + td->bar = sym->start; + + map__put(map); + + td->ip = MAP_START + td->foo; + td->addr = MAP_START + td->bar; + + return td->foo && td->bar ? 0 : -1; +} + +static int do_run_perf_script(struct test_data *td, int do_early) +{ + return system_cmd("%s script -i %s " + "--dlfilter %s/dlfilter-test-api-v0.so " + "--dlarg first " + "--dlarg %d " + "--dlarg %" PRIu64 " " + "--dlarg %" PRIu64 " " + "--dlarg %d " + "--dlarg last", + td->perf, td->perf_data_file_name, td->dlfilters, + verbose, td->ip, td->addr, do_early); +} + +static int run_perf_script(struct test_data *td) +{ + int do_early; + int err; + + for (do_early = 0; do_early < 3; do_early++) { + err = do_run_perf_script(td, do_early); + if (err) + return err; + } + return 0; +} + +#define TEST_SAMPLE_TYPE (PERF_SAMPLE_IP | PERF_SAMPLE_TID | \ + PERF_SAMPLE_IDENTIFIER | PERF_SAMPLE_TIME | \ + PERF_SAMPLE_ADDR | PERF_SAMPLE_CPU | \ + PERF_SAMPLE_PERIOD | PERF_SAMPLE_STREAM_ID) + +static int test__dlfilter_test(struct test_data *td) +{ + u64 sample_type = TEST_SAMPLE_TYPE; + pid_t pid = 12345; + pid_t tid = 12346; + u64 id = 99; + int err; + + if (get_dlfilters_path(td->dlfilters, PATH_MAX)) + return test_result("dlfilters not found", TEST_SKIP); + + if (check_filter_desc(td)) + return test_result("Failed to get expected filter description", TEST_FAIL); + + if (!have_gcc()) + return test_result("gcc not found", TEST_SKIP); + + pr_debug("dlfilters path: %s\n", td->dlfilters); + + if (write_prog(td->c_file_name)) + return test_result("Failed to write test C file", TEST_FAIL); + + if (verbose > 1) + system_cmd("cat %s ; echo", td->c_file_name); + + if (system_cmd("gcc -g -o %s %s", td->prog_file_name, td->c_file_name)) + return TEST_FAIL; + + if (verbose > 2) + system_cmd("objdump -x -dS %s", td->prog_file_name); + + if (get_ip_addr(td)) + return test_result("Failed to find program symbols", TEST_FAIL); + + pr_debug("Creating new host machine structure\n"); + td->machine = machine__new_host(); + td->machine->env = &perf_env; + + td->fd = creat(td->perf_data_file_name, 0644); + if (td->fd < 0) + return test_result("Failed to create test perf.data file", TEST_FAIL); + + err = perf_header__write_pipe(td->fd); + if (err < 0) + return test_result("perf_header__write_pipe() failed", TEST_FAIL); + + err = write_attr(td, sample_type, &id); + if (err) + return test_result("perf_event__synthesize_attr() failed", TEST_FAIL); + + if (write_comm(td->fd, pid, tid, "test-prog")) + return TEST_FAIL; + + if (write_mmap(td->fd, pid, tid, MAP_START, 0x10000, 0, td->prog_file_name)) + return TEST_FAIL; + + if (write_sample(td, sample_type, id, pid, tid) != TEST_OK) + return TEST_FAIL; + + if (verbose > 1) + system_cmd("%s script -i %s -D", td->perf, td->perf_data_file_name); + + err = run_perf_script(td); + if (err) + return TEST_FAIL; + + return TEST_OK; +} + +static void unlink_path(const char *path) +{ + if (*path) + unlink(path); +} + +static void test_data__free(struct test_data *td) +{ + machine__delete(td->machine); + close_fd(td->fd); + unlink_path(td->c_file_name); + unlink_path(td->prog_file_name); + unlink_path(td->perf_data_file_name); +} + +int test__dlfilter(struct test *test __maybe_unused, int subtest __maybe_unused) +{ + struct test_data td = {.fd = -1}; + int pid = getpid(); + int err; + + perf_exe(td.perf, sizeof(td.perf)); + + snprintf(td.perf_data_file_name, PATH_MAX, "/tmp/dlfilter-test-%u-perf-data", pid); + snprintf(td.c_file_name, PATH_MAX, "/tmp/dlfilter-test-%u-prog.c", pid); + snprintf(td.prog_file_name, PATH_MAX, "/tmp/dlfilter-test-%u-prog", pid); + + err = test__dlfilter_test(&td); + test_data__free(&td); + return err; +} diff --git a/tools/perf/tests/tests.h b/tools/perf/tests/tests.h index 1100dd55b657..fe1306f58495 100644 --- a/tools/perf/tests/tests.h +++ b/tools/perf/tests/tests.h @@ -127,6 +127,7 @@ int test__parse_metric(struct test *test, int subtest); int test__pe_file_parsing(struct test *test, int subtest); int test__expand_cgroup_events(struct test *test, int subtest); int test__perf_time_to_tsc(struct test *test, int subtest); +int test__dlfilter(struct test *test, int subtest); bool test__bp_signal_is_supported(void); bool test__bp_account_is_supported(void); diff --git a/tools/perf/util/dlfilter.c b/tools/perf/util/dlfilter.c index 7d11ce76157c..db964d5a52af 100644 --- a/tools/perf/util/dlfilter.c +++ b/tools/perf/util/dlfilter.c @@ -530,8 +530,8 @@ int dlfilter__do_filter_event(struct dlfilter *d, return ret; } -static bool get_filter_desc(const char *dirname, const char *name, - char **desc, char **long_desc) +bool get_filter_desc(const char *dirname, const char *name, char **desc, + char **long_desc) { char path[PATH_MAX]; void *handle; diff --git a/tools/perf/util/dlfilter.h b/tools/perf/util/dlfilter.h index 505980442360..cc4bb9657d05 100644 --- a/tools/perf/util/dlfilter.h +++ b/tools/perf/util/dlfilter.h @@ -93,5 +93,7 @@ static inline int dlfilter__filter_event_early(struct dlfilter *d, } int list_available_dlfilters(const struct option *opt, const char *s, int unset); +bool get_filter_desc(const char *dirname, const char *name, char **desc, + char **long_desc); #endif -- 2.17.1 ^ permalink raw reply related [flat|nested] 13+ messages in thread
* Re: [PATCH 5/5] perf tools: Add dlfilter test 2021-08-10 11:48 ` [PATCH 5/5] perf tools: Add dlfilter test Adrian Hunter @ 2021-08-10 18:32 ` Arnaldo Carvalho de Melo 2021-08-10 19:06 ` Adrian Hunter 0 siblings, 1 reply; 13+ messages in thread From: Arnaldo Carvalho de Melo @ 2021-08-10 18:32 UTC (permalink / raw) To: Adrian Hunter; +Cc: Jiri Olsa, linux-kernel Em Tue, Aug 10, 2021 at 02:48:13PM +0300, Adrian Hunter escreveu: > Add a perf test to test the dlfilter C API. > > A perf.data file is synthesized and then processed by perf script with a > dlfilter named dlfilter-test-api-v0.so. Also a C file is compiled to > provide a dso to match the synthesized perf.data file. [root@five ~]# perf test dlfilter 72: dlfilter C API : FAILED! [root@five ~]# perf test -v dlfilter 72: dlfilter C API : --- start --- test child forked, pid 3358542 Checking for gcc Command: gcc --version gcc (GCC) 11.1.1 20210531 (Red Hat 11.1.1-3) Copyright (C) 2021 Free Software Foundation, Inc. This is free software; see the source for copying conditions. There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. dlfilters path: /var/home/acme/libexec/perf-core/dlfilters Command: gcc -g -o /tmp/dlfilter-test-3358542-prog /tmp/dlfilter-test-3358542-prog.c Creating new host machine structure Command: /var/home/acme/bin/perf script -i /tmp/dlfilter-test-3358542-perf-data --dlfilter /var/home/acme/libexec/perf-core/dlfilters/dlfilter-test-api-v0.so --dlarg first --dlarg 1 --dlarg 4198669 --dlarg 4198662 --dlarg 0 --dlarg last Failed with return value 139 test child finished with -1 ---- end ---- dlfilter C API: FAILED! [root@five ~]# cat /etc/redhat-release Fedora release 34 (Thirty Four) [root@five ~]# cat /etc/os-release NAME=Fedora VERSION="34.20210721.0 (Silverblue)" ID=fedora VERSION_ID=34 VERSION_CODENAME="" PLATFORM_ID="platform:f34" PRETTY_NAME="Fedora 34.20210721.0 (Silverblue)" ANSI_COLOR="0;38;2;60;110;180" LOGO=fedora-logo-icon CPE_NAME="cpe:/o:fedoraproject:fedora:34" HOME_URL="https://fedoraproject.org/" DOCUMENTATION_URL="https://docs.fedoraproject.org/en-US/fedora-silverblue/" SUPPORT_URL="https://fedoraproject.org/wiki/Communicating_and_getting_help" BUG_REPORT_URL="https://bugzilla.redhat.com/" REDHAT_BUGZILLA_PRODUCT="Fedora" REDHAT_BUGZILLA_PRODUCT_VERSION=34 REDHAT_SUPPORT_PRODUCT="Fedora" REDHAT_SUPPORT_PRODUCT_VERSION=34 PRIVACY_POLICY_URL="https://fedoraproject.org/wiki/Legal:PrivacyPolicy" VARIANT="Silverblue" VARIANT_ID=silverblue OSTREE_VERSION='34.20210721.0' [root@five ~]# Trying to figure this out... - Arnaldo ^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [PATCH 5/5] perf tools: Add dlfilter test 2021-08-10 18:32 ` Arnaldo Carvalho de Melo @ 2021-08-10 19:06 ` Adrian Hunter 2021-08-10 20:21 ` Arnaldo Carvalho de Melo 0 siblings, 1 reply; 13+ messages in thread From: Adrian Hunter @ 2021-08-10 19:06 UTC (permalink / raw) To: Arnaldo Carvalho de Melo; +Cc: Jiri Olsa, linux-kernel On 10/08/21 9:32 pm, Arnaldo Carvalho de Melo wrote: > Em Tue, Aug 10, 2021 at 02:48:13PM +0300, Adrian Hunter escreveu: >> Add a perf test to test the dlfilter C API. >> >> A perf.data file is synthesized and then processed by perf script with a >> dlfilter named dlfilter-test-api-v0.so. Also a C file is compiled to >> provide a dso to match the synthesized perf.data file. > > [root@five ~]# perf test dlfilter > 72: dlfilter C API : FAILED! > [root@five ~]# perf test -v dlfilter > 72: dlfilter C API : > --- start --- > test child forked, pid 3358542 > Checking for gcc > Command: gcc --version > gcc (GCC) 11.1.1 20210531 (Red Hat 11.1.1-3) > Copyright (C) 2021 Free Software Foundation, Inc. > This is free software; see the source for copying conditions. There is NO > warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. > > dlfilters path: /var/home/acme/libexec/perf-core/dlfilters > Command: gcc -g -o /tmp/dlfilter-test-3358542-prog /tmp/dlfilter-test-3358542-prog.c > Creating new host machine structure > Command: /var/home/acme/bin/perf script -i /tmp/dlfilter-test-3358542-perf-data --dlfilter /var/home/acme/libexec/perf-core/dlfilters/dlfilter-test-api-v0.so --dlarg first --dlarg 1 --dlarg 4198669 --dlarg 4198662 --dlarg 0 --dlarg last > Failed with return value 139 > test child finished with -1 > ---- end ---- > dlfilter C API: FAILED! > [root@five ~]# cat /etc/redhat-release > Fedora release 34 (Thirty Four) > [root@five ~]# cat /etc/os-release > NAME=Fedora > VERSION="34.20210721.0 (Silverblue)" > ID=fedora > VERSION_ID=34 > VERSION_CODENAME="" > PLATFORM_ID="platform:f34" > PRETTY_NAME="Fedora 34.20210721.0 (Silverblue)" > ANSI_COLOR="0;38;2;60;110;180" > LOGO=fedora-logo-icon > CPE_NAME="cpe:/o:fedoraproject:fedora:34" > HOME_URL="https://fedoraproject.org/" > DOCUMENTATION_URL="https://docs.fedoraproject.org/en-US/fedora-silverblue/" > SUPPORT_URL="https://fedoraproject.org/wiki/Communicating_and_getting_help" > BUG_REPORT_URL="https://bugzilla.redhat.com/" > REDHAT_BUGZILLA_PRODUCT="Fedora" > REDHAT_BUGZILLA_PRODUCT_VERSION=34 > REDHAT_SUPPORT_PRODUCT="Fedora" > REDHAT_SUPPORT_PRODUCT_VERSION=34 > PRIVACY_POLICY_URL="https://fedoraproject.org/wiki/Legal:PrivacyPolicy" > VARIANT="Silverblue" > VARIANT_ID=silverblue > OSTREE_VERSION='34.20210721.0' > [root@five ~]# > > Trying to figure this out... What does it give with two 'v''s ? i.e. perf test -vv dlfilter ^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [PATCH 5/5] perf tools: Add dlfilter test 2021-08-10 19:06 ` Adrian Hunter @ 2021-08-10 20:21 ` Arnaldo Carvalho de Melo 2021-08-11 10:10 ` Adrian Hunter 0 siblings, 1 reply; 13+ messages in thread From: Arnaldo Carvalho de Melo @ 2021-08-10 20:21 UTC (permalink / raw) To: Adrian Hunter; +Cc: Jiri Olsa, linux-kernel Em Tue, Aug 10, 2021 at 10:06:13PM +0300, Adrian Hunter escreveu: > On 10/08/21 9:32 pm, Arnaldo Carvalho de Melo wrote: > > Em Tue, Aug 10, 2021 at 02:48:13PM +0300, Adrian Hunter escreveu: > >> Add a perf test to test the dlfilter C API. > >> > >> A perf.data file is synthesized and then processed by perf script with a > >> dlfilter named dlfilter-test-api-v0.so. Also a C file is compiled to > >> provide a dso to match the synthesized perf.data file. > > > > [root@five ~]# perf test dlfilter > > 72: dlfilter C API : FAILED! > > [root@five ~]# perf test -v dlfilter > > 72: dlfilter C API : > > --- start --- > > test child forked, pid 3358542 > > Checking for gcc > > Command: gcc --version > > gcc (GCC) 11.1.1 20210531 (Red Hat 11.1.1-3) > > Copyright (C) 2021 Free Software Foundation, Inc. > > This is free software; see the source for copying conditions. There is NO > > warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. > > > > dlfilters path: /var/home/acme/libexec/perf-core/dlfilters > > Command: gcc -g -o /tmp/dlfilter-test-3358542-prog /tmp/dlfilter-test-3358542-prog.c > > Creating new host machine structure > > Command: /var/home/acme/bin/perf script -i /tmp/dlfilter-test-3358542-perf-data --dlfilter /var/home/acme/libexec/perf-core/dlfilters/dlfilter-test-api-v0.so --dlarg first --dlarg 1 --dlarg 4198669 --dlarg 4198662 --dlarg 0 --dlarg last > > Failed with return value 139 > > test child finished with -1 > > ---- end ---- > > dlfilter C API: FAILED! > > [root@five ~]# cat /etc/redhat-release > > Fedora release 34 (Thirty Four) > > [root@five ~]# cat /etc/os-release > > NAME=Fedora > > VERSION="34.20210721.0 (Silverblue)" > > ID=fedora > > VERSION_ID=34 > > VERSION_CODENAME="" > > PLATFORM_ID="platform:f34" > > PRETTY_NAME="Fedora 34.20210721.0 (Silverblue)" > > ANSI_COLOR="0;38;2;60;110;180" > > LOGO=fedora-logo-icon > > CPE_NAME="cpe:/o:fedoraproject:fedora:34" > > HOME_URL="https://fedoraproject.org/" > > DOCUMENTATION_URL="https://docs.fedoraproject.org/en-US/fedora-silverblue/" > > SUPPORT_URL="https://fedoraproject.org/wiki/Communicating_and_getting_help" > > BUG_REPORT_URL="https://bugzilla.redhat.com/" > > REDHAT_BUGZILLA_PRODUCT="Fedora" > > REDHAT_BUGZILLA_PRODUCT_VERSION=34 > > REDHAT_SUPPORT_PRODUCT="Fedora" > > REDHAT_SUPPORT_PRODUCT_VERSION=34 > > PRIVACY_POLICY_URL="https://fedoraproject.org/wiki/Legal:PrivacyPolicy" > > VARIANT="Silverblue" > > VARIANT_ID=silverblue > > OSTREE_VERSION='34.20210721.0' > > [root@five ~]# > > > > Trying to figure this out... > > What does it give with two 'v''s ? > i.e. > > perf test -vv dlfilter What I've tried so far: [root@five ~]# perf probe -x /var/home/acme/libexec/perf-core/dlfilters/dlfilter-test-api-v0.so -F called.0 called.5 check_addr_al check_al check_attr check_sample completed.0 deregister_tm_clones do_checks filt_dat filter_description filter_description filter_event filter_event filter_event_early filter_event_early frame_dummy perf_dlfilter_fns perf_dlfilter_fns register_tm_clones start start stop stop test_fail verbose [root@five ~]# perf probe -l probe_dlfilter:check_addr_al (on check_addr_al in /var/home/acme/libexec/perf-core/dlfilters/dlfilter-test-api-v0.so) probe_dlfilter:check_al (on check_al in /var/home/acme/libexec/perf-core/dlfilters/dlfilter-test-api-v0.so) probe_dlfilter:check_attr (on check_attr in /var/home/acme/libexec/perf-core/dlfilters/dlfilter-test-api-v0.so) probe_dlfilter:check_sample (on check_sample in /var/home/acme/libexec/perf-core/dlfilters/dlfilter-test-api-v0.so) probe_dlfilter:filter_description (on filter_description in /var/home/acme/libexec/perf-core/dlfilters/dlfilter-test-api-v0.so) probe_dlfilter:filter_event (on filter_event in /var/home/acme/libexec/perf-core/dlfilters/dlfilter-test-api-v0.so) probe_dlfilter:filter_event_early (on filter_event_early in /var/home/acme/libexec/perf-core/dlfilters/dlfilter-test-api-v0.so) probe_dlfilter:start (on start in /var/home/acme/libexec/perf-core/dlfilters/dlfilter-test-api-v0.so) probe_dlfilter:stop (on stop in /var/home/acme/libexec/perf-core/dlfilters/dlfilter-test-api-v0.so) probe_dlfilter:test_fail (on test_fail in /var/home/acme/libexec/perf-core/dlfilters/dlfilter-test-api-v0.so) [root@five ~]# perf trace -e probe_dlfilter:*/max-stack=10/ perf test -v dlfilter 72: dlfilter C API : --- start --- test child forked, pid 3360902 Checking for gcc Command: gcc --version gcc (GCC) 11.1.1 20210531 (Red Hat 11.1.1-3) Copyright (C) 2021 Free Software Foundation, Inc. This is free software; see the source for copying conditions. There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. dlfilters path: /var/home/acme/libexec/perf-core/dlfilters Command: gcc -g -o /tmp/dlfilter-test-3360902-prog /tmp/dlfilter-test-3360902-prog.c 0.000 perf/3360902 probe_dlfilter:filter_description(__probe_ip: 140448631966717) filter_description (/var/home/acme/libexec/perf-core/dlfilters/dlfilter-test-api-v0.so) test__dlfilter (/var/home/acme/bin/perf) test_and_print (/var/home/acme/bin/perf) cmd_test (/var/home/acme/bin/perf) run_builtin (/var/home/acme/bin/perf) main (/var/home/acme/bin/perf) __libc_start_main (/usr/lib64/libc-2.33.so) Creating new host machine structure Command: /var/home/acme/bin/perf script -i /tmp/dlfilter-test-3360902-perf-data --dlfilter /var/home/acme/libexec/perf-core/dlfilters/dlfilter-test-api-v0.so --dlarg first --dlarg 1 --dlarg 4198669 --dlarg 4198662 --dlarg 0 --dlarg last Failed with return value 139 test child finished with -1 ---- end ---- dlfilter C API: FAILED! [root@five ~]# perf trace -e probe_dlfilter:*/max-stack=10/ perf test -vv dlfilter 72: dlfilter C API : --- start --- test child forked, pid 3360986 Checking for gcc Command: gcc --version 0.000 :3360986/3360986 probe_dlfilter:filter_description(__probe_ip: 140709239057405) filter_description (/var/home/acme/libexec/perf-core/dlfilters/dlfilter-test-api-v0.so) [0] ([unknown]) [0] ([unknown]) [0] ([unknown]) [0] ([unknown]) [0] ([unknown]) [0] ([unknown]) gcc (GCC) 11.1.1 20210531 (Red Hat 11.1.1-3) Copyright (C) 2021 Free Software Foundation, Inc. This is free software; see the source for copying conditions. There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. dlfilters path: /var/home/acme/libexec/perf-core/dlfilters Command: cat /tmp/dlfilter-test-3360986-prog.c ; echo int bar(){};int foo(){bar();};int main(){foo();return 0;} Command: gcc -g -o /tmp/dlfilter-test-3360986-prog /tmp/dlfilter-test-3360986-prog.c Creating new host machine structure Command: /var/home/acme/bin/perf script -i /tmp/dlfilter-test-3360986-perf-data -D 0 [0x90]: event: 64 . . ... raw event: size 144 bytes . 0000: 40 00 00 00 00 00 90 00 00 00 00 00 80 00 00 00 @............... . 0010: 04 00 00 00 00 00 00 00 01 00 00 00 00 00 00 00 ................ . 0020: 8f 03 01 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ . 0030: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ . 0040: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ . 0050: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ . 0060: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ . 0070: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ . 0080: 00 00 00 00 00 00 00 00 63 00 00 00 00 00 00 00 ........c....... -1 -1 0 [0x90]: PERF_RECORD_ATTR 0x90 [0x20]: event: 3 . . ... raw event: size 32 bytes . 0000: 03 00 00 00 02 00 20 00 39 30 00 00 3a 30 00 00 ...... .90..:0.. . 0010: 74 65 73 74 2d 70 72 6f 67 00 00 00 00 00 00 00 test-prog....... -1 -1 0x90 [0x20]: PERF_RECORD_COMM: test-prog:12345/12346 0xb0 [0x48]: event: 1 . . ... raw event: size 72 bytes . 0000: 01 00 00 00 02 00 48 00 39 30 00 00 3a 30 00 00 ......H.90..:0.. . 0010: 00 00 40 00 00 00 00 00 00 00 01 00 00 00 00 00 ..@............. . 0020: 00 00 00 00 00 00 00 00 2f 74 6d 70 2f 64 6c 66 ......../tmp/dlf . 0030: 69 6c 74 65 72 2d 74 65 73 74 2d 33 33 36 30 39 ilter-test-33609 . 0040: 38 36 2d 70 72 6f 67 00 86-prog. -1 -1 0xb0 [0x48]: PERF_RECORD_MMAP 12345/12346: [0x400000(0x10000) @ 0]: x /tmp/dlfilter-test-3360986-prog 0xf8 [0x48]: event: 9 . . ... raw event: size 72 bytes . 0000: 09 00 00 00 02 00 48 00 63 00 00 00 00 00 00 00 ......H.c....... . 0010: 0d 11 40 00 00 00 00 00 39 30 00 00 3a 30 00 00 ..@.....90..:0.. . 0020: d2 02 96 49 00 00 00 00 06 11 40 00 00 00 00 00 <D2>..I......@..... . 0030: 65 00 00 00 00 00 00 00 1f 00 00 00 00 00 00 00 e............... . 0040: 39 c3 60 20 00 00 00 00 9<C3>` .... 31 1234567890 0xf8 [0x48]: PERF_RECORD_SAMPLE(IP, 0x2): 12345/12346: 0x40110d period: 543212345 addr: 0x401106 ... thread: test-prog:12346 ...... dso: /tmp/dlfilter-test-3360986-prog test-prog 12346 [031] 1.234567: 543212345 branches:HG: 40110d foo+0x0 (/tmp/dlfilter-test-3360986-prog) => 401106 bar+0x0 (/tmp/dlfilter-test-3360986-prog) Command: /var/home/acme/bin/perf script -i /tmp/dlfilter-test-3360986-perf-data --dlfilter /var/home/acme/libexec/perf-core/dlfilters/dlfilter-test-api-v0.so --dlarg first --dlarg 2 --dlarg 4198669 --dlarg 4198662 --dlarg 0 --dlarg last Failed with return value 139 test child finished with -1 ---- end ---- dlfilter C API: FAILED! [root@five ~]# fg -bash: fg: current: no such job [root@five ~]# ls -la /tmp/dlfilter-test-3360986-perf-data ls: cannot access '/tmp/dlfilter-test-3360986-perf-data': No such file or directory [root@five ~]# ls -la /var/home/acme/libexec/perf-core/dlfilters/dlfilter-test-api-v0.so -rwxr-xr-x. 2 acme acme 17352 Aug 10 15:31 /var/home/acme/libexec/perf-core/dlfilters/dlfilter-test-api-v0.so [root@five ~]# perf trace -e probe_dlfilter:*/max-stack=10/ perf test -vvv dlfilter 72: dlfilter C API : --- start --- test child forked, pid 3361199 Checking for gcc Command: gcc --version gcc (GCC) 11.1.1 20210531 (Red Hat 11.1.1-3) Copyright (C) 2021 Free Software Foundation, Inc. This is free software; see the source for copying conditions. There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. dlfilters path: /var/home/acme/libexec/perf-core/dlfilters Command: cat /tmp/dlfilter-test-3361199-prog.c ; echo int bar(){};int foo(){bar();};int main(){foo();return 0;} Command: gcc -g -o /tmp/dlfilter-test-3361199-prog /tmp/dlfilter-test-3361199-prog.c 0.000 perf/3361199 probe_dlfilter:filter_description(__probe_ip: 140125348678653) filter_description (/var/home/acme/libexec/perf-core/dlfilters/dlfilter-test-api-v0.so) test__dlfilter (/var/home/acme/bin/perf) test_and_print (/var/home/acme/bin/perf) cmd_test (/var/home/acme/bin/perf) run_builtin (/var/home/acme/bin/perf) main (/var/home/acme/bin/perf) __libc_start_main (/usr/lib64/libc-2.33.so) Command: objdump -x -dS /tmp/dlfilter-test-3361199-prog /tmp/dlfilter-test-3361199-prog: file format elf64-x86-64 /tmp/dlfilter-test-3361199-prog architecture: i386:x86-64, flags 0x00000112: EXEC_P, HAS_SYMS, D_PAGED start address 0x0000000000401020 Program Header: PHDR off 0x0000000000000040 vaddr 0x0000000000400040 paddr 0x0000000000400040 align 2**3 filesz 0x00000000000002d8 memsz 0x00000000000002d8 flags r-- INTERP off 0x0000000000000318 vaddr 0x0000000000400318 paddr 0x0000000000400318 align 2**0 filesz 0x000000000000001c memsz 0x000000000000001c flags r-- LOAD off 0x0000000000000000 vaddr 0x0000000000400000 paddr 0x0000000000400000 align 2**12 filesz 0x0000000000000498 memsz 0x0000000000000498 flags r-- LOAD off 0x0000000000001000 vaddr 0x0000000000401000 paddr 0x0000000000401000 align 2**12 filesz 0x00000000000001c5 memsz 0x00000000000001c5 flags r-x LOAD off 0x0000000000002000 vaddr 0x0000000000402000 paddr 0x0000000000402000 align 2**12 filesz 0x0000000000000158 memsz 0x0000000000000158 flags r-- LOAD off 0x0000000000002e50 vaddr 0x0000000000403e50 paddr 0x0000000000403e50 align 2**12 filesz 0x00000000000001cc memsz 0x00000000000001d0 flags rw- DYNAMIC off 0x0000000000002e60 vaddr 0x0000000000403e60 paddr 0x0000000000403e60 align 2**3 filesz 0x0000000000000190 memsz 0x0000000000000190 flags rw- NOTE off 0x0000000000000338 vaddr 0x0000000000400338 paddr 0x0000000000400338 align 2**3 filesz 0x0000000000000020 memsz 0x0000000000000020 flags r-- NOTE off 0x0000000000000358 vaddr 0x0000000000400358 paddr 0x0000000000400358 align 2**2 filesz 0x0000000000000044 memsz 0x0000000000000044 flags r-- 0x6474e553 off 0x0000000000000338 vaddr 0x0000000000400338 paddr 0x0000000000400338 align 2**3 filesz 0x0000000000000020 memsz 0x0000000000000020 flags r-- EH_FRAME off 0x0000000000002010 vaddr 0x0000000000402010 paddr 0x0000000000402010 align 2**2 filesz 0x0000000000000044 memsz 0x0000000000000044 flags r-- STACK off 0x0000000000000000 vaddr 0x0000000000000000 paddr 0x0000000000000000 align 2**4 filesz 0x0000000000000000 memsz 0x0000000000000000 flags rw- RELRO off 0x0000000000002e50 vaddr 0x0000000000403e50 paddr 0x0000000000403e50 align 2**0 filesz 0x00000000000001b0 memsz 0x00000000000001b0 flags r-- Dynamic Section: NEEDED libc.so.6 INIT 0x0000000000401000 FINI 0x00000000004011b8 INIT_ARRAY 0x0000000000403e50 INIT_ARRAYSZ 0x0000000000000008 FINI_ARRAY 0x0000000000403e58 FINI_ARRAYSZ 0x0000000000000008 GNU_HASH 0x00000000004003a0 STRTAB 0x0000000000400408 SYMTAB 0x00000000004003c0 STRSZ 0x0000000000000038 SYMENT 0x0000000000000018 DEBUG 0x0000000000000000 RELA 0x0000000000400468 RELASZ 0x0000000000000030 RELAENT 0x0000000000000018 VERNEED 0x0000000000400448 VERNEEDNUM 0x0000000000000001 VERSYM 0x0000000000400440 Version References: required from libc.so.6: 0x09691a75 0x00 02 GLIBC_2.2.5 Sections: Idx Name Size VMA LMA File off Algn 0 .interp 0000001c 0000000000400318 0000000000400318 00000318 2**0 CONTENTS, ALLOC, LOAD, READONLY, DATA 1 .note.gnu.property 00000020 0000000000400338 0000000000400338 00000338 2**3 CONTENTS, ALLOC, LOAD, READONLY, DATA 2 .note.gnu.build-id 00000024 0000000000400358 0000000000400358 00000358 2**2 CONTENTS, ALLOC, LOAD, READONLY, DATA 3 .note.ABI-tag 00000020 000000000040037c 000000000040037c 0000037c 2**2 CONTENTS, ALLOC, LOAD, READONLY, DATA 4 .gnu.hash 0000001c 00000000004003a0 00000000004003a0 000003a0 2**3 CONTENTS, ALLOC, LOAD, READONLY, DATA 5 .dynsym 00000048 00000000004003c0 00000000004003c0 000003c0 2**3 CONTENTS, ALLOC, LOAD, READONLY, DATA 6 .dynstr 00000038 0000000000400408 0000000000400408 00000408 2**0 CONTENTS, ALLOC, LOAD, READONLY, DATA 7 .gnu.version 00000006 0000000000400440 0000000000400440 00000440 2**1 CONTENTS, ALLOC, LOAD, READONLY, DATA 8 .gnu.version_r 00000020 0000000000400448 0000000000400448 00000448 2**3 CONTENTS, ALLOC, LOAD, READONLY, DATA 9 .rela.dyn 00000030 0000000000400468 0000000000400468 00000468 2**3 CONTENTS, ALLOC, LOAD, READONLY, DATA 10 .init 0000001b 0000000000401000 0000000000401000 00001000 2**2 CONTENTS, ALLOC, LOAD, READONLY, CODE 11 .text 00000195 0000000000401020 0000000000401020 00001020 2**4 CONTENTS, ALLOC, LOAD, READONLY, CODE 12 .fini 0000000d 00000000004011b8 00000000004011b8 000011b8 2**2 CONTENTS, ALLOC, LOAD, READONLY, CODE 13 .rodata 00000010 0000000000402000 0000000000402000 00002000 2**3 CONTENTS, ALLOC, LOAD, READONLY, DATA 14 .eh_frame_hdr 00000044 0000000000402010 0000000000402010 00002010 2**2 CONTENTS, ALLOC, LOAD, READONLY, DATA 15 .eh_frame 00000100 0000000000402058 0000000000402058 00002058 2**3 CONTENTS, ALLOC, LOAD, READONLY, DATA 16 .init_array 00000008 0000000000403e50 0000000000403e50 00002e50 2**3 CONTENTS, ALLOC, LOAD, DATA 17 .fini_array 00000008 0000000000403e58 0000000000403e58 00002e58 2**3 CONTENTS, ALLOC, LOAD, DATA 18 .dynamic 00000190 0000000000403e60 0000000000403e60 00002e60 2**3 CONTENTS, ALLOC, LOAD, DATA 19 .got 00000010 0000000000403ff0 0000000000403ff0 00002ff0 2**3 CONTENTS, ALLOC, LOAD, DATA 20 .got.plt 00000018 0000000000404000 0000000000404000 00003000 2**3 CONTENTS, ALLOC, LOAD, DATA 21 .data 00000004 0000000000404018 0000000000404018 00003018 2**0 CONTENTS, ALLOC, LOAD, DATA 22 .bss 00000004 000000000040401c 000000000040401c 0000301c 2**0 ALLOC 23 .comment 0000002e 0000000000000000 0000000000000000 0000301c 2**0 CONTENTS, READONLY 24 .gnu.build.attributes 00001978 0000000000406020 0000000000406020 0000304c 2**2 CONTENTS, READONLY, OCTETS 25 .debug_aranges 00000030 0000000000000000 0000000000000000 000049c4 2**0 CONTENTS, READONLY, DEBUGGING, OCTETS 26 .debug_info 00000090 0000000000000000 0000000000000000 000049f4 2**0 CONTENTS, READONLY, DEBUGGING, OCTETS 27 .debug_abbrev 0000006a 0000000000000000 0000000000000000 00004a84 2**0 CONTENTS, READONLY, DEBUGGING, OCTETS 28 .debug_line 00000065 0000000000000000 0000000000000000 00004aee 2**0 CONTENTS, READONLY, DEBUGGING, OCTETS 29 .debug_str 00000050 0000000000000000 0000000000000000 00004b53 2**0 CONTENTS, READONLY, DEBUGGING, OCTETS 30 .debug_line_str 0000002d 0000000000000000 0000000000000000 00004ba3 2**0 CONTENTS, READONLY, DEBUGGING, OCTETS SYMBOL TABLE: 0000000000400318 l d .interp 0000000000000000 .interp 0000000000400338 l d .note.gnu.property 0000000000000000 .note.gnu.property 0000000000400358 l d .note.gnu.build-id 0000000000000000 .note.gnu.build-id 000000000040037c l d .note.ABI-tag 0000000000000000 .note.ABI-tag 00000000004003a0 l d .gnu.hash 0000000000000000 .gnu.hash 00000000004003c0 l d .dynsym 0000000000000000 .dynsym 0000000000400408 l d .dynstr 0000000000000000 .dynstr 0000000000400440 l d .gnu.version 0000000000000000 .gnu.version 0000000000400448 l d .gnu.version_r 0000000000000000 .gnu.version_r 0000000000400468 l d .rela.dyn 0000000000000000 .rela.dyn 0000000000401000 l d .init 0000000000000000 .init 0000000000401020 l d .text 0000000000000000 .text 00000000004011b8 l d .fini 0000000000000000 .fini 0000000000402000 l d .rodata 0000000000000000 .rodata 0000000000402010 l d .eh_frame_hdr 0000000000000000 .eh_frame_hdr 0000000000402058 l d .eh_frame 0000000000000000 .eh_frame 0000000000403e50 l d .init_array 0000000000000000 .init_array 0000000000403e58 l d .fini_array 0000000000000000 .fini_array 0000000000403e60 l d .dynamic 0000000000000000 .dynamic 0000000000403ff0 l d .got 0000000000000000 .got 0000000000404000 l d .got.plt 0000000000000000 .got.plt 0000000000404018 l d .data 0000000000000000 .data 000000000040401c l d .bss 0000000000000000 .bss 0000000000000000 l d .comment 0000000000000000 .comment 0000000000406020 l d .gnu.build.attributes 0000000000000000 .gnu.build.attributes 0000000000000000 l d .debug_aranges 0000000000000000 .debug_aranges 0000000000000000 l d .debug_info 0000000000000000 .debug_info 0000000000000000 l d .debug_abbrev 0000000000000000 .debug_abbrev 0000000000000000 l d .debug_line 0000000000000000 .debug_line 0000000000000000 l d .debug_str 0000000000000000 .debug_str 0000000000000000 l d .debug_line_str 0000000000000000 .debug_line_str 0000000000000000 l df *ABS* 0000000000000000 /usr/lib/gcc/x86_64-redhat-linux/11/../../../../lib64/crt1.o 000000000040104f l .text 0000000000000000 .hidden .annobin_lto 000000000040104f l .text 0000000000000000 .hidden .annobin_lto_end 0000000000401020 l .text 0000000000000000 .hidden .annobin_lto.hot 0000000000401020 l .text 0000000000000000 .hidden .annobin_lto_end.hot 0000000000401020 l .text 0000000000000000 .hidden .annobin_lto.unlikely 0000000000401020 l .text 0000000000000000 .hidden .annobin_lto_end.unlikely 0000000000401020 l .text 0000000000000000 .hidden .annobin_lto.startup 0000000000401020 l .text 0000000000000000 .hidden .annobin_lto_end.startup 0000000000401020 l .text 0000000000000000 .hidden .annobin_lto.exit 0000000000401020 l .text 0000000000000000 .hidden .annobin_lto_end.exit 000000000040037c l O .note.ABI-tag 0000000000000020 __abi_tag 000000000040104f l .text 0000000000000000 .hidden .annobin_lto 000000000040104f l .text 0000000000000000 .hidden .annobin_lto_end 0000000000401020 l .text 0000000000000000 .hidden .annobin_lto.hot 0000000000401020 l .text 0000000000000000 .hidden .annobin_lto_end.hot 0000000000401020 l .text 0000000000000000 .hidden .annobin_lto.unlikely 0000000000401020 l .text 0000000000000000 .hidden .annobin_lto_end.unlikely 0000000000401020 l .text 0000000000000000 .hidden .annobin_lto.startup 0000000000401020 l .text 0000000000000000 .hidden .annobin_lto_end.startup 0000000000401020 l .text 0000000000000000 .hidden .annobin_lto.exit 0000000000401020 l .text 0000000000000000 .hidden .annobin_lto_end.exit 0000000000401050 l .text 0000000000000000 .hidden .annobin_lto 0000000000401055 l .text 0000000000000000 .hidden .annobin_lto_end 0000000000401020 l .text 0000000000000000 .hidden .annobin_lto.hot 0000000000401020 l .text 0000000000000000 .hidden .annobin_lto_end.hot 0000000000401020 l .text 0000000000000000 .hidden .annobin_lto.unlikely 0000000000401020 l .text 0000000000000000 .hidden .annobin_lto_end.unlikely 0000000000401020 l .text 0000000000000000 .hidden .annobin_lto.startup 0000000000401020 l .text 0000000000000000 .hidden .annobin_lto_end.startup 0000000000401020 l .text 0000000000000000 .hidden .annobin_lto.exit 0000000000401020 l .text 0000000000000000 .hidden .annobin_lto_end.exit 0000000000401050 l .text 0000000000000000 .hidden .annobin__dl_relocate_static_pie.start 0000000000401055 l .text 0000000000000000 .hidden .annobin__dl_relocate_static_pie.end 0000000000000000 l df *ABS* 0000000000000000 crtstuff.c 0000000000401060 l F .text 0000000000000000 deregister_tm_clones 0000000000401090 l F .text 0000000000000000 register_tm_clones 00000000004010d0 l F .text 0000000000000000 __do_global_dtors_aux 000000000040401c l O .bss 0000000000000001 completed.0 0000000000403e58 l O .fini_array 0000000000000000 __do_global_dtors_aux_fini_array_entry 0000000000401100 l F .text 0000000000000000 frame_dummy 0000000000403e50 l O .init_array 0000000000000000 __frame_dummy_init_array_entry 0000000000000000 l df *ABS* 0000000000000000 dlfilter-test-3361199-prog.c 0000000000000000 l df *ABS* 0000000000000000 crtstuff.c 0000000000402154 l O .eh_frame 0000000000000000 __FRAME_END__ 0000000000000000 l df *ABS* 0000000000000000 0000000000403e58 l .init_array 0000000000000000 __init_array_end 0000000000403e60 l O .dynamic 0000000000000000 _DYNAMIC 0000000000403e50 l .init_array 0000000000000000 __init_array_start 0000000000402010 l .eh_frame_hdr 0000000000000000 __GNU_EH_FRAME_HDR 0000000000404000 l O .got.plt 0000000000000000 _GLOBAL_OFFSET_TABLE_ 00000000004011b0 g F .text 0000000000000005 __libc_csu_fini 0000000000404018 w .data 0000000000000000 data_start 000000000040401c g .data 0000000000000000 _edata 0000000000401106 g F .text 0000000000000007 bar 00000000004011b8 g F .fini 0000000000000000 .hidden _fini 0000000000000000 F *UND* 0000000000000000 __libc_start_main@@GLIBC_2.2.5 0000000000404018 g .data 0000000000000000 __data_start 0000000000000000 w *UND* 0000000000000000 __gmon_start__ 0000000000402008 g O .rodata 0000000000000000 .hidden __dso_handle 0000000000402000 g O .rodata 0000000000000004 _IO_stdin_used 0000000000401140 g F .text 0000000000000065 __libc_csu_init 000000000040110d g F .text 0000000000000011 foo 0000000000404020 g .bss 0000000000000000 _end 0000000000401050 g F .text 0000000000000005 .hidden _dl_relocate_static_pie 0000000000401020 g F .text 000000000000002f _start 000000000040401c g .bss 0000000000000000 __bss_start 000000000040111e g F .text 0000000000000015 main 0000000000404020 g O .data 0000000000000000 .hidden __TMC_END__ 0000000000401000 g F .init 0000000000000000 .hidden _init Disassembly of section .init: 0000000000401000 <_init>: 401000: f3 0f 1e fa endbr64 401004: 48 83 ec 08 sub $0x8,%rsp 401008: 48 8b 05 e9 2f 00 00 mov 0x2fe9(%rip),%rax # 403ff8 <__gmon_start__> 40100f: 48 85 c0 test %rax,%rax 401012: 74 02 je 401016 <_init+0x16> 401014: ff d0 callq *%rax 401016: 48 83 c4 08 add $0x8,%rsp 40101a: c3 retq Disassembly of section .text: 0000000000401020 <_start>: 401020: f3 0f 1e fa endbr64 401024: 31 ed xor %ebp,%ebp 401026: 49 89 d1 mov %rdx,%r9 401029: 5e pop %rsi 40102a: 48 89 e2 mov %rsp,%rdx 40102d: 48 83 e4 f0 and $0xfffffffffffffff0,%rsp 401031: 50 push %rax 401032: 54 push %rsp 401033: 49 c7 c0 b0 11 40 00 mov $0x4011b0,%r8 40103a: 48 c7 c1 40 11 40 00 mov $0x401140,%rcx 401041: 48 c7 c7 1e 11 40 00 mov $0x40111e,%rdi 401048: ff 15 a2 2f 00 00 callq *0x2fa2(%rip) # 403ff0 <__libc_start_main@GLIBC_2.2.5> 40104e: f4 hlt 000000000040104f <.annobin_lto>: 40104f: 90 nop 0000000000401050 <_dl_relocate_static_pie>: 401050: f3 0f 1e fa endbr64 401054: c3 retq 0000000000401055 <.annobin__dl_relocate_static_pie.end>: 401055: 66 2e 0f 1f 84 00 00 nopw %cs:0x0(%rax,%rax,1) 40105c: 00 00 00 40105f: 90 nop 0000000000401060 <deregister_tm_clones>: 401060: b8 20 40 40 00 mov $0x404020,%eax 401065: 48 3d 20 40 40 00 cmp $0x404020,%rax 40106b: 74 13 je 401080 <deregister_tm_clones+0x20> 40106d: b8 00 00 00 00 mov $0x0,%eax 401072: 48 85 c0 test %rax,%rax 401075: 74 09 je 401080 <deregister_tm_clones+0x20> 401077: bf 20 40 40 00 mov $0x404020,%edi 40107c: ff e0 jmpq *%rax 40107e: 66 90 xchg %ax,%ax 401080: c3 retq 401081: 66 66 2e 0f 1f 84 00 data16 nopw %cs:0x0(%rax,%rax,1) 401088: 00 00 00 00 40108c: 0f 1f 40 00 nopl 0x0(%rax) 0000000000401090 <register_tm_clones>: 401090: be 20 40 40 00 mov $0x404020,%esi 401095: 48 81 ee 20 40 40 00 sub $0x404020,%rsi 40109c: 48 89 f0 mov %rsi,%rax 40109f: 48 c1 ee 3f shr $0x3f,%rsi 4010a3: 48 c1 f8 03 sar $0x3,%rax 4010a7: 48 01 c6 add %rax,%rsi 4010aa: 48 d1 fe sar %rsi 4010ad: 74 11 je 4010c0 <register_tm_clones+0x30> 4010af: b8 00 00 00 00 mov $0x0,%eax 4010b4: 48 85 c0 test %rax,%rax 4010b7: 74 07 je 4010c0 <register_tm_clones+0x30> 4010b9: bf 20 40 40 00 mov $0x404020,%edi 4010be: ff e0 jmpq *%rax 4010c0: c3 retq 4010c1: 66 66 2e 0f 1f 84 00 data16 nopw %cs:0x0(%rax,%rax,1) 4010c8: 00 00 00 00 4010cc: 0f 1f 40 00 nopl 0x0(%rax) 00000000004010d0 <__do_global_dtors_aux>: 4010d0: f3 0f 1e fa endbr64 4010d4: 80 3d 41 2f 00 00 00 cmpb $0x0,0x2f41(%rip) # 40401c <completed.0> 4010db: 75 13 jne 4010f0 <__do_global_dtors_aux+0x20> 4010dd: 55 push %rbp 4010de: 48 89 e5 mov %rsp,%rbp 4010e1: e8 7a ff ff ff callq 401060 <deregister_tm_clones> 4010e6: c6 05 2f 2f 00 00 01 movb $0x1,0x2f2f(%rip) # 40401c <completed.0> 4010ed: 5d pop %rbp 4010ee: c3 retq 4010ef: 90 nop 4010f0: c3 retq 4010f1: 66 66 2e 0f 1f 84 00 data16 nopw %cs:0x0(%rax,%rax,1) 4010f8: 00 00 00 00 4010fc: 0f 1f 40 00 nopl 0x0(%rax) 0000000000401100 <frame_dummy>: 401100: f3 0f 1e fa endbr64 401104: eb 8a jmp 401090 <register_tm_clones> 0000000000401106 <bar>: 401106: 55 push %rbp 401107: 48 89 e5 mov %rsp,%rbp 40110a: 90 nop 40110b: 5d pop %rbp 40110c: c3 retq 000000000040110d <foo>: 40110d: 55 push %rbp 40110e: 48 89 e5 mov %rsp,%rbp 401111: b8 00 00 00 00 mov $0x0,%eax 401116: e8 eb ff ff ff callq 401106 <bar> 40111b: 90 nop 40111c: 5d pop %rbp 40111d: c3 retq 000000000040111e <main>: 40111e: 55 push %rbp 40111f: 48 89 e5 mov %rsp,%rbp 401122: b8 00 00 00 00 mov $0x0,%eax 401127: e8 e1 ff ff ff callq 40110d <foo> 40112c: b8 00 00 00 00 mov $0x0,%eax 401131: 5d pop %rbp 401132: c3 retq 401133: 66 2e 0f 1f 84 00 00 nopw %cs:0x0(%rax,%rax,1) 40113a: 00 00 00 40113d: 0f 1f 00 nopl (%rax) 0000000000401140 <__libc_csu_init>: 401140: f3 0f 1e fa endbr64 401144: 41 57 push %r15 401146: 4c 8d 3d 03 2d 00 00 lea 0x2d03(%rip),%r15 # 403e50 <__frame_dummy_init_array_entry> 40114d: 41 56 push %r14 40114f: 49 89 d6 mov %rdx,%r14 401152: 41 55 push %r13 401154: 49 89 f5 mov %rsi,%r13 401157: 41 54 push %r12 401159: 41 89 fc mov %edi,%r12d 40115c: 55 push %rbp 40115d: 48 8d 2d f4 2c 00 00 lea 0x2cf4(%rip),%rbp # 403e58 <__do_global_dtors_aux_fini_array_entry> 401164: 53 push %rbx 401165: 4c 29 fd sub %r15,%rbp 401168: 48 83 ec 08 sub $0x8,%rsp 40116c: e8 8f fe ff ff callq 401000 <_init> 401171: 48 c1 fd 03 sar $0x3,%rbp 401175: 74 1f je 401196 <__libc_csu_init+0x56> 401177: 31 db xor %ebx,%ebx 401179: 0f 1f 80 00 00 00 00 nopl 0x0(%rax) 401180: 4c 89 f2 mov %r14,%rdx 401183: 4c 89 ee mov %r13,%rsi 401186: 44 89 e7 mov %r12d,%edi 401189: 41 ff 14 df callq *(%r15,%rbx,8) 40118d: 48 83 c3 01 add $0x1,%rbx 401191: 48 39 dd cmp %rbx,%rbp 401194: 75 ea jne 401180 <__libc_csu_init+0x40> 401196: 48 83 c4 08 add $0x8,%rsp 40119a: 5b pop %rbx 40119b: 5d pop %rbp 40119c: 41 5c pop %r12 40119e: 41 5d pop %r13 4011a0: 41 5e pop %r14 4011a2: 41 5f pop %r15 4011a4: c3 retq 4011a5: 66 66 2e 0f 1f 84 00 data16 nopw %cs:0x0(%rax,%rax,1) 4011ac: 00 00 00 00 00000000004011b0 <__libc_csu_fini>: 4011b0: f3 0f 1e fa endbr64 4011b4: c3 retq Disassembly of section .fini: 00000000004011b8 <_fini>: 4011b8: f3 0f 1e fa endbr64 4011bc: 48 83 ec 08 sub $0x8,%rsp 4011c0: 48 83 c4 08 add $0x8,%rsp 4011c4: c3 retq Creating new host machine structure Command: /var/home/acme/bin/perf script -i /tmp/dlfilter-test-3361199-perf-data -D 0 [0x90]: event: 64 . . ... raw event: size 144 bytes . 0000: 40 00 00 00 00 00 90 00 00 00 00 00 80 00 00 00 @............... . 0010: 04 00 00 00 00 00 00 00 01 00 00 00 00 00 00 00 ................ . 0020: 8f 03 01 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ . 0030: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ . 0040: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ . 0050: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ . 0060: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ . 0070: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ . 0080: 00 00 00 00 00 00 00 00 63 00 00 00 00 00 00 00 ........c....... -1 -1 0 [0x90]: PERF_RECORD_ATTR 0x90 [0x20]: event: 3 . . ... raw event: size 32 bytes . 0000: 03 00 00 00 02 00 20 00 39 30 00 00 3a 30 00 00 ...... .90..:0.. . 0010: 74 65 73 74 2d 70 72 6f 67 00 00 00 00 00 00 00 test-prog....... -1 -1 0x90 [0x20]: PERF_RECORD_COMM: test-prog:12345/12346 0xb0 [0x48]: event: 1 . . ... raw event: size 72 bytes . 0000: 01 00 00 00 02 00 48 00 39 30 00 00 3a 30 00 00 ......H.90..:0.. . 0010: 00 00 40 00 00 00 00 00 00 00 01 00 00 00 00 00 ..@............. . 0020: 00 00 00 00 00 00 00 00 2f 74 6d 70 2f 64 6c 66 ......../tmp/dlf . 0030: 69 6c 74 65 72 2d 74 65 73 74 2d 33 33 36 31 31 ilter-test-33611 . 0040: 39 39 2d 70 72 6f 67 00 99-prog. -1 -1 0xb0 [0x48]: PERF_RECORD_MMAP 12345/12346: [0x400000(0x10000) @ 0]: x /tmp/dlfilter-test-3361199-prog 0xf8 [0x48]: event: 9 . . ... raw event: size 72 bytes . 0000: 09 00 00 00 02 00 48 00 63 00 00 00 00 00 00 00 ......H.c....... . 0010: 0d 11 40 00 00 00 00 00 39 30 00 00 3a 30 00 00 ..@.....90..:0.. . 0020: d2 02 96 49 00 00 00 00 06 11 40 00 00 00 00 00 <D2>..I......@..... . 0030: 65 00 00 00 00 00 00 00 1f 00 00 00 00 00 00 00 e............... . 0040: 39 c3 60 20 00 00 00 00 9<C3>` .... 31 1234567890 0xf8 [0x48]: PERF_RECORD_SAMPLE(IP, 0x2): 12345/12346: 0x40110d period: 543212345 addr: 0x401106 ... thread: test-prog:12346 ...... dso: /tmp/dlfilter-test-3361199-prog test-prog 12346 [031] 1.234567: 543212345 branches:HG: 40110d foo+0x0 (/tmp/dlfilter-test-3361199-prog) => 401106 bar+0x0 (/tmp/dlfilter-test-3361199-prog) Command: /var/home/acme/bin/perf script -i /tmp/dlfilter-test-3361199-perf-data --dlfilter /var/home/acme/libexec/perf-core/dlfilters/dlfilter-test-api-v0.so --dlarg first --dlarg 3 --dlarg 4198669 --dlarg 4198662 --dlarg 0 --dlarg last Failed with return value 139 test child finished with -1 ---- end ---- dlfilter C API: FAILED! [root@five ~]# ^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [PATCH 5/5] perf tools: Add dlfilter test 2021-08-10 20:21 ` Arnaldo Carvalho de Melo @ 2021-08-11 10:10 ` Adrian Hunter 0 siblings, 0 replies; 13+ messages in thread From: Adrian Hunter @ 2021-08-11 10:10 UTC (permalink / raw) To: Arnaldo Carvalho de Melo; +Cc: Jiri Olsa, linux-kernel On 10/08/21 11:21 pm, Arnaldo Carvalho de Melo wrote: > Em Tue, Aug 10, 2021 at 10:06:13PM +0300, Adrian Hunter escreveu: >> On 10/08/21 9:32 pm, Arnaldo Carvalho de Melo wrote: >>> Em Tue, Aug 10, 2021 at 02:48:13PM +0300, Adrian Hunter escreveu: >>>> Add a perf test to test the dlfilter C API. >>>> >>>> A perf.data file is synthesized and then processed by perf script with a >>>> dlfilter named dlfilter-test-api-v0.so. Also a C file is compiled to >>>> provide a dso to match the synthesized perf.data file. >>> >>> [root@five ~]# perf test dlfilter >>> 72: dlfilter C API : FAILED! Should be fixed in V2 ^ permalink raw reply [flat|nested] 13+ messages in thread
end of thread, other threads:[~2021-08-11 10:18 UTC | newest] Thread overview: 13+ messages (download: mbox.gz / follow: Atom feed) -- links below jump to the message on this page -- 2021-08-10 11:48 [PATCH 0/5] perf tools: Add dlfilter test Adrian Hunter 2021-08-10 11:48 ` [PATCH 1/5] perf script: Fix unnecessary machine_resolve() Adrian Hunter 2021-08-10 18:25 ` Arnaldo Carvalho de Melo 2021-08-11 10:18 ` Adrian Hunter 2021-08-10 11:48 ` [PATCH 2/5] perf script: Fix --list-dlfilters documentation Adrian Hunter 2021-08-10 18:28 ` Arnaldo Carvalho de Melo 2021-08-10 11:48 ` [PATCH 3/5] perf tools: Amend dlfilter documentation wrt library dependencies Adrian Hunter 2021-08-10 11:48 ` [PATCH 4/5] perf tools: Move perf_dlfilters.h in the source tree Adrian Hunter 2021-08-10 11:48 ` [PATCH 5/5] perf tools: Add dlfilter test Adrian Hunter 2021-08-10 18:32 ` Arnaldo Carvalho de Melo 2021-08-10 19:06 ` Adrian Hunter 2021-08-10 20:21 ` Arnaldo Carvalho de Melo 2021-08-11 10:10 ` Adrian Hunter
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox; as well as URLs for NNTP newsgroup(s).