aboutsummaryrefslogtreecommitdiffstats
path: root/tools/perf/builtin-script.c
diff options
context:
space:
mode:
Diffstat (limited to 'tools/perf/builtin-script.c')
-rw-r--r--tools/perf/builtin-script.c127
1 files changed, 89 insertions, 38 deletions
diff --git a/tools/perf/builtin-script.c b/tools/perf/builtin-script.c
index 9c333ff3dfeb..baf17989a216 100644
--- a/tools/perf/builtin-script.c
+++ b/tools/perf/builtin-script.c
@@ -15,6 +15,7 @@
15#include "util/evlist.h" 15#include "util/evlist.h"
16#include "util/evsel.h" 16#include "util/evsel.h"
17#include "util/sort.h" 17#include "util/sort.h"
18#include "util/data.h"
18#include <linux/bitmap.h> 19#include <linux/bitmap.h>
19 20
20static char const *script_name; 21static char const *script_name;
@@ -228,6 +229,24 @@ static int perf_evsel__check_attr(struct perf_evsel *evsel,
228 return 0; 229 return 0;
229} 230}
230 231
232static void set_print_ip_opts(struct perf_event_attr *attr)
233{
234 unsigned int type = attr->type;
235
236 output[type].print_ip_opts = 0;
237 if (PRINT_FIELD(IP))
238 output[type].print_ip_opts |= PRINT_IP_OPT_IP;
239
240 if (PRINT_FIELD(SYM))
241 output[type].print_ip_opts |= PRINT_IP_OPT_SYM;
242
243 if (PRINT_FIELD(DSO))
244 output[type].print_ip_opts |= PRINT_IP_OPT_DSO;
245
246 if (PRINT_FIELD(SYMOFFSET))
247 output[type].print_ip_opts |= PRINT_IP_OPT_SYMOFFSET;
248}
249
231/* 250/*
232 * verify all user requested events exist and the samples 251 * verify all user requested events exist and the samples
233 * have the expected data 252 * have the expected data
@@ -236,7 +255,6 @@ static int perf_session__check_output_opt(struct perf_session *session)
236{ 255{
237 int j; 256 int j;
238 struct perf_evsel *evsel; 257 struct perf_evsel *evsel;
239 struct perf_event_attr *attr;
240 258
241 for (j = 0; j < PERF_TYPE_MAX; ++j) { 259 for (j = 0; j < PERF_TYPE_MAX; ++j) {
242 evsel = perf_session__find_first_evtype(session, j); 260 evsel = perf_session__find_first_evtype(session, j);
@@ -259,20 +277,7 @@ static int perf_session__check_output_opt(struct perf_session *session)
259 if (evsel == NULL) 277 if (evsel == NULL)
260 continue; 278 continue;
261 279
262 attr = &evsel->attr; 280 set_print_ip_opts(&evsel->attr);
263
264 output[j].print_ip_opts = 0;
265 if (PRINT_FIELD(IP))
266 output[j].print_ip_opts |= PRINT_IP_OPT_IP;
267
268 if (PRINT_FIELD(SYM))
269 output[j].print_ip_opts |= PRINT_IP_OPT_SYM;
270
271 if (PRINT_FIELD(DSO))
272 output[j].print_ip_opts |= PRINT_IP_OPT_DSO;
273
274 if (PRINT_FIELD(SYMOFFSET))
275 output[j].print_ip_opts |= PRINT_IP_OPT_SYMOFFSET;
276 } 281 }
277 282
278 return 0; 283 return 0;
@@ -290,11 +295,11 @@ static void print_sample_start(struct perf_sample *sample,
290 295
291 if (PRINT_FIELD(COMM)) { 296 if (PRINT_FIELD(COMM)) {
292 if (latency_format) 297 if (latency_format)
293 printf("%8.8s ", thread->comm); 298 printf("%8.8s ", thread__comm_str(thread));
294 else if (PRINT_FIELD(IP) && symbol_conf.use_callchain) 299 else if (PRINT_FIELD(IP) && symbol_conf.use_callchain)
295 printf("%s ", thread->comm); 300 printf("%s ", thread__comm_str(thread));
296 else 301 else
297 printf("%16s ", thread->comm); 302 printf("%16s ", thread__comm_str(thread));
298 } 303 }
299 304
300 if (PRINT_FIELD(PID) && PRINT_FIELD(TID)) 305 if (PRINT_FIELD(PID) && PRINT_FIELD(TID))
@@ -409,7 +414,9 @@ static void print_sample_bts(union perf_event *event,
409 printf(" => "); 414 printf(" => ");
410 415
411 /* print branch_to information */ 416 /* print branch_to information */
412 if (PRINT_FIELD(ADDR)) 417 if (PRINT_FIELD(ADDR) ||
418 ((evsel->attr.sample_type & PERF_SAMPLE_ADDR) &&
419 !output[attr->type].user_set))
413 print_sample_addr(event, sample, machine, thread, attr); 420 print_sample_addr(event, sample, machine, thread, attr);
414 421
415 printf("\n"); 422 printf("\n");
@@ -539,32 +546,51 @@ static int process_sample_event(struct perf_tool *tool __maybe_unused,
539 return 0; 546 return 0;
540} 547}
541 548
542static struct perf_tool perf_script = { 549struct perf_script {
543 .sample = process_sample_event, 550 struct perf_tool tool;
544 .mmap = perf_event__process_mmap, 551 struct perf_session *session;
545 .mmap2 = perf_event__process_mmap2,
546 .comm = perf_event__process_comm,
547 .exit = perf_event__process_exit,
548 .fork = perf_event__process_fork,
549 .attr = perf_event__process_attr,
550 .tracing_data = perf_event__process_tracing_data,
551 .build_id = perf_event__process_build_id,
552 .ordered_samples = true,
553 .ordering_requires_timestamps = true,
554}; 552};
555 553
554static int process_attr(struct perf_tool *tool, union perf_event *event,
555 struct perf_evlist **pevlist)
556{
557 struct perf_script *scr = container_of(tool, struct perf_script, tool);
558 struct perf_evlist *evlist;
559 struct perf_evsel *evsel, *pos;
560 int err;
561
562 err = perf_event__process_attr(tool, event, pevlist);
563 if (err)
564 return err;
565
566 evlist = *pevlist;
567 evsel = perf_evlist__last(*pevlist);
568
569 if (evsel->attr.type >= PERF_TYPE_MAX)
570 return 0;
571
572 list_for_each_entry(pos, &evlist->entries, node) {
573 if (pos->attr.type == evsel->attr.type && pos != evsel)
574 return 0;
575 }
576
577 set_print_ip_opts(&evsel->attr);
578
579 return perf_evsel__check_attr(evsel, scr->session);
580}
581
556static void sig_handler(int sig __maybe_unused) 582static void sig_handler(int sig __maybe_unused)
557{ 583{
558 session_done = 1; 584 session_done = 1;
559} 585}
560 586
561static int __cmd_script(struct perf_session *session) 587static int __cmd_script(struct perf_script *script)
562{ 588{
563 int ret; 589 int ret;
564 590
565 signal(SIGINT, sig_handler); 591 signal(SIGINT, sig_handler);
566 592
567 ret = perf_session__process_events(session, &perf_script); 593 ret = perf_session__process_events(script->session, &script->tool);
568 594
569 if (debug_mode) 595 if (debug_mode)
570 pr_err("Misordered timestamps: %" PRIu64 "\n", nr_unordered); 596 pr_err("Misordered timestamps: %" PRIu64 "\n", nr_unordered);
@@ -1113,10 +1139,14 @@ int find_scripts(char **scripts_array, char **scripts_path_array)
1113 char scripts_path[MAXPATHLEN], lang_path[MAXPATHLEN]; 1139 char scripts_path[MAXPATHLEN], lang_path[MAXPATHLEN];
1114 DIR *scripts_dir, *lang_dir; 1140 DIR *scripts_dir, *lang_dir;
1115 struct perf_session *session; 1141 struct perf_session *session;
1142 struct perf_data_file file = {
1143 .path = input_name,
1144 .mode = PERF_DATA_MODE_READ,
1145 };
1116 char *temp; 1146 char *temp;
1117 int i = 0; 1147 int i = 0;
1118 1148
1119 session = perf_session__new(input_name, O_RDONLY, 0, false, NULL); 1149 session = perf_session__new(&file, false, NULL);
1120 if (!session) 1150 if (!session)
1121 return -1; 1151 return -1;
1122 1152
@@ -1266,6 +1296,21 @@ int cmd_script(int argc, const char **argv, const char *prefix __maybe_unused)
1266 char *script_path = NULL; 1296 char *script_path = NULL;
1267 const char **__argv; 1297 const char **__argv;
1268 int i, j, err; 1298 int i, j, err;
1299 struct perf_script script = {
1300 .tool = {
1301 .sample = process_sample_event,
1302 .mmap = perf_event__process_mmap,
1303 .mmap2 = perf_event__process_mmap2,
1304 .comm = perf_event__process_comm,
1305 .exit = perf_event__process_exit,
1306 .fork = perf_event__process_fork,
1307 .attr = process_attr,
1308 .tracing_data = perf_event__process_tracing_data,
1309 .build_id = perf_event__process_build_id,
1310 .ordered_samples = true,
1311 .ordering_requires_timestamps = true,
1312 },
1313 };
1269 const struct option options[] = { 1314 const struct option options[] = {
1270 OPT_BOOLEAN('D', "dump-raw-trace", &dump_trace, 1315 OPT_BOOLEAN('D', "dump-raw-trace", &dump_trace,
1271 "dump raw trace in ASCII"), 1316 "dump raw trace in ASCII"),
@@ -1317,12 +1362,17 @@ int cmd_script(int argc, const char **argv, const char *prefix __maybe_unused)
1317 "perf script [<options>] <top-script> [script-args]", 1362 "perf script [<options>] <top-script> [script-args]",
1318 NULL 1363 NULL
1319 }; 1364 };
1365 struct perf_data_file file = {
1366 .mode = PERF_DATA_MODE_READ,
1367 };
1320 1368
1321 setup_scripting(); 1369 setup_scripting();
1322 1370
1323 argc = parse_options(argc, argv, options, script_usage, 1371 argc = parse_options(argc, argv, options, script_usage,
1324 PARSE_OPT_STOP_AT_NON_OPTION); 1372 PARSE_OPT_STOP_AT_NON_OPTION);
1325 1373
1374 file.path = input_name;
1375
1326 if (argc > 1 && !strncmp(argv[0], "rec", strlen("rec"))) { 1376 if (argc > 1 && !strncmp(argv[0], "rec", strlen("rec"))) {
1327 rec_script_path = get_script_path(argv[1], RECORD_SUFFIX); 1377 rec_script_path = get_script_path(argv[1], RECORD_SUFFIX);
1328 if (!rec_script_path) 1378 if (!rec_script_path)
@@ -1486,11 +1536,12 @@ int cmd_script(int argc, const char **argv, const char *prefix __maybe_unused)
1486 if (!script_name) 1536 if (!script_name)
1487 setup_pager(); 1537 setup_pager();
1488 1538
1489 session = perf_session__new(input_name, O_RDONLY, 0, false, 1539 session = perf_session__new(&file, false, &script.tool);
1490 &perf_script);
1491 if (session == NULL) 1540 if (session == NULL)
1492 return -ENOMEM; 1541 return -ENOMEM;
1493 1542
1543 script.session = session;
1544
1494 if (cpu_list) { 1545 if (cpu_list) {
1495 if (perf_session__cpu_bitmap(session, cpu_list, cpu_bitmap)) 1546 if (perf_session__cpu_bitmap(session, cpu_list, cpu_bitmap))
1496 return -1; 1547 return -1;
@@ -1514,7 +1565,7 @@ int cmd_script(int argc, const char **argv, const char *prefix __maybe_unused)
1514 return -1; 1565 return -1;
1515 } 1566 }
1516 1567
1517 input = open(session->filename, O_RDONLY); /* input_name */ 1568 input = open(file.path, O_RDONLY); /* input_name */
1518 if (input < 0) { 1569 if (input < 0) {
1519 perror("failed to open file"); 1570 perror("failed to open file");
1520 return -1; 1571 return -1;
@@ -1554,7 +1605,7 @@ int cmd_script(int argc, const char **argv, const char *prefix __maybe_unused)
1554 if (err < 0) 1605 if (err < 0)
1555 goto out; 1606 goto out;
1556 1607
1557 err = __cmd_script(session); 1608 err = __cmd_script(&script);
1558 1609
1559 perf_session__delete(session); 1610 perf_session__delete(session);
1560 cleanup_scripting(); 1611 cleanup_scripting();