All of lore.kernel.org
 help / color / mirror / Atom feed
From: Ian Rogers <irogers@google.com>
To: acme@kernel.org, namhyung@kernel.org
Cc: irogers@google.com, 9erthalion6@gmail.com,
	adrian.hunter@intel.com,  james.clark@linaro.org,
	jolsa@kernel.org, leo.yan@arm.com,  linux-kernel@vger.kernel.org,
	linux-perf-users@vger.kernel.org,  mingo@redhat.com,
	peterz@infradead.org
Subject: [PATCH v4 3/3] perf test: Avoid stack trace noise in verbose=1 failure snippets
Date: Mon, 12 Oct 2026 16:47:24 -0700	[thread overview]
Message-ID: <20261012234724.721224-4-irogers@google.com> (raw)
In-Reply-To: <20261012234724.721224-1-irogers@google.com>

When a test fails with a signal or times out, child_test_sig_handler()
appends '---- unexpected signal (<sig>) ----' followed by a multi-line
stack trace ('    #0 ...' through '_start').

In verbose=1 mode, print_test_failure_snippet() selects up to
failure_snippet_lines (10) lines:
- Pass 1 selects lines matching failure keywords plus their immediate
  next line ('    #0 ... in child_test_sig_handler').
- Pass 2 fills the remaining quota by scanning backwards from the end
  of the output buffer, which consumes the remaining lines on outermost
  stack frames ('handle_internal_command', 'run_argv', 'main',
  '__libc_start_main', '_start') and hides the trailing test output
  showing where the test had run to.

Improve print_test_failure_snippet() by:
- Skipping blank lines and stack trace lines ('    #<digit>...') when
  selecting context in Pass 1 and when scanning backwards from the end
  in Pass 2, with a Pass 3 fallback from the top of the buffer if quota
  still remains.
- Prioritizing the non-blank line immediately preceding
  '---- unexpected signal' so there is no '...' gap before the signal
  message.
- Only printing '...' between selected lines when at least one non-blank
  line was omitted between them.

Assisted-by: Antigravity:gemini-3.1-pro
Signed-off-by: Ian Rogers <irogers@google.com>
---
 tools/perf/tests/builtin-test.c | 101 +++++++++++++++++++++++++-------
 1 file changed, 81 insertions(+), 20 deletions(-)

diff --git a/tools/perf/tests/builtin-test.c b/tools/perf/tests/builtin-test.c
index d0c2783cb312..b95e9704b79f 100644
--- a/tools/perf/tests/builtin-test.c
+++ b/tools/perf/tests/builtin-test.c
@@ -774,6 +774,47 @@ static void print_line_highlighted(FILE *fp, const char *line, size_t len)
 }
 
 
+static bool is_blank_line(const char *line, size_t len)
+{
+	for (size_t i = 0; i < len; i++) {
+		if (!isspace((unsigned char)line[i]))
+			return false;
+	}
+	return true;
+}
+
+static bool is_stack_line(const char *line, size_t len)
+{
+	size_t i = 0;
+
+	while (i < len && isspace((unsigned char)line[i]))
+		i++;
+	return i + 1 < len && line[i] == '#' && isdigit((unsigned char)line[i + 1]);
+}
+
+static bool is_ignorable_snippet_line(const char *line, size_t len)
+{
+	return is_blank_line(line, len) || is_stack_line(line, len);
+}
+
+static bool has_non_blank_between(const char **lines, const size_t *line_lens,
+				  size_t start, size_t end)
+{
+	for (size_t j = start + 1; j < end; j++) {
+		if (!is_blank_line(lines[j], line_lens[j]))
+			return true;
+	}
+	return false;
+}
+
+static void pick_snippet_line(bool *pick, size_t idx, unsigned int *picked_count)
+{
+	if (!pick[idx] && *picked_count < failure_snippet_lines) {
+		pick[idx] = true;
+		(*picked_count)++;
+	}
+}
+
 static void print_test_failure_snippet(FILE *fp, const char *buf)
 {
 	size_t num_lines = 0;
@@ -844,43 +885,63 @@ static void print_test_failure_snippet(FILE *fp, const char *buf)
 	}
 
 	/* Pass 0: Always pick the very first line */
-	if (num_lines > 0 && picked_count < failure_snippet_lines) {
-		pick[0] = true;
-		picked_count++;
-	}
+	if (num_lines > 0)
+		pick_snippet_line(pick, 0, &picked_count);
 
 	/* Pass 1: Pick lines with failure keywords from start (Highest Priority) */
 	for (i = 0; i < num_lines && picked_count < failure_snippet_lines; i++) {
 		size_t dummy;
 
-		if (find_next_keyword(lines[i], line_lens[i], &dummy)) {
-			if (!pick[i]) {
-				pick[i] = true;
-				picked_count++;
-			}
-			/* Prioritize getting the immediate next line for context */
-			if (i + 1 < num_lines && !pick[i + 1] &&
-			    picked_count < failure_snippet_lines) {
-				pick[i + 1] = true;
-				picked_count++;
+		if (is_ignorable_snippet_line(lines[i], line_lens[i]))
+			continue;
+		if (!find_next_keyword(lines[i], line_lens[i], &dummy))
+			continue;
+
+		pick_snippet_line(pick, i, &picked_count);
+		/*
+		 * For unexpected signals, prioritize the preceding non-blank
+		 * line showing where the test had run to before the signal.
+		 */
+		if (!strncmp(lines[i], "---- unexpected signal", 22)) {
+			size_t j = i;
+
+			while (j > 0) {
+				j--;
+				if (!is_ignorable_snippet_line(lines[j], line_lens[j])) {
+					pick_snippet_line(pick, j, &picked_count);
+					break;
+				}
 			}
 		}
+		/* Prioritize getting the immediate next line for context */
+		if (i + 1 < num_lines &&
+		    !is_ignorable_snippet_line(lines[i + 1], line_lens[i + 1]))
+			pick_snippet_line(pick, i + 1, &picked_count);
 	}
 
-	/* Pass 2: Fill remaining quota from the end backwards */
+	/*
+	 * Pass 2: Fill remaining quota from the end backwards, skipping blank
+	 * and stack trace lines so trailing test progress is shown instead of
+	 * outermost stack frames like main/_start.
+	 */
 	i = num_lines;
 	while (i > 0 && picked_count < failure_snippet_lines) {
 		i--;
-		if (!pick[i]) {
-			pick[i] = true;
-			picked_count++;
-		}
+		if (!is_ignorable_snippet_line(lines[i], line_lens[i]))
+			pick_snippet_line(pick, i, &picked_count);
+	}
+
+	/* Pass 3: Fallback to top stack frames if quota remains */
+	for (i = 0; i < num_lines && picked_count < failure_snippet_lines; i++) {
+		if (!is_blank_line(lines[i], line_lens[i]))
+			pick_snippet_line(pick, i, &picked_count);
 	}
 
 	for (i = 0; i < num_lines; i++) {
 		if (!pick[i])
 			continue;
-		if (last_printed != -1 && (int)i > last_printed + 1) {
+		if (last_printed != -1 &&
+		    has_non_blank_between(lines, line_lens, last_printed, i)) {
 			if (perf_use_color_default)
 				fprintf(fp, "%s...%s\n", PERF_COLOR_BLUE, PERF_COLOR_RESET);
 			else
-- 
2.56.0.385.gd3acb90ef8-goog


  parent reply	other threads:[~2026-10-12 23:47 UTC|newest]

Thread overview: 21+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-09-28 21:01 [PATCH v1 1/2] perf test: Add per-test timeout support Ian Rogers
2026-09-28 21:01 ` [PATCH v1 2/2] perf test: Improve JUnit XML schema compliance and completeness Ian Rogers
2026-09-28 21:08   ` sashiko-bot
2026-09-28 21:14 ` [PATCH v1 1/2] perf test: Add per-test timeout support sashiko-bot
2026-09-29  1:18 ` [PATCH v2 " Ian Rogers
2026-09-29  1:18   ` [PATCH v2 2/2] perf test: Improve JUnit XML schema compliance and completeness Ian Rogers
2026-09-29  1:24     ` sashiko-bot
2026-09-29  1:31   ` [PATCH v2 1/2] perf test: Add per-test timeout support sashiko-bot
2026-09-29  2:53   ` [PATCH v3 " Ian Rogers
2026-09-29  2:53     ` [PATCH v3 2/2] perf test: Improve JUnit XML schema compliance and completeness Ian Rogers
2026-09-29  2:59       ` sashiko-bot
2026-09-29  3:00     ` [PATCH v3 1/2] perf test: Add per-test timeout support sashiko-bot
2026-10-05 22:44     ` Namhyung Kim
2026-10-12 21:57       ` Ian Rogers
2026-10-12 23:47     ` [PATCH v4 0/3] perf test: Per-test timeouts, JUnit XML compliance, and snippet improvements Ian Rogers
2026-10-12 23:47       ` [PATCH v4 1/3] perf test: Add per-test timeout support Ian Rogers
2026-10-12 23:56         ` sashiko-bot
2026-10-12 23:47       ` [PATCH v4 2/3] perf test: Improve JUnit XML schema compliance and completeness Ian Rogers
2026-10-12 23:54         ` sashiko-bot
2026-10-12 23:47       ` Ian Rogers [this message]
2026-10-12 23:53         ` [PATCH v4 3/3] perf test: Avoid stack trace noise in verbose=1 failure snippets sashiko-bot

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20261012234724.721224-4-irogers@google.com \
    --to=irogers@google.com \
    --cc=9erthalion6@gmail.com \
    --cc=acme@kernel.org \
    --cc=adrian.hunter@intel.com \
    --cc=james.clark@linaro.org \
    --cc=jolsa@kernel.org \
    --cc=leo.yan@arm.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-perf-users@vger.kernel.org \
    --cc=mingo@redhat.com \
    --cc=namhyung@kernel.org \
    --cc=peterz@infradead.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
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.