aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorArnaldo Carvalho de Melo <acme@redhat.com>2024-02-20 09:55:26 -0300
committerArnaldo Carvalho de Melo <acme@redhat.com>2024-02-20 09:55:26 -0300
commitbe638365781ed0c843249c5bcebe90a01e74b2fe (patch)
tree3f9b7f24268bac601aec6fb0c894d1c9b39b9828
parente18ef2fed1b1a2c562883cbf31a072786cac814f (diff)
downloadpahole-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.c20
1 files changed, 14 insertions, 6 deletions
diff --git a/pahole.c b/pahole.c
index 1a7f7eb8..bb68d40b 100644
--- a/pahole.c
+++ b/pahole.c
@@ -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);