xref: /linux/tools/perf/util/probe-event.c (revision 5499b45190237ca90dd2ac86395cf464fe1f4cc7)
1 /*
2  * probe-event.c : perf-probe definition to kprobe_events format converter
3  *
4  * Written by Masami Hiramatsu <mhiramat@redhat.com>
5  *
6  * This program is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 2 of the License, or
9  * (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program; if not, write to the Free Software
18  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
19  *
20  */
21 
22 #define _GNU_SOURCE
23 #include <sys/utsname.h>
24 #include <sys/types.h>
25 #include <sys/stat.h>
26 #include <fcntl.h>
27 #include <errno.h>
28 #include <stdio.h>
29 #include <unistd.h>
30 #include <stdlib.h>
31 #include <string.h>
32 #include <stdarg.h>
33 #include <limits.h>
34 
35 #undef _GNU_SOURCE
36 #include "event.h"
37 #include "string.h"
38 #include "strlist.h"
39 #include "debug.h"
40 #include "cache.h"
41 #include "color.h"
42 #include "parse-events.h"  /* For debugfs_path */
43 #include "probe-event.h"
44 
45 #define MAX_CMDLEN 256
46 #define MAX_PROBE_ARGS 128
47 #define PERFPROBE_GROUP "probe"
48 
49 #define semantic_error(msg ...) die("Semantic error :" msg)
50 
51 /* If there is no space to write, returns -E2BIG. */
52 static int e_snprintf(char *str, size_t size, const char *format, ...)
53 	__attribute__((format(printf, 3, 4)));
54 
55 static int e_snprintf(char *str, size_t size, const char *format, ...)
56 {
57 	int ret;
58 	va_list ap;
59 	va_start(ap, format);
60 	ret = vsnprintf(str, size, format, ap);
61 	va_end(ap);
62 	if (ret >= (int)size)
63 		ret = -E2BIG;
64 	return ret;
65 }
66 
67 void parse_line_range_desc(const char *arg, struct line_range *lr)
68 {
69 	const char *ptr;
70 	char *tmp;
71 	/*
72 	 * <Syntax>
73 	 * SRC:SLN[+NUM|-ELN]
74 	 * FUNC[:SLN[+NUM|-ELN]]
75 	 */
76 	ptr = strchr(arg, ':');
77 	if (ptr) {
78 		lr->start = (unsigned int)strtoul(ptr + 1, &tmp, 0);
79 		if (*tmp == '+')
80 			lr->end = lr->start + (unsigned int)strtoul(tmp + 1,
81 								    &tmp, 0);
82 		else if (*tmp == '-')
83 			lr->end = (unsigned int)strtoul(tmp + 1, &tmp, 0);
84 		else
85 			lr->end = 0;
86 		pr_debug("Line range is %u to %u\n", lr->start, lr->end);
87 		if (lr->end && lr->start > lr->end)
88 			semantic_error("Start line must be smaller"
89 				       " than end line.");
90 		if (*tmp != '\0')
91 			semantic_error("Tailing with invalid character '%d'.",
92 				       *tmp);
93 		tmp = strndup(arg, (ptr - arg));
94 	} else
95 		tmp = strdup(arg);
96 
97 	if (strchr(tmp, '.'))
98 		lr->file = tmp;
99 	else
100 		lr->function = tmp;
101 }
102 
103 /* Check the name is good for event/group */
104 static bool check_event_name(const char *name)
105 {
106 	if (!isalpha(*name) && *name != '_')
107 		return false;
108 	while (*++name != '\0') {
109 		if (!isalpha(*name) && !isdigit(*name) && *name != '_')
110 			return false;
111 	}
112 	return true;
113 }
114 
115 /* Parse probepoint definition. */
116 static void parse_perf_probe_probepoint(char *arg, struct probe_point *pp)
117 {
118 	char *ptr, *tmp;
119 	char c, nc = 0;
120 	/*
121 	 * <Syntax>
122 	 * perf probe [EVENT=]SRC:LN
123 	 * perf probe [EVENT=]FUNC[+OFFS|%return][@SRC]
124 	 *
125 	 * TODO:Group name support
126 	 */
127 
128 	ptr = strchr(arg, '=');
129 	if (ptr) {	/* Event name */
130 		*ptr = '\0';
131 		tmp = ptr + 1;
132 		ptr = strchr(arg, ':');
133 		if (ptr)	/* Group name is not supported yet. */
134 			semantic_error("Group name is not supported yet.");
135 		if (!check_event_name(arg))
136 			semantic_error("%s is bad for event name -it must "
137 				       "follow C symbol-naming rule.", arg);
138 		pp->event = strdup(arg);
139 		arg = tmp;
140 	}
141 
142 	ptr = strpbrk(arg, ":+@%");
143 	if (ptr) {
144 		nc = *ptr;
145 		*ptr++ = '\0';
146 	}
147 
148 	/* Check arg is function or file and copy it */
149 	if (strchr(arg, '.'))	/* File */
150 		pp->file = strdup(arg);
151 	else			/* Function */
152 		pp->function = strdup(arg);
153 	DIE_IF(pp->file == NULL && pp->function == NULL);
154 
155 	/* Parse other options */
156 	while (ptr) {
157 		arg = ptr;
158 		c = nc;
159 		ptr = strpbrk(arg, ":+@%");
160 		if (ptr) {
161 			nc = *ptr;
162 			*ptr++ = '\0';
163 		}
164 		switch (c) {
165 		case ':':	/* Line number */
166 			pp->line = strtoul(arg, &tmp, 0);
167 			if (*tmp != '\0')
168 				semantic_error("There is non-digit charactor"
169 						" in line number.");
170 			break;
171 		case '+':	/* Byte offset from a symbol */
172 			pp->offset = strtoul(arg, &tmp, 0);
173 			if (*tmp != '\0')
174 				semantic_error("There is non-digit charactor"
175 						" in offset.");
176 			break;
177 		case '@':	/* File name */
178 			if (pp->file)
179 				semantic_error("SRC@SRC is not allowed.");
180 			pp->file = strdup(arg);
181 			DIE_IF(pp->file == NULL);
182 			if (ptr)
183 				semantic_error("@SRC must be the last "
184 					       "option.");
185 			break;
186 		case '%':	/* Probe places */
187 			if (strcmp(arg, "return") == 0) {
188 				pp->retprobe = 1;
189 			} else	/* Others not supported yet */
190 				semantic_error("%%%s is not supported.", arg);
191 			break;
192 		default:
193 			DIE_IF("Program has a bug.");
194 			break;
195 		}
196 	}
197 
198 	/* Exclusion check */
199 	if (pp->line && pp->offset)
200 		semantic_error("Offset can't be used with line number.");
201 
202 	if (!pp->line && pp->file && !pp->function)
203 		semantic_error("File always requires line number.");
204 
205 	if (pp->offset && !pp->function)
206 		semantic_error("Offset requires an entry function.");
207 
208 	if (pp->retprobe && !pp->function)
209 		semantic_error("Return probe requires an entry function.");
210 
211 	if ((pp->offset || pp->line) && pp->retprobe)
212 		semantic_error("Offset/Line can't be used with return probe.");
213 
214 	pr_debug("symbol:%s file:%s line:%d offset:%d, return:%d\n",
215 		 pp->function, pp->file, pp->line, pp->offset, pp->retprobe);
216 }
217 
218 /* Parse perf-probe event definition */
219 void parse_perf_probe_event(const char *str, struct probe_point *pp,
220 			    bool *need_dwarf)
221 {
222 	char **argv;
223 	int argc, i;
224 
225 	*need_dwarf = false;
226 
227 	argv = argv_split(str, &argc);
228 	if (!argv)
229 		die("argv_split failed.");
230 	if (argc > MAX_PROBE_ARGS + 1)
231 		semantic_error("Too many arguments");
232 
233 	/* Parse probe point */
234 	parse_perf_probe_probepoint(argv[0], pp);
235 	if (pp->file || pp->line)
236 		*need_dwarf = true;
237 
238 	/* Copy arguments and ensure return probe has no C argument */
239 	pp->nr_args = argc - 1;
240 	pp->args = zalloc(sizeof(char *) * pp->nr_args);
241 	for (i = 0; i < pp->nr_args; i++) {
242 		pp->args[i] = strdup(argv[i + 1]);
243 		if (!pp->args[i])
244 			die("Failed to copy argument.");
245 		if (is_c_varname(pp->args[i])) {
246 			if (pp->retprobe)
247 				semantic_error("You can't specify local"
248 						" variable for kretprobe");
249 			*need_dwarf = true;
250 		}
251 	}
252 
253 	argv_free(argv);
254 }
255 
256 /* Parse kprobe_events event into struct probe_point */
257 void parse_trace_kprobe_event(const char *str, struct probe_point *pp)
258 {
259 	char pr;
260 	char *p;
261 	int ret, i, argc;
262 	char **argv;
263 
264 	pr_debug("Parsing kprobe_events: %s\n", str);
265 	argv = argv_split(str, &argc);
266 	if (!argv)
267 		die("argv_split failed.");
268 	if (argc < 2)
269 		semantic_error("Too less arguments.");
270 
271 	/* Scan event and group name. */
272 	ret = sscanf(argv[0], "%c:%a[^/ \t]/%a[^ \t]",
273 		     &pr, (float *)(void *)&pp->group,
274 		     (float *)(void *)&pp->event);
275 	if (ret != 3)
276 		semantic_error("Failed to parse event name: %s", argv[0]);
277 	pr_debug("Group:%s Event:%s probe:%c\n", pp->group, pp->event, pr);
278 
279 	pp->retprobe = (pr == 'r');
280 
281 	/* Scan function name and offset */
282 	ret = sscanf(argv[1], "%a[^+]+%d", (float *)(void *)&pp->function,
283 		     &pp->offset);
284 	if (ret == 1)
285 		pp->offset = 0;
286 
287 	/* kprobe_events doesn't have this information */
288 	pp->line = 0;
289 	pp->file = NULL;
290 
291 	pp->nr_args = argc - 2;
292 	pp->args = zalloc(sizeof(char *) * pp->nr_args);
293 	for (i = 0; i < pp->nr_args; i++) {
294 		p = strchr(argv[i + 2], '=');
295 		if (p)	/* We don't need which register is assigned. */
296 			*p = '\0';
297 		pp->args[i] = strdup(argv[i + 2]);
298 		if (!pp->args[i])
299 			die("Failed to copy argument.");
300 	}
301 
302 	argv_free(argv);
303 }
304 
305 /* Synthesize only probe point (not argument) */
306 int synthesize_perf_probe_point(struct probe_point *pp)
307 {
308 	char *buf;
309 	char offs[64] = "", line[64] = "";
310 	int ret;
311 
312 	pp->probes[0] = buf = zalloc(MAX_CMDLEN);
313 	pp->found = 1;
314 	if (!buf)
315 		die("Failed to allocate memory by zalloc.");
316 	if (pp->offset) {
317 		ret = e_snprintf(offs, 64, "+%d", pp->offset);
318 		if (ret <= 0)
319 			goto error;
320 	}
321 	if (pp->line) {
322 		ret = e_snprintf(line, 64, ":%d", pp->line);
323 		if (ret <= 0)
324 			goto error;
325 	}
326 
327 	if (pp->function)
328 		ret = e_snprintf(buf, MAX_CMDLEN, "%s%s%s%s", pp->function,
329 				 offs, pp->retprobe ? "%return" : "", line);
330 	else
331 		ret = e_snprintf(buf, MAX_CMDLEN, "%s%s", pp->file, line);
332 	if (ret <= 0) {
333 error:
334 		free(pp->probes[0]);
335 		pp->probes[0] = NULL;
336 		pp->found = 0;
337 	}
338 	return ret;
339 }
340 
341 int synthesize_perf_probe_event(struct probe_point *pp)
342 {
343 	char *buf;
344 	int i, len, ret;
345 
346 	len = synthesize_perf_probe_point(pp);
347 	if (len < 0)
348 		return 0;
349 
350 	buf = pp->probes[0];
351 	for (i = 0; i < pp->nr_args; i++) {
352 		ret = e_snprintf(&buf[len], MAX_CMDLEN - len, " %s",
353 				 pp->args[i]);
354 		if (ret <= 0)
355 			goto error;
356 		len += ret;
357 	}
358 	pp->found = 1;
359 
360 	return pp->found;
361 error:
362 	free(pp->probes[0]);
363 	pp->probes[0] = NULL;
364 
365 	return ret;
366 }
367 
368 int synthesize_trace_kprobe_event(struct probe_point *pp)
369 {
370 	char *buf;
371 	int i, len, ret;
372 
373 	pp->probes[0] = buf = zalloc(MAX_CMDLEN);
374 	if (!buf)
375 		die("Failed to allocate memory by zalloc.");
376 	ret = e_snprintf(buf, MAX_CMDLEN, "%s+%d", pp->function, pp->offset);
377 	if (ret <= 0)
378 		goto error;
379 	len = ret;
380 
381 	for (i = 0; i < pp->nr_args; i++) {
382 		ret = e_snprintf(&buf[len], MAX_CMDLEN - len, " %s",
383 				 pp->args[i]);
384 		if (ret <= 0)
385 			goto error;
386 		len += ret;
387 	}
388 	pp->found = 1;
389 
390 	return pp->found;
391 error:
392 	free(pp->probes[0]);
393 	pp->probes[0] = NULL;
394 
395 	return ret;
396 }
397 
398 static int open_kprobe_events(int flags, int mode)
399 {
400 	char buf[PATH_MAX];
401 	int ret;
402 
403 	ret = e_snprintf(buf, PATH_MAX, "%s/../kprobe_events", debugfs_path);
404 	if (ret < 0)
405 		die("Failed to make kprobe_events path.");
406 
407 	ret = open(buf, flags, mode);
408 	if (ret < 0) {
409 		if (errno == ENOENT)
410 			die("kprobe_events file does not exist -"
411 			    " please rebuild with CONFIG_KPROBE_EVENT.");
412 		else
413 			die("Could not open kprobe_events file: %s",
414 			    strerror(errno));
415 	}
416 	return ret;
417 }
418 
419 /* Get raw string list of current kprobe_events */
420 static struct strlist *get_trace_kprobe_event_rawlist(int fd)
421 {
422 	int ret, idx;
423 	FILE *fp;
424 	char buf[MAX_CMDLEN];
425 	char *p;
426 	struct strlist *sl;
427 
428 	sl = strlist__new(true, NULL);
429 
430 	fp = fdopen(dup(fd), "r");
431 	while (!feof(fp)) {
432 		p = fgets(buf, MAX_CMDLEN, fp);
433 		if (!p)
434 			break;
435 
436 		idx = strlen(p) - 1;
437 		if (p[idx] == '\n')
438 			p[idx] = '\0';
439 		ret = strlist__add(sl, buf);
440 		if (ret < 0)
441 			die("strlist__add failed: %s", strerror(-ret));
442 	}
443 	fclose(fp);
444 
445 	return sl;
446 }
447 
448 /* Free and zero clear probe_point */
449 static void clear_probe_point(struct probe_point *pp)
450 {
451 	int i;
452 
453 	if (pp->event)
454 		free(pp->event);
455 	if (pp->group)
456 		free(pp->group);
457 	if (pp->function)
458 		free(pp->function);
459 	if (pp->file)
460 		free(pp->file);
461 	for (i = 0; i < pp->nr_args; i++)
462 		free(pp->args[i]);
463 	if (pp->args)
464 		free(pp->args);
465 	for (i = 0; i < pp->found; i++)
466 		free(pp->probes[i]);
467 	memset(pp, 0, sizeof(*pp));
468 }
469 
470 /* Show an event */
471 static void show_perf_probe_event(const char *event, const char *place,
472 				  struct probe_point *pp)
473 {
474 	int i, ret;
475 	char buf[128];
476 
477 	ret = e_snprintf(buf, 128, "%s:%s", pp->group, event);
478 	if (ret < 0)
479 		die("Failed to copy event: %s", strerror(-ret));
480 	printf("  %-40s (on %s", buf, place);
481 
482 	if (pp->nr_args > 0) {
483 		printf(" with");
484 		for (i = 0; i < pp->nr_args; i++)
485 			printf(" %s", pp->args[i]);
486 	}
487 	printf(")\n");
488 }
489 
490 /* List up current perf-probe events */
491 void show_perf_probe_events(void)
492 {
493 	int fd;
494 	struct probe_point pp;
495 	struct strlist *rawlist;
496 	struct str_node *ent;
497 
498 	setup_pager();
499 
500 	memset(&pp, 0, sizeof(pp));
501 	fd = open_kprobe_events(O_RDONLY, 0);
502 	rawlist = get_trace_kprobe_event_rawlist(fd);
503 	close(fd);
504 
505 	strlist__for_each(ent, rawlist) {
506 		parse_trace_kprobe_event(ent->s, &pp);
507 		/* Synthesize only event probe point */
508 		synthesize_perf_probe_point(&pp);
509 		/* Show an event */
510 		show_perf_probe_event(pp.event, pp.probes[0], &pp);
511 		clear_probe_point(&pp);
512 	}
513 
514 	strlist__delete(rawlist);
515 }
516 
517 /* Get current perf-probe event names */
518 static struct strlist *get_perf_event_names(int fd, bool include_group)
519 {
520 	char buf[128];
521 	struct strlist *sl, *rawlist;
522 	struct str_node *ent;
523 	struct probe_point pp;
524 
525 	memset(&pp, 0, sizeof(pp));
526 	rawlist = get_trace_kprobe_event_rawlist(fd);
527 
528 	sl = strlist__new(true, NULL);
529 	strlist__for_each(ent, rawlist) {
530 		parse_trace_kprobe_event(ent->s, &pp);
531 		if (include_group) {
532 			if (e_snprintf(buf, 128, "%s:%s", pp.group,
533 				       pp.event) < 0)
534 				die("Failed to copy group:event name.");
535 			strlist__add(sl, buf);
536 		} else
537 			strlist__add(sl, pp.event);
538 		clear_probe_point(&pp);
539 	}
540 
541 	strlist__delete(rawlist);
542 
543 	return sl;
544 }
545 
546 static void write_trace_kprobe_event(int fd, const char *buf)
547 {
548 	int ret;
549 
550 	pr_debug("Writing event: %s\n", buf);
551 	ret = write(fd, buf, strlen(buf));
552 	if (ret <= 0)
553 		die("Failed to write event: %s", strerror(errno));
554 }
555 
556 static void get_new_event_name(char *buf, size_t len, const char *base,
557 			       struct strlist *namelist, bool allow_suffix)
558 {
559 	int i, ret;
560 
561 	/* Try no suffix */
562 	ret = e_snprintf(buf, len, "%s", base);
563 	if (ret < 0)
564 		die("snprintf() failed: %s", strerror(-ret));
565 	if (!strlist__has_entry(namelist, buf))
566 		return;
567 
568 	if (!allow_suffix) {
569 		pr_warning("Error: event \"%s\" already exists. "
570 			   "(Use -f to force duplicates.)\n", base);
571 		die("Can't add new event.");
572 	}
573 
574 	/* Try to add suffix */
575 	for (i = 1; i < MAX_EVENT_INDEX; i++) {
576 		ret = e_snprintf(buf, len, "%s_%d", base, i);
577 		if (ret < 0)
578 			die("snprintf() failed: %s", strerror(-ret));
579 		if (!strlist__has_entry(namelist, buf))
580 			break;
581 	}
582 	if (i == MAX_EVENT_INDEX)
583 		die("Too many events are on the same function.");
584 }
585 
586 void add_trace_kprobe_events(struct probe_point *probes, int nr_probes,
587 			     bool force_add)
588 {
589 	int i, j, fd;
590 	struct probe_point *pp;
591 	char buf[MAX_CMDLEN];
592 	char event[64];
593 	struct strlist *namelist;
594 	bool allow_suffix;
595 
596 	fd = open_kprobe_events(O_RDWR, O_APPEND);
597 	/* Get current event names */
598 	namelist = get_perf_event_names(fd, false);
599 
600 	for (j = 0; j < nr_probes; j++) {
601 		pp = probes + j;
602 		if (!pp->event)
603 			pp->event = strdup(pp->function);
604 		if (!pp->group)
605 			pp->group = strdup(PERFPROBE_GROUP);
606 		DIE_IF(!pp->event || !pp->group);
607 		/* If force_add is true, suffix search is allowed */
608 		allow_suffix = force_add;
609 		for (i = 0; i < pp->found; i++) {
610 			/* Get an unused new event name */
611 			get_new_event_name(event, 64, pp->event, namelist,
612 					   allow_suffix);
613 			snprintf(buf, MAX_CMDLEN, "%c:%s/%s %s\n",
614 				 pp->retprobe ? 'r' : 'p',
615 				 pp->group, event,
616 				 pp->probes[i]);
617 			write_trace_kprobe_event(fd, buf);
618 			printf("Added new event:\n");
619 			/* Get the first parameter (probe-point) */
620 			sscanf(pp->probes[i], "%s", buf);
621 			show_perf_probe_event(event, buf, pp);
622 			/* Add added event name to namelist */
623 			strlist__add(namelist, event);
624 			/*
625 			 * Probes after the first probe which comes from same
626 			 * user input are always allowed to add suffix, because
627 			 * there might be several addresses corresponding to
628 			 * one code line.
629 			 */
630 			allow_suffix = true;
631 		}
632 	}
633 	/* Show how to use the event. */
634 	printf("\nYou can now use it on all perf tools, such as:\n\n");
635 	printf("\tperf record -e %s:%s -a sleep 1\n\n", PERFPROBE_GROUP, event);
636 
637 	strlist__delete(namelist);
638 	close(fd);
639 }
640 
641 static void __del_trace_kprobe_event(int fd, struct str_node *ent)
642 {
643 	char *p;
644 	char buf[128];
645 
646 	/* Convert from perf-probe event to trace-kprobe event */
647 	if (e_snprintf(buf, 128, "-:%s", ent->s) < 0)
648 		die("Failed to copy event.");
649 	p = strchr(buf + 2, ':');
650 	if (!p)
651 		die("Internal error: %s should have ':' but not.", ent->s);
652 	*p = '/';
653 
654 	write_trace_kprobe_event(fd, buf);
655 	printf("Remove event: %s\n", ent->s);
656 }
657 
658 static void del_trace_kprobe_event(int fd, const char *group,
659 				   const char *event, struct strlist *namelist)
660 {
661 	char buf[128];
662 	struct str_node *ent, *n;
663 	int found = 0;
664 
665 	if (e_snprintf(buf, 128, "%s:%s", group, event) < 0)
666 		die("Failed to copy event.");
667 
668 	if (strpbrk(buf, "*?")) { /* Glob-exp */
669 		strlist__for_each_safe(ent, n, namelist)
670 			if (strglobmatch(ent->s, buf)) {
671 				found++;
672 				__del_trace_kprobe_event(fd, ent);
673 				strlist__remove(namelist, ent);
674 			}
675 	} else {
676 		ent = strlist__find(namelist, buf);
677 		if (ent) {
678 			found++;
679 			__del_trace_kprobe_event(fd, ent);
680 			strlist__remove(namelist, ent);
681 		}
682 	}
683 	if (found == 0)
684 		pr_info("Info: event \"%s\" does not exist, could not remove it.\n", buf);
685 }
686 
687 void del_trace_kprobe_events(struct strlist *dellist)
688 {
689 	int fd;
690 	const char *group, *event;
691 	char *p, *str;
692 	struct str_node *ent;
693 	struct strlist *namelist;
694 
695 	fd = open_kprobe_events(O_RDWR, O_APPEND);
696 	/* Get current event names */
697 	namelist = get_perf_event_names(fd, true);
698 
699 	strlist__for_each(ent, dellist) {
700 		str = strdup(ent->s);
701 		if (!str)
702 			die("Failed to copy event.");
703 		pr_debug("Parsing: %s\n", str);
704 		p = strchr(str, ':');
705 		if (p) {
706 			group = str;
707 			*p = '\0';
708 			event = p + 1;
709 		} else {
710 			group = "*";
711 			event = str;
712 		}
713 		pr_debug("Group: %s, Event: %s\n", group, event);
714 		del_trace_kprobe_event(fd, group, event, namelist);
715 		free(str);
716 	}
717 	strlist__delete(namelist);
718 	close(fd);
719 }
720 
721 #define LINEBUF_SIZE 256
722 
723 static void show_one_line(FILE *fp, unsigned int l, bool skip, bool show_num)
724 {
725 	char buf[LINEBUF_SIZE];
726 	const char *color = PERF_COLOR_BLUE;
727 
728 	if (fgets(buf, LINEBUF_SIZE, fp) == NULL)
729 		goto error;
730 	if (!skip) {
731 		if (show_num)
732 			fprintf(stdout, "%7u  %s", l, buf);
733 		else
734 			color_fprintf(stdout, color, "         %s", buf);
735 	}
736 
737 	while (strlen(buf) == LINEBUF_SIZE - 1 &&
738 	       buf[LINEBUF_SIZE - 2] != '\n') {
739 		if (fgets(buf, LINEBUF_SIZE, fp) == NULL)
740 			goto error;
741 		if (!skip) {
742 			if (show_num)
743 				fprintf(stdout, "%s", buf);
744 			else
745 				color_fprintf(stdout, color, "%s", buf);
746 		}
747 	}
748 	return;
749 error:
750 	if (feof(fp))
751 		die("Source file is shorter than expected.");
752 	else
753 		die("File read error: %s", strerror(errno));
754 }
755 
756 void show_line_range(struct line_range *lr)
757 {
758 	unsigned int l = 1;
759 	struct line_node *ln;
760 	FILE *fp;
761 
762 	setup_pager();
763 
764 	if (lr->function)
765 		fprintf(stdout, "<%s:%d>\n", lr->function,
766 			lr->start - lr->offset);
767 	else
768 		fprintf(stdout, "<%s:%d>\n", lr->file, lr->start);
769 
770 	fp = fopen(lr->path, "r");
771 	if (fp == NULL)
772 		die("Failed to open %s: %s", lr->path, strerror(errno));
773 	/* Skip to starting line number */
774 	while (l < lr->start)
775 		show_one_line(fp, l++, true, false);
776 
777 	list_for_each_entry(ln, &lr->line_list, list) {
778 		while (ln->line > l)
779 			show_one_line(fp, (l++) - lr->offset, false, false);
780 		show_one_line(fp, (l++) - lr->offset, false, true);
781 	}
782 	fclose(fp);
783 }
784