From: Aaron Tomlin <atomlin@atomlin.com>
To: peterz@infradead.org, mingo@redhat.com, acme@kernel.org,
namhyung@kernel.org
Cc: mark.rutland@arm.com, alexander.shishkin@linux.intel.com,
jolsa@kernel.org, irogers@google.com, adrian.hunter@intel.com,
james.clark@linaro.org, howardchu95@gmail.com,
atomlin@atomlin.com, neelx@suse.com, chjohnst@mail.com,
sean@ashe.io, steve@abita.co, rishil1999@outlook.com,
linux-perf-users@vger.kernel.org, linux-kernel@vger.kernel.org
Subject: [PATCH] perf trace: Format fields with hex specifiers in print_fmt as hexadecimal
Date: Fri, 31 Jul 2026 17:59:09 -0400 [thread overview]
Message-ID: <20260731215909.125335-1-atomlin@atomlin.com> (raw)
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
next reply other threads:[~2026-07-31 21:59 UTC|newest]
Thread overview: 2+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-07-31 21:59 Aaron Tomlin [this message]
2026-07-31 22:12 ` [PATCH] perf trace: Format fields with hex specifiers in print_fmt as hexadecimal 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=20260731215909.125335-1-atomlin@atomlin.com \
--to=atomlin@atomlin.com \
--cc=acme@kernel.org \
--cc=adrian.hunter@intel.com \
--cc=alexander.shishkin@linux.intel.com \
--cc=chjohnst@mail.com \
--cc=howardchu95@gmail.com \
--cc=irogers@google.com \
--cc=james.clark@linaro.org \
--cc=jolsa@kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-perf-users@vger.kernel.org \
--cc=mark.rutland@arm.com \
--cc=mingo@redhat.com \
--cc=namhyung@kernel.org \
--cc=neelx@suse.com \
--cc=peterz@infradead.org \
--cc=rishil1999@outlook.com \
--cc=sean@ashe.io \
--cc=steve@abita.co \
/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.