* [PATCH] libtracecmd: Print call offset in parent function for funcgraph-retaddr
@ 2026-02-09 4:35 Donglin Peng
0 siblings, 0 replies; only message in thread
From: Donglin Peng @ 2026-02-09 4:35 UTC (permalink / raw)
To: rostedt; +Cc: mhiramat, linux-trace-devel, Donglin Peng
From: Donglin Peng <pengdonglin@xiaomi.com>
When the "funcgraph-retaddr" option is enabled, trace-cmd currently
prints only the parent function name using the return address.
Enhance it to include the call offset within the parent function,
enabling tools like faddr2line to locate the exact call site.
Before:
preempt_count_add(val=65536) /* <-irq_enter_rcu */
After:
preempt_count_add(val=65536) /* <-irq_enter_rcu+0x17 */
Example usage with faddr2line:
$ ./scripts/faddr2line vmlinux irq_enter_rcu+0x17
irq_enter_rcu+0x17/0x80:
irq_enter_rcu at kernel/softirq.c:664
Signed-off-by: Donglin Peng <pengdonglin@xiaomi.com>
---
lib/trace-cmd/trace-ftrace.c | 19 +++++++++++++------
1 file changed, 13 insertions(+), 6 deletions(-)
diff --git a/lib/trace-cmd/trace-ftrace.c b/lib/trace-cmd/trace-ftrace.c
index 53c958653c28..069ed51bf3fe 100644
--- a/lib/trace-cmd/trace-ftrace.c
+++ b/lib/trace-cmd/trace-ftrace.c
@@ -237,6 +237,7 @@ print_graph_entry_leaf(struct trace_seq *s,
unsigned long long duration, depth;
unsigned long long val;
unsigned long long retval;
+ unsigned long long offset;
bool fgraph_retval_supported = true;
const char *retfunc = NULL;
const char *func;
@@ -257,8 +258,10 @@ print_graph_entry_leaf(struct trace_seq *s,
}
/* In case this is a retaddr event */
- if (!tep_get_field_val(s, event, "retaddr", record, &val, 0))
+ if (!tep_get_field_val(s, event, "retaddr", record, &val, 0)) {
retfunc = tep_find_function(pevent, val);
+ offset = val - tep_find_function_address(pevent, val);
+ }
duration = rettime - calltime;
@@ -290,7 +293,7 @@ print_graph_entry_leaf(struct trace_seq *s,
ret = trace_seq_printf(s, " (%lld)", depth);
if (retfunc)
- ret = trace_seq_printf(s, " /* <-%s */", retfunc);
+ ret = trace_seq_printf(s, " /* <-%s+0x%x */", retfunc, (int)offset);
/* Return Value */
if (ret && fgraph_retval_supported && !fgraph_retval_skip->set) {
@@ -317,6 +320,7 @@ static int print_graph_nested(struct trace_seq *s,
struct tep_handle *pevent = event->tep;
unsigned long long depth;
unsigned long long val;
+ unsigned long long offset;
const char *retfunc = NULL;
const char *func;
int ret;
@@ -332,8 +336,10 @@ static int print_graph_nested(struct trace_seq *s,
return trace_seq_putc(s, '!');
/* In case this is a retaddr event */
- if (!tep_get_field_val(s, event, "retaddr", record, &val, 0))
+ if (!tep_get_field_val(s, event, "retaddr", record, &val, 0)) {
retfunc = tep_find_function(pevent, val);
+ offset = val - tep_find_function_address(pevent, val);
+ }
/* Function */
for (i = 0; i < (int)(depth * TRACE_GRAPH_INDENT); i++)
@@ -344,17 +350,18 @@ static int print_graph_nested(struct trace_seq *s,
func = tep_find_function(pevent, val);
-
if (func) {
ret = trace_seq_printf(s, "%s(", func);
print_args(s, event, record, func);
if (retfunc)
- ret = trace_seq_printf(s, ") /* <-%s */ {", retfunc);
+ ret = trace_seq_printf(s, ") /* <-%s+0x%x */ {", retfunc,
+ (int)offset);
else
ret = trace_seq_puts(s, ") {");
} else {
if (retfunc)
- ret = trace_seq_printf(s, "%llx() /* <-%s */ {", val, retfunc);
+ ret = trace_seq_printf(s, "%llx() /* <-%s+0x%x */ {", val,
+ retfunc, (int)offset);
else
ret = trace_seq_puts(s, ") {");
}
--
2.34.1
^ permalink raw reply related [flat|nested] only message in thread
only message in thread, other threads:[~2026-02-09 4:35 UTC | newest]
Thread overview: (only message) (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-02-09 4:35 [PATCH] libtracecmd: Print call offset in parent function for funcgraph-retaddr Donglin Peng
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox