diff options
author | Ingo Molnar <mingo@kernel.org> | 2015-04-11 02:31:19 -0400 |
---|---|---|
committer | Ingo Molnar <mingo@kernel.org> | 2015-04-11 02:31:19 -0400 |
commit | 5dafd7cb96ec75454eb1fcbf993000bf41175f13 (patch) | |
tree | f0d3281f2d9b5ff8beb6209e5e226778a5d803b6 /tools | |
parent | 51ab7155c08baf45cc2aa911961e5b78422e478f (diff) | |
parent | 7b8283b56d9fb36106ff1c459dfd399a20bd374d (diff) |
Merge tag 'perf-core-for-mingo' of git://git.kernel.org/pub/scm/linux/kernel/git/acme/linux into perf/core
Pull perf/core improvements and fixes from Arnaldo Carvalho de Melo:
New user visible features:
- Support multiple probes on different binaries on the same command line (Masami Hiramatsu)
User visible changes:
- Fix synthesizing fork_event.ppid for non-main thread (David Ahern)
- Fix cross-endian analysis (David Ahern)
- Fix segfault in 'perf buildid-list' when show DSOs with hits (He Kuang)
Infrastructure changes:
- Fix type for references to data_head/tail (David Ahern)
- Fix error path to do closedir() when synthesizing threads (Arnaldo Carvalho de Melo)
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
Signed-off-by: Ingo Molnar <mingo@kernel.org>
Diffstat (limited to 'tools')
-rw-r--r-- | tools/perf/builtin-probe.c | 19 | ||||
-rw-r--r-- | tools/perf/builtin-record.c | 4 | ||||
-rw-r--r-- | tools/perf/util/build-id.c | 8 | ||||
-rw-r--r-- | tools/perf/util/event.c | 31 | ||||
-rw-r--r-- | tools/perf/util/evlist.c | 6 | ||||
-rw-r--r-- | tools/perf/util/evlist.h | 9 | ||||
-rw-r--r-- | tools/perf/util/header.c | 5 | ||||
-rw-r--r-- | tools/perf/util/machine.c | 4 | ||||
-rw-r--r-- | tools/perf/util/machine.h | 1 | ||||
-rw-r--r-- | tools/perf/util/probe-event.c | 5 | ||||
-rw-r--r-- | tools/perf/util/probe-event.h | 6 |
11 files changed, 61 insertions, 37 deletions
diff --git a/tools/perf/builtin-probe.c b/tools/perf/builtin-probe.c index 921bb6942503..f7b1af67e9f6 100644 --- a/tools/perf/builtin-probe.c +++ b/tools/perf/builtin-probe.c | |||
@@ -56,6 +56,7 @@ static struct { | |||
56 | bool mod_events; | 56 | bool mod_events; |
57 | bool uprobes; | 57 | bool uprobes; |
58 | bool quiet; | 58 | bool quiet; |
59 | bool target_used; | ||
59 | int nevents; | 60 | int nevents; |
60 | struct perf_probe_event events[MAX_PROBES]; | 61 | struct perf_probe_event events[MAX_PROBES]; |
61 | struct strlist *dellist; | 62 | struct strlist *dellist; |
@@ -78,6 +79,12 @@ static int parse_probe_event(const char *str) | |||
78 | } | 79 | } |
79 | 80 | ||
80 | pev->uprobes = params.uprobes; | 81 | pev->uprobes = params.uprobes; |
82 | if (params.target) { | ||
83 | pev->target = strdup(params.target); | ||
84 | if (!pev->target) | ||
85 | return -ENOMEM; | ||
86 | params.target_used = true; | ||
87 | } | ||
81 | 88 | ||
82 | /* Parse a perf-probe command into event */ | 89 | /* Parse a perf-probe command into event */ |
83 | ret = parse_perf_probe_command(str, pev); | 90 | ret = parse_perf_probe_command(str, pev); |
@@ -102,6 +109,7 @@ static int set_target(const char *ptr) | |||
102 | params.target = strdup(ptr); | 109 | params.target = strdup(ptr); |
103 | if (!params.target) | 110 | if (!params.target) |
104 | return -ENOMEM; | 111 | return -ENOMEM; |
112 | params.target_used = false; | ||
105 | 113 | ||
106 | found = 1; | 114 | found = 1; |
107 | buf = ptr + (strlen(ptr) - 3); | 115 | buf = ptr + (strlen(ptr) - 3); |
@@ -178,7 +186,7 @@ static int opt_set_target(const struct option *opt, const char *str, | |||
178 | int ret = -ENOENT; | 186 | int ret = -ENOENT; |
179 | char *tmp; | 187 | char *tmp; |
180 | 188 | ||
181 | if (str && !params.target) { | 189 | if (str) { |
182 | if (!strcmp(opt->long_name, "exec")) | 190 | if (!strcmp(opt->long_name, "exec")) |
183 | params.uprobes = true; | 191 | params.uprobes = true; |
184 | #ifdef HAVE_DWARF_SUPPORT | 192 | #ifdef HAVE_DWARF_SUPPORT |
@@ -200,7 +208,9 @@ static int opt_set_target(const struct option *opt, const char *str, | |||
200 | if (!tmp) | 208 | if (!tmp) |
201 | return -ENOMEM; | 209 | return -ENOMEM; |
202 | } | 210 | } |
211 | free(params.target); | ||
203 | params.target = tmp; | 212 | params.target = tmp; |
213 | params.target_used = false; | ||
204 | ret = 0; | 214 | ret = 0; |
205 | } | 215 | } |
206 | 216 | ||
@@ -485,9 +495,14 @@ __cmd_probe(int argc, const char **argv, const char *prefix __maybe_unused) | |||
485 | } | 495 | } |
486 | 496 | ||
487 | if (params.nevents) { | 497 | if (params.nevents) { |
498 | /* Ensure the last given target is used */ | ||
499 | if (params.target && !params.target_used) { | ||
500 | pr_warning(" Error: -x/-m must follow the probe definitions.\n"); | ||
501 | usage_with_options(probe_usage, options); | ||
502 | } | ||
503 | |||
488 | ret = add_perf_probe_events(params.events, params.nevents, | 504 | ret = add_perf_probe_events(params.events, params.nevents, |
489 | params.max_probe_points, | 505 | params.max_probe_points, |
490 | params.target, | ||
491 | params.force_add); | 506 | params.force_add); |
492 | if (ret < 0) { | 507 | if (ret < 0) { |
493 | pr_err_with_code(" Error: Failed to add events.", ret); | 508 | pr_err_with_code(" Error: Failed to add events.", ret); |
diff --git a/tools/perf/builtin-record.c b/tools/perf/builtin-record.c index ac610488d2e1..c3efdfb630b5 100644 --- a/tools/perf/builtin-record.c +++ b/tools/perf/builtin-record.c | |||
@@ -70,8 +70,8 @@ static int process_synthesized_event(struct perf_tool *tool, | |||
70 | static int record__mmap_read(struct record *rec, int idx) | 70 | static int record__mmap_read(struct record *rec, int idx) |
71 | { | 71 | { |
72 | struct perf_mmap *md = &rec->evlist->mmap[idx]; | 72 | struct perf_mmap *md = &rec->evlist->mmap[idx]; |
73 | unsigned int head = perf_mmap__read_head(md); | 73 | u64 head = perf_mmap__read_head(md); |
74 | unsigned int old = md->prev; | 74 | u64 old = md->prev; |
75 | unsigned char *data = md->base + page_size; | 75 | unsigned char *data = md->base + page_size; |
76 | unsigned long size; | 76 | unsigned long size; |
77 | void *buf; | 77 | void *buf; |
diff --git a/tools/perf/util/build-id.c b/tools/perf/util/build-id.c index f7fb2587df69..61867dff5d5a 100644 --- a/tools/perf/util/build-id.c +++ b/tools/perf/util/build-id.c | |||
@@ -59,12 +59,8 @@ static int perf_event__exit_del_thread(struct perf_tool *tool __maybe_unused, | |||
59 | dump_printf("(%d:%d):(%d:%d)\n", event->fork.pid, event->fork.tid, | 59 | dump_printf("(%d:%d):(%d:%d)\n", event->fork.pid, event->fork.tid, |
60 | event->fork.ppid, event->fork.ptid); | 60 | event->fork.ppid, event->fork.ptid); |
61 | 61 | ||
62 | if (thread) { | 62 | if (thread) |
63 | rb_erase(&thread->rb_node, &machine->threads); | 63 | machine__remove_thread(machine, thread); |
64 | if (machine->last_match == thread) | ||
65 | thread__zput(machine->last_match); | ||
66 | thread__put(thread); | ||
67 | } | ||
68 | 64 | ||
69 | return 0; | 65 | return 0; |
70 | } | 66 | } |
diff --git a/tools/perf/util/event.c b/tools/perf/util/event.c index 5516236df6ab..ff866c4d2e2f 100644 --- a/tools/perf/util/event.c +++ b/tools/perf/util/event.c | |||
@@ -183,8 +183,18 @@ static int perf_event__synthesize_fork(struct perf_tool *tool, | |||
183 | { | 183 | { |
184 | memset(&event->fork, 0, sizeof(event->fork) + machine->id_hdr_size); | 184 | memset(&event->fork, 0, sizeof(event->fork) + machine->id_hdr_size); |
185 | 185 | ||
186 | event->fork.ppid = ppid; | 186 | /* |
187 | event->fork.ptid = ppid; | 187 | * for main thread set parent to ppid from status file. For other |
188 | * threads set parent pid to main thread. ie., assume main thread | ||
189 | * spawns all threads in a process | ||
190 | */ | ||
191 | if (tgid == pid) { | ||
192 | event->fork.ppid = ppid; | ||
193 | event->fork.ptid = ppid; | ||
194 | } else { | ||
195 | event->fork.ppid = tgid; | ||
196 | event->fork.ptid = tgid; | ||
197 | } | ||
188 | event->fork.pid = tgid; | 198 | event->fork.pid = tgid; |
189 | event->fork.tid = pid; | 199 | event->fork.tid = pid; |
190 | event->fork.header.type = PERF_RECORD_FORK; | 200 | event->fork.header.type = PERF_RECORD_FORK; |
@@ -377,6 +387,7 @@ static int __event__synthesize_thread(union perf_event *comm_event, | |||
377 | DIR *tasks; | 387 | DIR *tasks; |
378 | struct dirent dirent, *next; | 388 | struct dirent dirent, *next; |
379 | pid_t tgid, ppid; | 389 | pid_t tgid, ppid; |
390 | int rc = 0; | ||
380 | 391 | ||
381 | /* special case: only send one comm event using passed in pid */ | 392 | /* special case: only send one comm event using passed in pid */ |
382 | if (!full) { | 393 | if (!full) { |
@@ -404,38 +415,38 @@ static int __event__synthesize_thread(union perf_event *comm_event, | |||
404 | 415 | ||
405 | while (!readdir_r(tasks, &dirent, &next) && next) { | 416 | while (!readdir_r(tasks, &dirent, &next) && next) { |
406 | char *end; | 417 | char *end; |
407 | int rc = 0; | ||
408 | pid_t _pid; | 418 | pid_t _pid; |
409 | 419 | ||
410 | _pid = strtol(dirent.d_name, &end, 10); | 420 | _pid = strtol(dirent.d_name, &end, 10); |
411 | if (*end) | 421 | if (*end) |
412 | continue; | 422 | continue; |
413 | 423 | ||
424 | rc = -1; | ||
414 | if (perf_event__prepare_comm(comm_event, _pid, machine, | 425 | if (perf_event__prepare_comm(comm_event, _pid, machine, |
415 | &tgid, &ppid) != 0) | 426 | &tgid, &ppid) != 0) |
416 | return -1; | 427 | break; |
417 | 428 | ||
418 | if (perf_event__synthesize_fork(tool, fork_event, _pid, tgid, | 429 | if (perf_event__synthesize_fork(tool, fork_event, _pid, tgid, |
419 | ppid, process, machine) < 0) | 430 | ppid, process, machine) < 0) |
420 | return -1; | 431 | break; |
421 | /* | 432 | /* |
422 | * Send the prepared comm event | 433 | * Send the prepared comm event |
423 | */ | 434 | */ |
424 | if (process(tool, comm_event, &synth_sample, machine) != 0) | 435 | if (process(tool, comm_event, &synth_sample, machine) != 0) |
425 | return -1; | 436 | break; |
426 | 437 | ||
438 | rc = 0; | ||
427 | if (_pid == pid) { | 439 | if (_pid == pid) { |
428 | /* process the parent's maps too */ | 440 | /* process the parent's maps too */ |
429 | rc = perf_event__synthesize_mmap_events(tool, mmap_event, pid, tgid, | 441 | rc = perf_event__synthesize_mmap_events(tool, mmap_event, pid, tgid, |
430 | process, machine, mmap_data); | 442 | process, machine, mmap_data); |
443 | if (rc) | ||
444 | break; | ||
431 | } | 445 | } |
432 | |||
433 | if (rc) | ||
434 | return rc; | ||
435 | } | 446 | } |
436 | 447 | ||
437 | closedir(tasks); | 448 | closedir(tasks); |
438 | return 0; | 449 | return rc; |
439 | } | 450 | } |
440 | 451 | ||
441 | int perf_event__synthesize_thread_map(struct perf_tool *tool, | 452 | int perf_event__synthesize_thread_map(struct perf_tool *tool, |
diff --git a/tools/perf/util/evlist.c b/tools/perf/util/evlist.c index 76ef7ee62640..080be93eea96 100644 --- a/tools/perf/util/evlist.c +++ b/tools/perf/util/evlist.c | |||
@@ -634,8 +634,8 @@ static struct perf_evsel *perf_evlist__event2evsel(struct perf_evlist *evlist, | |||
634 | union perf_event *perf_evlist__mmap_read(struct perf_evlist *evlist, int idx) | 634 | union perf_event *perf_evlist__mmap_read(struct perf_evlist *evlist, int idx) |
635 | { | 635 | { |
636 | struct perf_mmap *md = &evlist->mmap[idx]; | 636 | struct perf_mmap *md = &evlist->mmap[idx]; |
637 | unsigned int head = perf_mmap__read_head(md); | 637 | u64 head = perf_mmap__read_head(md); |
638 | unsigned int old = md->prev; | 638 | u64 old = md->prev; |
639 | unsigned char *data = md->base + page_size; | 639 | unsigned char *data = md->base + page_size; |
640 | union perf_event *event = NULL; | 640 | union perf_event *event = NULL; |
641 | 641 | ||
@@ -716,7 +716,7 @@ void perf_evlist__mmap_consume(struct perf_evlist *evlist, int idx) | |||
716 | struct perf_mmap *md = &evlist->mmap[idx]; | 716 | struct perf_mmap *md = &evlist->mmap[idx]; |
717 | 717 | ||
718 | if (!evlist->overwrite) { | 718 | if (!evlist->overwrite) { |
719 | unsigned int old = md->prev; | 719 | u64 old = md->prev; |
720 | 720 | ||
721 | perf_mmap__write_tail(md, old); | 721 | perf_mmap__write_tail(md, old); |
722 | } | 722 | } |
diff --git a/tools/perf/util/evlist.h b/tools/perf/util/evlist.h index fb19c47b8aac..b5cce95d644e 100644 --- a/tools/perf/util/evlist.h +++ b/tools/perf/util/evlist.h | |||
@@ -27,7 +27,7 @@ struct perf_mmap { | |||
27 | void *base; | 27 | void *base; |
28 | int mask; | 28 | int mask; |
29 | int refcnt; | 29 | int refcnt; |
30 | unsigned int prev; | 30 | u64 prev; |
31 | char event_copy[PERF_SAMPLE_MAX_SIZE] __attribute__((aligned(8))); | 31 | char event_copy[PERF_SAMPLE_MAX_SIZE] __attribute__((aligned(8))); |
32 | }; | 32 | }; |
33 | 33 | ||
@@ -189,16 +189,15 @@ size_t perf_evlist__fprintf(struct perf_evlist *evlist, FILE *fp); | |||
189 | int perf_evlist__strerror_open(struct perf_evlist *evlist, int err, char *buf, size_t size); | 189 | int perf_evlist__strerror_open(struct perf_evlist *evlist, int err, char *buf, size_t size); |
190 | int perf_evlist__strerror_mmap(struct perf_evlist *evlist, int err, char *buf, size_t size); | 190 | int perf_evlist__strerror_mmap(struct perf_evlist *evlist, int err, char *buf, size_t size); |
191 | 191 | ||
192 | static inline unsigned int perf_mmap__read_head(struct perf_mmap *mm) | 192 | static inline u64 perf_mmap__read_head(struct perf_mmap *mm) |
193 | { | 193 | { |
194 | struct perf_event_mmap_page *pc = mm->base; | 194 | struct perf_event_mmap_page *pc = mm->base; |
195 | int head = ACCESS_ONCE(pc->data_head); | 195 | u64 head = ACCESS_ONCE(pc->data_head); |
196 | rmb(); | 196 | rmb(); |
197 | return head; | 197 | return head; |
198 | } | 198 | } |
199 | 199 | ||
200 | static inline void perf_mmap__write_tail(struct perf_mmap *md, | 200 | static inline void perf_mmap__write_tail(struct perf_mmap *md, u64 tail) |
201 | unsigned long tail) | ||
202 | { | 201 | { |
203 | struct perf_event_mmap_page *pc = md->base; | 202 | struct perf_event_mmap_page *pc = md->base; |
204 | 203 | ||
diff --git a/tools/perf/util/header.c b/tools/perf/util/header.c index fff3b2a455ae..918fd8ae2d80 100644 --- a/tools/perf/util/header.c +++ b/tools/perf/util/header.c | |||
@@ -2504,8 +2504,11 @@ int perf_session__read_header(struct perf_session *session) | |||
2504 | if (read_attr(fd, header, &f_attr) < 0) | 2504 | if (read_attr(fd, header, &f_attr) < 0) |
2505 | goto out_errno; | 2505 | goto out_errno; |
2506 | 2506 | ||
2507 | if (header->needs_swap) | 2507 | if (header->needs_swap) { |
2508 | f_attr.ids.size = bswap_64(f_attr.ids.size); | ||
2509 | f_attr.ids.offset = bswap_64(f_attr.ids.offset); | ||
2508 | perf_event__attr_swap(&f_attr.attr); | 2510 | perf_event__attr_swap(&f_attr.attr); |
2511 | } | ||
2509 | 2512 | ||
2510 | tmp = lseek(fd, 0, SEEK_CUR); | 2513 | tmp = lseek(fd, 0, SEEK_CUR); |
2511 | evsel = perf_evsel__new(&f_attr.attr); | 2514 | evsel = perf_evsel__new(&f_attr.attr); |
diff --git a/tools/perf/util/machine.c b/tools/perf/util/machine.c index 9c380a2caa54..527e032e24f6 100644 --- a/tools/perf/util/machine.c +++ b/tools/perf/util/machine.c | |||
@@ -14,8 +14,6 @@ | |||
14 | #include "unwind.h" | 14 | #include "unwind.h" |
15 | #include "linux/hash.h" | 15 | #include "linux/hash.h" |
16 | 16 | ||
17 | static void machine__remove_thread(struct machine *machine, struct thread *th); | ||
18 | |||
19 | static void dsos__init(struct dsos *dsos) | 17 | static void dsos__init(struct dsos *dsos) |
20 | { | 18 | { |
21 | INIT_LIST_HEAD(&dsos->head); | 19 | INIT_LIST_HEAD(&dsos->head); |
@@ -1256,7 +1254,7 @@ out_problem: | |||
1256 | return 0; | 1254 | return 0; |
1257 | } | 1255 | } |
1258 | 1256 | ||
1259 | static void machine__remove_thread(struct machine *machine, struct thread *th) | 1257 | void machine__remove_thread(struct machine *machine, struct thread *th) |
1260 | { | 1258 | { |
1261 | if (machine->last_match == th) | 1259 | if (machine->last_match == th) |
1262 | thread__zput(machine->last_match); | 1260 | thread__zput(machine->last_match); |
diff --git a/tools/perf/util/machine.h b/tools/perf/util/machine.h index e2faf3b47e7b..6d64cedb9d1e 100644 --- a/tools/perf/util/machine.h +++ b/tools/perf/util/machine.h | |||
@@ -120,6 +120,7 @@ int machine__init(struct machine *machine, const char *root_dir, pid_t pid); | |||
120 | void machine__exit(struct machine *machine); | 120 | void machine__exit(struct machine *machine); |
121 | void machine__delete_threads(struct machine *machine); | 121 | void machine__delete_threads(struct machine *machine); |
122 | void machine__delete(struct machine *machine); | 122 | void machine__delete(struct machine *machine); |
123 | void machine__remove_thread(struct machine *machine, struct thread *th); | ||
123 | 124 | ||
124 | struct branch_info *sample__resolve_bstack(struct perf_sample *sample, | 125 | struct branch_info *sample__resolve_bstack(struct perf_sample *sample, |
125 | struct addr_location *al); | 126 | struct addr_location *al); |
diff --git a/tools/perf/util/probe-event.c b/tools/perf/util/probe-event.c index b78851732a71..30545ce2c712 100644 --- a/tools/perf/util/probe-event.c +++ b/tools/perf/util/probe-event.c | |||
@@ -1906,6 +1906,7 @@ void clear_perf_probe_event(struct perf_probe_event *pev) | |||
1906 | 1906 | ||
1907 | free(pev->event); | 1907 | free(pev->event); |
1908 | free(pev->group); | 1908 | free(pev->group); |
1909 | free(pev->target); | ||
1909 | clear_perf_probe_point(&pev->point); | 1910 | clear_perf_probe_point(&pev->point); |
1910 | 1911 | ||
1911 | for (i = 0; i < pev->nargs; i++) { | 1912 | for (i = 0; i < pev->nargs; i++) { |
@@ -2654,7 +2655,7 @@ struct __event_package { | |||
2654 | }; | 2655 | }; |
2655 | 2656 | ||
2656 | int add_perf_probe_events(struct perf_probe_event *pevs, int npevs, | 2657 | int add_perf_probe_events(struct perf_probe_event *pevs, int npevs, |
2657 | int max_tevs, const char *target, bool force_add) | 2658 | int max_tevs, bool force_add) |
2658 | { | 2659 | { |
2659 | int i, j, ret; | 2660 | int i, j, ret; |
2660 | struct __event_package *pkgs; | 2661 | struct __event_package *pkgs; |
@@ -2678,7 +2679,7 @@ int add_perf_probe_events(struct perf_probe_event *pevs, int npevs, | |||
2678 | ret = convert_to_probe_trace_events(pkgs[i].pev, | 2679 | ret = convert_to_probe_trace_events(pkgs[i].pev, |
2679 | &pkgs[i].tevs, | 2680 | &pkgs[i].tevs, |
2680 | max_tevs, | 2681 | max_tevs, |
2681 | target); | 2682 | pkgs[i].pev->target); |
2682 | if (ret < 0) | 2683 | if (ret < 0) |
2683 | goto end; | 2684 | goto end; |
2684 | pkgs[i].ntevs = ret; | 2685 | pkgs[i].ntevs = ret; |
diff --git a/tools/perf/util/probe-event.h b/tools/perf/util/probe-event.h index e01e9943139f..d6b783447be9 100644 --- a/tools/perf/util/probe-event.h +++ b/tools/perf/util/probe-event.h | |||
@@ -73,7 +73,8 @@ struct perf_probe_event { | |||
73 | char *group; /* Group name */ | 73 | char *group; /* Group name */ |
74 | struct perf_probe_point point; /* Probe point */ | 74 | struct perf_probe_point point; /* Probe point */ |
75 | int nargs; /* Number of arguments */ | 75 | int nargs; /* Number of arguments */ |
76 | bool uprobes; | 76 | bool uprobes; /* Uprobe event flag */ |
77 | char *target; /* Target binary */ | ||
77 | struct perf_probe_arg *args; /* Arguments */ | 78 | struct perf_probe_arg *args; /* Arguments */ |
78 | }; | 79 | }; |
79 | 80 | ||
@@ -124,8 +125,7 @@ extern int line_range__init(struct line_range *lr); | |||
124 | extern const char *kernel_get_module_path(const char *module); | 125 | extern const char *kernel_get_module_path(const char *module); |
125 | 126 | ||
126 | extern int add_perf_probe_events(struct perf_probe_event *pevs, int npevs, | 127 | extern int add_perf_probe_events(struct perf_probe_event *pevs, int npevs, |
127 | int max_probe_points, const char *module, | 128 | int max_probe_points, bool force_add); |
128 | bool force_add); | ||
129 | extern int del_perf_probe_events(struct strlist *dellist); | 129 | extern int del_perf_probe_events(struct strlist *dellist); |
130 | extern int show_perf_probe_events(void); | 130 | extern int show_perf_probe_events(void); |
131 | extern int show_line_range(struct line_range *lr, const char *module, | 131 | extern int show_line_range(struct line_range *lr, const char *module, |