diff options
Diffstat (limited to 'tools/perf/builtin-script.c')
-rw-r--r-- | tools/perf/builtin-script.c | 73 |
1 files changed, 68 insertions, 5 deletions
diff --git a/tools/perf/builtin-script.c b/tools/perf/builtin-script.c index 24809787369f..4430340292c0 100644 --- a/tools/perf/builtin-script.c +++ b/tools/perf/builtin-script.c | |||
@@ -623,6 +623,7 @@ struct perf_script { | |||
623 | struct perf_session *session; | 623 | struct perf_session *session; |
624 | bool show_task_events; | 624 | bool show_task_events; |
625 | bool show_mmap_events; | 625 | bool show_mmap_events; |
626 | bool show_switch_events; | ||
626 | }; | 627 | }; |
627 | 628 | ||
628 | static int process_attr(struct perf_tool *tool, union perf_event *event, | 629 | static int process_attr(struct perf_tool *tool, union perf_event *event, |
@@ -661,7 +662,7 @@ static int process_comm_event(struct perf_tool *tool, | |||
661 | struct thread *thread; | 662 | struct thread *thread; |
662 | struct perf_script *script = container_of(tool, struct perf_script, tool); | 663 | struct perf_script *script = container_of(tool, struct perf_script, tool); |
663 | struct perf_session *session = script->session; | 664 | struct perf_session *session = script->session; |
664 | struct perf_evsel *evsel = perf_evlist__first(session->evlist); | 665 | struct perf_evsel *evsel = perf_evlist__id2evsel(session->evlist, sample->id); |
665 | int ret = -1; | 666 | int ret = -1; |
666 | 667 | ||
667 | thread = machine__findnew_thread(machine, event->comm.pid, event->comm.tid); | 668 | thread = machine__findnew_thread(machine, event->comm.pid, event->comm.tid); |
@@ -695,7 +696,7 @@ static int process_fork_event(struct perf_tool *tool, | |||
695 | struct thread *thread; | 696 | struct thread *thread; |
696 | struct perf_script *script = container_of(tool, struct perf_script, tool); | 697 | struct perf_script *script = container_of(tool, struct perf_script, tool); |
697 | struct perf_session *session = script->session; | 698 | struct perf_session *session = script->session; |
698 | struct perf_evsel *evsel = perf_evlist__first(session->evlist); | 699 | struct perf_evsel *evsel = perf_evlist__id2evsel(session->evlist, sample->id); |
699 | 700 | ||
700 | if (perf_event__process_fork(tool, event, sample, machine) < 0) | 701 | if (perf_event__process_fork(tool, event, sample, machine) < 0) |
701 | return -1; | 702 | return -1; |
@@ -727,7 +728,7 @@ static int process_exit_event(struct perf_tool *tool, | |||
727 | struct thread *thread; | 728 | struct thread *thread; |
728 | struct perf_script *script = container_of(tool, struct perf_script, tool); | 729 | struct perf_script *script = container_of(tool, struct perf_script, tool); |
729 | struct perf_session *session = script->session; | 730 | struct perf_session *session = script->session; |
730 | struct perf_evsel *evsel = perf_evlist__first(session->evlist); | 731 | struct perf_evsel *evsel = perf_evlist__id2evsel(session->evlist, sample->id); |
731 | 732 | ||
732 | thread = machine__findnew_thread(machine, event->fork.pid, event->fork.tid); | 733 | thread = machine__findnew_thread(machine, event->fork.pid, event->fork.tid); |
733 | if (thread == NULL) { | 734 | if (thread == NULL) { |
@@ -759,7 +760,7 @@ static int process_mmap_event(struct perf_tool *tool, | |||
759 | struct thread *thread; | 760 | struct thread *thread; |
760 | struct perf_script *script = container_of(tool, struct perf_script, tool); | 761 | struct perf_script *script = container_of(tool, struct perf_script, tool); |
761 | struct perf_session *session = script->session; | 762 | struct perf_session *session = script->session; |
762 | struct perf_evsel *evsel = perf_evlist__first(session->evlist); | 763 | struct perf_evsel *evsel = perf_evlist__id2evsel(session->evlist, sample->id); |
763 | 764 | ||
764 | if (perf_event__process_mmap(tool, event, sample, machine) < 0) | 765 | if (perf_event__process_mmap(tool, event, sample, machine) < 0) |
765 | return -1; | 766 | return -1; |
@@ -790,7 +791,7 @@ static int process_mmap2_event(struct perf_tool *tool, | |||
790 | struct thread *thread; | 791 | struct thread *thread; |
791 | struct perf_script *script = container_of(tool, struct perf_script, tool); | 792 | struct perf_script *script = container_of(tool, struct perf_script, tool); |
792 | struct perf_session *session = script->session; | 793 | struct perf_session *session = script->session; |
793 | struct perf_evsel *evsel = perf_evlist__first(session->evlist); | 794 | struct perf_evsel *evsel = perf_evlist__id2evsel(session->evlist, sample->id); |
794 | 795 | ||
795 | if (perf_event__process_mmap2(tool, event, sample, machine) < 0) | 796 | if (perf_event__process_mmap2(tool, event, sample, machine) < 0) |
796 | return -1; | 797 | return -1; |
@@ -813,6 +814,32 @@ static int process_mmap2_event(struct perf_tool *tool, | |||
813 | return 0; | 814 | return 0; |
814 | } | 815 | } |
815 | 816 | ||
817 | static int process_switch_event(struct perf_tool *tool, | ||
818 | union perf_event *event, | ||
819 | struct perf_sample *sample, | ||
820 | struct machine *machine) | ||
821 | { | ||
822 | struct thread *thread; | ||
823 | struct perf_script *script = container_of(tool, struct perf_script, tool); | ||
824 | struct perf_session *session = script->session; | ||
825 | struct perf_evsel *evsel = perf_evlist__id2evsel(session->evlist, sample->id); | ||
826 | |||
827 | if (perf_event__process_switch(tool, event, sample, machine) < 0) | ||
828 | return -1; | ||
829 | |||
830 | thread = machine__findnew_thread(machine, sample->pid, | ||
831 | sample->tid); | ||
832 | if (thread == NULL) { | ||
833 | pr_debug("problem processing SWITCH event, skipping it.\n"); | ||
834 | return -1; | ||
835 | } | ||
836 | |||
837 | print_sample_start(sample, thread, evsel); | ||
838 | perf_event__fprintf(event, stdout); | ||
839 | thread__put(thread); | ||
840 | return 0; | ||
841 | } | ||
842 | |||
816 | static void sig_handler(int sig __maybe_unused) | 843 | static void sig_handler(int sig __maybe_unused) |
817 | { | 844 | { |
818 | session_done = 1; | 845 | session_done = 1; |
@@ -834,6 +861,8 @@ static int __cmd_script(struct perf_script *script) | |||
834 | script->tool.mmap = process_mmap_event; | 861 | script->tool.mmap = process_mmap_event; |
835 | script->tool.mmap2 = process_mmap2_event; | 862 | script->tool.mmap2 = process_mmap2_event; |
836 | } | 863 | } |
864 | if (script->show_switch_events) | ||
865 | script->tool.context_switch = process_switch_event; | ||
837 | 866 | ||
838 | ret = perf_session__process_events(script->session); | 867 | ret = perf_session__process_events(script->session); |
839 | 868 | ||
@@ -1532,6 +1561,22 @@ static int have_cmd(int argc, const char **argv) | |||
1532 | return 0; | 1561 | return 0; |
1533 | } | 1562 | } |
1534 | 1563 | ||
1564 | static void script__setup_sample_type(struct perf_script *script) | ||
1565 | { | ||
1566 | struct perf_session *session = script->session; | ||
1567 | u64 sample_type = perf_evlist__combined_sample_type(session->evlist); | ||
1568 | |||
1569 | if (symbol_conf.use_callchain || symbol_conf.cumulate_callchain) { | ||
1570 | if ((sample_type & PERF_SAMPLE_REGS_USER) && | ||
1571 | (sample_type & PERF_SAMPLE_STACK_USER)) | ||
1572 | callchain_param.record_mode = CALLCHAIN_DWARF; | ||
1573 | else if (sample_type & PERF_SAMPLE_BRANCH_STACK) | ||
1574 | callchain_param.record_mode = CALLCHAIN_LBR; | ||
1575 | else | ||
1576 | callchain_param.record_mode = CALLCHAIN_FP; | ||
1577 | } | ||
1578 | } | ||
1579 | |||
1535 | int cmd_script(int argc, const char **argv, const char *prefix __maybe_unused) | 1580 | int cmd_script(int argc, const char **argv, const char *prefix __maybe_unused) |
1536 | { | 1581 | { |
1537 | bool show_full_info = false; | 1582 | bool show_full_info = false; |
@@ -1618,10 +1663,19 @@ int cmd_script(int argc, const char **argv, const char *prefix __maybe_unused) | |||
1618 | "Show the fork/comm/exit events"), | 1663 | "Show the fork/comm/exit events"), |
1619 | OPT_BOOLEAN('\0', "show-mmap-events", &script.show_mmap_events, | 1664 | OPT_BOOLEAN('\0', "show-mmap-events", &script.show_mmap_events, |
1620 | "Show the mmap events"), | 1665 | "Show the mmap events"), |
1666 | OPT_BOOLEAN('\0', "show-switch-events", &script.show_switch_events, | ||
1667 | "Show context switch events (if recorded)"), | ||
1621 | OPT_BOOLEAN('f', "force", &file.force, "don't complain, do it"), | 1668 | OPT_BOOLEAN('f', "force", &file.force, "don't complain, do it"), |
1622 | OPT_CALLBACK_OPTARG(0, "itrace", &itrace_synth_opts, NULL, "opts", | 1669 | OPT_CALLBACK_OPTARG(0, "itrace", &itrace_synth_opts, NULL, "opts", |
1623 | "Instruction Tracing options", | 1670 | "Instruction Tracing options", |
1624 | itrace_parse_synth_opts), | 1671 | itrace_parse_synth_opts), |
1672 | OPT_BOOLEAN(0, "full-source-path", &srcline_full_filename, | ||
1673 | "Show full source file name path for source lines"), | ||
1674 | OPT_BOOLEAN(0, "demangle", &symbol_conf.demangle, | ||
1675 | "Enable symbol demangling"), | ||
1676 | OPT_BOOLEAN(0, "demangle-kernel", &symbol_conf.demangle_kernel, | ||
1677 | "Enable kernel symbol demangling"), | ||
1678 | |||
1625 | OPT_END() | 1679 | OPT_END() |
1626 | }; | 1680 | }; |
1627 | const char * const script_subcommands[] = { "record", "report", NULL }; | 1681 | const char * const script_subcommands[] = { "record", "report", NULL }; |
@@ -1816,6 +1870,7 @@ int cmd_script(int argc, const char **argv, const char *prefix __maybe_unused) | |||
1816 | goto out_delete; | 1870 | goto out_delete; |
1817 | 1871 | ||
1818 | script.session = session; | 1872 | script.session = session; |
1873 | script__setup_sample_type(&script); | ||
1819 | 1874 | ||
1820 | session->itrace_synth_opts = &itrace_synth_opts; | 1875 | session->itrace_synth_opts = &itrace_synth_opts; |
1821 | 1876 | ||
@@ -1830,6 +1885,14 @@ int cmd_script(int argc, const char **argv, const char *prefix __maybe_unused) | |||
1830 | else | 1885 | else |
1831 | symbol_conf.use_callchain = false; | 1886 | symbol_conf.use_callchain = false; |
1832 | 1887 | ||
1888 | if (session->tevent.pevent && | ||
1889 | pevent_set_function_resolver(session->tevent.pevent, | ||
1890 | machine__resolve_kernel_addr, | ||
1891 | &session->machines.host) < 0) { | ||
1892 | pr_err("%s: failed to set libtraceevent function resolver\n", __func__); | ||
1893 | return -1; | ||
1894 | } | ||
1895 | |||
1833 | if (generate_script_lang) { | 1896 | if (generate_script_lang) { |
1834 | struct stat perf_stat; | 1897 | struct stat perf_stat; |
1835 | int input; | 1898 | int input; |