ftrace: Show all tramps registered to a record on ftrace_bug()
[cascardo/linux.git] / kernel / trace / ftrace.c
index 7870c03..e371aed 100644 (file)
@@ -1952,6 +1952,8 @@ static void print_ip_ins(const char *fmt, const unsigned char *p)
 
 static struct ftrace_ops *
 ftrace_find_tramp_ops_any(struct dyn_ftrace *rec);
+static struct ftrace_ops *
+ftrace_find_tramp_ops_next(struct dyn_ftrace *rec, struct ftrace_ops *ops);
 
 enum ftrace_bug_type ftrace_bug_type;
 const void *ftrace_expected;
@@ -2028,15 +2030,19 @@ void ftrace_bug(int failed, struct dyn_ftrace *rec)
                        rec->flags & FTRACE_FL_REGS ? " R" : "  ");
                if (rec->flags & FTRACE_FL_TRAMP_EN) {
                        ops = ftrace_find_tramp_ops_any(rec);
-                       if (ops)
-                               pr_cont("\ttramp: %pS",
-                                       (void *)ops->trampoline);
-                       else
+                       if (ops) {
+                               do {
+                                       pr_cont("\ttramp: %pS (%pS)",
+                                               (void *)ops->trampoline,
+                                               (void *)ops->func);
+                                       ops = ftrace_find_tramp_ops_next(rec, ops);
+                               } while (ops);
+                       } else
                                pr_cont("\ttramp: ERROR!");
 
                }
                ip = ftrace_get_addr_curr(rec);
-               pr_cont(" expected tramp: %lx\n", ip);
+               pr_cont("\n expected tramp: %lx\n", ip);
        }
 }
 
@@ -2178,6 +2184,24 @@ ftrace_find_tramp_ops_any(struct dyn_ftrace *rec)
        return NULL;
 }
 
+static struct ftrace_ops *
+ftrace_find_tramp_ops_next(struct dyn_ftrace *rec,
+                          struct ftrace_ops *op)
+{
+       unsigned long ip = rec->ip;
+
+       while_for_each_ftrace_op(op) {
+
+               if (!op->trampoline)
+                       continue;
+
+               if (hash_contains_ip(ip, op->func_hash))
+                       return op;
+       } 
+
+       return NULL;
+}
+
 static struct ftrace_ops *
 ftrace_find_tramp_ops_curr(struct dyn_ftrace *rec)
 {
@@ -3306,10 +3330,14 @@ static int t_show(struct seq_file *m, void *v)
                           rec->flags & FTRACE_FL_IPMODIFY ? " I" : "  ");
                if (rec->flags & FTRACE_FL_TRAMP_EN) {
                        ops = ftrace_find_tramp_ops_any(rec);
-                       if (ops)
-                               seq_printf(m, "\ttramp: %pS",
-                                          (void *)ops->trampoline);
-                       else
+                       if (ops) {
+                               do {
+                                       seq_printf(m, "\ttramp: %pS (%pS)",
+                                                  (void *)ops->trampoline,
+                                                  (void *)ops->func);
+                                       ops = ftrace_find_tramp_ops_next(rec, ops);
+                               } while (ops);
+                       } else
                                seq_puts(m, "\ttramp: ERROR!");
 
                }