Linux Perf Users
 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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox