builtin-probe.c 10.9 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37
/*
 * builtin-probe.c
 *
 * Builtin probe command: Set up probe events by C expression
 *
 * Written by Masami Hiramatsu <mhiramat@redhat.com>
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
 *
 */
#define _GNU_SOURCE
#include <sys/utsname.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <errno.h>
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>

#undef _GNU_SOURCE
#include "perf.h"
#include "builtin.h"
#include "util/util.h"
38 39
#include "util/event.h"
#include "util/debug.h"
40 41 42 43 44 45 46 47 48 49 50 51 52 53
#include "util/parse-options.h"
#include "util/parse-events.h"	/* For debugfs_path */
#include "util/probe-finder.h"

/* Default vmlinux search paths */
#define NR_SEARCH_PATH 3
const char *default_search_path[NR_SEARCH_PATH] = {
"/lib/modules/%s/build/vmlinux",		/* Custom build kernel */
"/usr/lib/debug/lib/modules/%s/vmlinux",	/* Red Hat debuginfo */
"/boot/vmlinux-debug-%s",			/* Ubuntu */
};

#define MAX_PATH_LEN 256
#define MAX_PROBES 128
54
#define MAX_PROBE_ARGS 128
55
#define PERFPROBE_GROUP "probe"
56 57 58 59 60

/* Session management structure */
static struct {
	char *vmlinux;
	char *release;
61
	int need_dwarf;
62 63 64 65
	int nr_probe;
	struct probe_point probes[MAX_PROBES];
} session;

66
#define semantic_error(msg ...) die("Semantic error :" msg)
67

68 69 70 71
/* Parse probe point. Return 1 if return probe */
static void parse_probe_point(char *arg, struct probe_point *pp)
{
	char *ptr, *tmp;
72
	char c, nc = 0;
73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135
	/*
	 * <Syntax>
	 * perf probe SRC:LN
	 * perf probe FUNC[+OFFS|%return][@SRC]
	 */

	ptr = strpbrk(arg, ":+@%");
	if (ptr) {
		nc = *ptr;
		*ptr++ = '\0';
	}

	/* Check arg is function or file and copy it */
	if (strchr(arg, '.'))	/* File */
		pp->file = strdup(arg);
	else			/* Function */
		pp->function = strdup(arg);
	DIE_IF(pp->file == NULL && pp->function == NULL);

	/* Parse other options */
	while (ptr) {
		arg = ptr;
		c = nc;
		ptr = strpbrk(arg, ":+@%");
		if (ptr) {
			nc = *ptr;
			*ptr++ = '\0';
		}
		switch (c) {
		case ':':	/* Line number */
			pp->line = strtoul(arg, &tmp, 0);
			if (*tmp != '\0')
				semantic_error("There is non-digit charactor"
						" in line number.");
			break;
		case '+':	/* Byte offset from a symbol */
			pp->offset = strtoul(arg, &tmp, 0);
			if (*tmp != '\0')
				semantic_error("There is non-digit charactor"
						" in offset.");
			break;
		case '@':	/* File name */
			if (pp->file)
				semantic_error("SRC@SRC is not allowed.");
			pp->file = strdup(arg);
			DIE_IF(pp->file == NULL);
			if (ptr)
				semantic_error("@SRC must be the last "
					       "option.");
			break;
		case '%':	/* Probe places */
			if (strcmp(arg, "return") == 0) {
				pp->retprobe = 1;
			} else	/* Others not supported yet */
				semantic_error("%%%s is not supported.", arg);
			break;
		default:
			DIE_IF("Program has a bug.");
			break;
		}
	}

	/* Exclusion check */
136 137
	if (pp->line && pp->offset)
		semantic_error("Offset can't be used with line number.");
138 139 140 141 142 143
	if (!pp->line && pp->file && !pp->function)
		semantic_error("File always requires line number.");
	if (pp->offset && !pp->function)
		semantic_error("Offset requires an entry function.");
	if (pp->retprobe && !pp->function)
		semantic_error("Return probe requires an entry function.");
144 145
	if ((pp->offset || pp->line) && pp->retprobe)
		semantic_error("Offset/Line can't be used with return probe.");
146 147 148 149 150 151 152

	pr_debug("symbol:%s file:%s line:%d offset:%d, return:%d\n",
		 pp->function, pp->file, pp->line, pp->offset, pp->retprobe);
}

/* Parse an event definition. Note that any error must die. */
static void parse_probe_event(const char *str)
153 154 155 156 157
{
	char *argv[MAX_PROBE_ARGS + 2];	/* Event + probe + args */
	int argc, i;
	struct probe_point *pp = &session.probes[session.nr_probe];

158
	pr_debug("probe-definition(%d): %s\n", session.nr_probe, str);
159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179
	if (++session.nr_probe == MAX_PROBES)
		semantic_error("Too many probes");

	/* Separate arguments, similar to argv_split */
	argc = 0;
	do {
		/* Skip separators */
		while (isspace(*str))
			str++;

		/* Add an argument */
		if (*str != '\0') {
			const char *s = str;

			/* Skip the argument */
			while (!isspace(*str) && *str != '\0')
				str++;

			/* Duplicate the argument */
			argv[argc] = strndup(s, str - s);
			if (argv[argc] == NULL)
180
				die("strndup");
181 182
			if (++argc == MAX_PROBE_ARGS)
				semantic_error("Too many arguments");
183
			pr_debug("argv[%d]=%s\n", argc, argv[argc - 1]);
184 185
		}
	} while (*str != '\0');
186 187
	if (!argc)
		semantic_error("An empty argument.");
188 189

	/* Parse probe point */
190 191
	parse_probe_point(argv[0], pp);
	free(argv[0]);
192
	if (pp->file || pp->line)
193
		session.need_dwarf = 1;
194 195

	/* Copy arguments */
196
	pp->nr_args = argc - 1;
197 198 199
	if (pp->nr_args > 0) {
		pp->args = (char **)malloc(sizeof(char *) * pp->nr_args);
		if (!pp->args)
200
			die("malloc");
201
		memcpy(pp->args, &argv[1], sizeof(char *) * pp->nr_args);
202 203 204
	}

	/* Ensure return probe has no C argument */
205 206
	for (i = 0; i < pp->nr_args; i++)
		if (is_c_varname(pp->args[i])) {
207
			if (pp->retprobe)
208 209
				semantic_error("You can't specify local"
						" variable for kretprobe");
210 211 212
			session.need_dwarf = 1;
		}

213
	pr_debug("%d arguments\n", pp->nr_args);
214 215
}

216
static int opt_add_probe_event(const struct option *opt __used,
217 218 219
			      const char *str, int unset __used)
{
	if (str)
220
		parse_probe_event(str);
221 222 223
	return 0;
}

224
#ifndef NO_LIBDWARF
225 226 227 228 229 230 231 232
static int open_default_vmlinux(void)
{
	struct utsname uts;
	char fname[MAX_PATH_LEN];
	int fd, ret, i;

	ret = uname(&uts);
	if (ret) {
233
		pr_debug("uname() failed.\n");
234 235 236 237 238 239 240
		return -errno;
	}
	session.release = uts.release;
	for (i = 0; i < NR_SEARCH_PATH; i++) {
		ret = snprintf(fname, MAX_PATH_LEN,
			       default_search_path[i], session.release);
		if (ret >= MAX_PATH_LEN || ret < 0) {
241
			pr_debug("Filename(%d,%s) is too long.\n", i,
242
				uts.release);
243 244 245
			errno = E2BIG;
			return -E2BIG;
		}
246
		pr_debug("try to open %s\n", fname);
247 248 249 250 251 252
		fd = open(fname, O_RDONLY);
		if (fd >= 0)
			break;
	}
	return fd;
}
253
#endif
254 255

static const char * const probe_usage[] = {
256 257
	"perf probe [<options>] 'PROBEDEF' ['PROBEDEF' ...]",
	"perf probe [<options>] --add 'PROBEDEF' [--add 'PROBEDEF' ...]",
258 259 260 261
	NULL
};

static const struct option options[] = {
262 263
	OPT_BOOLEAN('v', "verbose", &verbose,
		    "be more verbose (show parsed arguments, etc)"),
264
#ifndef NO_LIBDWARF
265 266
	OPT_STRING('k', "vmlinux", &session.vmlinux, "file",
		"vmlinux/module pathname"),
267
#endif
268
	OPT_CALLBACK('a', "add", NULL,
269
#ifdef NO_LIBDWARF
270
		"FUNC[+OFFS|%return] [ARG ...]",
271
#else
272
		"FUNC[+OFFS|%return|:RLN][@SRC]|SRC:ALN [ARG ...]",
273
#endif
274 275 276 277 278
		"probe point definition, where\n"
		"\t\tGRP:\tGroup name (optional)\n"
		"\t\tNAME:\tEvent name\n"
		"\t\tFUNC:\tFunction name\n"
		"\t\tOFFS:\tOffset from function entry (in byte)\n"
279
		"\t\t%return:\tPut the probe at function return\n"
280 281 282
#ifdef NO_LIBDWARF
		"\t\tARG:\tProbe argument (only \n"
#else
283
		"\t\tSRC:\tSource code path\n"
284 285
		"\t\tRLN:\tRelative line number from function entry.\n"
		"\t\tALN:\tAbsolute line number in file.\n"
286
		"\t\tARG:\tProbe argument (local variable name or\n"
287
#endif
288
		"\t\t\tkprobe-tracer argument format is supported.)\n",
289
		opt_add_probe_event),
290 291 292 293 294 295 296 297 298
	OPT_END()
};

static int write_new_event(int fd, const char *buf)
{
	int ret;

	ret = write(fd, buf, strlen(buf));
	if (ret <= 0)
299 300 301
		die("Failed to create event.");
	else
		printf("Added new event: %s\n", buf);
302 303 304 305 306 307

	return ret;
}

#define MAX_CMDLEN 256

308
static int synthesize_probe_event(struct probe_point *pp)
309 310 311
{
	char *buf;
	int i, len, ret;
312
	pp->probes[0] = buf = zalloc(MAX_CMDLEN);
313
	if (!buf)
314
		die("Failed to allocate memory by zalloc.");
315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337
	ret = snprintf(buf, MAX_CMDLEN, "%s+%d", pp->function, pp->offset);
	if (ret <= 0 || ret >= MAX_CMDLEN)
		goto error;
	len = ret;

	for (i = 0; i < pp->nr_args; i++) {
		ret = snprintf(&buf[len], MAX_CMDLEN - len, " %s",
			       pp->args[i]);
		if (ret <= 0 || ret >= MAX_CMDLEN - len)
			goto error;
		len += ret;
	}
	pp->found = 1;
	return pp->found;
error:
	free(pp->probes[0]);
	if (ret > 0)
		ret = -E2BIG;
	return ret;
}

int cmd_probe(int argc, const char **argv, const char *prefix __used)
{
338
	int i, j, fd, ret;
339 340 341 342
	struct probe_point *pp;
	char buf[MAX_CMDLEN];

	argc = parse_options(argc, argv, options, probe_usage,
343 344 345 346 347
			     PARSE_OPT_STOP_AT_NON_OPTION);
	for (i = 0; i < argc; i++)
		parse_probe_event(argv[i]);

	if (session.nr_probe == 0)
348 349
		usage_with_options(probe_usage, options);

350
	if (session.need_dwarf)
351 352 353 354
#ifdef NO_LIBDWARF
		semantic_error("Debuginfo-analysis is not supported");
#else	/* !NO_LIBDWARF */
		pr_info("Some probes require debuginfo.\n");
355 356 357 358 359

	if (session.vmlinux)
		fd = open(session.vmlinux, O_RDONLY);
	else
		fd = open_default_vmlinux();
360 361 362 363 364 365 366 367
	if (fd < 0) {
		if (session.need_dwarf)
			die("Could not open vmlinux/module file.");

		pr_warning("Could not open vmlinux/module file."
			   " Try to use symbols.\n");
		goto end_dwarf;
	}
368 369 370 371 372 373 374 375 376

	/* Searching probe points */
	for (j = 0; j < session.nr_probe; j++) {
		pp = &session.probes[j];
		if (pp->found)
			continue;

		lseek(fd, SEEK_SET, 0);
		ret = find_probepoint(fd, pp);
377 378 379 380 381 382 383 384 385
		if (ret < 0) {
			if (session.need_dwarf)
				die("Could not analyze debuginfo.");

			pr_warning("An error occurred in debuginfo analysis. Try to use symbols.\n");
			break;
		}
		if (ret == 0)	/* No error but failed to find probe point. */
			die("No probe point found.");
386 387 388
	}
	close(fd);

389
end_dwarf:
390 391
#endif /* !NO_LIBDWARF */

392 393 394 395 396 397 398 399 400 401 402 403 404
	/* Synthesize probes without dwarf */
	for (j = 0; j < session.nr_probe; j++) {
		pp = &session.probes[j];
		if (pp->found)	/* This probe is already found. */
			continue;

		ret = synthesize_probe_event(pp);
		if (ret == -E2BIG)
			semantic_error("probe point is too long.");
		else if (ret < 0)
			die("Failed to synthesize a probe point.");
	}

405 406 407
	/* Settng up probe points */
	snprintf(buf, MAX_CMDLEN, "%s/../kprobe_events", debugfs_path);
	fd = open(buf, O_WRONLY, O_APPEND);
408 409 410 411 412 413 414
	if (fd < 0) {
		if (errno == ENOENT)
			die("kprobe_events file does not exist - please rebuild with CONFIG_KPROBE_TRACER.");
		else
			die("Could not open kprobe_events file: %s",
			    strerror(errno));
	}
415 416 417
	for (j = 0; j < session.nr_probe; j++) {
		pp = &session.probes[j];
		if (pp->found == 1) {
418 419 420
			snprintf(buf, MAX_CMDLEN, "%c:%s/%s_%x %s\n",
				pp->retprobe ? 'r' : 'p', PERFPROBE_GROUP,
				pp->function, pp->offset, pp->probes[0]);
421 422 423
			write_new_event(fd, buf);
		} else
			for (i = 0; i < pp->found; i++) {
424 425 426 427 428
				snprintf(buf, MAX_CMDLEN, "%c:%s/%s_%x_%d %s\n",
					pp->retprobe ? 'r' : 'p',
					PERFPROBE_GROUP,
					pp->function, pp->offset, i,
					pp->probes[0]);
429 430 431 432 433 434 435
				write_new_event(fd, buf);
			}
	}
	close(fd);
	return 0;
}