aboutsummaryrefslogtreecommitdiffstats
path: root/kernel
diff options
context:
space:
mode:
authorAbhishek Sagar <sagar.abhishek@gmail.com>2008-05-27 14:33:18 -0400
committerIngo Molnar <mingo@elte.hu>2008-06-02 06:41:19 -0400
commit76094a2cf46e4ab776055d4086615b884408568c (patch)
treed6c7bd23772fb8ed34a5c176af9d21b4c434b1eb /kernel
parent014c257cce65e9d1cd2d28ec1c89a37c536b151d (diff)
ftrace: distinguish kretprobe'd functions in trace logs
Tracing functions via ftrace which have a kretprobe installed on them, can produce misleading output in their trace logs. E.g, consider the correct trace of the following sequence: do_IRQ() { ~ irq_enter(); ~ } Trace log (sample): <idle>-0 [00] 4154504455.781616: irq_enter <- do_IRQ But if irq_enter() has a kretprobe installed on it, the return value stored on the stack at each invocation is modified to divert the return to a kprobe trampoline function called kretprobe_trampoline(). So with this the trace would (currently) look like: <idle>-0 [00] 4154504455.781616: irq_enter <- kretprobe_trampoline Now this is quite misleading to the end user, as it suggests something that didn't actually happen. So just to avoid such misinterpretations, the inlined patch aims to output such a log as: <idle>-0 [00] 4154504455.781616: irq_enter <- [unknown/kretprobe'd] Signed-off-by: Abhishek Sagar <sagar.abhishek@gmail.com> Acked-by: Steven Rostedt <srostedt@redhat.com> Signed-off-by: Ingo Molnar <mingo@elte.hu>
Diffstat (limited to 'kernel')
-rw-r--r--kernel/trace/trace.c27
1 files changed, 24 insertions, 3 deletions
diff --git a/kernel/trace/trace.c b/kernel/trace/trace.c
index 0feae23d9893..12f5e817380e 100644
--- a/kernel/trace/trace.c
+++ b/kernel/trace/trace.c
@@ -27,6 +27,7 @@
27#include <linux/poll.h> 27#include <linux/poll.h>
28#include <linux/gfp.h> 28#include <linux/gfp.h>
29#include <linux/fs.h> 29#include <linux/fs.h>
30#include <linux/kprobes.h>
30#include <linux/writeback.h> 31#include <linux/writeback.h>
31 32
32#include <linux/stacktrace.h> 33#include <linux/stacktrace.h>
@@ -1199,6 +1200,20 @@ static void s_stop(struct seq_file *m, void *p)
1199 mutex_unlock(&trace_types_lock); 1200 mutex_unlock(&trace_types_lock);
1200} 1201}
1201 1202
1203#define KRETPROBE_MSG "[unknown/kretprobe'd]"
1204
1205#ifdef CONFIG_KRETPROBES
1206static inline int kretprobed(unsigned long addr)
1207{
1208 return addr == (unsigned long)kretprobe_trampoline;
1209}
1210#else
1211static inline int kretprobed(unsigned long addr)
1212{
1213 return 0;
1214}
1215#endif /* CONFIG_KRETPROBES */
1216
1202static int 1217static int
1203seq_print_sym_short(struct trace_seq *s, const char *fmt, unsigned long address) 1218seq_print_sym_short(struct trace_seq *s, const char *fmt, unsigned long address)
1204{ 1219{
@@ -1434,7 +1449,10 @@ print_lat_fmt(struct trace_iterator *iter, unsigned int trace_idx, int cpu)
1434 case TRACE_FN: 1449 case TRACE_FN:
1435 seq_print_ip_sym(s, entry->fn.ip, sym_flags); 1450 seq_print_ip_sym(s, entry->fn.ip, sym_flags);
1436 trace_seq_puts(s, " ("); 1451 trace_seq_puts(s, " (");
1437 seq_print_ip_sym(s, entry->fn.parent_ip, sym_flags); 1452 if (kretprobed(entry->fn.parent_ip))
1453 trace_seq_puts(s, KRETPROBE_MSG);
1454 else
1455 seq_print_ip_sym(s, entry->fn.parent_ip, sym_flags);
1438 trace_seq_puts(s, ")\n"); 1456 trace_seq_puts(s, ")\n");
1439 break; 1457 break;
1440 case TRACE_CTX: 1458 case TRACE_CTX:
@@ -1514,8 +1532,11 @@ static int print_trace_fmt(struct trace_iterator *iter)
1514 ret = trace_seq_printf(s, " <-"); 1532 ret = trace_seq_printf(s, " <-");
1515 if (!ret) 1533 if (!ret)
1516 return 0; 1534 return 0;
1517 ret = seq_print_ip_sym(s, entry->fn.parent_ip, 1535 if (kretprobed(entry->fn.parent_ip))
1518 sym_flags); 1536 ret = trace_seq_puts(s, KRETPROBE_MSG);
1537 else
1538 ret = seq_print_ip_sym(s, entry->fn.parent_ip,
1539 sym_flags);
1519 if (!ret) 1540 if (!ret)
1520 return 0; 1541 return 0;
1521 } 1542 }