Skip to content

Commit

Permalink
perf script: Print Intel ptwrite value as a string if it is ASCII
Browse files Browse the repository at this point in the history
It can be convenient to put a string value into a ptwrite payload as
a quick and easy way to identify what is being printed.

To make that useful, if the Intel ptwrite payload value contains only
printable ASCII characters padded with NULLs, then print it also as a
string.

Using the example program from the "Emulated PTWRITE" section of
tools/perf/Documentation/perf-intel-pt.txt:

 $ echo -n "Hello" | od -t x8
 0000000 0000006f6c6c6548
 0000005
 $ perf record -e intel_pt//u ./eg_ptw 0x0000006f6c6c6548
 [ perf record: Woken up 1 times to write data ]
 [ perf record: Captured and wrote 0.016 MB perf.data ]
 $ perf script --itrace=ew
           eg_ptw 35563 [005] 18256.087338:     ptwrite:  IP: 0 payload: 0x6f6c6c6548 Hello      55e764db5196 perf_emulate_ptwrite+0x16 (/home/user/eg_ptw)
 $

Signed-off-by: Adrian Hunter <adrian.hunter@intel.com>
Cc: Jiri Olsa <jolsa@kernel.org>
Link: https://lore.kernel.org/r/20220509152400.376613-3-adrian.hunter@intel.com
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
  • Loading branch information
Adrian Hunter authored and Arnaldo Carvalho de Melo committed May 17, 2022
1 parent d7015e5 commit a501431
Showing 1 changed file with 30 additions and 2 deletions.
32 changes: 30 additions & 2 deletions tools/perf/builtin-script.c
Original file line number Diff line number Diff line change
Expand Up @@ -1742,16 +1742,44 @@ static int perf_sample__fprintf_pt_spacing(int len, FILE *fp)
return perf_sample__fprintf_spacing(len, 34, fp);
}

/* If a value contains only printable ASCII characters padded with NULLs */
static bool ptw_is_prt(u64 val)
{
char c;
u32 i;

for (i = 0; i < sizeof(val); i++) {
c = ((char *)&val)[i];
if (!c)
break;
if (!isprint(c) || !isascii(c))
return false;
}
for (; i < sizeof(val); i++) {
c = ((char *)&val)[i];
if (c)
return false;
}
return true;
}

static int perf_sample__fprintf_synth_ptwrite(struct perf_sample *sample, FILE *fp)
{
struct perf_synth_intel_ptwrite *data = perf_sample__synth_ptr(sample);
char str[sizeof(u64) + 1] = "";
int len;
u64 val;

if (perf_sample__bad_synth_size(sample, *data))
return 0;

len = fprintf(fp, " IP: %u payload: %#" PRIx64 " ",
data->ip, le64_to_cpu(data->payload));
val = le64_to_cpu(data->payload);
if (ptw_is_prt(val)) {
memcpy(str, &val, sizeof(val));
str[sizeof(val)] = 0;
}
len = fprintf(fp, " IP: %u payload: %#" PRIx64 " %s ",
data->ip, val, str);
return len + perf_sample__fprintf_pt_spacing(len, fp);
}

Expand Down

0 comments on commit a501431

Please sign in to comment.