4 * Builtin probe command: Set up probe events by C expression
6 * Written by Masami Hiramatsu <mhiramat@redhat.com>
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
24 #include <sys/utsname.h>
25 #include <sys/types.h>
37 #include "util/util.h"
38 #include "util/parse-options.h"
39 #include "util/parse-events.h" /* For debugfs_path */
40 #include "util/probe-finder.h"
42 /* Default vmlinux search paths */
43 #define NR_SEARCH_PATH 3
44 const char *default_search_path
[NR_SEARCH_PATH
] = {
45 "/lib/modules/%s/build/vmlinux", /* Custom build kernel */
46 "/usr/lib/debug/lib/modules/%s/vmlinux", /* Red Hat debuginfo */
47 "/boot/vmlinux-debug-%s", /* Ubuntu */
50 #define MAX_PATH_LEN 256
51 #define MAX_PROBES 128
53 /* Session management structure */
59 struct probe_point probes
[MAX_PROBES
];
60 char *events
[MAX_PROBES
];
63 static void semantic_error(const char *msg
)
65 fprintf(stderr
, "Semantic error: %s\n", msg
);
69 static void perror_exit(const char *msg
)
75 #define MAX_PROBE_ARGS 128
77 static int parse_probepoint(const struct option
*opt __used
,
78 const char *str
, int unset __used
)
80 char *argv
[MAX_PROBE_ARGS
+ 2]; /* Event + probe + args */
83 struct probe_point
*pp
= &session
.probes
[session
.nr_probe
];
84 char **event
= &session
.events
[session
.nr_probe
];
87 if (!str
) /* The end of probe points */
90 debug("Probe-define(%d): %s\n", session
.nr_probe
, str
);
91 if (++session
.nr_probe
== MAX_PROBES
)
92 semantic_error("Too many probes");
94 /* Separate arguments, similar to argv_split */
101 /* Add an argument */
105 /* Skip the argument */
106 while (!isspace(*str
) && *str
!= '\0')
109 /* Duplicate the argument */
110 argv
[argc
] = strndup(s
, str
- s
);
111 if (argv
[argc
] == NULL
)
112 perror_exit("strndup");
113 if (++argc
== MAX_PROBE_ARGS
)
114 semantic_error("Too many arguments");
115 debug("argv[%d]=%s\n", argc
, argv
[argc
- 1]);
117 } while (*str
!= '\0');
119 semantic_error("Need event-name and probe-point at least.");
121 /* Parse the event name */
122 if (argv
[0][0] == 'r')
124 else if (argv
[0][0] != 'p')
125 semantic_error("You must specify 'p'(kprobe) or"
126 " 'r'(kretprobe) first.");
127 /* TODO: check event name */
130 /* Parse probe point */
135 ptr
= strchr(arg
, ':');
136 if (!ptr
|| !isdigit(ptr
[1]))
137 semantic_error("Line number is required.");
139 if (strlen(arg
) == 0)
140 semantic_error("No file name.");
141 pp
->file
= strdup(arg
);
142 pp
->line
= atoi(ptr
);
143 if (!pp
->file
|| !pp
->line
)
144 semantic_error("Failed to parse line.");
145 debug("file:%s line:%d\n", pp
->file
, pp
->line
);
148 ptr
= strchr(arg
, '+');
150 if (!isdigit(ptr
[1]))
151 semantic_error("Offset is required.");
153 pp
->offset
= atoi(ptr
);
156 ptr
= strchr(ptr
, '@');
159 pp
->file
= strdup(ptr
);
161 pp
->function
= strdup(arg
);
162 debug("symbol:%s file:%s offset:%d\n",
163 pp
->function
, pp
->file
, pp
->offset
);
167 session
.need_dwarf
= 1;
170 pp
->nr_args
= argc
- 2;
171 if (pp
->nr_args
> 0) {
172 pp
->args
= (char **)malloc(sizeof(char *) * pp
->nr_args
);
174 perror_exit("malloc");
175 memcpy(pp
->args
, &argv
[2], sizeof(char *) * pp
->nr_args
);
178 /* Ensure return probe has no C argument */
179 for (i
= 0; i
< pp
->nr_args
; i
++)
180 if (is_c_varname(pp
->args
[i
])) {
182 semantic_error("You can't specify local"
183 " variable for kretprobe");
184 session
.need_dwarf
= 1;
187 debug("%d arguments\n", pp
->nr_args
);
192 static int open_default_vmlinux(void)
195 char fname
[MAX_PATH_LEN
];
200 debug("uname() failed.\n");
203 session
.release
= uts
.release
;
204 for (i
= 0; i
< NR_SEARCH_PATH
; i
++) {
205 ret
= snprintf(fname
, MAX_PATH_LEN
,
206 default_search_path
[i
], session
.release
);
207 if (ret
>= MAX_PATH_LEN
|| ret
< 0) {
208 debug("Filename(%d,%s) is too long.\n", i
, uts
.release
);
212 debug("try to open %s\n", fname
);
213 fd
= open(fname
, O_RDONLY
);
221 static const char * const probe_usage
[] = {
222 "perf probe [<options>] -P 'PROBEDEF' [-P 'PROBEDEF' ...]",
226 static const struct option options
[] = {
228 OPT_STRING('k', "vmlinux", &session
.vmlinux
, "file",
229 "vmlinux/module pathname"),
231 OPT_CALLBACK('P', "probe", NULL
,
233 "p|r:[GRP/]NAME FUNC[+OFFS] [ARG ...]",
235 "p|r:[GRP/]NAME FUNC[+OFFS][@SRC]|@SRC:LINE [ARG ...]",
237 "probe point definition, where\n"
238 "\t\tp:\tkprobe probe\n"
239 "\t\tr:\tkretprobe probe\n"
240 "\t\tGRP:\tGroup name (optional)\n"
241 "\t\tNAME:\tEvent name\n"
242 "\t\tFUNC:\tFunction name\n"
243 "\t\tOFFS:\tOffset from function entry (in byte)\n"
245 "\t\tARG:\tProbe argument (only \n"
247 "\t\tSRC:\tSource code path\n"
248 "\t\tLINE:\tLine number\n"
249 "\t\tARG:\tProbe argument (local variable name or\n"
251 "\t\t\tkprobe-tracer argument format is supported.)\n",
256 static int write_new_event(int fd
, const char *buf
)
260 printf("Adding new event: %s\n", buf
);
261 ret
= write(fd
, buf
, strlen(buf
));
263 perror("Error: Failed to create event");
268 #define MAX_CMDLEN 256
270 static int synthesize_probepoint(struct probe_point
*pp
)
274 pp
->probes
[0] = buf
= (char *)calloc(MAX_CMDLEN
, sizeof(char));
276 perror_exit("calloc");
277 ret
= snprintf(buf
, MAX_CMDLEN
, "%s+%d", pp
->function
, pp
->offset
);
278 if (ret
<= 0 || ret
>= MAX_CMDLEN
)
282 for (i
= 0; i
< pp
->nr_args
; i
++) {
283 ret
= snprintf(&buf
[len
], MAX_CMDLEN
- len
, " %s",
285 if (ret
<= 0 || ret
>= MAX_CMDLEN
- len
)
298 int cmd_probe(int argc
, const char **argv
, const char *prefix __used
)
301 struct probe_point
*pp
;
302 char buf
[MAX_CMDLEN
];
304 argc
= parse_options(argc
, argv
, options
, probe_usage
,
305 PARSE_OPT_STOP_AT_NON_OPTION
);
306 if (argc
|| session
.nr_probe
== 0)
307 usage_with_options(probe_usage
, options
);
310 if (session
.need_dwarf
)
311 semantic_error("Dwarf-analysis is not supported");
314 /* Synthesize probes without dwarf */
315 for (j
= 0; j
< session
.nr_probe
; j
++) {
317 if (session
.events
[j
][0] != 'r') {
318 session
.need_dwarf
= 1;
322 ret
= synthesize_probepoint(&session
.probes
[j
]);
324 semantic_error("probe point is too long.");
332 if (!session
.need_dwarf
)
336 fd
= open(session
.vmlinux
, O_RDONLY
);
338 fd
= open_default_vmlinux();
340 perror("vmlinux/module file open");
344 /* Searching probe points */
345 for (j
= 0; j
< session
.nr_probe
; j
++) {
346 pp
= &session
.probes
[j
];
350 lseek(fd
, SEEK_SET
, 0);
351 ret
= find_probepoint(fd
, pp
);
353 fprintf(stderr
, "Error: No probe point found.\n");
356 debug("probe event %s found\n", session
.events
[j
]);
361 #endif /* !NO_LIBDWARF */
363 /* Settng up probe points */
364 snprintf(buf
, MAX_CMDLEN
, "%s/../kprobe_events", debugfs_path
);
365 fd
= open(buf
, O_WRONLY
, O_APPEND
);
367 perror("kprobe_events open");
370 for (j
= 0; j
< session
.nr_probe
; j
++) {
371 pp
= &session
.probes
[j
];
372 if (pp
->found
== 1) {
373 snprintf(buf
, MAX_CMDLEN
, "%s %s\n",
374 session
.events
[j
], pp
->probes
[0]);
375 write_new_event(fd
, buf
);
377 for (i
= 0; i
< pp
->found
; i
++) {
378 snprintf(buf
, MAX_CMDLEN
, "%s%d %s\n",
379 session
.events
[j
], i
, pp
->probes
[i
]);
380 write_new_event(fd
, buf
);