[PATCH 1/1] perf report: append inlines to non-dwarf callchains

From: Artem Savkov
Date: Thu Mar 16 2023 - 09:37:03 EST


Append information about inlined functions to fp and lbr callchains
from dwarf debuginfo when available. Do so by calling append_inlines()
from add_callchain_ip(). This requires append_inlies to be moved up a
bit.

Suggested-by: Andrii Nakryiko <andrii.nakryiko@xxxxxxxxx>
Signed-off-by: Artem Savkov <asavkov@xxxxxxxxxx>
---
tools/perf/util/machine.c | 82 ++++++++++++++++++++-------------------
1 file changed, 43 insertions(+), 39 deletions(-)

diff --git a/tools/perf/util/machine.c b/tools/perf/util/machine.c
index 803c9d1803dd..2dd46b9f0083 100644
--- a/tools/perf/util/machine.c
+++ b/tools/perf/util/machine.c
@@ -2249,6 +2249,45 @@ struct iterations {
u64 cycles;
};

+static int append_inlines(struct callchain_cursor *cursor, struct map_symbol *ms, u64 ip)
+{
+ struct symbol *sym = ms->sym;
+ struct map *map = ms->map;
+ struct inline_node *inline_node;
+ struct inline_list *ilist;
+ u64 addr;
+ int ret = 1;
+
+ if (!symbol_conf.inline_name || !map || !sym)
+ return ret;
+
+ addr = map__map_ip(map, ip);
+ addr = map__rip_2objdump(map, addr);
+
+ inline_node = inlines__tree_find(&map->dso->inlined_nodes, addr);
+ if (!inline_node) {
+ inline_node = dso__parse_addr_inlines(map->dso, addr, sym);
+ if (!inline_node)
+ return ret;
+ inlines__tree_insert(&map->dso->inlined_nodes, inline_node);
+ }
+
+ list_for_each_entry(ilist, &inline_node->val, list) {
+ struct map_symbol ilist_ms = {
+ .maps = ms->maps,
+ .map = map,
+ .sym = ilist->symbol,
+ };
+ ret = callchain_cursor_append(cursor, ip, &ilist_ms, false,
+ NULL, 0, 0, 0, ilist->srcline);
+
+ if (ret != 0)
+ return ret;
+ }
+
+ return ret;
+}
+
static int add_callchain_ip(struct thread *thread,
struct callchain_cursor *cursor,
struct symbol **parent,
@@ -2322,6 +2361,10 @@ static int add_callchain_ip(struct thread *thread,
ms.maps = al.maps;
ms.map = al.map;
ms.sym = al.sym;
+
+ if (append_inlines(cursor, &ms, ip) == 0)
+ return 0;
+
srcline = callchain_srcline(&ms, al.addr);
return callchain_cursor_append(cursor, ip, &ms,
branch, flags, nr_loop_iter,
@@ -3008,45 +3051,6 @@ static int thread__resolve_callchain_sample(struct thread *thread,
return 0;
}

-static int append_inlines(struct callchain_cursor *cursor, struct map_symbol *ms, u64 ip)
-{
- struct symbol *sym = ms->sym;
- struct map *map = ms->map;
- struct inline_node *inline_node;
- struct inline_list *ilist;
- u64 addr;
- int ret = 1;
-
- if (!symbol_conf.inline_name || !map || !sym)
- return ret;
-
- addr = map__map_ip(map, ip);
- addr = map__rip_2objdump(map, addr);
-
- inline_node = inlines__tree_find(&map->dso->inlined_nodes, addr);
- if (!inline_node) {
- inline_node = dso__parse_addr_inlines(map->dso, addr, sym);
- if (!inline_node)
- return ret;
- inlines__tree_insert(&map->dso->inlined_nodes, inline_node);
- }
-
- list_for_each_entry(ilist, &inline_node->val, list) {
- struct map_symbol ilist_ms = {
- .maps = ms->maps,
- .map = map,
- .sym = ilist->symbol,
- };
- ret = callchain_cursor_append(cursor, ip, &ilist_ms, false,
- NULL, 0, 0, 0, ilist->srcline);
-
- if (ret != 0)
- return ret;
- }
-
- return ret;
-}
-
static int unwind_entry(struct unwind_entry *entry, void *arg)
{
struct callchain_cursor *cursor = arg;
--
2.39.2