All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH] perf trace: Format fields with hex specifiers in print_fmt as hexadecimal
@ 2026-07-31 21:59 Aaron Tomlin
  2026-07-31 22:12 ` sashiko-bot
  0 siblings, 1 reply; 2+ messages in thread
From: Aaron Tomlin @ 2026-07-31 21:59 UTC (permalink / raw)
  To: peterz, mingo, acme, namhyung
  Cc: mark.rutland, alexander.shishkin, jolsa, irogers, adrian.hunter,
	james.clark, howardchu95, atomlin, neelx, chjohnst, sean, steve,
	rishil1999, linux-perf-users, linux-kernel

Currently, when a probe event is added using perf probe --add with a
hexadecimal type cast (e.g., var:x64 and var:x32), the kernel traceprobe
subsystem sets the field type to "u64" in the event's format file, yet
generates a print format specifier of "var=0x%Lx" or "0x%x".

By default, perf trace uses its internal beautifiers which only inspect
field->type and field->flags. Because traceprobe events declare
primitive integer field types ("u64") without a C pointer asterisk
(i.e., "*"), perf trace defaults to printing the field's value as a
decimal unsigned long ("%ld"), ignoring the hexadecimal intent.

Introduce field_has_hex_fmt() to inspect the tracepoint's print_fmt
format string. If a field's print format assignment uses hexadecimal
specifiers (i.e., "=0x", "=%#", or "=%p"), assign SCA_PTR formatting so
perf trace displays the value in hexadecimal by default without
requiring --libtraceevent. For example:

    ❯ sudo ./perf probe --add 'enqueue_task_fair rq=rq:x64 p=p:x64 flags=flags:x32'
    Added new event:
      probe:enqueue_task_fair (on enqueue_task_fair with rq=rq:x64 p=p:x64 flags=flags:x32)

    You can now use it in all perf tools, such as:

            perf record -e probe:enqueue_task_fair -aR sleep 1

    ❯ sudo ./perf trace --show-cpu --event probe:enqueue_task_fair --max-event 3
         0.000 [000] :0/0 probe:enqueue_task_fair(rq: 0xffff8ac632233180, p: 0xffff8ac2c1240000, flags: 0x100009)
         0.006 [004] :0/0 probe:enqueue_task_fair(rq: 0xffff8ac632433180, p: 0xffff8ac624cf8000, flags: 0x9)
         0.069 [001] :0/0 probe:enqueue_task_fair(rq: 0xffff8ac6322b3180, p: 0xffff8ac4c4212c40, flags: 0x9)

Signed-off-by: Aaron Tomlin <atomlin@atomlin.com>
---
 tools/perf/builtin-trace.c | 34 +++++++++++++++++++++++++++++++++-
 1 file changed, 33 insertions(+), 1 deletion(-)

diff --git a/tools/perf/builtin-trace.c b/tools/perf/builtin-trace.c
index ba0f8749fc7d..b0ce9c2a24e5 100644
--- a/tools/perf/builtin-trace.c
+++ b/tools/perf/builtin-trace.c
@@ -2098,6 +2098,37 @@ static bool is_internal_field(struct tep_format_field *field)
 	return !strcmp(field->type, "__data_loc char[]");
 }
 
+static bool field_has_hex_fmt(struct tep_format_field *field, int len)
+{
+	const char *fmt, *pos, *end;
+
+	if (!field || !field->event || !field->event->print_fmt.format)
+		return false;
+
+	fmt = field->event->print_fmt.format;
+
+	/* Limit scanning strictly to the quoted printf format string */
+	if (*fmt == '"') {
+		fmt++;
+		end = strchr(fmt, '"');
+	} else {
+		end = strchr(fmt, ',');
+	}
+
+	for (pos = strstr(fmt, field->name); pos && (!end || pos < end); pos = strstr(pos + 1, field->name)) {
+		if (pos == fmt || !(isalnum(pos[-1]) || pos[-1] == '_')) {
+			const char *after = pos + len;
+
+			if (*after == '=' && (strstarts(after + 1, "0x") ||
+					      strstarts(after + 1, "%#") ||
+					      strstarts(after + 1, "%p")))
+				return true;
+		}
+	}
+
+	return false;
+}
+
 static struct tep_format_field *
 syscall_arg_fmt__init_array(struct syscall_arg_fmt *arg, struct tep_format_field *field,
 			    bool *use_btf)
@@ -2125,7 +2156,8 @@ syscall_arg_fmt__init_array(struct syscall_arg_fmt *arg, struct tep_format_field
 		    ((len >= 4 && strcmp(field->name + len - 4, "name") == 0) ||
 		     strstr(field->name, "path") != NULL)) {
 			arg->scnprintf = SCA_FILENAME;
-		} else if ((field->flags & TEP_FIELD_IS_POINTER) || strstr(field->name, "addr"))
+		} else if ((field->flags & TEP_FIELD_IS_POINTER) || strstr(field->name, "addr") ||
+			   field_has_hex_fmt(field, len))
 			arg->scnprintf = SCA_PTR;
 		else if (strcmp(field->type, "pid_t") == 0)
 			arg->scnprintf = SCA_PID;
-- 
2.55.0


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

* Re: [PATCH] perf trace: Format fields with hex specifiers in print_fmt as hexadecimal
  2026-07-31 21:59 [PATCH] perf trace: Format fields with hex specifiers in print_fmt as hexadecimal Aaron Tomlin
@ 2026-07-31 22:12 ` sashiko-bot
  0 siblings, 0 replies; 2+ messages in thread
From: sashiko-bot @ 2026-07-31 22:12 UTC (permalink / raw)
  To: Aaron Tomlin; +Cc: linux-perf-users

Thank you for your contribution! Sashiko AI review found 1 potential issue(s) to consider:
- [Medium] field_has_hex_fmt() prematurely truncates the format string search when it encounters escaped quotes.
--

--- Patch [1]: [PATCH] perf trace: Format fields with hex specifiers in print_fmt as hexadecimal ---
commit 1d9edf5adf3cf666d7e9393e5db036cd73d6656a
Author: Aaron Tomlin <atomlin@atomlin.com>

perf trace: Format fields with hex specifiers in print_fmt as hexadecimal

This commit introduces field_has_hex_fmt to inspect tracepoint print_fmt
strings. If a field uses hexadecimal specifiers, it assigns SCA_PTR formatting
to display the value in hexadecimal by default.

> diff --git a/tools/perf/builtin-trace.c b/tools/perf/builtin-trace.c
> index ba0f8749fc7d7..b0ce9c2a24e57 100644
> --- a/tools/perf/builtin-trace.c
> +++ b/tools/perf/builtin-trace.c
[ ... ]
> @@ -2098,6 +2098,37 @@ static bool is_internal_field(struct tep_format_field *field)
>  	return !strcmp(field->type, "__data_loc char[]");
>  }
>  
> +static bool field_has_hex_fmt(struct tep_format_field *field, int len)
> +{
> +	const char *fmt, *pos, *end;
> +
> +	if (!field || !field->event || !field->event->print_fmt.format)
> +		return false;
> +
> +	fmt = field->event->print_fmt.format;
> +
> +	/* Limit scanning strictly to the quoted printf format string */
> +	if (*fmt == '"') {
> +		fmt++;
> +		end = strchr(fmt, '"');

[Severity: Medium]
Does this parsing correctly handle escaped quotes inside the format string?

If a tracepoint format string contains an escaped quote, this strchr call
will incorrectly match it as the end of the format string, causing the end
pointer to be prematurely truncated.

> +	} else {
> +		end = strchr(fmt, ',');
> +	}
> +
> +	for (pos = strstr(fmt, field->name); pos && (!end || pos < end); pos = strstr(pos + 1, field->name)) {

[Severity: Medium]
Because the end pointer can be truncated by an escaped quote earlier, won't
the pos < end loop condition evaluate to false for any fields positioned after
that escaped quote?

This seems like it would skip hex format detection for those subsequent fields,
causing them to fall back to default decimal formatting.

> +		if (pos == fmt || !(isalnum(pos[-1]) || pos[-1] == '_')) {
> +			const char *after = pos + len;
[ ... ]

-- 
Sashiko AI review · https://sashiko.dev/#/patchset/20260731215909.125335-1-atomlin@atomlin.com?part=1

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

end of thread, other threads:[~2026-07-31 22:12 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-07-31 21:59 [PATCH] perf trace: Format fields with hex specifiers in print_fmt as hexadecimal Aaron Tomlin
2026-07-31 22:12 ` sashiko-bot

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.