Namhyung mentioned that 'set_task_cpu' wasn't being printed with pfunct, that was because those functions (with DW_AT_external=1) were not being printed at all, out of some wrong expectations, this was added to avoid printing it multiple times to allow for things like --compile to work, but that was too much of a big hammer. So add fn_stats->printed and use it to determine if functions were already printed. Also don't print definitions for functions marked as declarations, as it clashes with the ones in system headers, like __builtin_memcpy, etc. This all needs a more thorough love and care, but at least for now --compile works with 'fullcircle tcp.o' (generating the functions and the types it uses and then compiling it to get the original types and functions and prints the external functions: $ pfunct -F dwarf -f set_task_cpu vmlinux void set_task_cpu(struct task_struct * p, unsigned int new_cpu); $ pfunct -F btf -f set_task_cpu vmlinux void set_task_cpu(struct task_struct * p, unsigned int new_cpu); $ Reported-by: Namhyung Kim <namhyung@xxxxxxxxxx> Cc: Alan Maguire <alan.maguire@xxxxxxxxxx> Cc: Jiri Olsa <jolsa@xxxxxxxxxx> Signed-off-by: Arnaldo Carvalho de Melo <acme@xxxxxxxxxx> --- pfunct.c | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) diff --git a/pfunct.c b/pfunct.c index 938dd724e44a9416..bc3026b384284cb4 100644 --- a/pfunct.c +++ b/pfunct.c @@ -49,6 +49,7 @@ struct fn_stats { uint32_t nr_expansions; uint32_t size_expansions; uint32_t nr_files; + bool printed; }; static struct fn_stats *fn_stats__new(struct tag *tag, const struct cu *cu) @@ -95,11 +96,13 @@ static void fn_stats__delete_list(void) } } -static void fn_stats__add(struct tag *tag, const struct cu *cu) +static struct fn_stats *fn_stats__add(struct tag *tag, const struct cu *cu) { struct fn_stats *fns = fn_stats__new(tag, cu); if (fns != NULL) list_add(&fns->node, &fn_stats__list); + + return fns; } static void fn_stats_inline_exps_fmtr(const struct fn_stats *stats) @@ -366,7 +369,12 @@ static void function__show(struct function *func, struct cu *cu) { struct tag *tag = function__tag(func); - if (func->abstract_origin || func->external) + if (func->abstract_origin || func->declaration) + return; + + struct fn_stats *fstats = fn_stats__find(func->name); + + if (fstats && fstats->printed) return; if (expand_types) @@ -393,6 +401,11 @@ static void function__show(struct function *func, struct cu *cu) putchar('\n'); if (show_variables || show_inline_expansions) function__fprintf_stats(tag, cu, &conf, stdout); + + if (!fstats) + fstats = fn_stats__add(tag, cu); + if (fstats) + fstats->printed = true; } static int cu_function_iterator(struct cu *cu, void *cookie) -- 2.46.0