Re: [PATCH 2/3 v2] perf trace: Introduce errno_to_name()

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Hi Arnaldo,

On Thu, Dec 07, 2017 at 02:52:56PM -0300, Arnaldo Carvalho de Melo wrote:
> Em Thu, Dec 07, 2017 at 04:00:10PM +0100, Hendrik Brueckner escreveu:
> > Introduce an errno_to_name() function to return the name of a
> > give errno number as string.
> 
> Humm, we cannot use asm-generic for all, as there are differences in the
> errno numbers from arch to arch, for instance:
> 
> In arch/alpha/include/uapi/asm/errno.h we use errno-base.h but even in
> that part one of its entries gets a different number on the Alpha arch,
> EAGAIN:
> -------------------
> #include <asm-generic/errno-base.h>
> 
> #undef  EAGAIN                  /* 11 in errno-base.h */
> 
> #define EDEADLK         11      /* Resource deadlock would occur */
> 
> #define EAGAIN          35      /* Try again */
> #define EWOULDBLOCK     EAGAIN  /* Operation would block */
> -------------------

With that in the mind, I have changed the generation in a way similar
I did for s390 syscall table generation.  The util/generate-errno-names.sh
script can simply process the arch specific errno.h with cpp/gcc.

This approach will work fine if the arch errno.h does only include the
asm-generic/errno*.h files and does not have any differences between 32/64
bit.  Otherwise it becomes more difficult.

> So you can try to copy all arch/*/include/uapi/asm/errno.h files and
> use the arch to key that, i.e. its almost what you did, but needs to
> take the arch into consideration.

util/generate-errno-names.sh is also extended to process architectures
for which there is a resp. directory below the tools/arch/ directory.
Generation of the errno name mappings is still the same but one ALL_
define for each architecture.


> 
> Later we'll generate a two dimensional table of sorts, having the first
> dimension be the arch name, so that we can translate errnos in a
> perf.data file collected on, say, mips (one of these routers) in a tool
> running on x86_64 (or S/390 :)).

Yep... for this I need your help: How to obtain the arch string/ID whatever
in builtin-trace to use the correct errno map?

Below you can find an update on the patch (excluding the patch(es) to grab
the header files, one can do that simply with
	cp --parents -v $(find arch/ -name errno.h) tools/
in the linux source tree.)

---->8---------

Introduce an errno_to_name() function to return the name of a
give errno number as string.

With this change, the dependency to libaudit can be removed for
architectures that support syscall tables.  Hence, remove the
audit_errno_to_name() call in builtin-trace.c and just link
util/syscalltbl.c against libaudit.  A follow-up commit could
then clean-up this dependency with respect to the syscall table.

The errno name strings are generated by util/generate-errno-names.sh
script and saved as util/errno-names.h.  Errno mappings are created
for the architectures that are available in the tool/arch/ directory
in the Linux source tree.

Signed-off-by: Hendrik Brueckner <brueckner@xxxxxxxxxxxxxxxxxx>
---
 tools/perf/.gitignore                   |  1 +
 tools/perf/Makefile.config              |  2 +-
 tools/perf/Makefile.perf                |  9 ++++-
 tools/perf/builtin-trace.c              | 26 +++++++++++--
 tools/perf/util/generate-errno-names.sh | 67 +++++++++++++++++++++++++++++++++
 5 files changed, 99 insertions(+), 6 deletions(-)
 create mode 100755 tools/perf/util/generate-errno-names.sh

diff --git a/tools/perf/.gitignore b/tools/perf/.gitignore
index 643cc4ba..4e022f9 100644
--- a/tools/perf/.gitignore
+++ b/tools/perf/.gitignore
@@ -14,6 +14,7 @@ perf*.1
 perf*.xml
 perf*.html
 common-cmds.h
+errno-names.h
 perf.data
 perf.data.old
 output.svg
diff --git a/tools/perf/Makefile.config b/tools/perf/Makefile.config
index ab16aab..d8447b1 100644
--- a/tools/perf/Makefile.config
+++ b/tools/perf/Makefile.config
@@ -251,7 +251,7 @@ INC_FLAGS += -I$(srctree)/tools/arch/$(SRCARCH)/include/uapi
 INC_FLAGS += -I$(srctree)/tools/arch/$(SRCARCH)/include/
 INC_FLAGS += -I$(srctree)/tools/arch/$(SRCARCH)/
 
-# $(obj-perf)      for generated common-cmds.h
+# $(obj-perf)      for generated common-cmds.h and errno-names.h
 # $(obj-perf)/util for generated bison/flex headers
 ifneq ($(OUTPUT),)
 INC_FLAGS += -I$(obj-perf)/util
diff --git a/tools/perf/Makefile.perf b/tools/perf/Makefile.perf
index 68cf136..73a2616 100644
--- a/tools/perf/Makefile.perf
+++ b/tools/perf/Makefile.perf
@@ -518,6 +518,9 @@ $(OUTPUT)common-cmds.h: util/generate-cmdlist.sh command-list.txt
 $(OUTPUT)common-cmds.h: $(wildcard Documentation/perf-*.txt)
 	$(QUIET_GEN). util/generate-cmdlist.sh > $@+ && mv $@+ $@
 
+$(OUTPUT)util/errno-names.h: util/generate-errno-names.sh
+	$(QUIET_GEN). util/generate-errno-names.sh "$(CC)" "$(srctree)/tools" > $@+ && mv $@+ $@
+
 $(SCRIPTS) : % : %.sh
 	$(QUIET_GEN)$(INSTALL) '$@.sh' '$(OUTPUT)$@'
 
@@ -565,7 +568,8 @@ prepare: $(OUTPUT)PERF-VERSION-FILE $(OUTPUT)common-cmds.h archheaders $(drm_ioc
 	$(vhost_virtio_ioctl_array) \
 	$(madvise_behavior_array) \
 	$(perf_ioctl_array) \
-	$(prctl_option_array)
+	$(prctl_option_array) \
+	$(OUTPUT)util/errno-names.h
 
 $(OUTPUT)%.o: %.c prepare FORCE
 	$(Q)$(MAKE) -f $(srctree)/tools/build/Makefile.build dir=$(build-dir) $@
@@ -847,7 +851,8 @@ clean:: $(LIBTRACEEVENT)-clean $(LIBAPI)-clean $(LIBBPF)-clean $(LIBSUBCMD)-clea
 		$(OUTPUT)$(kcmp_type_array) \
 		$(OUTPUT)$(vhost_virtio_ioctl_array) \
 		$(OUTPUT)$(perf_ioctl_array) \
-		$(OUTPUT)$(prctl_option_array)
+		$(OUTPUT)$(prctl_option_array) \
+		$(OUTPUT)util/errno-names.h
 	$(QUIET_SUBDIR0)Documentation $(QUIET_SUBDIR1) clean
 
 #
diff --git a/tools/perf/builtin-trace.c b/tools/perf/builtin-trace.c
index 84debdb..4c7805d 100644
--- a/tools/perf/builtin-trace.c
+++ b/tools/perf/builtin-trace.c
@@ -42,17 +42,16 @@
 #include "string2.h"
 #include "syscalltbl.h"
 #include "rb_resort.h"
+#include "util/errno-names.h"
 
 #include <errno.h>
 #include <inttypes.h>
-#include <libaudit.h> /* FIXME: Still needed for audit_errno_to_name */
 #include <poll.h>
 #include <signal.h>
 #include <stdlib.h>
 #include <string.h>
 #include <linux/err.h>
 #include <linux/filter.h>
-#include <linux/audit.h>
 #include <linux/kernel.h>
 #include <linux/random.h>
 #include <linux/stringify.h>
@@ -1659,6 +1658,27 @@ static int trace__fprintf_callchain(struct trace *trace, struct perf_sample *sam
 	return sample__fprintf_callchain(sample, 38, print_opts, &callchain_cursor, trace->output);
 }
 
+static const char *__generic_errno_to_name(int err)
+{
+#define ERRNO_NAME_MAP(_err, _num) case _num: return #_err;
+#define ERRNO_NAME_MAP(_err, _num) case _num: return #_err;
+	switch (err) {
+	ALL_ERRNO_NAME_MAPPINGS__GENERIC
+#undef ERRNO_NAME_MAP
+	default:
+		return "(unknown)";
+		break;
+	}
+}
+
+static const char *errno_to_name(const int arch, int err)
+{
+	switch (arch) {
+	default:
+		return __generic_errno_to_name(err);
+	}
+}
+
 static int trace__sys_exit(struct trace *trace, struct perf_evsel *evsel,
 			   union perf_event *event __maybe_unused,
 			   struct perf_sample *sample)
@@ -1729,7 +1749,7 @@ static int trace__sys_exit(struct trace *trace, struct perf_evsel *evsel,
 errno_print: {
 		char bf[STRERR_BUFSIZE];
 		const char *emsg = str_error_r(-ret, bf, sizeof(bf)),
-			   *e = audit_errno_to_name(-ret);
+			   *e = errno_to_name(0, -ret);
 
 		fprintf(trace->output, ") = -1 %s %s", e, emsg);
 	}
diff --git a/tools/perf/util/generate-errno-names.sh b/tools/perf/util/generate-errno-names.sh
new file mode 100755
index 0000000..57f74d4
--- /dev/null
+++ b/tools/perf/util/generate-errno-names.sh
@@ -0,0 +1,67 @@
+#!/bin/sh
+# SPDX-License-Identifier: GPL-2.0
+#
+# Generate errno names header file
+#
+# Copyright IBM Corp. 2017
+# Author(s):  Hendrik Brueckner <brueckner@xxxxxxxxxxxxxxxxxx>
+
+gcc="$1"
+toolsdir="$2"
+include_path="-I$toolsdir/include/uapi"
+
+arch_string()
+{
+	echo "$1" |sed -e 'y/- /__/' |tr '[[:lower:]]' '[[:upper:]]'
+}
+
+asm_errno_file()
+{
+	local arch="$1"
+	local header
+
+	header="$toolsdir/arch/$arch/include/uapi/asm/errno.h"
+	if test -r "$header"; then
+		echo "$header"
+	else
+		echo "$toolsdir/include/uapi/asm-generic/errno.h"
+	fi
+}
+
+process_arch()
+{
+	local arch="$1"
+	local tmpfile=$(mktemp -t generate-errno-names.XXXXXXXXX)
+	local asm_errno=$(asm_errno_file "$arch")
+
+	$gcc $include_path -E -dM -x c $asm_errno \
+		|grep -hE '^#define[[:blank:]]+(E[^[:blank:]]+)[[:blank:]]+([[:digit:]]+).*' \
+		|awk '{ print $2", "$3; }' \
+		|sort -t, -k2 -nu \
+		|sed -e 's/^/\tERRNO_NAME_MAP(/' -e 's/$/)/' \
+		>  $tmpfile
+
+	printf '#define ALL_ERRNO_NAME_MAPPINGS__%s \\\n' $(arch_string "$arch")
+	head -n -1 $tmpfile |sed -e 's/$/ \\/'
+	tail -1 $tmpfile
+	printf "\n"
+	rm $tmpfile
+}
+
+cat <<EoHeader
+/* SPDX-License-Identifier: GPL-2.0 */
+#ifndef _UTIL_ERRNO_NAMES_H
+#define _UTIL_ERRNO_NAMES_H
+
+EoHeader
+
+for arch in $(find $toolsdir/arch -maxdepth 1 -mindepth 1 -type d -printf "%f\n" |sort); do
+	process_arch "$arch"
+done
+
+# Generic fallback
+process_arch "generic"
+
+cat <<EoFooter
+#endif	/* _UTIL_ERRNO_NAMES_H */
+EoFooter
-- 
1.8.3.1

--
To unsubscribe from this list: send the line "unsubscribe linux-s390" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html



[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Index of Archives]     [Kernel Development]     [Kernel Newbies]     [IDE]     [Security]     [Git]     [Netfilter]     [Bugtraq]     [Yosemite Info]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Linux ATA RAID]     [Samba]     [Linux Media]     [Device Mapper]

  Powered by Linux