aboutsummaryrefslogtreecommitdiffstats
path: root/kernel/trace/trace.c
diff options
context:
space:
mode:
authorSteven Rostedt <rostedt@goodmis.org>2008-10-31 15:44:07 -0400
committerIngo Molnar <mingo@elte.hu>2008-11-03 04:41:29 -0500
commitb3aa557722b3d5858f14ca559e03461c24125aaf (patch)
tree37a8814cd1d1584e77d9d999797ff0f0de8ed19c /kernel/trace/trace.c
parentc2c80529460095035752bf0ecc1af82c1e0f6e0f (diff)
ftrace: use kretprobe trampoline name to test in output
Impact: ia64+tracing build fix When a function is kprobed, the return address is set to the kprobe_trampoline, or something similar. This caused the output of the trace to look confusing when the parent seemed to be this "kprobe_trampoline" function. To fix this, Abhishek Sagar added a test of the instruction pointer of the parent to see if it matched the kprobe_trampoline. If it did, the output would print a "[unknown/kretprobe'd]" instead. Unfortunately, not all archs do this the same way, and the trampoline function may not be exported, which causes failures in builds. This patch will compare the name instead of the pointer to see if it matches. This prevents us from depending on a function from being exported, and should work on all archs. The worst that can happen is that an arch might use a different name and then we go back to the confusing output. At least the arch will still build. Reported-by: Abhishek Sagar <sagar.abhishek@gmail.com> Signed-off-by: Steven Rostedt <srostedt@redhat.com> Signed-off-by: Ingo Molnar <mingo@elte.hu> Tested-by: Abhishek Sagar <sagar.abhishek@gmail.com> Acked-by: Abhishek Sagar <sagar.abhishek@gmail.com>
Diffstat (limited to 'kernel/trace/trace.c')
-rw-r--r--kernel/trace/trace.c39
1 files changed, 21 insertions, 18 deletions
diff --git a/kernel/trace/trace.c b/kernel/trace/trace.c
index 85bee775a03e..9f3b478f9171 100644
--- a/kernel/trace/trace.c
+++ b/kernel/trace/trace.c
@@ -1088,17 +1088,20 @@ static void s_stop(struct seq_file *m, void *p)
1088 mutex_unlock(&trace_types_lock); 1088 mutex_unlock(&trace_types_lock);
1089} 1089}
1090 1090
1091#define KRETPROBE_MSG "[unknown/kretprobe'd]"
1092
1093#ifdef CONFIG_KRETPROBES 1091#ifdef CONFIG_KRETPROBES
1094static inline int kretprobed(unsigned long addr) 1092static inline const char *kretprobed(const char *name)
1095{ 1093{
1096 return addr == (unsigned long)kretprobe_trampoline; 1094 static const char tramp_name[] = "kretprobe_trampoline";
1095 int size = sizeof(tramp_name);
1096
1097 if (strncmp(tramp_name, name, size) == 0)
1098 return "[unknown/kretprobe'd]";
1099 return name;
1097} 1100}
1098#else 1101#else
1099static inline int kretprobed(unsigned long addr) 1102static inline const char *kretprobed(const char *name)
1100{ 1103{
1101 return 0; 1104 return name;
1102} 1105}
1103#endif /* CONFIG_KRETPROBES */ 1106#endif /* CONFIG_KRETPROBES */
1104 1107
@@ -1107,10 +1110,13 @@ seq_print_sym_short(struct trace_seq *s, const char *fmt, unsigned long address)
1107{ 1110{
1108#ifdef CONFIG_KALLSYMS 1111#ifdef CONFIG_KALLSYMS
1109 char str[KSYM_SYMBOL_LEN]; 1112 char str[KSYM_SYMBOL_LEN];
1113 const char *name;
1110 1114
1111 kallsyms_lookup(address, NULL, NULL, NULL, str); 1115 kallsyms_lookup(address, NULL, NULL, NULL, str);
1112 1116
1113 return trace_seq_printf(s, fmt, str); 1117 name = kretprobed(str);
1118
1119 return trace_seq_printf(s, fmt, name);
1114#endif 1120#endif
1115 return 1; 1121 return 1;
1116} 1122}
@@ -1121,9 +1127,12 @@ seq_print_sym_offset(struct trace_seq *s, const char *fmt,
1121{ 1127{
1122#ifdef CONFIG_KALLSYMS 1128#ifdef CONFIG_KALLSYMS
1123 char str[KSYM_SYMBOL_LEN]; 1129 char str[KSYM_SYMBOL_LEN];
1130 const char *name;
1124 1131
1125 sprint_symbol(str, address); 1132 sprint_symbol(str, address);
1126 return trace_seq_printf(s, fmt, str); 1133 name = kretprobed(str);
1134
1135 return trace_seq_printf(s, fmt, name);
1127#endif 1136#endif
1128 return 1; 1137 return 1;
1129} 1138}
@@ -1377,10 +1386,7 @@ print_lat_fmt(struct trace_iterator *iter, unsigned int trace_idx, int cpu)
1377 1386
1378 seq_print_ip_sym(s, field->ip, sym_flags); 1387 seq_print_ip_sym(s, field->ip, sym_flags);
1379 trace_seq_puts(s, " ("); 1388 trace_seq_puts(s, " (");
1380 if (kretprobed(field->parent_ip)) 1389 seq_print_ip_sym(s, field->parent_ip, sym_flags);
1381 trace_seq_puts(s, KRETPROBE_MSG);
1382 else
1383 seq_print_ip_sym(s, field->parent_ip, sym_flags);
1384 trace_seq_puts(s, ")\n"); 1390 trace_seq_puts(s, ")\n");
1385 break; 1391 break;
1386 } 1392 }
@@ -1496,12 +1502,9 @@ static enum print_line_t print_trace_fmt(struct trace_iterator *iter)
1496 ret = trace_seq_printf(s, " <-"); 1502 ret = trace_seq_printf(s, " <-");
1497 if (!ret) 1503 if (!ret)
1498 return TRACE_TYPE_PARTIAL_LINE; 1504 return TRACE_TYPE_PARTIAL_LINE;
1499 if (kretprobed(field->parent_ip)) 1505 ret = seq_print_ip_sym(s,
1500 ret = trace_seq_puts(s, KRETPROBE_MSG); 1506 field->parent_ip,
1501 else 1507 sym_flags);
1502 ret = seq_print_ip_sym(s,
1503 field->parent_ip,
1504 sym_flags);
1505 if (!ret) 1508 if (!ret)
1506 return TRACE_TYPE_PARTIAL_LINE; 1509 return TRACE_TYPE_PARTIAL_LINE;
1507 } 1510 }