Linux Perf Users
 help / color / mirror / Atom feed
From: sashiko-bot@kernel.org
To: "Ian Rogers" <irogers@google.com>
Cc: linux-perf-users@vger.kernel.org
Subject: Re: [RFC PATCH v1 02/14] perf stat: Implement standard console (STD) formatting callbacks
Date: Fri, 22 May 2026 22:54:45 +0000	[thread overview]
Message-ID: <20260522225446.1C60A1F000E9@smtp.kernel.org> (raw)
In-Reply-To: <20260522223342.2393553-3-irogers@google.com>

Thank you for your contribution! Sashiko AI review found 4 potential issue(s) to consider:
- [High] Skipping a zero-valued counter leaves a stale `current_event` pointer, causing a false temporal coupling violation and aborting the printing process.
- [High] Unchecked `aggr_idx` parameter in `should_skip_zero_counter` can lead to an out-of-bounds array access.
- [Medium] Queued events and metrics are leaked if the traversal callback chain fails early.
- [Medium] In interval mode with `--metric-only`, metric column headers are repeatedly printed for every interval.
--

commit 574c7c40ab2b1b89dd11b7fbe55c2b8a5b292b35
Author: Ian Rogers <irogers@google.com>

perf stat: Implement standard console (STD) formatting callbacks

This patch implements standard console formatting callbacks inside
util/stat-print-std.c. It uses buffered DOM nodes for streams and
centralizes aggregation helpers for prefixes and interval-mode timestamp
support.

> diff --git a/tools/perf/util/stat-print-std.c b/tools/perf/util/stat-print-std.c
> index 83987e97c8895..0aa4e2669bbaa 100644
> --- a/tools/perf/util/stat-print-std.c
> +++ b/tools/perf/util/stat-print-std.c

[ ... ]

> +static bool should_skip_zero_counter(const struct perf_stat_config *config, struct evsel *counter,
> +				     int aggr_idx)
> +{
> +	struct perf_cpu cpu;
> +	unsigned int idx;
> +	struct aggr_cpu_id id;
> +
> +	if (verbose == 0 && counter->skippable && !counter->supported)
> +		return true;
> +
> +	if (config->metric_only)
> +		return false;
> +
> +	if (config->aggr_mode == AGGR_THREAD && config->system_wide)
> +		return true;
> +
> +	if (!config->aggr_map || !config->aggr_get_id)
> +		return false;
> +
> +	id = config->aggr_map->map[aggr_idx];

[Severity: High]
Can this result in an out-of-bounds array access?

When using global aggregation modes or unaggregated events, aggr_idx can
be -1. If so, config->aggr_map->map[aggr_idx] would read before the array
base.

> +
> +	if (evsel__is_tool(counter)) {
> +		struct aggr_cpu_id own_id = config->aggr_get_id((struct perf_stat_config *)config,

[ ... ]

> +static int std_print_event(void *ctx, const struct perf_stat_config *config, struct evsel *evsel,
> +			   int aggr_idx, u64 val, u64 ena, u64 run, double stdev_pct)
> +{
> +	struct std_print_state *ps = ctx;
> +	struct queued_event *ev;
> +
> +	/* Skip zero counters locally in STD callbacks if they qualify */
> +	if (val == 0 && should_skip_zero_counter(config, evsel, aggr_idx))
> +		return 0;

[Severity: High]
Does returning early here leave ps->current_event pointing to the
previous event?

If the traversal driver synchronously invokes std_print_metric() for this
skipped event, it will compare the passed evsel against the old
ps->current_event->evsel, triggering the temporal coupling violation
error and aborting the print.

> +
> +	ev = malloc(sizeof(*ev));
> +	if (!ev)
> +		return -ENOMEM;

[ ... ]

> +static int std_metric_only_print_end(void *ctx, const struct perf_stat_config *config)
> +{
> +	struct std_metric_only_print_state *ps = ctx;
> +	struct queued_metric *b, *tmp;
> +	FILE *out = ps->fp;
> +	int first_aggr = -1;
> +	int current_aggr = -1;
> +	const char *color;
> +	char *str;
> +	int mlen;
> +	int ret = 0;
> +	int err;
> +
> +	if (list_empty(&ps->queued_metrics))
> +		return 0;
> +
> +	/* Print the formatted header prefix */
> +	if (!config->interval)
> +		print_header_std(config, ps->target, ps->argc, ps->argv);
> +
> +	first_aggr = list_first_entry(&ps->queued_metrics, struct queued_metric, list)->aggr_idx;
> +
> +	/* Print headers */
> +	list_for_each_entry(b, &ps->queued_metrics, list) {

[Severity: Medium]
Is it intended for the metric column headers to print unconditionally here?

In interval mode, perf_stat__print_cb() calls this end callback
repeatedly, which appears to cause the header row to print before every
interval's row of values instead of just once at the beginning.

> +		if (b->aggr_idx == first_aggr) {
> +			char *header_name;
> +			if (b->unit && b->unit[0]) {

[ ... ]

> +int perf_stat__print_std(struct evlist *evlist, const struct perf_stat_config *config,
> +			 const struct target *target, const struct timespec *ts, int argc,
> +			 const char **argv)
> +{
> +	struct std_print_state ps = {
> +		.fp = config->output,
> +		.target = target,
> +		.argc = argc,
> +		.argv = argv,
> +	};
> +
> +	if (config->metric_only) {
> +		struct std_metric_only_print_state mops = {
> +			.fp = config->output,
> +			.target = target,
> +			.argc = argc,
> +			.argv = argv,
> +		};
> +		if (config->interval && ts) {
> +			scnprintf(mops.timestamp, sizeof(mops.timestamp), "%6lu.%09lu ",
> +				  (unsigned long)ts->tv_sec, ts->tv_nsec);
> +		} else {
> +			mops.timestamp[0] = '\0';
> +		}
> +		return perf_stat__print_cb(evlist, config, target, ts, argc, argv,
> +					   &std_metric_only_print_callbacks, &mops);

[Severity: Medium]
Does this leak the queued events and metrics if perf_stat__print_cb()
returns an error?

The local state structures contain linked lists buffering dynamically
allocated items. If the callback chain fails early (e.g., from an ENOMEM
or EINVAL), the function returns here without executing a cleanup path.

> +	} else {
> +		if (config->interval && ts) {
> +			scnprintf(ps.timestamp, sizeof(ps.timestamp), "%6lu.%09lu ",
> +				  (unsigned long)ts->tv_sec, ts->tv_nsec);
> +		} else {
> +			ps.timestamp[0] = '\0';
> +		}
> +		return perf_stat__print_cb(evlist, config, target, ts, argc, argv,
> +					   &std_print_callbacks, &ps);

[Severity: Medium]
Similarly, does this leak the queued events in ps.events_list if
perf_stat__print_cb() returns an error?

> +	}
> +}

-- 
Sashiko AI review · https://sashiko.dev/#/patchset/20260522223342.2393553-1-irogers@google.com?part=2

  reply	other threads:[~2026-05-22 22:54 UTC|newest]

Thread overview: 45+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-05-22 22:33 [RFC PATCH v1 00/14] perf stat: Decouple and modularize metrics/events output printing API Ian Rogers
2026-05-22 22:33 ` [RFC PATCH v1 01/14] perf stat: Introduce core generic print traversal engine and header stubs Ian Rogers
2026-05-22 23:47   ` sashiko-bot
2026-05-22 22:33 ` [RFC PATCH v1 02/14] perf stat: Implement standard console (STD) formatting callbacks Ian Rogers
2026-05-22 22:54   ` sashiko-bot [this message]
2026-05-22 22:33 ` [RFC PATCH v1 03/14] perf stat: Extend STD output linter to test basic New API checks Ian Rogers
2026-05-22 22:33 ` [RFC PATCH v1 04/14] perf stat: Extend STD output linter to test core aggregation checks Ian Rogers
2026-05-22 22:33 ` [RFC PATCH v1 05/14] perf stat: Extend STD output linter to test advanced PMU checks Ian Rogers
2026-05-22 22:33 ` [RFC PATCH v1 06/14] perf stat: Extend STD output linter to test metric-only checks Ian Rogers
2026-05-22 22:33 ` [RFC PATCH v1 07/14] perf stat: Implement CSV formatting callbacks Ian Rogers
2026-05-22 23:01   ` sashiko-bot
2026-05-22 22:33 ` [RFC PATCH v1 08/14] perf stat: Extend CSV output linter to test core aggregation checks Ian Rogers
2026-05-22 22:59   ` sashiko-bot
2026-05-22 22:33 ` [RFC PATCH v1 09/14] perf stat: Extend CSV output linter to test advanced PMU and metric-only checks Ian Rogers
2026-05-22 22:48   ` sashiko-bot
2026-05-22 22:33 ` [RFC PATCH v1 10/14] perf stat: Implement streaming JSON formatting callbacks Ian Rogers
2026-05-22 23:02   ` sashiko-bot
2026-05-22 22:33 ` [RFC PATCH v1 11/14] perf stat: Extend JSON output linter to test core aggregation checks Ian Rogers
2026-05-22 22:53   ` sashiko-bot
2026-05-22 22:33 ` [RFC PATCH v1 12/14] perf stat: Extend JSON output linter to test advanced PMU and metric-only checks Ian Rogers
2026-05-22 22:33 ` [RFC PATCH v1 13/14] perf stat: Add --new support to PMU metrics Python validator Ian Rogers
2026-05-22 22:33 ` [RFC PATCH v1 14/14] perf stat: Extend PMU metrics value linter to validate --new outputs Ian Rogers
2026-05-25 23:18 ` [RFC PATCH v2 00/14] perf stat: Decouple and modularize metrics/events output printing API Ian Rogers
2026-05-25 23:18   ` [RFC PATCH v2 01/14] perf stat: Introduce core generic print traversal engine and header stubs Ian Rogers
2026-05-25 23:38     ` Arnaldo Carvalho de Melo
2026-05-25 23:48       ` Ian Rogers
2026-05-26  0:20         ` Arnaldo Carvalho de Melo
2026-05-25 23:18   ` [RFC PATCH v2 02/14] perf stat: Implement standard console (STD) formatting callbacks Ian Rogers
2026-05-25 23:49     ` Arnaldo Carvalho de Melo
2026-05-26  0:09       ` Ian Rogers
2026-05-25 23:53     ` sashiko-bot
2026-05-25 23:18   ` [RFC PATCH v2 03/14] perf stat: Extend STD output linter to test basic New API checks Ian Rogers
2026-05-25 23:39     ` Arnaldo Carvalho de Melo
2026-05-25 23:18   ` [RFC PATCH v2 04/14] perf stat: Extend STD output linter to test core aggregation checks Ian Rogers
2026-05-25 23:18   ` [RFC PATCH v2 05/14] perf stat: Extend STD output linter to test advanced PMU checks Ian Rogers
2026-05-25 23:18   ` [RFC PATCH v2 06/14] perf stat: Extend STD output linter to test metric-only checks Ian Rogers
2026-05-25 23:18   ` [RFC PATCH v2 07/14] perf stat: Implement CSV formatting callbacks Ian Rogers
2026-05-25 23:18   ` [RFC PATCH v2 08/14] perf stat: Extend CSV output linter to test core aggregation checks Ian Rogers
2026-05-25 23:18   ` [RFC PATCH v2 09/14] perf stat: Extend CSV output linter to test advanced PMU and metric-only checks Ian Rogers
2026-05-25 23:18   ` [RFC PATCH v2 10/14] perf stat: Implement streaming JSON formatting callbacks Ian Rogers
2026-05-25 23:18   ` [RFC PATCH v2 11/14] perf stat: Extend JSON output linter to test core aggregation checks Ian Rogers
2026-05-25 23:18   ` [RFC PATCH v2 12/14] perf stat: Extend JSON output linter to test advanced PMU and metric-only checks Ian Rogers
2026-05-25 23:18   ` [RFC PATCH v2 13/14] perf stat: Add --new support to PMU metrics Python validator Ian Rogers
2026-05-25 23:19   ` [RFC PATCH v2 14/14] perf stat: Extend PMU metrics value linter to validate --new outputs Ian Rogers
2026-05-25 23:53     ` 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=20260522225446.1C60A1F000E9@smtp.kernel.org \
    --to=sashiko-bot@kernel.org \
    --cc=irogers@google.com \
    --cc=linux-perf-users@vger.kernel.org \
    --cc=sashiko-reviews@lists.linux.dev \
    /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