On Thu, Oct 22, 2020 at 01:00:19PM -0700, Andrii Nakryiko wrote: SNIP > > > > hi, > > FYI there's still no solution yet, so far the progress is: > > > > the proposed workaround was to use the negation -> we don't have > > DW_AT_declaration tag, so let's find out instead which DW_TAG_subprogram > > tags have attached code and skip them if they don't have any: > > https://gcc.gnu.org/bugzilla/show_bug.cgi?id=97060#c10 > > > > the attached patch is doing that, but the resulting BTF is missing > > several functions due to another bug in dwarf: > > https://bugzilla.redhat.com/show_bug.cgi?id=1890107 > > It seems fine if there are only few functions (especially if those are > unlikely to be traced). Do you have an estimate of how many functions > have this second DWARF bug? it wasn't that many, I'll recheck > > > > > > > the only other workaround I can think of is to check each DW_TAG_subprogram > > tag name with vmlinux symbol to ensure it's actually present, > > I'll check on it, because as Mark suggested it might be good > > for future not to completely rely on dwarf being correct, even > > if that gcc bug gets eventually fixed > > This might be a good thing to do anyways. Currently BTF contains only > global functions, but a lot of static functions that didn't end up > inlined are available for attachment, but because BTF info is not > there, we can't use fentry/fexit on them. Checking against ELF symbols > would match kallsyms, right? So we would be able to drop fn->external > requirement and have all the attachable functions available. right, both static and global > > Have you tried this? I'm curious how good the data is and how much > bigger BTF size is with all the functions included? I did not realize that with droping fn->external this would bring static functions as well, now I want to try ;-) jirka > > > > > jirka > > > > > > --- > > diff --git a/btf_encoder.c b/btf_encoder.c > > index e90150784282..51a370d580b7 100644 > > --- a/btf_encoder.c > > +++ b/btf_encoder.c > > @@ -302,8 +302,9 @@ int cu__encode_btf(struct cu *cu, int verbose, bool force, > > > > cu__for_each_function(cu, core_id, fn) { > > int btf_fnproto_id, btf_fn_id; > > + bool has_pc = !!function__addr(fn) || fn->ranges; > > > > - if (fn->declaration || !fn->external) > > + if (!has_pc || !fn->external) > > continue; > > > > btf_fnproto_id = btf_elf__add_func_proto(btfe, &fn->proto, type_id_off); > > diff --git a/dwarf_loader.c b/dwarf_loader.c > > index d3586aa5b0dd..4763b9118475 100644 > > --- a/dwarf_loader.c > > +++ b/dwarf_loader.c > > @@ -953,6 +953,7 @@ static struct function *function__new(Dwarf_Die *die, struct cu *cu) > > func->declaration = dwarf_hasattr(die, DW_AT_declaration); > > func->external = dwarf_hasattr(die, DW_AT_external); > > func->abstract_origin = dwarf_hasattr(die, DW_AT_abstract_origin); > > + func->ranges = dwarf_hasattr(die, DW_AT_ranges); > > dwarf_tag__set_spec(func->proto.tag.priv, > > attr_type(die, DW_AT_specification)); > > func->accessibility = attr_numeric(die, DW_AT_accessibility); > > @@ -2023,8 +2024,10 @@ static int tag__recode_dwarf_type(struct tag *tag, struct cu *cu) > > dtype = dwarf_cu__find_tag_by_ref(cu->priv, &dtag->abstract_origin); > > if (dtype == NULL) > > dtype = dwarf_cu__find_tag_by_ref(cu->priv, &specification); > > - if (dtype != NULL) > > + if (dtype != NULL) { > > fn->name = tag__function(dtype->tag)->name; > > + fn->external = tag__function(dtype->tag)->external; > > + } > > else { > > fprintf(stderr, > > "%s: couldn't find name for " > > diff --git a/dwarves.h b/dwarves.h > > index 7c4254eded1f..3204f69abfe5 100644 > > --- a/dwarves.h > > +++ b/dwarves.h > > @@ -813,6 +813,7 @@ struct function { > > uint8_t virtuality:2; /* DW_VIRTUALITY_{none,virtual,pure_virtual} */ > > uint8_t declaration:1; > > uint8_t btf:1; > > + uint8_t ranges:1; > > int32_t vtable_entry; > > struct list_head vtable_node; > > /* fields used by tools */ > > >