Skip to content

Commit 39daa7b

Browse files
committed
ftrace: Show all tramps registered to a record on ftrace_bug()
When an anomaly is detected in the function call modification code, ftrace_bug() is called to disable function tracing as well as give any information that may help debug the problem. Currently, only the first found trampoline that is attached to the failed record is reported. Instead, show all trampolines that are hooked to it. Also, not only show the ops pointer but also report the function it calls. While at it, add this info to the enabled_functions debug file too. Signed-off-by: Steven Rostedt <[email protected]>
1 parent b05086c commit 39daa7b

File tree

1 file changed

+37
-9
lines changed

1 file changed

+37
-9
lines changed

kernel/trace/ftrace.c

Lines changed: 37 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1952,6 +1952,8 @@ static void print_ip_ins(const char *fmt, const unsigned char *p)
19521952

19531953
static struct ftrace_ops *
19541954
ftrace_find_tramp_ops_any(struct dyn_ftrace *rec);
1955+
static struct ftrace_ops *
1956+
ftrace_find_tramp_ops_next(struct dyn_ftrace *rec, struct ftrace_ops *ops);
19551957

19561958
enum ftrace_bug_type ftrace_bug_type;
19571959
const void *ftrace_expected;
@@ -2028,15 +2030,19 @@ void ftrace_bug(int failed, struct dyn_ftrace *rec)
20282030
rec->flags & FTRACE_FL_REGS ? " R" : " ");
20292031
if (rec->flags & FTRACE_FL_TRAMP_EN) {
20302032
ops = ftrace_find_tramp_ops_any(rec);
2031-
if (ops)
2032-
pr_cont("\ttramp: %pS",
2033-
(void *)ops->trampoline);
2034-
else
2033+
if (ops) {
2034+
do {
2035+
pr_cont("\ttramp: %pS (%pS)",
2036+
(void *)ops->trampoline,
2037+
(void *)ops->func);
2038+
ops = ftrace_find_tramp_ops_next(rec, ops);
2039+
} while (ops);
2040+
} else
20352041
pr_cont("\ttramp: ERROR!");
20362042

20372043
}
20382044
ip = ftrace_get_addr_curr(rec);
2039-
pr_cont(" expected tramp: %lx\n", ip);
2045+
pr_cont("\n expected tramp: %lx\n", ip);
20402046
}
20412047
}
20422048

@@ -2178,6 +2184,24 @@ ftrace_find_tramp_ops_any(struct dyn_ftrace *rec)
21782184
return NULL;
21792185
}
21802186

2187+
static struct ftrace_ops *
2188+
ftrace_find_tramp_ops_next(struct dyn_ftrace *rec,
2189+
struct ftrace_ops *op)
2190+
{
2191+
unsigned long ip = rec->ip;
2192+
2193+
while_for_each_ftrace_op(op) {
2194+
2195+
if (!op->trampoline)
2196+
continue;
2197+
2198+
if (hash_contains_ip(ip, op->func_hash))
2199+
return op;
2200+
}
2201+
2202+
return NULL;
2203+
}
2204+
21812205
static struct ftrace_ops *
21822206
ftrace_find_tramp_ops_curr(struct dyn_ftrace *rec)
21832207
{
@@ -3306,10 +3330,14 @@ static int t_show(struct seq_file *m, void *v)
33063330
rec->flags & FTRACE_FL_IPMODIFY ? " I" : " ");
33073331
if (rec->flags & FTRACE_FL_TRAMP_EN) {
33083332
ops = ftrace_find_tramp_ops_any(rec);
3309-
if (ops)
3310-
seq_printf(m, "\ttramp: %pS",
3311-
(void *)ops->trampoline);
3312-
else
3333+
if (ops) {
3334+
do {
3335+
seq_printf(m, "\ttramp: %pS (%pS)",
3336+
(void *)ops->trampoline,
3337+
(void *)ops->func);
3338+
ops = ftrace_find_tramp_ops_next(rec, ops);
3339+
} while (ops);
3340+
} else
33133341
seq_puts(m, "\ttramp: ERROR!");
33143342

33153343
}

0 commit comments

Comments
 (0)