]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
tracing: Fix function name for trampoline
authorTatsuya S <tatsuya.s2862@gmail.com>
Mon, 21 Oct 2024 07:14:53 +0000 (07:14 +0000)
committerSteven Rostedt (Google) <rostedt@goodmis.org>
Mon, 18 Nov 2024 20:08:10 +0000 (15:08 -0500)
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>
kernel/trace/trace.c
kernel/trace/trace.h
kernel/trace/trace_output.c

index a587fd7d74474f8af3e66fc1b5f3db2d54b99913..566d99f9f08667140bd1c794e12217d09d1f517f 100644 (file)
@@ -975,7 +975,8 @@ static inline void trace_access_lock_init(void)
 #endif
 
 #ifdef CONFIG_STACKTRACE
-static void __ftrace_trace_stack(struct trace_buffer *buffer,
+static void __ftrace_trace_stack(struct trace_array *tr,
+                                struct trace_buffer *buffer,
                                 unsigned int trace_ctx,
                                 int skip, struct pt_regs *regs);
 static inline void ftrace_trace_stack(struct trace_array *tr,
@@ -984,7 +985,8 @@ static inline void ftrace_trace_stack(struct trace_array *tr,
                                      int skip, struct pt_regs *regs);
 
 #else
-static inline void __ftrace_trace_stack(struct trace_buffer *buffer,
+static inline void __ftrace_trace_stack(struct trace_array *tr,
+                                       struct trace_buffer *buffer,
                                        unsigned int trace_ctx,
                                        int skip, struct pt_regs *regs)
 {
@@ -2912,7 +2914,8 @@ struct ftrace_stacks {
 static DEFINE_PER_CPU(struct ftrace_stacks, ftrace_stacks);
 static DEFINE_PER_CPU(int, ftrace_stack_reserve);
 
-static void __ftrace_trace_stack(struct trace_buffer *buffer,
+static void __ftrace_trace_stack(struct trace_array *tr,
+                                struct trace_buffer *buffer,
                                 unsigned int trace_ctx,
                                 int skip, struct pt_regs *regs)
 {
@@ -2958,6 +2961,20 @@ static void __ftrace_trace_stack(struct trace_buffer *buffer,
                nr_entries = stack_trace_save(fstack->calls, size, skip);
        }
 
+#ifdef CONFIG_DYNAMIC_FTRACE
+       /* Mark entry of stack trace as trampoline code */
+       if (tr->ops && tr->ops->trampoline) {
+               unsigned long tramp_start = tr->ops->trampoline;
+               unsigned long tramp_end = tramp_start + tr->ops->trampoline_size;
+               unsigned long *calls = fstack->calls;
+
+               for (int i = 0; i < nr_entries; i++) {
+                       if (calls[i] >= tramp_start && calls[i] < tramp_end)
+                               calls[i] = FTRACE_TRAMPOLINE_MARKER;
+               }
+       }
+#endif
+
        event = __trace_buffer_lock_reserve(buffer, TRACE_STACK,
                                    struct_size(entry, caller, nr_entries),
                                    trace_ctx);
@@ -2987,7 +3004,7 @@ static inline void ftrace_trace_stack(struct trace_array *tr,
        if (!(tr->trace_flags & TRACE_ITER_STACKTRACE))
                return;
 
-       __ftrace_trace_stack(buffer, trace_ctx, skip, regs);
+       __ftrace_trace_stack(tr, buffer, trace_ctx, skip, regs);
 }
 
 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,
        struct trace_buffer *buffer = tr->array_buffer.buffer;
 
        if (rcu_is_watching()) {
-               __ftrace_trace_stack(buffer, trace_ctx, skip, NULL);
+               __ftrace_trace_stack(tr, buffer, trace_ctx, skip, NULL);
                return;
        }
 
@@ -3013,7 +3030,7 @@ void __trace_stack(struct trace_array *tr, unsigned int trace_ctx,
                return;
 
        ct_irq_enter_irqson();
-       __ftrace_trace_stack(buffer, trace_ctx, skip, NULL);
+       __ftrace_trace_stack(tr, buffer, trace_ctx, skip, NULL);
        ct_irq_exit_irqson();
 }
 
@@ -3030,8 +3047,8 @@ void trace_dump_stack(int skip)
        /* Skip 1 to skip this function. */
        skip++;
 #endif
-       __ftrace_trace_stack(printk_trace->array_buffer.buffer,
-                            tracing_gen_ctx(), skip, NULL);
+       __ftrace_trace_stack(printk_trace, printk_trace->array_buffer.buffer,
+                               tracing_gen_ctx(), skip, NULL);
 }
 EXPORT_SYMBOL_GPL(trace_dump_stack);
 
index 638f452eec1005155b45e74d136b71affd9c3336..6e66b666c3e97b5b7250af2887cffc920a7d370e 100644 (file)
@@ -2172,4 +2172,11 @@ static inline int rv_init_interface(void)
 }
 #endif
 
+/*
+ * This is used only to distinguish
+ * function address from trampoline code.
+ * So this value has no meaning.
+ */
+#define FTRACE_TRAMPOLINE_MARKER  ((unsigned long) INT_MAX)
+
 #endif /* _LINUX_KERNEL_TRACE_H */
index 2ee6613dce6dcead6237bb6c290b985080bdad70..e08aee34ef63de4cebef5e991d95aff1aa513f62 100644 (file)
@@ -1245,6 +1245,10 @@ static enum print_line_t trace_stack_print(struct trace_iterator *iter,
                        break;
 
                trace_seq_puts(s, " => ");
+               if ((*p) == FTRACE_TRAMPOLINE_MARKER) {
+                       trace_seq_puts(s, "[FTRACE TRAMPOLINE]\n");
+                       continue;
+               }
                seq_print_ip_sym(s, (*p) + delta, flags);
                trace_seq_putc(s, '\n');
        }