diff options
author | Arnaldo Carvalho de Melo <acme@redhat.com> | 2024-02-20 09:55:26 -0300 |
---|---|---|
committer | Arnaldo Carvalho de Melo <acme@redhat.com> | 2024-02-20 09:55:26 -0300 |
commit | be638365781ed0c843249c5bcebe90a01e74b2fe (patch) | |
tree | 3f9b7f24268bac601aec6fb0c894d1c9b39b9828 | |
parent | e18ef2fed1b1a2c562883cbf31a072786cac814f (diff) | |
download | pahole-be638365781ed0c843249c5bcebe90a01e74b2fe.tar.gz |
pahole: Improve error message when not resolving symbolic names in filters
To improve figuring out why this command line fails:
$ pahole -F dwarf -V ~/bin/perf --header=perf_file_header --seek_bytes '$header.data.offset' --size_bytes='$header.data.size' -C 'perf_event_header(sizeof,type,type_enum=perf_event_type,filter=type==PERF_RECORD_MMAP2)' --prettify perf.data
pahole: sizeof_operator for 'perf_event_header' is 'size'
pahole: type member for 'perf_event_header' is 'type'
pahole: type enum for 'perf_event_header' is 'perf_event_type'
pahole: filter for 'perf_event_header' is 'type==PERF_RECORD_MMAP2'
Symbolic right operand in 'type==PERF_RECORD_MMAP2' but no way to resolve it to a number (type_enum empty or hasn't found any so far) at CU 'builtin-annotate.c')
pahole: invalid filter 'type==PERF_RECORD_MMAP2' for 'perf_event_header'
pahole: type 'perf_event_header' not found or arguments not validated
$
In this case we don't have the 'enum perf_event_header' in
builtin-annotate.o, so we must defer trying to parse that
perf_event_header(sizeof,type,type_enum=perf_event_type,filter=type==PERF_RECORD_MMAP2)
class expression to when we find it.
When using BTF it all works as all types are in just one CU:
$ pahole -F btf -V ~/bin/perf --header=perf_file_header --seek_bytes '$header.data.offset' --size_bytes='$header.data.size' -C 'perf_event_header(sizeof,type,type_enum=perf_event_type,filter=type==PERF_RECORD_MMAP2)' --prettify perf.data
pahole: sizeof_operator for 'perf_event_header' is 'size'
pahole: type member for 'perf_event_header' is 'type'
pahole: type enum for 'perf_event_header' is 'perf_event_type'
pahole: filter for 'perf_event_header' is 'type==PERF_RECORD_MMAP2'
pahole: seek bytes evaluated from --seek_bytes=$header.data.offset is 0x3f0
pahole: size bytes evaluated from --size_bytes=$header.data.size is 0xd10
// type=perf_event_header, offset=0xc20, sizeof=8, real_sizeof=112
{
.header = {
.type = PERF_RECORD_MMAP2,
.misc = 2,
.size = 112,
},
.pid = 1533617,
.tid = 1533617,
.start = 94667542700032,
.len = 90112,
.pgoff = 16384,{
.maj = 0,
.min = 33,
.ino = 35914923,
.ino_generation = 26870,
},{
.build_id_size = 0,
.__reserved_1 = 0,
.__reserved_2 = 0,
.build_id = { 33, 0, 0, 0, -85, 4, 36, 2, 0, 0, 0, 0, -10, 104, 0, 0, 0, 0, 0, 0 },
},
.prot = 5,
.flags = 2,
.filename = "/usr/bin/ls",
},
// type=perf_event_header, offset=0xc90, sizeof=8, real_sizeof=128
{
.header = {
.type = PERF_RECORD_MMAP2,
.misc = 2,
.size = 128,
},
.pid = 1533617,
.tid = 1533617,
.start = 140033104936960,
.len = 159744,
.pgoff = 4096,{
.maj = 0,
.min = 33,
.ino = 35909039,
.ino_generation = 26870,
},{
.build_id_size = 0,
.__reserved_1 = 0,
.__reserved_2 = 0,
.build_id = { 33, 0, 0, 0, -81, -19, 35, 2, 0, 0, 0, 0, -10, 104, 0, 0, 0, 0, 0, 0 },
},
.prot = 5,
.flags = 2,
.filename = "/usr/lib64/ld-linux-x86-64.so.2",
},
<SNIP more PERF_RECORD_MMAP2 records>
$
$ pahole --contains_enumerator PERF_RECORD_MMAP2
enum perf_event_type {
PERF_RECORD_MMAP = 1,
PERF_RECORD_LOST = 2,
PERF_RECORD_COMM = 3,
PERF_RECORD_EXIT = 4,
PERF_RECORD_THROTTLE = 5,
PERF_RECORD_UNTHROTTLE = 6,
PERF_RECORD_FORK = 7,
PERF_RECORD_READ = 8,
PERF_RECORD_SAMPLE = 9,
PERF_RECORD_MMAP2 = 10,
PERF_RECORD_AUX = 11,
PERF_RECORD_ITRACE_START = 12,
PERF_RECORD_LOST_SAMPLES = 13,
PERF_RECORD_SWITCH = 14,
PERF_RECORD_SWITCH_CPU_WIDE = 15,
PERF_RECORD_NAMESPACES = 16,
PERF_RECORD_KSYMBOL = 17,
PERF_RECORD_BPF_EVENT = 18,
PERF_RECORD_CGROUP = 19,
PERF_RECORD_TEXT_POKE = 20,
PERF_RECORD_AUX_OUTPUT_HW_ID = 21,
PERF_RECORD_MAX = 22,
}
$
If we replace PERF_RECORD_MMAP2 with its numeric value, then it works
with DWARF as well.
$ pahole -F dwarf -V ~/bin/perf --header=perf_file_header --seek_bytes '$header.data.offset' --size_bytes='$header.data.size' -C 'perf_event_header(sizeof,type,type_enum=perf_event_type,filter=type==10)' --prettify perf.data --count 1
pahole: sizeof_operator for 'perf_event_header' is 'size'
pahole: type member for 'perf_event_header' is 'type'
pahole: type enum for 'perf_event_header' is 'perf_event_type'
pahole: filter for 'perf_event_header' is 'type==10'
pahole: seek bytes evaluated from --seek_bytes=$header.data.offset is 0x3f0
pahole: size bytes evaluated from --size_bytes=$header.data.size is 0xd10
// type=perf_event_header, offset=0xc20, sizeof=8, real_sizeof=112
{
.header = {
.type = PERF_RECORD_MMAP2,
.misc = 2,
.size = 112,
},
.pid = 1533617,
.tid = 1533617,
.start = 94667542700032,
.len = 90112,
.pgoff = 16384,{
.maj = 0,
.min = 33,
.ino = 35914923,
.ino_generation = 26870,
},{
.build_id_size = 0,
.__reserved_1 = 0,
.__reserved_2 = 0,
.build_id = { 33, 0, 0, 0, -85, 4, 36, 2, 0, 0, 0, 0, -10, 104, 0, 0, 0, 0, 0, 0 },
},
.prot = 5,
.flags = 2,
.filename = "/usr/bin/ls",
},
$
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
-rw-r--r-- | pahole.c | 20 |
1 files changed, 14 insertions, 6 deletions
@@ -2839,7 +2839,7 @@ out: return printed; } -static int class_member_filter__parse(struct class_member_filter *filter, struct type *type, char *sfilter) +static int class_member_filter__parse(struct class_member_filter *filter, struct type *type, const struct cu *cu, char *sfilter) { const char *member_name = sfilter; char *sep = strstr(sfilter, "=="); @@ -2888,9 +2888,17 @@ static int class_member_filter__parse(struct class_member_filter *filter, struct // If t he filter member is the 'type=' one: - if (list_empty(&type->type_enum) || type->type_member != filter->left) { + if (list_empty(&type->type_enum)) { + if (global_verbose) { + fprintf(stderr, "Symbolic right operand in '%s' but no way to resolve it to a number (type_enum empty or hasn't found any so far) at CU '%s')\n", + sfilter, cu->name); + } + return -1; + } + + if (type->type_member != filter->left) { if (global_verbose) - fprintf(stderr, "Symbolic right operand in '%s' but no way to resolve it to a number (type= + type_enum= so far)\n", sfilter); + fprintf(stderr, "type->type_member (%p) != filter->left (%p)\n", type->type_member, filter->left); return -1; } @@ -2910,11 +2918,11 @@ static int class_member_filter__parse(struct class_member_filter *filter, struct return 0; } -static struct class_member_filter *class_member_filter__new(struct type *type, char *sfilter) +static struct class_member_filter *class_member_filter__new(struct type *type, const struct cu *cu, char *sfilter) { struct class_member_filter *filter = zalloc(sizeof(*filter)); - if (filter && class_member_filter__parse(filter, type, sfilter)) { + if (filter && class_member_filter__parse(filter, type, cu, sfilter)) { free(filter); filter = NULL; } @@ -3394,7 +3402,7 @@ out_btf: } if (prototype->filter) { - type->filter = class_member_filter__new(type, prototype->filter); + type->filter = class_member_filter__new(type, cu, prototype->filter); if (type->filter == NULL) { fprintf(stderr, "pahole: invalid filter '%s' for '%s'\n", prototype->filter, prototype->name); |