From 261210854462ef5e587eb1b740aa06dbab3b3a40 Mon Sep 17 00:00:00 2001 From: Ivan Lazaric Date: Wed, 8 Jul 2026 15:14:01 +0200 Subject: [PATCH] perf stat: reject --field-separator and --json-output combination Specifying --field-separator option is stating you want CSV output. Passing both --field-separator and --json-output is then stating you want output to be in CSV and JSON format at same time. Currently this combination is not rejected, and the outcome is a malformed combination of CSV and JSON output. This is because of inconsistencies in various printing functions, some of them have if-else chains that start with "Should I print JSON?", and some start with "Should I print CSV?". Example of current output: $ tools/perf/perf stat -x , -j -e cpu-migrations true {"counter-value" : "0.000000", "unit" : "", "event" : "cpu-migrations", "event-runtime" : 474817, "pcnt-running" : 100.00,, Instead reject the option combination, with a helpful error message and non-zero exit code. Example of new output: $ tools/perf/perf stat -x , -j true cannot use both --field-separator and --json-output Usage: perf stat [] [] -x, --field-separator print counts with custom separator -j, --json-output print counts in JSON format Signed-off-by: Ivan Lazaric Signed-off-by: Namhyung Kim --- tools/perf/builtin-stat.c | 7 +++++++ tools/perf/tests/shell/stat.sh | 12 ++++++++++++ 2 files changed, 19 insertions(+) diff --git a/tools/perf/builtin-stat.c b/tools/perf/builtin-stat.c index 92cdb2df7285..3f685beba384 100644 --- a/tools/perf/builtin-stat.c +++ b/tools/perf/builtin-stat.c @@ -2655,6 +2655,13 @@ int cmd_stat(int argc, const char **argv) stat_config.aggr_mode = opt_aggr_mode_to_aggr_mode(&opt_mode); + if (stat_config.csv_sep && stat_config.json_output) { + fprintf(stderr, "cannot use both --field-separator and --json-output\n"); + parse_options_usage(stat_usage, stat_options, "x", 1); + parse_options_usage(NULL, stat_options, "j", 1); + goto out; + } + if (stat_config.csv_sep) { stat_config.csv_output = true; if (!strcmp(stat_config.csv_sep, "\\t")) diff --git a/tools/perf/tests/shell/stat.sh b/tools/perf/tests/shell/stat.sh index 1e17bee026bd..649de1166fed 100755 --- a/tools/perf/tests/shell/stat.sh +++ b/tools/perf/tests/shell/stat.sh @@ -535,6 +535,17 @@ test_stat_delay() { echo "stat -D test [Success]" } +test_csv_json_fail() { + echo "stat -x -j test" + if perf stat -x , -j true > /dev/null 2>&1 + then + echo "stat -x -j test [Failed - command should have errored]" + err=1 + else + echo "stat -x -j test [Success]" + fi +} + test_default_stat test_null_stat test_offline_cpu_stat @@ -551,6 +562,7 @@ test_stat_detailed test_stat_repeat test_stat_pid test_stat_delay +test_csv_json_fail cleanup exit $err