On Fri, 5 Aug 2016 20:53:21 +0900 Naohiro Aota <naohiro.a...@hgst.com> wrote:
> Perf-probe detects a variable's type and use the detected type to add new > probe. Then, kprobes prints its variable in hexadecimal format if the > variable is unsigned and prints in decimal if it is signed. > > We sometimes want to see unsigned variable in decimal format (i.e. > sector_t or size_t). In that case, we need to investigate variable's > size manually to specify just signedness. > > This patch add signedness casting support. By specifying "s" or "u" as a > type, perf-probe will investigate variable size as usual and use > the specified signedness. > > E.g. without this: > > $ perf probe -a 'submit_bio bio->bi_iter.bi_sector' > Added new event: > probe:submit_bio (on submit_bio with bi_sector=bio->bi_iter.bi_sector) > You can now use it in all perf tools, such as: > perf record -e probe:submit_bio -aR sleep 1 > $ cat trace_pipe|head > dbench-9692 [003] d..1 971.096633: submit_bio: > (submit_bio+0x0/0x140) bi_sector=0x3a3d00 > dbench-9692 [003] d..1 971.096685: submit_bio: > (submit_bio+0x0/0x140) bi_sector=0x1a3d80 > dbench-9692 [003] d..1 971.096687: submit_bio: > (submit_bio+0x0/0x140) bi_sector=0x3a3d80 > ... > // need to investigate the variable size > $ perf probe -a 'submit_bio bio->bi_iter.bi_sector:s64' > Added new event: > probe:submit_bio (on submit_bio with > bi_sector=bio->bi_iter.bi_sector:s64) > You can now use it in all perf tools, such as: > perf record -e probe:submit_bio -aR sleep 1 > > With this: > > // just use "s" to cast its signedness > $ perf probe -v -a 'submit_bio bio->bi_iter.bi_sector:s' > Added new event: > probe:submit_bio (on submit_bio with bi_sector=bio->bi_iter.bi_sector:s) > You can now use it in all perf tools, such as: > perf record -e probe:submit_bio -aR sleep 1 > $ cat trace_pipe|head > dbench-9689 [001] d..1 1212.391237: submit_bio: > (submit_bio+0x0/0x140) bi_sector=128 > dbench-9689 [001] d..1 1212.391252: submit_bio: > (submit_bio+0x0/0x140) bi_sector=131072 > dbench-9697 [006] d..1 1212.398611: submit_bio: > (submit_bio+0x0/0x140) bi_sector=30208 > > This commit also update perf-probe.txt to describe "types". Most parts > are based on existing documentation: Documentation/trace/kprobetrace.txt > > Signed-off-by: Naohiro Aota <naohiro.a...@hgst.com> > --- > tools/perf/Documentation/perf-probe.txt | 10 +++++++++- > tools/perf/util/probe-finder.c | 15 ++++++++++++--- > 2 files changed, 21 insertions(+), 4 deletions(-) > > diff --git a/tools/perf/Documentation/perf-probe.txt > b/tools/perf/Documentation/perf-probe.txt > index 736da44..a23b124 100644 > --- a/tools/perf/Documentation/perf-probe.txt > +++ b/tools/perf/Documentation/perf-probe.txt > @@ -176,10 +176,18 @@ Each probe argument follows below syntax. > > 'NAME' specifies the name of this argument (optional). You can use the name > of local variable, local data structure member (e.g. var->field, var.field2), > local array with fixed index (e.g. array[1], var->array[0], var->pointer[2]), > or kprobe-tracer argument format (e.g. $retval, %ax, etc). Note that the name > of this argument will be set as the last member name if you specify a local > data structure member (e.g. field2 for 'var->field1.field2'.) > '$vars' and '$params' special arguments are also available for NAME, '$vars' > is expanded to the local variables (including function parameters) which can > access at given probe point. '$params' is expanded to only the function > parameters. > -'TYPE' casts the type of this argument (optional). If omitted, perf probe > automatically set the type based on debuginfo. You can specify 'string' type > only for the local variable or structure member which is an array of or a > pointer to 'char' or 'unsigned char' type. > +'TYPE' casts the type of this argument (optional). If omitted, perf probe > automatically set the type based on debuginfo. Currently, basic types > (u8/u16/u32/u64/s8/s16/s32/s64), "string" and bitfield are supported. (see > TYPES for detail) Hmm, have you added the 's' and 'u' here too ?? > > On x86 systems %REG is always the short form of the register: for example > %AX. %RAX or %EAX is not valid. > > +TYPES > +----- > +Basic types (u8/u16/u32/u64/s8/s16/s32/s64) are integer types. Prefix 's' > and 'u' means those types are signed and unsigned respectively. Traced > arguments are shown in decimal (signed) or hex (unsigned). You can also use > 's' or 'u' to specify only signedness and leave its size auto-detected by > perf probe. So, not only the details, but also the brief information about the TYPE, there should be 's' and 'u'. Other are good to me. Thanks, > +String type is a special type, which fetches a "null-terminated" string from > kernel space. This means it will fail and store NULL if the string container > has been paged out. You can specify 'string' type only for the local variable > or structure member which is an array of or a pointer to 'char' or 'unsigned > char' type. > +Bitfield is another special type, which takes 3 parameters, bit-width, > bit-offset, and container-size (usually 32). The syntax is; > + > + b<bit-width>@<bit-offset>/<container-size> > + > LINE SYNTAX > ----------- > Line range is described by following syntax. > diff --git a/tools/perf/util/probe-finder.c b/tools/perf/util/probe-finder.c > index f2d9ff0..5c290c6 100644 > --- a/tools/perf/util/probe-finder.c > +++ b/tools/perf/util/probe-finder.c > @@ -297,10 +297,13 @@ static int convert_variable_type(Dwarf_Die *vr_die, > char sbuf[STRERR_BUFSIZE]; > int bsize, boffs, total; > int ret; > + char sign; > > /* TODO: check all types */ > - if (cast && strcmp(cast, "string") != 0) { > + if (cast && strcmp(cast, "string") != 0 && > + strcmp(cast, "s") != 0 && strcmp(cast, "u") != 0) { > /* Non string type is OK */ > + /* and respect signedness cast */ > tvar->type = strdup(cast); > return (tvar->type == NULL) ? -ENOMEM : 0; > } > @@ -361,6 +364,13 @@ static int convert_variable_type(Dwarf_Die *vr_die, > return (tvar->type == NULL) ? -ENOMEM : 0; > } > > + if (cast && (strcmp(cast, "u") == 0)) > + sign = 'u'; > + else if (cast && (strcmp(cast, "s") == 0)) > + sign = 's'; > + else > + sign = die_is_signed_type(&type) ? 's' : 'u'; > + > ret = dwarf_bytesize(&type); > if (ret <= 0) > /* No size ... try to use default type */ > @@ -373,8 +383,7 @@ static int convert_variable_type(Dwarf_Die *vr_die, > dwarf_diename(&type), MAX_BASIC_TYPE_BITS); > ret = MAX_BASIC_TYPE_BITS; > } > - ret = snprintf(buf, 16, "%c%d", > - die_is_signed_type(&type) ? 's' : 'u', ret); > + ret = snprintf(buf, 16, "%c%d", sign, ret); > > formatted: > if (ret < 0 || ret >= 16) { -- Masami Hiramatsu <mhira...@kernel.org>