Commit b257fac1 authored by Howard Chu's avatar Howard Chu Committed by Arnaldo Carvalho de Melo

perf trace: Pretty print buffer data

Define TRACE_AUG_MAX_BUF in trace_augment.h data, which is the maximum
buffer size we can augment. BPF will include this header too.

Print buffer in a way that's different than just printing a string, we
print all the control characters in \digits (such as \0 for null, and
\10 for newline, LF).

For character that has a bigger value than 127, we print the digits
instead of the character itself as well.

Committer notes:

Simplified the buffer scnprintf to avoid using multiple buffers as
discussed in the patch review thread.

We can't really all 'buf' args to SCA_BUF as we're collecting so far
just on the sys_enter path, so we would be printing the previous 'read'
arg buffer contents, not what the kernel puts there.

So instead of:
   static int syscall_fmt__cmp(const void *name, const void *fmtp)
  @@ -1987,8 +1989,6 @@ syscall_arg_fmt__init_array(struct syscall_arg_fmt *arg, struct tep_format_field
  -               else if (strstr(field->type, "char *") && strstr(field->name, "buf"))
  -                       arg->scnprintf = SCA_BUF;

Do:

static const struct syscall_fmt syscall_fmts[] = {
  +       { .name     = "write",      .errpid = true,
  +         .arg = { [1] = { .scnprintf = SCA_BUF /* buf */, from_user = true, }, }, },
Signed-off-by: default avatarHoward Chu <howardchu95@gmail.com>
Cc: Adrian Hunter <adrian.hunter@intel.com>
Cc: Ian Rogers <irogers@google.com>
Cc: Jiri Olsa <jolsa@kernel.org>
Cc: Kan Liang <kan.liang@linux.intel.com>
Cc: Namhyung Kim <namhyung@kernel.org>
Link: https://lore.kernel.org/r/20240815013626.935097-8-howardchu95@gmail.com
Link: https://lore.kernel.org/r/20240824163322.60796-6-howardchu95@gmail.comSigned-off-by: default avatarArnaldo Carvalho de Melo <acme@redhat.com>
parent cb320352
...@@ -65,6 +65,7 @@ ...@@ -65,6 +65,7 @@
#include "syscalltbl.h" #include "syscalltbl.h"
#include "rb_resort.h" #include "rb_resort.h"
#include "../perf.h" #include "../perf.h"
#include "trace_augment.h"
#include <errno.h> #include <errno.h>
#include <inttypes.h> #include <inttypes.h>
...@@ -864,6 +865,10 @@ static size_t syscall_arg__scnprintf_filename(char *bf, size_t size, ...@@ -864,6 +865,10 @@ static size_t syscall_arg__scnprintf_filename(char *bf, size_t size,
{ .scnprintf = SCA_FILENAME, \ { .scnprintf = SCA_FILENAME, \
.from_user = true, } .from_user = true, }
static size_t syscall_arg__scnprintf_buf(char *bf, size_t size, struct syscall_arg *arg);
#define SCA_BUF syscall_arg__scnprintf_buf
static size_t syscall_arg__scnprintf_pipe_flags(char *bf, size_t size, static size_t syscall_arg__scnprintf_pipe_flags(char *bf, size_t size,
struct syscall_arg *arg) struct syscall_arg *arg)
{ {
...@@ -1387,6 +1392,8 @@ static const struct syscall_fmt syscall_fmts[] = { ...@@ -1387,6 +1392,8 @@ static const struct syscall_fmt syscall_fmts[] = {
.arg = { [2] = { .scnprintf = SCA_WAITID_OPTIONS, /* options */ }, }, }, .arg = { [2] = { .scnprintf = SCA_WAITID_OPTIONS, /* options */ }, }, },
{ .name = "waitid", .errpid = true, { .name = "waitid", .errpid = true,
.arg = { [3] = { .scnprintf = SCA_WAITID_OPTIONS, /* options */ }, }, }, .arg = { [3] = { .scnprintf = SCA_WAITID_OPTIONS, /* options */ }, }, },
{ .name = "write", .errpid = true,
.arg = { [1] = { .scnprintf = SCA_BUF /* buf */, .from_user = true, }, }, },
}; };
static int syscall_fmt__cmp(const void *name, const void *fmtp) static int syscall_fmt__cmp(const void *name, const void *fmtp)
...@@ -1758,6 +1765,32 @@ static size_t syscall_arg__scnprintf_filename(char *bf, size_t size, ...@@ -1758,6 +1765,32 @@ static size_t syscall_arg__scnprintf_filename(char *bf, size_t size,
return 0; return 0;
} }
#define MAX_CONTROL_CHAR 31
#define MAX_ASCII 127
static size_t syscall_arg__scnprintf_buf(char *bf, size_t size, struct syscall_arg *arg)
{
struct augmented_arg *augmented_arg = arg->augmented.args;
unsigned char *orig = (unsigned char *)augmented_arg->value;
size_t printed = 0;
int consumed;
if (augmented_arg == NULL)
return 0;
for (int j = 0; j < augmented_arg->size; ++j) {
bool control_char = orig[j] <= MAX_CONTROL_CHAR || orig[j] >= MAX_ASCII;
/* print control characters (0~31 and 127), and non-ascii characters in \(digits) */
printed += scnprintf(bf + printed, size - printed, control_char ? "\\%d" : "%c", (int)orig[j]);
}
consumed = sizeof(*augmented_arg) + augmented_arg->size;
arg->augmented.args = ((void *)arg->augmented.args) + consumed;
arg->augmented.size -= consumed;
return printed;
}
static bool trace__filter_duration(struct trace *trace, double t) static bool trace__filter_duration(struct trace *trace, double t)
{ {
return t < (trace->duration_filter * NSEC_PER_MSEC); return t < (trace->duration_filter * NSEC_PER_MSEC);
......
#ifndef TRACE_AUGMENT_H
#define TRACE_AUGMENT_H
#define TRACE_AUG_MAX_BUF 32 /* for buffer augmentation in perf trace */
#endif
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment