Skip to content

Commit 6ce5a6f

Browse files
66542erostedt
authored andcommitted
tracing: Fix function name for trampoline
The issue that unrelated function name is shown on stack trace like following even though it should be trampoline code address is caused by the creation of trampoline code in the area where .init.text section of module was freed after module is loaded. bash-1344 [002] ..... 43.644608: <stack trace> => (MODULE INIT FUNCTION) => vfs_write => ksys_write => do_syscall_64 => entry_SYSCALL_64_after_hwframe To resolve this, when function address of stack trace entry is in trampoline, output without looking up symbol name. Cc: Mathieu Desnoyers <mathieu.desnoyers@efficios.com> Link: https://lore.kernel.org/20241021071454.34610-2-tatsuya.s2862@gmail.com Signed-off-by: Tatsuya S <tatsuya.s2862@gmail.com> Acked-by: Masami Hiramatsu (Google) <mhiramat@kernel.org> Signed-off-by: Steven Rostedt (Google) <rostedt@goodmis.org>
1 parent 60b1f57 commit 6ce5a6f

File tree

3 files changed

+36
-8
lines changed

3 files changed

+36
-8
lines changed

kernel/trace/trace.c

Lines changed: 25 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -975,7 +975,8 @@ static inline void trace_access_lock_init(void)
975975
#endif
976976

977977
#ifdef CONFIG_STACKTRACE
978-
static void __ftrace_trace_stack(struct trace_buffer *buffer,
978+
static void __ftrace_trace_stack(struct trace_array *tr,
979+
struct trace_buffer *buffer,
979980
unsigned int trace_ctx,
980981
int skip, struct pt_regs *regs);
981982
static inline void ftrace_trace_stack(struct trace_array *tr,
@@ -984,7 +985,8 @@ static inline void ftrace_trace_stack(struct trace_array *tr,
984985
int skip, struct pt_regs *regs);
985986

986987
#else
987-
static inline void __ftrace_trace_stack(struct trace_buffer *buffer,
988+
static inline void __ftrace_trace_stack(struct trace_array *tr,
989+
struct trace_buffer *buffer,
988990
unsigned int trace_ctx,
989991
int skip, struct pt_regs *regs)
990992
{
@@ -2912,7 +2914,8 @@ struct ftrace_stacks {
29122914
static DEFINE_PER_CPU(struct ftrace_stacks, ftrace_stacks);
29132915
static DEFINE_PER_CPU(int, ftrace_stack_reserve);
29142916

2915-
static void __ftrace_trace_stack(struct trace_buffer *buffer,
2917+
static void __ftrace_trace_stack(struct trace_array *tr,
2918+
struct trace_buffer *buffer,
29162919
unsigned int trace_ctx,
29172920
int skip, struct pt_regs *regs)
29182921
{
@@ -2958,6 +2961,20 @@ static void __ftrace_trace_stack(struct trace_buffer *buffer,
29582961
nr_entries = stack_trace_save(fstack->calls, size, skip);
29592962
}
29602963

2964+
#ifdef CONFIG_DYNAMIC_FTRACE
2965+
/* Mark entry of stack trace as trampoline code */
2966+
if (tr->ops && tr->ops->trampoline) {
2967+
unsigned long tramp_start = tr->ops->trampoline;
2968+
unsigned long tramp_end = tramp_start + tr->ops->trampoline_size;
2969+
unsigned long *calls = fstack->calls;
2970+
2971+
for (int i = 0; i < nr_entries; i++) {
2972+
if (calls[i] >= tramp_start && calls[i] < tramp_end)
2973+
calls[i] = FTRACE_TRAMPOLINE_MARKER;
2974+
}
2975+
}
2976+
#endif
2977+
29612978
event = __trace_buffer_lock_reserve(buffer, TRACE_STACK,
29622979
struct_size(entry, caller, nr_entries),
29632980
trace_ctx);
@@ -2987,7 +3004,7 @@ static inline void ftrace_trace_stack(struct trace_array *tr,
29873004
if (!(tr->trace_flags & TRACE_ITER_STACKTRACE))
29883005
return;
29893006

2990-
__ftrace_trace_stack(buffer, trace_ctx, skip, regs);
3007+
__ftrace_trace_stack(tr, buffer, trace_ctx, skip, regs);
29913008
}
29923009

29933010
void __trace_stack(struct trace_array *tr, unsigned int trace_ctx,
@@ -2996,7 +3013,7 @@ void __trace_stack(struct trace_array *tr, unsigned int trace_ctx,
29963013
struct trace_buffer *buffer = tr->array_buffer.buffer;
29973014

29983015
if (rcu_is_watching()) {
2999-
__ftrace_trace_stack(buffer, trace_ctx, skip, NULL);
3016+
__ftrace_trace_stack(tr, buffer, trace_ctx, skip, NULL);
30003017
return;
30013018
}
30023019

@@ -3013,7 +3030,7 @@ void __trace_stack(struct trace_array *tr, unsigned int trace_ctx,
30133030
return;
30143031

30153032
ct_irq_enter_irqson();
3016-
__ftrace_trace_stack(buffer, trace_ctx, skip, NULL);
3033+
__ftrace_trace_stack(tr, buffer, trace_ctx, skip, NULL);
30173034
ct_irq_exit_irqson();
30183035
}
30193036

@@ -3030,8 +3047,8 @@ void trace_dump_stack(int skip)
30303047
/* Skip 1 to skip this function. */
30313048
skip++;
30323049
#endif
3033-
__ftrace_trace_stack(printk_trace->array_buffer.buffer,
3034-
tracing_gen_ctx(), skip, NULL);
3050+
__ftrace_trace_stack(printk_trace, printk_trace->array_buffer.buffer,
3051+
tracing_gen_ctx(), skip, NULL);
30353052
}
30363053
EXPORT_SYMBOL_GPL(trace_dump_stack);
30373054

kernel/trace/trace.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2172,4 +2172,11 @@ static inline int rv_init_interface(void)
21722172
}
21732173
#endif
21742174

2175+
/*
2176+
* This is used only to distinguish
2177+
* function address from trampoline code.
2178+
* So this value has no meaning.
2179+
*/
2180+
#define FTRACE_TRAMPOLINE_MARKER ((unsigned long) INT_MAX)
2181+
21752182
#endif /* _LINUX_KERNEL_TRACE_H */

kernel/trace/trace_output.c

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1245,6 +1245,10 @@ static enum print_line_t trace_stack_print(struct trace_iterator *iter,
12451245
break;
12461246

12471247
trace_seq_puts(s, " => ");
1248+
if ((*p) == FTRACE_TRAMPOLINE_MARKER) {
1249+
trace_seq_puts(s, "[FTRACE TRAMPOLINE]\n");
1250+
continue;
1251+
}
12481252
seq_print_ip_sym(s, (*p) + delta, flags);
12491253
trace_seq_putc(s, '\n');
12501254
}

0 commit comments

Comments
 (0)