aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMasami Hiramatsu <mhiramat@redhat.com>2009-09-10 19:53:38 -0400
committerFrederic Weisbecker <fweisbec@gmail.com>2009-09-11 00:08:00 -0400
commiteca0d916f6429785bbc88db3ff66631cde62b432 (patch)
treeba4ddf9900d128e7c8c24b6ee931eace0aad6a36
parente08d1c657f70bcaca11401cd6ac5c8fe59bd2bb7 (diff)
tracing/kprobes: Add argument name support
Add argument name assignment support and remove "alias" lines from format. This allows user to assign unique name to each argument. For example, $ echo p do_sys_open dfd=a0 filename=a1 flags=a2 mode=a3 > kprobe_events This assigns dfd, filename, flags, and mode to 1st - 4th arguments respectively. Trace buffer shows those names too. <...>-1439 [000] 1200885.933147: do_sys_open+0x0/0xdf: dfd=ffffff9c filename=bfa898ac flags=8000 mode=0 This helps users to know what each value means. Users can filter each events by these names too. Note that you can not filter by argN anymore. Signed-off-by: Masami Hiramatsu <mhiramat@redhat.com> Cc: Jim Keniston <jkenisto@us.ibm.com> Cc: Ananth N Mavinakayanahalli <ananth@in.ibm.com> Cc: Andi Kleen <ak@linux.intel.com> Cc: Christoph Hellwig <hch@infradead.org> Cc: Frank Ch. Eigler <fche@redhat.com> Cc: Frederic Weisbecker <fweisbec@gmail.com> Cc: H. Peter Anvin <hpa@zytor.com> Cc: Ingo Molnar <mingo@elte.hu> Cc: Jason Baron <jbaron@redhat.com> Cc: K.Prasad <prasad@linux.vnet.ibm.com> Cc: Lai Jiangshan <laijs@cn.fujitsu.com> Cc: Li Zefan <lizf@cn.fujitsu.com> Cc: Peter Zijlstra <peterz@infradead.org> Cc: Srikar Dronamraju <srikar@linux.vnet.ibm.com> Cc: Steven Rostedt <rostedt@goodmis.org> Cc: Tom Zanussi <tzanussi@gmail.com> LKML-Reference: <20090910235337.22412.77383.stgit@dhcp-100-2-132.bos.redhat.com> Signed-off-by: Frederic Weisbecker <fweisbec@gmail.com>
-rw-r--r--Documentation/trace/kprobetrace.txt46
-rw-r--r--kernel/trace/trace_kprobe.c128
2 files changed, 84 insertions, 90 deletions
diff --git a/Documentation/trace/kprobetrace.txt b/Documentation/trace/kprobetrace.txt
index 8f882ebd1368..aaa6c1067c78 100644
--- a/Documentation/trace/kprobetrace.txt
+++ b/Documentation/trace/kprobetrace.txt
@@ -42,7 +42,8 @@ Synopsis of kprobe_events
42 aN : Fetch function argument. (N >= 0)(*) 42 aN : Fetch function argument. (N >= 0)(*)
43 rv : Fetch return value.(**) 43 rv : Fetch return value.(**)
44 ra : Fetch return address.(**) 44 ra : Fetch return address.(**)
45 +|-offs(FETCHARG) : fetch memory at FETCHARG +|- offs address.(***) 45 +|-offs(FETCHARG) : Fetch memory at FETCHARG +|- offs address.(***)
46 NAME=FETCHARG: Set NAME as the argument name of FETCHARG.
46 47
47 (*) aN may not correct on asmlinkaged functions and at the middle of 48 (*) aN may not correct on asmlinkaged functions and at the middle of
48 function body. 49 function body.
@@ -62,12 +63,10 @@ enabled:
62 You can enable/disable the probe by writing 1 or 0 on it. 63 You can enable/disable the probe by writing 1 or 0 on it.
63 64
64format: 65format:
65 This shows the format of this probe event. It also shows aliases of arguments 66 This shows the format of this probe event.
66 which you specified to kprobe_events.
67 67
68filter: 68filter:
69 You can write filtering rules of this event. And you can use both of aliase 69 You can write filtering rules of this event.
70 names and field names for describing filters.
71 70
72id: 71id:
73 This shows the id of this probe event. 72 This shows the id of this probe event.
@@ -85,10 +84,11 @@ Usage examples
85To add a probe as a new event, write a new definition to kprobe_events 84To add a probe as a new event, write a new definition to kprobe_events
86as below. 85as below.
87 86
88 echo p:myprobe do_sys_open a0 a1 a2 a3 > /sys/kernel/debug/tracing/kprobe_events 87 echo p:myprobe do_sys_open dfd=a0 filename=a1 flags=a2 mode=a3 > /sys/kernel/debug/tracing/kprobe_events
89 88
90 This sets a kprobe on the top of do_sys_open() function with recording 89 This sets a kprobe on the top of do_sys_open() function with recording
911st to 4th arguments as "myprobe" event. 901st to 4th arguments as "myprobe" event. As this example shows, users can
91choose more familiar names for each arguments.
92 92
93 echo r:myretprobe do_sys_open rv ra >> /sys/kernel/debug/tracing/kprobe_events 93 echo r:myretprobe do_sys_open rv ra >> /sys/kernel/debug/tracing/kprobe_events
94 94
@@ -99,7 +99,7 @@ recording return value and return address as "myretprobe" event.
99 99
100 cat /sys/kernel/debug/tracing/events/kprobes/myprobe/format 100 cat /sys/kernel/debug/tracing/events/kprobes/myprobe/format
101name: myprobe 101name: myprobe
102ID: 23 102ID: 75
103format: 103format:
104 field:unsigned short common_type; offset:0; size:2; 104 field:unsigned short common_type; offset:0; size:2;
105 field:unsigned char common_flags; offset:2; size:1; 105 field:unsigned char common_flags; offset:2; size:1;
@@ -109,21 +109,15 @@ format:
109 109
110 field: unsigned long ip; offset:16;tsize:8; 110 field: unsigned long ip; offset:16;tsize:8;
111 field: int nargs; offset:24;tsize:4; 111 field: int nargs; offset:24;tsize:4;
112 field: unsigned long arg0; offset:32;tsize:8; 112 field: unsigned long dfd; offset:32;tsize:8;
113 field: unsigned long arg1; offset:40;tsize:8; 113 field: unsigned long filename; offset:40;tsize:8;
114 field: unsigned long arg2; offset:48;tsize:8; 114 field: unsigned long flags; offset:48;tsize:8;
115 field: unsigned long arg3; offset:56;tsize:8; 115 field: unsigned long mode; offset:56;tsize:8;
116 116
117 alias: a0; original: arg0; 117print fmt: "%lx: dfd=%lx filename=%lx flags=%lx mode=%lx", ip, REC->dfd, REC->filename, REC->flags, REC->mode
118 alias: a1; original: arg1;
119 alias: a2; original: arg2;
120 alias: a3; original: arg3;
121 118
122print fmt: "%lx: 0x%lx 0x%lx 0x%lx 0x%lx", ip, arg0, arg1, arg2, arg3
123 119
124 120 You can see that the event has 4 arguments as in the expressions you specified.
125 You can see that the event has 4 arguments and alias expressions
126corresponding to it.
127 121
128 echo > /sys/kernel/debug/tracing/kprobe_events 122 echo > /sys/kernel/debug/tracing/kprobe_events
129 123
@@ -135,12 +129,12 @@ corresponding to it.
135# 129#
136# TASK-PID CPU# TIMESTAMP FUNCTION 130# TASK-PID CPU# TIMESTAMP FUNCTION
137# | | | | | 131# | | | | |
138 <...>-1447 [001] 1038282.286875: do_sys_open+0x0/0xd6: 0x3 0x7fffd1ec4440 0x8000 0x0 132 <...>-1447 [001] 1038282.286875: do_sys_open+0x0/0xd6: dfd=3 filename=7fffd1ec4440 flags=8000 mode=0
139 <...>-1447 [001] 1038282.286878: sys_openat+0xc/0xe <- do_sys_open: 0xfffffffffffffffe 0xffffffff81367a3a 133 <...>-1447 [001] 1038282.286878: sys_openat+0xc/0xe <- do_sys_open: rv=fffffffffffffffe ra=ffffffff81367a3a
140 <...>-1447 [001] 1038282.286885: do_sys_open+0x0/0xd6: 0xffffff9c 0x40413c 0x8000 0x1b6 134 <...>-1447 [001] 1038282.286885: do_sys_open+0x0/0xd6: dfd=ffffff9c filename=40413c flags=8000 mode=1b6
141 <...>-1447 [001] 1038282.286915: sys_open+0x1b/0x1d <- do_sys_open: 0x3 0xffffffff81367a3a 135 <...>-1447 [001] 1038282.286915: sys_open+0x1b/0x1d <- do_sys_open: rv=3 ra=ffffffff81367a3a
142 <...>-1447 [001] 1038282.286969: do_sys_open+0x0/0xd6: 0xffffff9c 0x4041c6 0x98800 0x10 136 <...>-1447 [001] 1038282.286969: do_sys_open+0x0/0xd6: dfd=ffffff9c filename=4041c6 flags=98800 mode=10
143 <...>-1447 [001] 1038282.286976: sys_open+0x1b/0x1d <- do_sys_open: 0x3 0xffffffff81367a3a 137 <...>-1447 [001] 1038282.286976: sys_open+0x1b/0x1d <- do_sys_open: rv=3 ra=ffffffff81367a3a
144 138
145 139
146 Each line shows when the kernel hits a probe, and <- SYMBOL means kernel 140 Each line shows when the kernel hits a probe, and <- SYMBOL means kernel
diff --git a/kernel/trace/trace_kprobe.c b/kernel/trace/trace_kprobe.c
index 730e992d28da..44dad1aa95d3 100644
--- a/kernel/trace/trace_kprobe.c
+++ b/kernel/trace/trace_kprobe.c
@@ -176,9 +176,14 @@ static __kprobes void free_indirect_fetch_data(struct indirect_fetch_data *data)
176} 176}
177 177
178/** 178/**
179 * kprobe_trace_core 179 * Kprobe tracer core functions
180 */ 180 */
181 181
182struct probe_arg {
183 struct fetch_func fetch;
184 const char *name;
185};
186
182struct trace_probe { 187struct trace_probe {
183 struct list_head list; 188 struct list_head list;
184 struct kretprobe rp; /* Use rp.kp for kprobe use */ 189 struct kretprobe rp; /* Use rp.kp for kprobe use */
@@ -187,12 +192,12 @@ struct trace_probe {
187 struct ftrace_event_call call; 192 struct ftrace_event_call call;
188 struct trace_event event; 193 struct trace_event event;
189 unsigned int nr_args; 194 unsigned int nr_args;
190 struct fetch_func args[]; 195 struct probe_arg args[];
191}; 196};
192 197
193#define SIZEOF_TRACE_PROBE(n) \ 198#define SIZEOF_TRACE_PROBE(n) \
194 (offsetof(struct trace_probe, args) + \ 199 (offsetof(struct trace_probe, args) + \
195 (sizeof(struct fetch_func) * (n))) 200 (sizeof(struct probe_arg) * (n)))
196 201
197static int kprobe_trace_func(struct kprobe *kp, struct pt_regs *regs); 202static int kprobe_trace_func(struct kprobe *kp, struct pt_regs *regs);
198static int kretprobe_trace_func(struct kretprobe_instance *ri, 203static int kretprobe_trace_func(struct kretprobe_instance *ri,
@@ -301,15 +306,21 @@ error:
301 return ERR_PTR(-ENOMEM); 306 return ERR_PTR(-ENOMEM);
302} 307}
303 308
309static void free_probe_arg(struct probe_arg *arg)
310{
311 if (arg->fetch.func == fetch_symbol)
312 free_symbol_cache(arg->fetch.data);
313 else if (arg->fetch.func == fetch_indirect)
314 free_indirect_fetch_data(arg->fetch.data);
315 kfree(arg->name);
316}
317
304static void free_trace_probe(struct trace_probe *tp) 318static void free_trace_probe(struct trace_probe *tp)
305{ 319{
306 int i; 320 int i;
307 321
308 for (i = 0; i < tp->nr_args; i++) 322 for (i = 0; i < tp->nr_args; i++)
309 if (tp->args[i].func == fetch_symbol) 323 free_probe_arg(&tp->args[i]);
310 free_symbol_cache(tp->args[i].data);
311 else if (tp->args[i].func == fetch_indirect)
312 free_indirect_fetch_data(tp->args[i].data);
313 324
314 kfree(tp->call.name); 325 kfree(tp->call.name);
315 kfree(tp->symbol); 326 kfree(tp->symbol);
@@ -532,11 +543,13 @@ static int create_trace_probe(int argc, char **argv)
532 * %REG : fetch register REG 543 * %REG : fetch register REG
533 * Indirect memory fetch: 544 * Indirect memory fetch:
534 * +|-offs(ARG) : fetch memory at ARG +|- offs address. 545 * +|-offs(ARG) : fetch memory at ARG +|- offs address.
546 * Alias name of args:
547 * NAME=FETCHARG : set NAME as alias of FETCHARG.
535 */ 548 */
536 struct trace_probe *tp; 549 struct trace_probe *tp;
537 int i, ret = 0; 550 int i, ret = 0;
538 int is_return = 0; 551 int is_return = 0;
539 char *symbol = NULL, *event = NULL; 552 char *symbol = NULL, *event = NULL, *arg = NULL;
540 unsigned long offset = 0; 553 unsigned long offset = 0;
541 void *addr = NULL; 554 void *addr = NULL;
542 char buf[MAX_EVENT_NAME_LEN]; 555 char buf[MAX_EVENT_NAME_LEN];
@@ -596,12 +609,21 @@ static int create_trace_probe(int argc, char **argv)
596 /* parse arguments */ 609 /* parse arguments */
597 ret = 0; 610 ret = 0;
598 for (i = 0; i < argc && i < MAX_TRACE_ARGS; i++) { 611 for (i = 0; i < argc && i < MAX_TRACE_ARGS; i++) {
599 if (strlen(argv[i]) > MAX_ARGSTR_LEN) { 612 /* Parse argument name */
600 pr_info("Argument%d(%s) is too long.\n", i, argv[i]); 613 arg = strchr(argv[i], '=');
614 if (arg)
615 *arg++ = '\0';
616 else
617 arg = argv[i];
618 tp->args[i].name = kstrdup(argv[i], GFP_KERNEL);
619
620 /* Parse fetch argument */
621 if (strlen(arg) > MAX_ARGSTR_LEN) {
622 pr_info("Argument%d(%s) is too long.\n", i, arg);
601 ret = -ENOSPC; 623 ret = -ENOSPC;
602 goto error; 624 goto error;
603 } 625 }
604 ret = parse_probe_arg(argv[i], &tp->args[i], is_return); 626 ret = parse_probe_arg(arg, &tp->args[i].fetch, is_return);
605 if (ret) 627 if (ret)
606 goto error; 628 goto error;
607 } 629 }
@@ -664,12 +686,12 @@ static int probes_seq_show(struct seq_file *m, void *v)
664 seq_printf(m, " 0x%p", tp->rp.kp.addr); 686 seq_printf(m, " 0x%p", tp->rp.kp.addr);
665 687
666 for (i = 0; i < tp->nr_args; i++) { 688 for (i = 0; i < tp->nr_args; i++) {
667 ret = probe_arg_string(buf, MAX_ARGSTR_LEN, &tp->args[i]); 689 ret = probe_arg_string(buf, MAX_ARGSTR_LEN, &tp->args[i].fetch);
668 if (ret < 0) { 690 if (ret < 0) {
669 pr_warning("Argument%d decoding error(%d).\n", i, ret); 691 pr_warning("Argument%d decoding error(%d).\n", i, ret);
670 return ret; 692 return ret;
671 } 693 }
672 seq_printf(m, " %s", buf); 694 seq_printf(m, " %s=%s", tp->args[i].name, buf);
673 } 695 }
674 seq_printf(m, "\n"); 696 seq_printf(m, "\n");
675 return 0; 697 return 0;
@@ -824,7 +846,7 @@ static __kprobes int kprobe_trace_func(struct kprobe *kp, struct pt_regs *regs)
824 entry->nargs = tp->nr_args; 846 entry->nargs = tp->nr_args;
825 entry->ip = (unsigned long)kp->addr; 847 entry->ip = (unsigned long)kp->addr;
826 for (i = 0; i < tp->nr_args; i++) 848 for (i = 0; i < tp->nr_args; i++)
827 entry->args[i] = call_fetch(&tp->args[i], regs); 849 entry->args[i] = call_fetch(&tp->args[i].fetch, regs);
828 850
829 if (!filter_current_check_discard(buffer, call, entry, event)) 851 if (!filter_current_check_discard(buffer, call, entry, event))
830 trace_nowake_buffer_unlock_commit(buffer, event, irq_flags, pc); 852 trace_nowake_buffer_unlock_commit(buffer, event, irq_flags, pc);
@@ -858,7 +880,7 @@ static __kprobes int kretprobe_trace_func(struct kretprobe_instance *ri,
858 entry->func = (unsigned long)tp->rp.kp.addr; 880 entry->func = (unsigned long)tp->rp.kp.addr;
859 entry->ret_ip = (unsigned long)ri->ret_addr; 881 entry->ret_ip = (unsigned long)ri->ret_addr;
860 for (i = 0; i < tp->nr_args; i++) 882 for (i = 0; i < tp->nr_args; i++)
861 entry->args[i] = call_fetch(&tp->args[i], regs); 883 entry->args[i] = call_fetch(&tp->args[i].fetch, regs);
862 884
863 if (!filter_current_check_discard(buffer, call, entry, event)) 885 if (!filter_current_check_discard(buffer, call, entry, event))
864 trace_nowake_buffer_unlock_commit(buffer, event, irq_flags, pc); 886 trace_nowake_buffer_unlock_commit(buffer, event, irq_flags, pc);
@@ -872,9 +894,13 @@ print_kprobe_event(struct trace_iterator *iter, int flags)
872{ 894{
873 struct kprobe_trace_entry *field; 895 struct kprobe_trace_entry *field;
874 struct trace_seq *s = &iter->seq; 896 struct trace_seq *s = &iter->seq;
897 struct trace_event *event;
898 struct trace_probe *tp;
875 int i; 899 int i;
876 900
877 field = (struct kprobe_trace_entry *)iter->ent; 901 field = (struct kprobe_trace_entry *)iter->ent;
902 event = ftrace_find_event(field->ent.type);
903 tp = container_of(event, struct trace_probe, event);
878 904
879 if (!seq_print_ip_sym(s, field->ip, flags | TRACE_ITER_SYM_OFFSET)) 905 if (!seq_print_ip_sym(s, field->ip, flags | TRACE_ITER_SYM_OFFSET))
880 goto partial; 906 goto partial;
@@ -883,7 +909,8 @@ print_kprobe_event(struct trace_iterator *iter, int flags)
883 goto partial; 909 goto partial;
884 910
885 for (i = 0; i < field->nargs; i++) 911 for (i = 0; i < field->nargs; i++)
886 if (!trace_seq_printf(s, " 0x%lx", field->args[i])) 912 if (!trace_seq_printf(s, " %s=%lx",
913 tp->args[i].name, field->args[i]))
887 goto partial; 914 goto partial;
888 915
889 if (!trace_seq_puts(s, "\n")) 916 if (!trace_seq_puts(s, "\n"))
@@ -899,9 +926,13 @@ print_kretprobe_event(struct trace_iterator *iter, int flags)
899{ 926{
900 struct kretprobe_trace_entry *field; 927 struct kretprobe_trace_entry *field;
901 struct trace_seq *s = &iter->seq; 928 struct trace_seq *s = &iter->seq;
929 struct trace_event *event;
930 struct trace_probe *tp;
902 int i; 931 int i;
903 932
904 field = (struct kretprobe_trace_entry *)iter->ent; 933 field = (struct kretprobe_trace_entry *)iter->ent;
934 event = ftrace_find_event(field->ent.type);
935 tp = container_of(event, struct trace_probe, event);
905 936
906 if (!seq_print_ip_sym(s, field->ret_ip, flags | TRACE_ITER_SYM_OFFSET)) 937 if (!seq_print_ip_sym(s, field->ret_ip, flags | TRACE_ITER_SYM_OFFSET))
907 goto partial; 938 goto partial;
@@ -916,7 +947,8 @@ print_kretprobe_event(struct trace_iterator *iter, int flags)
916 goto partial; 947 goto partial;
917 948
918 for (i = 0; i < field->nargs; i++) 949 for (i = 0; i < field->nargs; i++)
919 if (!trace_seq_printf(s, " 0x%lx", field->args[i])) 950 if (!trace_seq_printf(s, " %s=%lx",
951 tp->args[i].name, field->args[i]))
920 goto partial; 952 goto partial;
921 953
922 if (!trace_seq_puts(s, "\n")) 954 if (!trace_seq_puts(s, "\n"))
@@ -972,7 +1004,6 @@ static int kprobe_event_define_fields(struct ftrace_event_call *event_call)
972{ 1004{
973 int ret, i; 1005 int ret, i;
974 struct kprobe_trace_entry field; 1006 struct kprobe_trace_entry field;
975 char buf[MAX_ARGSTR_LEN + 1];
976 struct trace_probe *tp = (struct trace_probe *)event_call->data; 1007 struct trace_probe *tp = (struct trace_probe *)event_call->data;
977 1008
978 ret = trace_define_common_fields(event_call); 1009 ret = trace_define_common_fields(event_call);
@@ -981,16 +1012,9 @@ static int kprobe_event_define_fields(struct ftrace_event_call *event_call)
981 1012
982 DEFINE_FIELD(unsigned long, ip, "ip", 0); 1013 DEFINE_FIELD(unsigned long, ip, "ip", 0);
983 DEFINE_FIELD(int, nargs, "nargs", 1); 1014 DEFINE_FIELD(int, nargs, "nargs", 1);
984 for (i = 0; i < tp->nr_args; i++) { 1015 /* Set argument names as fields */
985 /* Set argN as a field */ 1016 for (i = 0; i < tp->nr_args; i++)
986 sprintf(buf, "arg%d", i); 1017 DEFINE_FIELD(unsigned long, args[i], tp->args[i].name, 0);
987 DEFINE_FIELD(unsigned long, args[i], buf, 0);
988 /* Set argument string as an alias field */
989 ret = probe_arg_string(buf, MAX_ARGSTR_LEN, &tp->args[i]);
990 if (ret < 0)
991 return ret;
992 DEFINE_FIELD(unsigned long, args[i], buf, 0);
993 }
994 return 0; 1018 return 0;
995} 1019}
996 1020
@@ -998,7 +1022,6 @@ static int kretprobe_event_define_fields(struct ftrace_event_call *event_call)
998{ 1022{
999 int ret, i; 1023 int ret, i;
1000 struct kretprobe_trace_entry field; 1024 struct kretprobe_trace_entry field;
1001 char buf[MAX_ARGSTR_LEN + 1];
1002 struct trace_probe *tp = (struct trace_probe *)event_call->data; 1025 struct trace_probe *tp = (struct trace_probe *)event_call->data;
1003 1026
1004 ret = trace_define_common_fields(event_call); 1027 ret = trace_define_common_fields(event_call);
@@ -1008,16 +1031,9 @@ static int kretprobe_event_define_fields(struct ftrace_event_call *event_call)
1008 DEFINE_FIELD(unsigned long, func, "func", 0); 1031 DEFINE_FIELD(unsigned long, func, "func", 0);
1009 DEFINE_FIELD(unsigned long, ret_ip, "ret_ip", 0); 1032 DEFINE_FIELD(unsigned long, ret_ip, "ret_ip", 0);
1010 DEFINE_FIELD(int, nargs, "nargs", 1); 1033 DEFINE_FIELD(int, nargs, "nargs", 1);
1011 for (i = 0; i < tp->nr_args; i++) { 1034 /* Set argument names as fields */
1012 /* Set argN as a field */ 1035 for (i = 0; i < tp->nr_args; i++)
1013 sprintf(buf, "arg%d", i); 1036 DEFINE_FIELD(unsigned long, args[i], tp->args[i].name, 0);
1014 DEFINE_FIELD(unsigned long, args[i], buf, 0);
1015 /* Set argument string as an alias field */
1016 ret = probe_arg_string(buf, MAX_ARGSTR_LEN, &tp->args[i]);
1017 if (ret < 0)
1018 return ret;
1019 DEFINE_FIELD(unsigned long, args[i], buf, 0);
1020 }
1021 return 0; 1037 return 0;
1022} 1038}
1023 1039
@@ -1025,31 +1041,21 @@ static int __probe_event_show_format(struct trace_seq *s,
1025 struct trace_probe *tp, const char *fmt, 1041 struct trace_probe *tp, const char *fmt,
1026 const char *arg) 1042 const char *arg)
1027{ 1043{
1028 int i, ret; 1044 int i;
1029 char buf[MAX_ARGSTR_LEN + 1];
1030 1045
1031 /* Show aliases */
1032 for (i = 0; i < tp->nr_args; i++) {
1033 ret = probe_arg_string(buf, MAX_ARGSTR_LEN, &tp->args[i]);
1034 if (ret < 0)
1035 return ret;
1036 if (!trace_seq_printf(s, "\talias: %s;\toriginal: arg%d;\n",
1037 buf, i))
1038 return 0;
1039 }
1040 /* Show format */ 1046 /* Show format */
1041 if (!trace_seq_printf(s, "\nprint fmt: \"%s", fmt)) 1047 if (!trace_seq_printf(s, "\nprint fmt: \"%s", fmt))
1042 return 0; 1048 return 0;
1043 1049
1044 for (i = 0; i < tp->nr_args; i++) 1050 for (i = 0; i < tp->nr_args; i++)
1045 if (!trace_seq_puts(s, " 0x%lx")) 1051 if (!trace_seq_printf(s, " %s=%%lx", tp->args[i].name))
1046 return 0; 1052 return 0;
1047 1053
1048 if (!trace_seq_printf(s, "\", %s", arg)) 1054 if (!trace_seq_printf(s, "\", %s", arg))
1049 return 0; 1055 return 0;
1050 1056
1051 for (i = 0; i < tp->nr_args; i++) 1057 for (i = 0; i < tp->nr_args; i++)
1052 if (!trace_seq_printf(s, ", arg%d", i)) 1058 if (!trace_seq_printf(s, ", REC->%s", tp->args[i].name))
1053 return 0; 1059 return 0;
1054 1060
1055 return trace_seq_puts(s, "\n"); 1061 return trace_seq_puts(s, "\n");
@@ -1071,17 +1077,14 @@ static int kprobe_event_show_format(struct ftrace_event_call *call,
1071{ 1077{
1072 struct kprobe_trace_entry field __attribute__((unused)); 1078 struct kprobe_trace_entry field __attribute__((unused));
1073 int ret, i; 1079 int ret, i;
1074 char buf[8];
1075 struct trace_probe *tp = (struct trace_probe *)call->data; 1080 struct trace_probe *tp = (struct trace_probe *)call->data;
1076 1081
1077 SHOW_FIELD(unsigned long, ip, "ip"); 1082 SHOW_FIELD(unsigned long, ip, "ip");
1078 SHOW_FIELD(int, nargs, "nargs"); 1083 SHOW_FIELD(int, nargs, "nargs");
1079 1084
1080 /* Show fields */ 1085 /* Show fields */
1081 for (i = 0; i < tp->nr_args; i++) { 1086 for (i = 0; i < tp->nr_args; i++)
1082 sprintf(buf, "arg%d", i); 1087 SHOW_FIELD(unsigned long, args[i], tp->args[i].name);
1083 SHOW_FIELD(unsigned long, args[i], buf);
1084 }
1085 trace_seq_puts(s, "\n"); 1088 trace_seq_puts(s, "\n");
1086 1089
1087 return __probe_event_show_format(s, tp, "%lx:", "ip"); 1090 return __probe_event_show_format(s, tp, "%lx:", "ip");
@@ -1092,7 +1095,6 @@ static int kretprobe_event_show_format(struct ftrace_event_call *call,
1092{ 1095{
1093 struct kretprobe_trace_entry field __attribute__((unused)); 1096 struct kretprobe_trace_entry field __attribute__((unused));
1094 int ret, i; 1097 int ret, i;
1095 char buf[8];
1096 struct trace_probe *tp = (struct trace_probe *)call->data; 1098 struct trace_probe *tp = (struct trace_probe *)call->data;
1097 1099
1098 SHOW_FIELD(unsigned long, func, "func"); 1100 SHOW_FIELD(unsigned long, func, "func");
@@ -1100,10 +1102,8 @@ static int kretprobe_event_show_format(struct ftrace_event_call *call,
1100 SHOW_FIELD(int, nargs, "nargs"); 1102 SHOW_FIELD(int, nargs, "nargs");
1101 1103
1102 /* Show fields */ 1104 /* Show fields */
1103 for (i = 0; i < tp->nr_args; i++) { 1105 for (i = 0; i < tp->nr_args; i++)
1104 sprintf(buf, "arg%d", i); 1106 SHOW_FIELD(unsigned long, args[i], tp->args[i].name);
1105 SHOW_FIELD(unsigned long, args[i], buf);
1106 }
1107 trace_seq_puts(s, "\n"); 1107 trace_seq_puts(s, "\n");
1108 1108
1109 return __probe_event_show_format(s, tp, "%lx <- %lx:", 1109 return __probe_event_show_format(s, tp, "%lx <- %lx:",
@@ -1140,7 +1140,7 @@ static __kprobes int kprobe_profile_func(struct kprobe *kp,
1140 entry->nargs = tp->nr_args; 1140 entry->nargs = tp->nr_args;
1141 entry->ip = (unsigned long)kp->addr; 1141 entry->ip = (unsigned long)kp->addr;
1142 for (i = 0; i < tp->nr_args; i++) 1142 for (i = 0; i < tp->nr_args; i++)
1143 entry->args[i] = call_fetch(&tp->args[i], regs); 1143 entry->args[i] = call_fetch(&tp->args[i].fetch, regs);
1144 perf_tpcounter_event(call->id, entry->ip, 1, entry, size); 1144 perf_tpcounter_event(call->id, entry->ip, 1, entry, size);
1145 } while (0); 1145 } while (0);
1146 return 0; 1146 return 0;
@@ -1175,7 +1175,7 @@ static __kprobes int kretprobe_profile_func(struct kretprobe_instance *ri,
1175 entry->func = (unsigned long)tp->rp.kp.addr; 1175 entry->func = (unsigned long)tp->rp.kp.addr;
1176 entry->ret_ip = (unsigned long)ri->ret_addr; 1176 entry->ret_ip = (unsigned long)ri->ret_addr;
1177 for (i = 0; i < tp->nr_args; i++) 1177 for (i = 0; i < tp->nr_args; i++)
1178 entry->args[i] = call_fetch(&tp->args[i], regs); 1178 entry->args[i] = call_fetch(&tp->args[i].fetch, regs);
1179 perf_tpcounter_event(call->id, entry->ret_ip, 1, entry, size); 1179 perf_tpcounter_event(call->id, entry->ret_ip, 1, entry, size);
1180 } while (0); 1180 } while (0);
1181 return 0; 1181 return 0;