All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v2 0/4] Support for llvm-addr2line
@ 2023-04-03 18:40 Ian Rogers
  2023-04-03 18:40 ` [PATCH v2 1/4] tools api: Add io__getline Ian Rogers
                   ` (4 more replies)
  0 siblings, 5 replies; 8+ messages in thread
From: Ian Rogers @ 2023-04-03 18:40 UTC (permalink / raw)
  To: Peter Zijlstra, Ingo Molnar, Arnaldo Carvalho de Melo,
	Mark Rutland, Alexander Shishkin, Jiri Olsa, Namhyung Kim,
	Ian Rogers, Adrian Hunter, Nathan Chancellor, Nick Desaulniers,
	Tom Rix, linux-kernel, linux-perf-users, llvm

The addr2line command is started and then addresses piped to it. In
order to determine the end of a addr2lines output a ',' it output with
an expectation to get '??\n??:0\n' as a reply. llvm-addr2line differs
in that ',' generates a reply of ','.

The approach detects and then caches the addr2line style. When records
are read the sentinel is detected appropriately.

Comparing the output there is a little more inline data on my machine
with llvm-addr2line:
$ sudo perf record -a -g sleep 1
$ sudo perf report --addr2line=addr2line > a.txt
$ sudo perf report --addr2line=llvm-addr2line > b.txt
$ wc -l a.txt b.txt
  12386 a.txt
  12477 b.txt

Some other small changes, switching to the api/io code to avoid file
streams wrapping the command's stdin/stdout. Ignore SIGPIPE for when
addr2line exits and writes fail.

v2. Address review comments from Arnaldo and Namhyung, fixing a
    realloc error path, argument ordering and a comment.

Ian Rogers (4):
  tools api: Add io__getline
  perf srcline: Simplify addr2line subprocess
  perf srcline: Support for llvm-addr2line
  perf srcline: Avoid addr2line SIGPIPEs

 tools/lib/api/io.h        |  45 ++++++++++
 tools/perf/tests/api-io.c |  36 ++++++++
 tools/perf/util/srcline.c | 171 +++++++++++++++++++++++---------------
 3 files changed, 184 insertions(+), 68 deletions(-)

-- 
2.40.0.348.gf938b09366-goog


^ permalink raw reply	[flat|nested] 8+ messages in thread

* [PATCH v2 1/4] tools api: Add io__getline
  2023-04-03 18:40 [PATCH v2 0/4] Support for llvm-addr2line Ian Rogers
@ 2023-04-03 18:40 ` Ian Rogers
  2023-04-03 18:40 ` [PATCH v2 2/4] perf srcline: Simplify addr2line subprocess Ian Rogers
                   ` (3 subsequent siblings)
  4 siblings, 0 replies; 8+ messages in thread
From: Ian Rogers @ 2023-04-03 18:40 UTC (permalink / raw)
  To: Peter Zijlstra, Ingo Molnar, Arnaldo Carvalho de Melo,
	Mark Rutland, Alexander Shishkin, Jiri Olsa, Namhyung Kim,
	Ian Rogers, Adrian Hunter, Nathan Chancellor, Nick Desaulniers,
	Tom Rix, linux-kernel, linux-perf-users, llvm

Reads a line to allocated memory up to a newline following the getline
API.

Signed-off-by: Ian Rogers <irogers@google.com>
---
 tools/lib/api/io.h        | 45 +++++++++++++++++++++++++++++++++++++++
 tools/perf/tests/api-io.c | 36 +++++++++++++++++++++++++++++++
 2 files changed, 81 insertions(+)

diff --git a/tools/lib/api/io.h b/tools/lib/api/io.h
index 777c20f6b604..d5e8cf0dada0 100644
--- a/tools/lib/api/io.h
+++ b/tools/lib/api/io.h
@@ -7,7 +7,9 @@
 #ifndef __API_IO__
 #define __API_IO__
 
+#include <errno.h>
 #include <stdlib.h>
+#include <string.h>
 #include <unistd.h>
 
 struct io {
@@ -112,4 +114,47 @@ static inline int io__get_dec(struct io *io, __u64 *dec)
 	}
 }
 
+/* Read up to and including the first newline following the pattern of getline. */
+static inline ssize_t io__getline(struct io *io, char **line_out, size_t *line_len_out)
+{
+	char buf[128];
+	int buf_pos = 0;
+	char *line = NULL, *temp;
+	size_t line_len = 0;
+	int ch = 0;
+
+	/* TODO: reuse previously allocated memory. */
+	free(*line_out);
+	while (ch != '\n') {
+		ch = io__get_char(io);
+
+		if (ch < 0)
+			break;
+
+		if (buf_pos == sizeof(buf)) {
+			temp = realloc(line, line_len + sizeof(buf));
+			if (!temp)
+				goto err_out;
+			line = temp;
+			memcpy(&line[line_len], buf, sizeof(buf));
+			line_len += sizeof(buf);
+			buf_pos = 0;
+		}
+		buf[buf_pos++] = (char)ch;
+	}
+	temp = realloc(line, line_len + buf_pos + 1);
+	if (!temp)
+		goto err_out;
+	line = temp;
+	memcpy(&line[line_len], buf, buf_pos);
+	line[line_len + buf_pos] = '\0';
+	line_len += buf_pos;
+	*line_out = line;
+	*line_len_out = line_len;
+	return line_len;
+err_out:
+	free(line);
+	return -ENOMEM;
+}
+
 #endif /* __API_IO__ */
diff --git a/tools/perf/tests/api-io.c b/tools/perf/tests/api-io.c
index e91cf2c127f1..6aea84ca6673 100644
--- a/tools/perf/tests/api-io.c
+++ b/tools/perf/tests/api-io.c
@@ -289,6 +289,40 @@ static int test_get_dec(void)
 	return ret;
 }
 
+static int test_get_line(void)
+{
+	char path[PATH_MAX];
+	struct io io;
+	char test_string[1024];
+	char *line = NULL;
+	size_t i, line_len = 0;
+	size_t buf_size = 128;
+	int ret = 0;
+
+	for (i = 0; i < 512; i++)
+		test_string[i] = 'a';
+	test_string[512] = '\n';
+	for (i = 513; i < 1023; i++)
+		test_string[i] = 'b';
+	test_string[1023] = '\0';
+
+	if (setup_test(path, test_string, buf_size, &io))
+		return -1;
+
+	EXPECT_EQUAL((int)io__getline(&io, &line, &line_len), 513);
+	EXPECT_EQUAL((int)strlen(line), 513);
+	for (i = 0; i < 512; i++)
+		EXPECT_EQUAL(line[i], 'a');
+	EXPECT_EQUAL(line[512], '\n');
+	EXPECT_EQUAL((int)io__getline(&io, &line, &line_len), 510);
+	for (i = 0; i < 510; i++)
+		EXPECT_EQUAL(line[i], 'b');
+
+	free(line);
+	cleanup_test(path, &io);
+	return ret;
+}
+
 static int test__api_io(struct test_suite *test __maybe_unused,
 			int subtest __maybe_unused)
 {
@@ -300,6 +334,8 @@ static int test__api_io(struct test_suite *test __maybe_unused,
 		ret = TEST_FAIL;
 	if (test_get_dec())
 		ret = TEST_FAIL;
+	if (test_get_line())
+		ret = TEST_FAIL;
 	return ret;
 }
 
-- 
2.40.0.348.gf938b09366-goog


^ permalink raw reply related	[flat|nested] 8+ messages in thread

* [PATCH v2 2/4] perf srcline: Simplify addr2line subprocess
  2023-04-03 18:40 [PATCH v2 0/4] Support for llvm-addr2line Ian Rogers
  2023-04-03 18:40 ` [PATCH v2 1/4] tools api: Add io__getline Ian Rogers
@ 2023-04-03 18:40 ` Ian Rogers
  2023-04-03 18:40 ` [PATCH v2 3/4] perf srcline: Support for llvm-addr2line Ian Rogers
                   ` (2 subsequent siblings)
  4 siblings, 0 replies; 8+ messages in thread
From: Ian Rogers @ 2023-04-03 18:40 UTC (permalink / raw)
  To: Peter Zijlstra, Ingo Molnar, Arnaldo Carvalho de Melo,
	Mark Rutland, Alexander Shishkin, Jiri Olsa, Namhyung Kim,
	Ian Rogers, Adrian Hunter, Nathan Chancellor, Nick Desaulniers,
	Tom Rix, linux-kernel, linux-perf-users, llvm

Don't wrap stdin and stdout of subprocess with streams, use the api/io
library for buffering.

Signed-off-by: Ian Rogers <irogers@google.com>
---
 tools/perf/util/srcline.c | 103 ++++++++++++++------------------------
 1 file changed, 38 insertions(+), 65 deletions(-)

diff --git a/tools/perf/util/srcline.c b/tools/perf/util/srcline.c
index f0a96a834e4b..5339ab4c5e12 100644
--- a/tools/perf/util/srcline.c
+++ b/tools/perf/util/srcline.c
@@ -10,6 +10,8 @@
 #include <linux/string.h>
 #include <linux/zalloc.h>
 
+#include <api/io.h>
+
 #include "util/dso.h"
 #include "util/debug.h"
 #include "util/callchain.h"
@@ -366,12 +368,6 @@ void dso__free_a2l(struct dso *dso)
 
 #else /* HAVE_LIBBFD_SUPPORT */
 
-struct a2l_subprocess {
-	struct child_process addr2line;
-	FILE *to_child;
-	FILE *from_child;
-};
-
 static int filename_split(char *filename, unsigned int *line_nr)
 {
 	char *sep;
@@ -393,28 +389,18 @@ static int filename_split(char *filename, unsigned int *line_nr)
 	return 0;
 }
 
-static void addr2line_subprocess_cleanup(struct a2l_subprocess *a2l)
+static void addr2line_subprocess_cleanup(struct child_process *a2l)
 {
-	if (a2l->addr2line.pid != -1) {
-		kill(a2l->addr2line.pid, SIGKILL);
-		finish_command(&a2l->addr2line); /* ignore result, we don't care */
-		a2l->addr2line.pid = -1;
-	}
-
-	if (a2l->to_child != NULL) {
-		fclose(a2l->to_child);
-		a2l->to_child = NULL;
-	}
-
-	if (a2l->from_child != NULL) {
-		fclose(a2l->from_child);
-		a2l->from_child = NULL;
+	if (a2l->pid != -1) {
+		kill(a2l->pid, SIGKILL);
+		finish_command(a2l); /* ignore result, we don't care */
+		a2l->pid = -1;
 	}
 
 	free(a2l);
 }
 
-static struct a2l_subprocess *addr2line_subprocess_init(const char *addr2line_path,
+static struct child_process *addr2line_subprocess_init(const char *addr2line_path,
 							const char *binary_path)
 {
 	const char *argv[] = {
@@ -422,54 +408,34 @@ static struct a2l_subprocess *addr2line_subprocess_init(const char *addr2line_pa
 		"-e", binary_path,
 		"-i", "-f", NULL
 	};
-	struct a2l_subprocess *a2l = zalloc(sizeof(*a2l));
+	struct child_process *a2l = zalloc(sizeof(*a2l));
 	int start_command_status = 0;
 
-	if (a2l == NULL)
-		goto out;
-
-	a2l->to_child = NULL;
-	a2l->from_child = NULL;
+	if (a2l == NULL) {
+		pr_err("Failed to allocate memory for addr2line");
+		return NULL;
+	}
 
-	a2l->addr2line.pid = -1;
-	a2l->addr2line.in = -1;
-	a2l->addr2line.out = -1;
-	a2l->addr2line.no_stderr = 1;
+	a2l->pid = -1;
+	a2l->in = -1;
+	a2l->out = -1;
+	a2l->no_stderr = 1;
 
-	a2l->addr2line.argv = argv;
-	start_command_status = start_command(&a2l->addr2line);
-	a2l->addr2line.argv = NULL; /* it's not used after start_command; avoid dangling pointers */
+	a2l->argv = argv;
+	start_command_status = start_command(a2l);
+	a2l->argv = NULL; /* it's not used after start_command; avoid dangling pointers */
 
 	if (start_command_status != 0) {
 		pr_warning("could not start addr2line (%s) for %s: start_command return code %d\n",
 			addr2line_path, binary_path, start_command_status);
-		goto out;
-	}
-
-	a2l->to_child = fdopen(a2l->addr2line.in, "w");
-	if (a2l->to_child == NULL) {
-		pr_warning("could not open write-stream to addr2line (%s) of %s\n",
-			addr2line_path, binary_path);
-		goto out;
-	}
-
-	a2l->from_child = fdopen(a2l->addr2line.out, "r");
-	if (a2l->from_child == NULL) {
-		pr_warning("could not open read-stream from addr2line (%s) of %s\n",
-			addr2line_path, binary_path);
-		goto out;
+		addr2line_subprocess_cleanup(a2l);
+		return NULL;
 	}
 
 	return a2l;
-
-out:
-	if (a2l)
-		addr2line_subprocess_cleanup(a2l);
-
-	return NULL;
 }
 
-static int read_addr2line_record(struct a2l_subprocess *a2l,
+static int read_addr2line_record(struct io *io,
 				 char **function,
 				 char **filename,
 				 unsigned int *line_nr)
@@ -494,7 +460,7 @@ static int read_addr2line_record(struct a2l_subprocess *a2l,
 	if (line_nr != NULL)
 		*line_nr = 0;
 
-	if (getline(&line, &line_len, a2l->from_child) < 0 || !line_len)
+	if (io__getline(io, &line, &line_len) < 0 || !line_len)
 		goto error;
 	if (function != NULL)
 		*function = strdup(strim(line));
@@ -502,7 +468,7 @@ static int read_addr2line_record(struct a2l_subprocess *a2l,
 	zfree(&line);
 	line_len = 0;
 
-	if (getline(&line, &line_len, a2l->from_child) < 0 || !line_len)
+	if (io__getline(io, &line, &line_len) < 0 || !line_len)
 		goto error;
 
 	if (filename_split(line, line_nr == NULL ? &dummy_line_nr : line_nr) == 0) {
@@ -546,13 +512,17 @@ static int addr2line(const char *dso_name, u64 addr,
 		     struct inline_node *node,
 		     struct symbol *sym __maybe_unused)
 {
-	struct a2l_subprocess *a2l = dso->a2l;
+	struct child_process *a2l = dso->a2l;
 	char *record_function = NULL;
 	char *record_filename = NULL;
 	unsigned int record_line_nr = 0;
 	int record_status = -1;
 	int ret = 0;
 	size_t inline_count = 0;
+	int len;
+	char buf[128];
+	ssize_t written;
+	struct io io;
 
 	if (!a2l) {
 		if (!filename__has_section(dso_name, ".debug_line"))
@@ -578,13 +548,16 @@ static int addr2line(const char *dso_name, u64 addr,
 	 * though, because it may be genuinely unknown, in which case we'll get two sets of
 	 * "??"/"??:0" lines.
 	 */
-	if (fprintf(a2l->to_child, "%016"PRIx64"\n,\n", addr) < 0 || fflush(a2l->to_child) != 0) {
+	len = snprintf(buf, sizeof(buf), "%016"PRIx64"\n,\n", addr);
+	written = len > 0 ? write(a2l->in, buf, len) : -1;
+	if (written != len) {
 		if (!symbol_conf.disable_add2line_warn)
 			pr_warning("%s %s: could not send request\n", __func__, dso_name);
 		goto out;
 	}
+	io__init(&io, a2l->out, buf, sizeof(buf));
 
-	switch (read_addr2line_record(a2l, &record_function, &record_filename, &record_line_nr)) {
+	switch (read_addr2line_record(&io, &record_function, &record_filename, &record_line_nr)) {
 	case -1:
 		if (!symbol_conf.disable_add2line_warn)
 			pr_warning("%s %s: could not read first record\n", __func__, dso_name);
@@ -594,7 +567,7 @@ static int addr2line(const char *dso_name, u64 addr,
 		 * The first record was invalid, so return failure, but first read another
 		 * record, since we asked a junk question and have to clear the answer out.
 		 */
-		switch (read_addr2line_record(a2l, NULL, NULL, NULL)) {
+		switch (read_addr2line_record(&io, NULL, NULL, NULL)) {
 		case -1:
 			if (!symbol_conf.disable_add2line_warn)
 				pr_warning("%s %s: could not read delimiter record\n",
@@ -632,7 +605,7 @@ static int addr2line(const char *dso_name, u64 addr,
 	}
 
 	/* We have to read the records even if we don't care about the inline info. */
-	while ((record_status = read_addr2line_record(a2l,
+	while ((record_status = read_addr2line_record(&io,
 						      &record_function,
 						      &record_filename,
 						      &record_line_nr)) == 1) {
@@ -656,7 +629,7 @@ static int addr2line(const char *dso_name, u64 addr,
 
 void dso__free_a2l(struct dso *dso)
 {
-	struct a2l_subprocess *a2l = dso->a2l;
+	struct child_process *a2l = dso->a2l;
 
 	if (!a2l)
 		return;
-- 
2.40.0.348.gf938b09366-goog


^ permalink raw reply related	[flat|nested] 8+ messages in thread

* [PATCH v2 3/4] perf srcline: Support for llvm-addr2line
  2023-04-03 18:40 [PATCH v2 0/4] Support for llvm-addr2line Ian Rogers
  2023-04-03 18:40 ` [PATCH v2 1/4] tools api: Add io__getline Ian Rogers
  2023-04-03 18:40 ` [PATCH v2 2/4] perf srcline: Simplify addr2line subprocess Ian Rogers
@ 2023-04-03 18:40 ` Ian Rogers
  2023-04-03 18:40 ` [PATCH v2 4/4] perf srcline: Avoid addr2line SIGPIPEs Ian Rogers
  2023-04-03 20:24 ` [PATCH v2 0/4] Support for llvm-addr2line Arnaldo Carvalho de Melo
  4 siblings, 0 replies; 8+ messages in thread
From: Ian Rogers @ 2023-04-03 18:40 UTC (permalink / raw)
  To: Peter Zijlstra, Ingo Molnar, Arnaldo Carvalho de Melo,
	Mark Rutland, Alexander Shishkin, Jiri Olsa, Namhyung Kim,
	Ian Rogers, Adrian Hunter, Nathan Chancellor, Nick Desaulniers,
	Tom Rix, linux-kernel, linux-perf-users, llvm

The sentinel value differs for llvm-addr2line. Configure this once and
then detect when reading records.

Signed-off-by: Ian Rogers <irogers@google.com>
---
 tools/perf/util/srcline.c | 74 +++++++++++++++++++++++++++++++++++----
 1 file changed, 67 insertions(+), 7 deletions(-)

diff --git a/tools/perf/util/srcline.c b/tools/perf/util/srcline.c
index 5339ab4c5e12..f4fcdada821b 100644
--- a/tools/perf/util/srcline.c
+++ b/tools/perf/util/srcline.c
@@ -435,7 +435,50 @@ static struct child_process *addr2line_subprocess_init(const char *addr2line_pat
 	return a2l;
 }
 
+enum a2l_style {
+	BROKEN,
+	GNU_BINUTILS,
+	LLVM,
+};
+
+static enum a2l_style addr2line_configure(struct child_process *a2l)
+{
+	static bool cached;
+	static enum a2l_style style;
+
+	if (!cached) {
+		char buf[128];
+		struct io io;
+		int ch;
+
+		if (write(a2l->in, ",\n", 2) != 2)
+			return BROKEN;
+
+		io__init(&io, a2l->out, buf, sizeof(buf));
+		ch = io__get_char(&io);
+		if (ch == ',') {
+			style = LLVM;
+			cached = true;
+		} else if (ch == '?') {
+			style = GNU_BINUTILS;
+			cached = true;
+		} else {
+			style = BROKEN;
+		}
+		do {
+			ch = io__get_char(&io);
+		} while (ch > 0 && ch != '\n');
+		if (style == GNU_BINUTILS) {
+			do {
+				ch = io__get_char(&io);
+			} while (ch > 0 && ch != '\n');
+		}
+	}
+	return style;
+}
+
 static int read_addr2line_record(struct io *io,
+				 enum a2l_style style,
 				 char **function,
 				 char **filename,
 				 unsigned int *line_nr)
@@ -462,6 +505,12 @@ static int read_addr2line_record(struct io *io,
 
 	if (io__getline(io, &line, &line_len) < 0 || !line_len)
 		goto error;
+
+	if (style == LLVM && line_len == 2 && line[0] == ',') {
+		zfree(&line);
+		return 0;
+	}
+
 	if (function != NULL)
 		*function = strdup(strim(line));
 
@@ -471,7 +520,8 @@ static int read_addr2line_record(struct io *io,
 	if (io__getline(io, &line, &line_len) < 0 || !line_len)
 		goto error;
 
-	if (filename_split(line, line_nr == NULL ? &dummy_line_nr : line_nr) == 0) {
+	if (filename_split(line, line_nr == NULL ? &dummy_line_nr : line_nr) == 0 &&
+	    style == GNU_BINUTILS) {
 		ret = 0;
 		goto error;
 	}
@@ -523,6 +573,7 @@ static int addr2line(const char *dso_name, u64 addr,
 	char buf[128];
 	ssize_t written;
 	struct io io;
+	enum a2l_style a2l_style;
 
 	if (!a2l) {
 		if (!filename__has_section(dso_name, ".debug_line"))
@@ -538,15 +589,22 @@ static int addr2line(const char *dso_name, u64 addr,
 			pr_warning("%s %s: addr2line_subprocess_init failed\n", __func__, dso_name);
 		goto out;
 	}
+	a2l_style = addr2line_configure(a2l);
+	if (a2l_style == BROKEN) {
+		if (!symbol_conf.disable_add2line_warn)
+			pr_warning("%s: addr2line configuration failed\n", __func__);
+		goto out;
+	}
 
 	/*
 	 * Send our request and then *deliberately* send something that can't be interpreted as
 	 * a valid address to ask addr2line about (namely, ","). This causes addr2line to first
 	 * write out the answer to our request, in an unbounded/unknown number of records, and
-	 * then to write out the lines "??" and "??:0", so that we can detect when it has
-	 * finished giving us anything useful. We have to be careful about the first record,
-	 * though, because it may be genuinely unknown, in which case we'll get two sets of
-	 * "??"/"??:0" lines.
+	 * then to write out the lines "??" and "??:0", for GNU binutils, or "," for
+	 * llvm-addr2line, so that we can detect when it has finished giving us anything
+	 * useful. With GNU binutils, we have to be careful about the first record, though,
+	 * because it may be genuinely unknown, in which case we'll get two sets of "??"/"??:0"
+	 * lines.
 	 */
 	len = snprintf(buf, sizeof(buf), "%016"PRIx64"\n,\n", addr);
 	written = len > 0 ? write(a2l->in, buf, len) : -1;
@@ -557,7 +615,8 @@ static int addr2line(const char *dso_name, u64 addr,
 	}
 	io__init(&io, a2l->out, buf, sizeof(buf));
 
-	switch (read_addr2line_record(&io, &record_function, &record_filename, &record_line_nr)) {
+	switch (read_addr2line_record(&io, a2l_style,
+				      &record_function, &record_filename, &record_line_nr)) {
 	case -1:
 		if (!symbol_conf.disable_add2line_warn)
 			pr_warning("%s %s: could not read first record\n", __func__, dso_name);
@@ -567,7 +626,7 @@ static int addr2line(const char *dso_name, u64 addr,
 		 * The first record was invalid, so return failure, but first read another
 		 * record, since we asked a junk question and have to clear the answer out.
 		 */
-		switch (read_addr2line_record(&io, NULL, NULL, NULL)) {
+		switch (read_addr2line_record(&io, a2l_style, NULL, NULL, NULL)) {
 		case -1:
 			if (!symbol_conf.disable_add2line_warn)
 				pr_warning("%s %s: could not read delimiter record\n",
@@ -606,6 +665,7 @@ static int addr2line(const char *dso_name, u64 addr,
 
 	/* We have to read the records even if we don't care about the inline info. */
 	while ((record_status = read_addr2line_record(&io,
+						      a2l_style,
 						      &record_function,
 						      &record_filename,
 						      &record_line_nr)) == 1) {
-- 
2.40.0.348.gf938b09366-goog


^ permalink raw reply related	[flat|nested] 8+ messages in thread

* [PATCH v2 4/4] perf srcline: Avoid addr2line SIGPIPEs
  2023-04-03 18:40 [PATCH v2 0/4] Support for llvm-addr2line Ian Rogers
                   ` (2 preceding siblings ...)
  2023-04-03 18:40 ` [PATCH v2 3/4] perf srcline: Support for llvm-addr2line Ian Rogers
@ 2023-04-03 18:40 ` Ian Rogers
  2023-04-03 20:24 ` [PATCH v2 0/4] Support for llvm-addr2line Arnaldo Carvalho de Melo
  4 siblings, 0 replies; 8+ messages in thread
From: Ian Rogers @ 2023-04-03 18:40 UTC (permalink / raw)
  To: Peter Zijlstra, Ingo Molnar, Arnaldo Carvalho de Melo,
	Mark Rutland, Alexander Shishkin, Jiri Olsa, Namhyung Kim,
	Ian Rogers, Adrian Hunter, Nathan Chancellor, Nick Desaulniers,
	Tom Rix, linux-kernel, linux-perf-users, llvm

Ignore SIGPIPEs when addr2line is configured.

Signed-off-by: Ian Rogers <irogers@google.com>
---
 tools/perf/util/srcline.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/tools/perf/util/srcline.c b/tools/perf/util/srcline.c
index f4fcdada821b..cfca03abd6f8 100644
--- a/tools/perf/util/srcline.c
+++ b/tools/perf/util/srcline.c
@@ -473,6 +473,8 @@ static enum a2l_style addr2line_configure(struct child_process *a2l)
 				ch = io__get_char(&io);
 			} while (ch > 0 && ch != '\n');
 		}
+		/* Ignore SIGPIPE in the event addr2line exits. */
+		signal(SIGPIPE, SIG_IGN);
 	}
 	return style;
 }
-- 
2.40.0.348.gf938b09366-goog


^ permalink raw reply related	[flat|nested] 8+ messages in thread

* Re: [PATCH v2 0/4] Support for llvm-addr2line
  2023-04-03 18:40 [PATCH v2 0/4] Support for llvm-addr2line Ian Rogers
                   ` (3 preceding siblings ...)
  2023-04-03 18:40 ` [PATCH v2 4/4] perf srcline: Avoid addr2line SIGPIPEs Ian Rogers
@ 2023-04-03 20:24 ` Arnaldo Carvalho de Melo
  2023-04-04  5:18   ` Namhyung Kim
  4 siblings, 1 reply; 8+ messages in thread
From: Arnaldo Carvalho de Melo @ 2023-04-03 20:24 UTC (permalink / raw)
  To: Ian Rogers
  Cc: Peter Zijlstra, Ingo Molnar, Mark Rutland, Alexander Shishkin,
	Jiri Olsa, Namhyung Kim, Adrian Hunter, Nathan Chancellor,
	Nick Desaulniers, Tom Rix, linux-kernel, linux-perf-users, llvm

Em Mon, Apr 03, 2023 at 11:40:29AM -0700, Ian Rogers escreveu:
> The addr2line command is started and then addresses piped to it. In
> order to determine the end of a addr2lines output a ',' it output with
> an expectation to get '??\n??:0\n' as a reply. llvm-addr2line differs
> in that ',' generates a reply of ','.
> 
> The approach detects and then caches the addr2line style. When records
> are read the sentinel is detected appropriately.
> 
> Comparing the output there is a little more inline data on my machine
> with llvm-addr2line:
> $ sudo perf record -a -g sleep 1
> $ sudo perf report --addr2line=addr2line > a.txt
> $ sudo perf report --addr2line=llvm-addr2line > b.txt
> $ wc -l a.txt b.txt
>   12386 a.txt
>   12477 b.txt
> 
> Some other small changes, switching to the api/io code to avoid file
> streams wrapping the command's stdin/stdout. Ignore SIGPIPE for when
> addr2line exits and writes fail.
> 
> v2. Address review comments from Arnaldo and Namhyung, fixing a
>     realloc error path, argument ordering and a comment.

Added to local repo, build testing, will be in tmp.perf-tools-next soon.

- Arnaldo
 
> Ian Rogers (4):
>   tools api: Add io__getline
>   perf srcline: Simplify addr2line subprocess
>   perf srcline: Support for llvm-addr2line
>   perf srcline: Avoid addr2line SIGPIPEs
> 
>  tools/lib/api/io.h        |  45 ++++++++++
>  tools/perf/tests/api-io.c |  36 ++++++++
>  tools/perf/util/srcline.c | 171 +++++++++++++++++++++++---------------
>  3 files changed, 184 insertions(+), 68 deletions(-)
> 
> -- 
> 2.40.0.348.gf938b09366-goog
> 

-- 

- Arnaldo

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [PATCH v2 0/4] Support for llvm-addr2line
  2023-04-03 20:24 ` [PATCH v2 0/4] Support for llvm-addr2line Arnaldo Carvalho de Melo
@ 2023-04-04  5:18   ` Namhyung Kim
  2023-04-04 12:48     ` Arnaldo Carvalho de Melo
  0 siblings, 1 reply; 8+ messages in thread
From: Namhyung Kim @ 2023-04-04  5:18 UTC (permalink / raw)
  To: Arnaldo Carvalho de Melo
  Cc: Ian Rogers, Peter Zijlstra, Ingo Molnar, Mark Rutland,
	Alexander Shishkin, Jiri Olsa, Adrian Hunter, Nathan Chancellor,
	Nick Desaulniers, Tom Rix, linux-kernel, linux-perf-users, llvm

Hi,

On Mon, Apr 3, 2023 at 1:24 PM Arnaldo Carvalho de Melo <acme@kernel.org> wrote:
>
> Em Mon, Apr 03, 2023 at 11:40:29AM -0700, Ian Rogers escreveu:
> > The addr2line command is started and then addresses piped to it. In
> > order to determine the end of a addr2lines output a ',' it output with
> > an expectation to get '??\n??:0\n' as a reply. llvm-addr2line differs
> > in that ',' generates a reply of ','.
> >
> > The approach detects and then caches the addr2line style. When records
> > are read the sentinel is detected appropriately.
> >
> > Comparing the output there is a little more inline data on my machine
> > with llvm-addr2line:
> > $ sudo perf record -a -g sleep 1
> > $ sudo perf report --addr2line=addr2line > a.txt
> > $ sudo perf report --addr2line=llvm-addr2line > b.txt
> > $ wc -l a.txt b.txt
> >   12386 a.txt
> >   12477 b.txt
> >
> > Some other small changes, switching to the api/io code to avoid file
> > streams wrapping the command's stdin/stdout. Ignore SIGPIPE for when
> > addr2line exits and writes fail.
> >
> > v2. Address review comments from Arnaldo and Namhyung, fixing a
> >     realloc error path, argument ordering and a comment.
>
> Added to local repo, build testing, will be in tmp.perf-tools-next soon.
>
> - Arnaldo
>
> > Ian Rogers (4):
> >   tools api: Add io__getline
> >   perf srcline: Simplify addr2line subprocess
> >   perf srcline: Support for llvm-addr2line
> >   perf srcline: Avoid addr2line SIGPIPEs

Acked-by: Namhyung Kim <namhyung@kernel.org>

Thanks,
Namhyung


> >
> >  tools/lib/api/io.h        |  45 ++++++++++
> >  tools/perf/tests/api-io.c |  36 ++++++++
> >  tools/perf/util/srcline.c | 171 +++++++++++++++++++++++---------------
> >  3 files changed, 184 insertions(+), 68 deletions(-)
> >
> > --
> > 2.40.0.348.gf938b09366-goog
> >
>
> --
>
> - Arnaldo

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [PATCH v2 0/4] Support for llvm-addr2line
  2023-04-04  5:18   ` Namhyung Kim
@ 2023-04-04 12:48     ` Arnaldo Carvalho de Melo
  0 siblings, 0 replies; 8+ messages in thread
From: Arnaldo Carvalho de Melo @ 2023-04-04 12:48 UTC (permalink / raw)
  To: Namhyung Kim
  Cc: Ian Rogers, Peter Zijlstra, Ingo Molnar, Mark Rutland,
	Alexander Shishkin, Jiri Olsa, Adrian Hunter, Nathan Chancellor,
	Nick Desaulniers, Tom Rix, linux-kernel, linux-perf-users, llvm

Em Mon, Apr 03, 2023 at 10:18:47PM -0700, Namhyung Kim escreveu:
> Hi,
> 
> On Mon, Apr 3, 2023 at 1:24 PM Arnaldo Carvalho de Melo <acme@kernel.org> wrote:
> >
> > Em Mon, Apr 03, 2023 at 11:40:29AM -0700, Ian Rogers escreveu:
> > > The addr2line command is started and then addresses piped to it. In
> > > order to determine the end of a addr2lines output a ',' it output with
> > > an expectation to get '??\n??:0\n' as a reply. llvm-addr2line differs
> > > in that ',' generates a reply of ','.
> > >
> > > The approach detects and then caches the addr2line style. When records
> > > are read the sentinel is detected appropriately.
> > >
> > > Comparing the output there is a little more inline data on my machine
> > > with llvm-addr2line:
> > > $ sudo perf record -a -g sleep 1
> > > $ sudo perf report --addr2line=addr2line > a.txt
> > > $ sudo perf report --addr2line=llvm-addr2line > b.txt
> > > $ wc -l a.txt b.txt
> > >   12386 a.txt
> > >   12477 b.txt
> > >
> > > Some other small changes, switching to the api/io code to avoid file
> > > streams wrapping the command's stdin/stdout. Ignore SIGPIPE for when
> > > addr2line exits and writes fail.
> > >
> > > v2. Address review comments from Arnaldo and Namhyung, fixing a
> > >     realloc error path, argument ordering and a comment.
> >
> > Added to local repo, build testing, will be in tmp.perf-tools-next soon.
> >
> > - Arnaldo
> >
> > > Ian Rogers (4):
> > >   tools api: Add io__getline
> > >   perf srcline: Simplify addr2line subprocess
> > >   perf srcline: Support for llvm-addr2line
> > >   perf srcline: Avoid addr2line SIGPIPEs
> 
> Acked-by: Namhyung Kim <namhyung@kernel.org>

Thanks, added to those patches.

- Arnaldo


^ permalink raw reply	[flat|nested] 8+ messages in thread

end of thread, other threads:[~2023-04-04 12:48 UTC | newest]

Thread overview: 8+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2023-04-03 18:40 [PATCH v2 0/4] Support for llvm-addr2line Ian Rogers
2023-04-03 18:40 ` [PATCH v2 1/4] tools api: Add io__getline Ian Rogers
2023-04-03 18:40 ` [PATCH v2 2/4] perf srcline: Simplify addr2line subprocess Ian Rogers
2023-04-03 18:40 ` [PATCH v2 3/4] perf srcline: Support for llvm-addr2line Ian Rogers
2023-04-03 18:40 ` [PATCH v2 4/4] perf srcline: Avoid addr2line SIGPIPEs Ian Rogers
2023-04-03 20:24 ` [PATCH v2 0/4] Support for llvm-addr2line Arnaldo Carvalho de Melo
2023-04-04  5:18   ` Namhyung Kim
2023-04-04 12:48     ` Arnaldo Carvalho de Melo

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.