aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorIngo Molnar <mingo@kernel.org>2012-10-25 03:42:03 -0400
committerIngo Molnar <mingo@kernel.org>2012-10-25 03:42:03 -0400
commit6ca2a9c6543dd1a307c0250991d4de93550209ce (patch)
treefc0e6ea775be9bc10e16d2aab31f018f4b027c0c
parentce37f400336a34bb6e72c4700f9dcc2a41ff7163 (diff)
parentaf3df2cf17f5df079189c3cc88870d28e219496b (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: * Align the 'Ok'/'FAILED!' test results in 'perf test. * Support interrupted syscalls in 'trace' * Add an event duration column and filter in 'trace'. * There are references to the man pages in some tools, so try to build Documentation when installing, warning the user if that is not possible, from Borislav Petkov. * Give user better message if precise is not supported, from David Ahern. * Try to find cross-built objdump path by using the session environment information in the perf.data file header, from Irina Tirdea, original patch and idea by Namhyung Kim. * Diplays more output on features check for make V=1, so that one can figure out what is happening by looking at gcc output, etc. From Jiri Olsa. * Account the nr_entries in rblist properly, fix by Suzuki K. Poulose. Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
-rw-r--r--tools/perf/Documentation/Makefile31
-rw-r--r--tools/perf/Documentation/perf-trace.txt3
-rw-r--r--tools/perf/Makefile53
-rw-r--r--tools/perf/arch/common.c178
-rw-r--r--tools/perf/arch/common.h10
-rw-r--r--tools/perf/builtin-annotate.c7
-rw-r--r--tools/perf/builtin-record.c5
-rw-r--r--tools/perf/builtin-report.c7
-rw-r--r--tools/perf/builtin-test.c18
-rw-r--r--tools/perf/builtin-top.c4
-rw-r--r--tools/perf/builtin-trace.c250
-rw-r--r--tools/perf/config/feature-tests.mak5
-rw-r--r--tools/perf/config/utilities.mak11
-rw-r--r--tools/perf/util/annotate.h1
-rw-r--r--tools/perf/util/parse-events.c2
-rw-r--r--tools/perf/util/rblist.c4
-rw-r--r--tools/perf/util/util.h4
17 files changed, 535 insertions, 58 deletions
diff --git a/tools/perf/Documentation/Makefile b/tools/perf/Documentation/Makefile
index 9f2e44f2b17a..ef6d22e879eb 100644
--- a/tools/perf/Documentation/Makefile
+++ b/tools/perf/Documentation/Makefile
@@ -1,3 +1,5 @@
1include ../config/utilities.mak
2
1OUTPUT := ./ 3OUTPUT := ./
2ifeq ("$(origin O)", "command line") 4ifeq ("$(origin O)", "command line")
3 ifneq ($(O),) 5 ifneq ($(O),)
@@ -64,6 +66,7 @@ MAKEINFO=makeinfo
64INSTALL_INFO=install-info 66INSTALL_INFO=install-info
65DOCBOOK2X_TEXI=docbook2x-texi 67DOCBOOK2X_TEXI=docbook2x-texi
66DBLATEX=dblatex 68DBLATEX=dblatex
69XMLTO=xmlto
67ifndef PERL_PATH 70ifndef PERL_PATH
68 PERL_PATH = /usr/bin/perl 71 PERL_PATH = /usr/bin/perl
69endif 72endif
@@ -71,6 +74,16 @@ endif
71-include ../config.mak.autogen 74-include ../config.mak.autogen
72-include ../config.mak 75-include ../config.mak
73 76
77_tmp_tool_path := $(call get-executable,$(ASCIIDOC))
78ifeq ($(_tmp_tool_path),)
79 missing_tools = $(ASCIIDOC)
80endif
81
82_tmp_tool_path := $(call get-executable,$(XMLTO))
83ifeq ($(_tmp_tool_path),)
84 missing_tools += $(XMLTO)
85endif
86
74# 87#
75# For asciidoc ... 88# For asciidoc ...
76# -7.1.2, no extra settings are needed. 89# -7.1.2, no extra settings are needed.
@@ -170,7 +183,12 @@ pdf: $(OUTPUT)user-manual.pdf
170 183
171install: install-man 184install: install-man
172 185
173install-man: man 186check-man-tools:
187ifdef missing_tools
188 $(error "You need to install $(missing_tools) for man pages")
189endif
190
191do-install-man: man
174 $(INSTALL) -d -m 755 $(DESTDIR)$(man1dir) 192 $(INSTALL) -d -m 755 $(DESTDIR)$(man1dir)
175# $(INSTALL) -d -m 755 $(DESTDIR)$(man5dir) 193# $(INSTALL) -d -m 755 $(DESTDIR)$(man5dir)
176# $(INSTALL) -d -m 755 $(DESTDIR)$(man7dir) 194# $(INSTALL) -d -m 755 $(DESTDIR)$(man7dir)
@@ -178,6 +196,15 @@ install-man: man
178# $(INSTALL) -m 644 $(DOC_MAN5) $(DESTDIR)$(man5dir) 196# $(INSTALL) -m 644 $(DOC_MAN5) $(DESTDIR)$(man5dir)
179# $(INSTALL) -m 644 $(DOC_MAN7) $(DESTDIR)$(man7dir) 197# $(INSTALL) -m 644 $(DOC_MAN7) $(DESTDIR)$(man7dir)
180 198
199install-man: check-man-tools man
200
201try-install-man:
202ifdef missing_tools
203 $(warning Please install $(missing_tools) to have the man pages installed)
204else
205 $(MAKE) do-install-man
206endif
207
181install-info: info 208install-info: info
182 $(INSTALL) -d -m 755 $(DESTDIR)$(infodir) 209 $(INSTALL) -d -m 755 $(DESTDIR)$(infodir)
183 $(INSTALL) -m 644 $(OUTPUT)perf.info $(OUTPUT)perfman.info $(DESTDIR)$(infodir) 210 $(INSTALL) -m 644 $(OUTPUT)perf.info $(OUTPUT)perfman.info $(DESTDIR)$(infodir)
@@ -246,7 +273,7 @@ $(MAN_HTML): $(OUTPUT)%.html : %.txt
246 273
247$(OUTPUT)%.1 $(OUTPUT)%.5 $(OUTPUT)%.7 : $(OUTPUT)%.xml 274$(OUTPUT)%.1 $(OUTPUT)%.5 $(OUTPUT)%.7 : $(OUTPUT)%.xml
248 $(QUIET_XMLTO)$(RM) $@ && \ 275 $(QUIET_XMLTO)$(RM) $@ && \
249 xmlto -o $(OUTPUT) -m $(MANPAGE_XSL) $(XMLTO_EXTRA) man $< 276 $(XMLTO) -o $(OUTPUT) -m $(MANPAGE_XSL) $(XMLTO_EXTRA) man $<
250 277
251$(OUTPUT)%.xml : %.txt 278$(OUTPUT)%.xml : %.txt
252 $(QUIET_ASCIIDOC)$(RM) $@+ $@ && \ 279 $(QUIET_ASCIIDOC)$(RM) $@+ $@ && \
diff --git a/tools/perf/Documentation/perf-trace.txt b/tools/perf/Documentation/perf-trace.txt
index 3a2ae37310a9..38d4b682af0b 100644
--- a/tools/perf/Documentation/perf-trace.txt
+++ b/tools/perf/Documentation/perf-trace.txt
@@ -48,6 +48,9 @@ comma-separated list with no space: 0,1. Ranges of CPUs are specified with -: 0-
48In per-thread mode with inheritance mode on (default), Events are captured only when 48In per-thread mode with inheritance mode on (default), Events are captured only when
49the thread executes on the designated CPUs. Default is to monitor all CPUs. 49the thread executes on the designated CPUs. Default is to monitor all CPUs.
50 50
51--duration:
52 Show only events that had a duration greater than N.M ms.
53
51SEE ALSO 54SEE ALSO
52-------- 55--------
53linkperf:perf-record[1], linkperf:perf-script[1] 56linkperf:perf-record[1], linkperf:perf-script[1]
diff --git a/tools/perf/Makefile b/tools/perf/Makefile
index f530502630a4..b14eeb86d8d7 100644
--- a/tools/perf/Makefile
+++ b/tools/perf/Makefile
@@ -155,15 +155,15 @@ SPARSE_FLAGS = -D__BIG_ENDIAN__ -D__powerpc__
155 155
156-include config/feature-tests.mak 156-include config/feature-tests.mak
157 157
158ifeq ($(call try-cc,$(SOURCE_HELLO),$(CFLAGS) -Werror -fstack-protector-all),y) 158ifeq ($(call try-cc,$(SOURCE_HELLO),$(CFLAGS) -Werror -fstack-protector-all,-fstack-protector-all),y)
159 CFLAGS := $(CFLAGS) -fstack-protector-all 159 CFLAGS := $(CFLAGS) -fstack-protector-all
160endif 160endif
161 161
162ifeq ($(call try-cc,$(SOURCE_HELLO),$(CFLAGS) -Werror -Wstack-protector),y) 162ifeq ($(call try-cc,$(SOURCE_HELLO),$(CFLAGS) -Werror -Wstack-protector,-Wstack-protector),y)
163 CFLAGS := $(CFLAGS) -Wstack-protector 163 CFLAGS := $(CFLAGS) -Wstack-protector
164endif 164endif
165 165
166ifeq ($(call try-cc,$(SOURCE_HELLO),$(CFLAGS) -Werror -Wvolatile-register-var),y) 166ifeq ($(call try-cc,$(SOURCE_HELLO),$(CFLAGS) -Werror -Wvolatile-register-var,-Wvolatile-register-var),y)
167 CFLAGS := $(CFLAGS) -Wvolatile-register-var 167 CFLAGS := $(CFLAGS) -Wvolatile-register-var
168endif 168endif
169 169
@@ -172,7 +172,7 @@ endif
172BASIC_CFLAGS = -Iutil/include -Iarch/$(ARCH)/include -I$(OUTPUT)util -I$(TRACE_EVENT_DIR) -D_LARGEFILE64_SOURCE -D_FILE_OFFSET_BITS=64 -D_GNU_SOURCE 172BASIC_CFLAGS = -Iutil/include -Iarch/$(ARCH)/include -I$(OUTPUT)util -I$(TRACE_EVENT_DIR) -D_LARGEFILE64_SOURCE -D_FILE_OFFSET_BITS=64 -D_GNU_SOURCE
173BASIC_LDFLAGS = 173BASIC_LDFLAGS =
174 174
175ifeq ($(call try-cc,$(SOURCE_BIONIC),$(CFLAGS)),y) 175ifeq ($(call try-cc,$(SOURCE_BIONIC),$(CFLAGS),bionic),y)
176 BIONIC := 1 176 BIONIC := 1
177 EXTLIBS := $(filter-out -lrt,$(EXTLIBS)) 177 EXTLIBS := $(filter-out -lrt,$(EXTLIBS))
178 EXTLIBS := $(filter-out -lpthread,$(EXTLIBS)) 178 EXTLIBS := $(filter-out -lpthread,$(EXTLIBS))
@@ -426,6 +426,8 @@ LIB_OBJS += $(OUTPUT)ui/helpline.o
426LIB_OBJS += $(OUTPUT)ui/hist.o 426LIB_OBJS += $(OUTPUT)ui/hist.o
427LIB_OBJS += $(OUTPUT)ui/stdio/hist.o 427LIB_OBJS += $(OUTPUT)ui/stdio/hist.o
428 428
429LIB_OBJS += $(OUTPUT)arch/common.o
430
429BUILTIN_OBJS += $(OUTPUT)builtin-annotate.o 431BUILTIN_OBJS += $(OUTPUT)builtin-annotate.o
430BUILTIN_OBJS += $(OUTPUT)builtin-bench.o 432BUILTIN_OBJS += $(OUTPUT)builtin-bench.o
431# Benchmark modules 433# Benchmark modules
@@ -477,9 +479,9 @@ ifdef NO_LIBELF
477 NO_LIBUNWIND := 1 479 NO_LIBUNWIND := 1
478else 480else
479FLAGS_LIBELF=$(ALL_CFLAGS) $(ALL_LDFLAGS) $(EXTLIBS) 481FLAGS_LIBELF=$(ALL_CFLAGS) $(ALL_LDFLAGS) $(EXTLIBS)
480ifneq ($(call try-cc,$(SOURCE_LIBELF),$(FLAGS_LIBELF)),y) 482ifneq ($(call try-cc,$(SOURCE_LIBELF),$(FLAGS_LIBELF),libelf),y)
481 FLAGS_GLIBC=$(ALL_CFLAGS) $(ALL_LDFLAGS) 483 FLAGS_GLIBC=$(ALL_CFLAGS) $(ALL_LDFLAGS)
482 ifeq ($(call try-cc,$(SOURCE_GLIBC),$(FLAGS_GLIBC)),y) 484 ifeq ($(call try-cc,$(SOURCE_GLIBC),$(FLAGS_GLIBC),glibc),y)
483 LIBC_SUPPORT := 1 485 LIBC_SUPPORT := 1
484 endif 486 endif
485 ifeq ($(BIONIC),1) 487 ifeq ($(BIONIC),1)
@@ -494,7 +496,7 @@ ifneq ($(call try-cc,$(SOURCE_LIBELF),$(FLAGS_LIBELF)),y)
494 endif 496 endif
495else 497else
496 FLAGS_DWARF=$(ALL_CFLAGS) -ldw -lelf $(ALL_LDFLAGS) $(EXTLIBS) 498 FLAGS_DWARF=$(ALL_CFLAGS) -ldw -lelf $(ALL_LDFLAGS) $(EXTLIBS)
497 ifneq ($(call try-cc,$(SOURCE_DWARF),$(FLAGS_DWARF)),y) 499 ifneq ($(call try-cc,$(SOURCE_DWARF),$(FLAGS_DWARF),libdw),y)
498 msg := $(warning No libdw.h found or old libdw.h found or elfutils is older than 0.138, disables dwarf support. Please install new elfutils-devel/libdw-dev); 500 msg := $(warning No libdw.h found or old libdw.h found or elfutils is older than 0.138, disables dwarf support. Please install new elfutils-devel/libdw-dev);
499 NO_DWARF := 1 501 NO_DWARF := 1
500 endif # Dwarf support 502 endif # Dwarf support
@@ -510,7 +512,7 @@ ifdef LIBUNWIND_DIR
510endif 512endif
511 513
512FLAGS_UNWIND=$(LIBUNWIND_CFLAGS) $(ALL_CFLAGS) $(LIBUNWIND_LDFLAGS) $(ALL_LDFLAGS) $(EXTLIBS) $(LIBUNWIND_LIBS) 514FLAGS_UNWIND=$(LIBUNWIND_CFLAGS) $(ALL_CFLAGS) $(LIBUNWIND_LDFLAGS) $(ALL_LDFLAGS) $(EXTLIBS) $(LIBUNWIND_LIBS)
513ifneq ($(call try-cc,$(SOURCE_LIBUNWIND),$(FLAGS_UNWIND)),y) 515ifneq ($(call try-cc,$(SOURCE_LIBUNWIND),$(FLAGS_UNWIND),libunwind),y)
514 msg := $(warning No libunwind found, disabling post unwind support. Please install libunwind-dev[el] >= 0.99); 516 msg := $(warning No libunwind found, disabling post unwind support. Please install libunwind-dev[el] >= 0.99);
515 NO_LIBUNWIND := 1 517 NO_LIBUNWIND := 1
516endif # Libunwind support 518endif # Libunwind support
@@ -539,7 +541,7 @@ LIB_OBJS += $(OUTPUT)util/symbol-minimal.o
539else # NO_LIBELF 541else # NO_LIBELF
540BASIC_CFLAGS += -DLIBELF_SUPPORT 542BASIC_CFLAGS += -DLIBELF_SUPPORT
541 543
542ifeq ($(call try-cc,$(SOURCE_ELF_MMAP),$(FLAGS_COMMON)),y) 544ifeq ($(call try-cc,$(SOURCE_ELF_MMAP),$(FLAGS_COMMON),-DLIBELF_MMAP),y)
543 BASIC_CFLAGS += -DLIBELF_MMAP 545 BASIC_CFLAGS += -DLIBELF_MMAP
544endif 546endif
545 547
@@ -565,7 +567,7 @@ endif
565 567
566ifndef NO_LIBAUDIT 568ifndef NO_LIBAUDIT
567 FLAGS_LIBAUDIT = $(ALL_CFLAGS) $(ALL_LDFLAGS) -laudit 569 FLAGS_LIBAUDIT = $(ALL_CFLAGS) $(ALL_LDFLAGS) -laudit
568 ifneq ($(call try-cc,$(SOURCE_LIBAUDIT),$(FLAGS_LIBAUDIT)),y) 570 ifneq ($(call try-cc,$(SOURCE_LIBAUDIT),$(FLAGS_LIBAUDIT),libaudit),y)
569 msg := $(warning No libaudit.h found, disables 'trace' tool, please install audit-libs-devel or libaudit-dev); 571 msg := $(warning No libaudit.h found, disables 'trace' tool, please install audit-libs-devel or libaudit-dev);
570 else 572 else
571 BASIC_CFLAGS += -DLIBAUDIT_SUPPORT 573 BASIC_CFLAGS += -DLIBAUDIT_SUPPORT
@@ -576,7 +578,7 @@ endif
576 578
577ifndef NO_NEWT 579ifndef NO_NEWT
578 FLAGS_NEWT=$(ALL_CFLAGS) $(ALL_LDFLAGS) $(EXTLIBS) -lnewt 580 FLAGS_NEWT=$(ALL_CFLAGS) $(ALL_LDFLAGS) $(EXTLIBS) -lnewt
579 ifneq ($(call try-cc,$(SOURCE_NEWT),$(FLAGS_NEWT)),y) 581 ifneq ($(call try-cc,$(SOURCE_NEWT),$(FLAGS_NEWT),libnewt),y)
580 msg := $(warning newt not found, disables TUI support. Please install newt-devel or libnewt-dev); 582 msg := $(warning newt not found, disables TUI support. Please install newt-devel or libnewt-dev);
581 else 583 else
582 # Fedora has /usr/include/slang/slang.h, but ubuntu /usr/include/slang.h 584 # Fedora has /usr/include/slang/slang.h, but ubuntu /usr/include/slang.h
@@ -605,10 +607,10 @@ endif
605 607
606ifndef NO_GTK2 608ifndef NO_GTK2
607 FLAGS_GTK2=$(ALL_CFLAGS) $(ALL_LDFLAGS) $(EXTLIBS) $(shell pkg-config --libs --cflags gtk+-2.0 2>/dev/null) 609 FLAGS_GTK2=$(ALL_CFLAGS) $(ALL_LDFLAGS) $(EXTLIBS) $(shell pkg-config --libs --cflags gtk+-2.0 2>/dev/null)
608 ifneq ($(call try-cc,$(SOURCE_GTK2),$(FLAGS_GTK2)),y) 610 ifneq ($(call try-cc,$(SOURCE_GTK2),$(FLAGS_GTK2),gtk2),y)
609 msg := $(warning GTK2 not found, disables GTK2 support. Please install gtk2-devel or libgtk2.0-dev); 611 msg := $(warning GTK2 not found, disables GTK2 support. Please install gtk2-devel or libgtk2.0-dev);
610 else 612 else
611 ifeq ($(call try-cc,$(SOURCE_GTK2_INFOBAR),$(FLAGS_GTK2)),y) 613 ifeq ($(call try-cc,$(SOURCE_GTK2_INFOBAR),$(FLAGS_GTK2),-DHAVE_GTK_INFO_BAR),y)
612 BASIC_CFLAGS += -DHAVE_GTK_INFO_BAR 614 BASIC_CFLAGS += -DHAVE_GTK_INFO_BAR
613 endif 615 endif
614 BASIC_CFLAGS += -DGTK2_SUPPORT 616 BASIC_CFLAGS += -DGTK2_SUPPORT
@@ -635,7 +637,7 @@ else
635 PERL_EMBED_CCOPTS = `perl -MExtUtils::Embed -e ccopts 2>/dev/null` 637 PERL_EMBED_CCOPTS = `perl -MExtUtils::Embed -e ccopts 2>/dev/null`
636 FLAGS_PERL_EMBED=$(PERL_EMBED_CCOPTS) $(PERL_EMBED_LDOPTS) 638 FLAGS_PERL_EMBED=$(PERL_EMBED_CCOPTS) $(PERL_EMBED_LDOPTS)
637 639
638 ifneq ($(call try-cc,$(SOURCE_PERL_EMBED),$(FLAGS_PERL_EMBED)),y) 640 ifneq ($(call try-cc,$(SOURCE_PERL_EMBED),$(FLAGS_PERL_EMBED),perl),y)
639 BASIC_CFLAGS += -DNO_LIBPERL 641 BASIC_CFLAGS += -DNO_LIBPERL
640 else 642 else
641 ALL_LDFLAGS += $(PERL_EMBED_LDFLAGS) 643 ALL_LDFLAGS += $(PERL_EMBED_LDFLAGS)
@@ -689,11 +691,11 @@ else
689 PYTHON_EMBED_CCOPTS := $(shell $(PYTHON_CONFIG_SQ) --cflags 2>/dev/null) 691 PYTHON_EMBED_CCOPTS := $(shell $(PYTHON_CONFIG_SQ) --cflags 2>/dev/null)
690 FLAGS_PYTHON_EMBED := $(PYTHON_EMBED_CCOPTS) $(PYTHON_EMBED_LDOPTS) 692 FLAGS_PYTHON_EMBED := $(PYTHON_EMBED_CCOPTS) $(PYTHON_EMBED_LDOPTS)
691 693
692 ifneq ($(call try-cc,$(SOURCE_PYTHON_EMBED),$(FLAGS_PYTHON_EMBED)),y) 694 ifneq ($(call try-cc,$(SOURCE_PYTHON_EMBED),$(FLAGS_PYTHON_EMBED),python),y)
693 $(call disable-python,Python.h (for Python 2.x)) 695 $(call disable-python,Python.h (for Python 2.x))
694 else 696 else
695 697
696 ifneq ($(call try-cc,$(SOURCE_PYTHON_VERSION),$(FLAGS_PYTHON_EMBED)),y) 698 ifneq ($(call try-cc,$(SOURCE_PYTHON_VERSION),$(FLAGS_PYTHON_EMBED),python version),y)
697 $(warning Python 3 is not yet supported; please set) 699 $(warning Python 3 is not yet supported; please set)
698 $(warning PYTHON and/or PYTHON_CONFIG appropriately.) 700 $(warning PYTHON and/or PYTHON_CONFIG appropriately.)
699 $(warning If you also have Python 2 installed, then) 701 $(warning If you also have Python 2 installed, then)
@@ -727,22 +729,22 @@ else
727 BASIC_CFLAGS += -DHAVE_CPLUS_DEMANGLE 729 BASIC_CFLAGS += -DHAVE_CPLUS_DEMANGLE
728 else 730 else
729 FLAGS_BFD=$(ALL_CFLAGS) $(ALL_LDFLAGS) $(EXTLIBS) -DPACKAGE='perf' -lbfd 731 FLAGS_BFD=$(ALL_CFLAGS) $(ALL_LDFLAGS) $(EXTLIBS) -DPACKAGE='perf' -lbfd
730 has_bfd := $(call try-cc,$(SOURCE_BFD),$(FLAGS_BFD)) 732 has_bfd := $(call try-cc,$(SOURCE_BFD),$(FLAGS_BFD),libbfd)
731 ifeq ($(has_bfd),y) 733 ifeq ($(has_bfd),y)
732 EXTLIBS += -lbfd 734 EXTLIBS += -lbfd
733 else 735 else
734 FLAGS_BFD_IBERTY=$(FLAGS_BFD) -liberty 736 FLAGS_BFD_IBERTY=$(FLAGS_BFD) -liberty
735 has_bfd_iberty := $(call try-cc,$(SOURCE_BFD),$(FLAGS_BFD_IBERTY)) 737 has_bfd_iberty := $(call try-cc,$(SOURCE_BFD),$(FLAGS_BFD_IBERTY),liberty)
736 ifeq ($(has_bfd_iberty),y) 738 ifeq ($(has_bfd_iberty),y)
737 EXTLIBS += -lbfd -liberty 739 EXTLIBS += -lbfd -liberty
738 else 740 else
739 FLAGS_BFD_IBERTY_Z=$(FLAGS_BFD_IBERTY) -lz 741 FLAGS_BFD_IBERTY_Z=$(FLAGS_BFD_IBERTY) -lz
740 has_bfd_iberty_z := $(call try-cc,$(SOURCE_BFD),$(FLAGS_BFD_IBERTY_Z)) 742 has_bfd_iberty_z := $(call try-cc,$(SOURCE_BFD),$(FLAGS_BFD_IBERTY_Z),libz)
741 ifeq ($(has_bfd_iberty_z),y) 743 ifeq ($(has_bfd_iberty_z),y)
742 EXTLIBS += -lbfd -liberty -lz 744 EXTLIBS += -lbfd -liberty -lz
743 else 745 else
744 FLAGS_CPLUS_DEMANGLE=$(ALL_CFLAGS) $(ALL_LDFLAGS) $(EXTLIBS) -liberty 746 FLAGS_CPLUS_DEMANGLE=$(ALL_CFLAGS) $(ALL_LDFLAGS) $(EXTLIBS) -liberty
745 has_cplus_demangle := $(call try-cc,$(SOURCE_CPLUS_DEMANGLE),$(FLAGS_CPLUS_DEMANGLE)) 747 has_cplus_demangle := $(call try-cc,$(SOURCE_CPLUS_DEMANGLE),$(FLAGS_CPLUS_DEMANGLE),demangle)
746 ifeq ($(has_cplus_demangle),y) 748 ifeq ($(has_cplus_demangle),y)
747 EXTLIBS += -liberty 749 EXTLIBS += -liberty
748 BASIC_CFLAGS += -DHAVE_CPLUS_DEMANGLE 750 BASIC_CFLAGS += -DHAVE_CPLUS_DEMANGLE
@@ -764,19 +766,19 @@ ifeq ($(NO_PERF_REGS),0)
764endif 766endif
765 767
766ifndef NO_STRLCPY 768ifndef NO_STRLCPY
767 ifeq ($(call try-cc,$(SOURCE_STRLCPY),),y) 769 ifeq ($(call try-cc,$(SOURCE_STRLCPY),,-DHAVE_STRLCPY),y)
768 BASIC_CFLAGS += -DHAVE_STRLCPY 770 BASIC_CFLAGS += -DHAVE_STRLCPY
769 endif 771 endif
770endif 772endif
771 773
772ifndef NO_ON_EXIT 774ifndef NO_ON_EXIT
773 ifeq ($(call try-cc,$(SOURCE_ON_EXIT),),y) 775 ifeq ($(call try-cc,$(SOURCE_ON_EXIT),,-DHAVE_ON_EXIT),y)
774 BASIC_CFLAGS += -DHAVE_ON_EXIT 776 BASIC_CFLAGS += -DHAVE_ON_EXIT
775 endif 777 endif
776endif 778endif
777 779
778ifndef NO_BACKTRACE 780ifndef NO_BACKTRACE
779 ifeq ($(call try-cc,$(SOURCE_BACKTRACE),),y) 781 ifeq ($(call try-cc,$(SOURCE_BACKTRACE),,-DBACKTRACE_SUPPORT),y)
780 BASIC_CFLAGS += -DBACKTRACE_SUPPORT 782 BASIC_CFLAGS += -DBACKTRACE_SUPPORT
781 endif 783 endif
782endif 784endif
@@ -1039,7 +1041,7 @@ perfexec_instdir = $(prefix)/$(perfexecdir)
1039endif 1041endif
1040perfexec_instdir_SQ = $(subst ','\'',$(perfexec_instdir)) 1042perfexec_instdir_SQ = $(subst ','\'',$(perfexec_instdir))
1041 1043
1042install: all 1044install: all try-install-man
1043 $(INSTALL) -d -m 755 '$(DESTDIR_SQ)$(bindir_SQ)' 1045 $(INSTALL) -d -m 755 '$(DESTDIR_SQ)$(bindir_SQ)'
1044 $(INSTALL) $(OUTPUT)perf '$(DESTDIR_SQ)$(bindir_SQ)' 1046 $(INSTALL) $(OUTPUT)perf '$(DESTDIR_SQ)$(bindir_SQ)'
1045 $(INSTALL) -d -m 755 '$(DESTDIR_SQ)$(perfexec_instdir_SQ)/scripts/perl/Perf-Trace-Util/lib/Perf/Trace' 1047 $(INSTALL) -d -m 755 '$(DESTDIR_SQ)$(perfexec_instdir_SQ)/scripts/perl/Perf-Trace-Util/lib/Perf/Trace'
@@ -1065,6 +1067,9 @@ install-doc:
1065install-man: 1067install-man:
1066 $(MAKE) -C Documentation install-man 1068 $(MAKE) -C Documentation install-man
1067 1069
1070try-install-man:
1071 $(MAKE) -C Documentation try-install-man
1072
1068install-html: 1073install-html:
1069 $(MAKE) -C Documentation install-html 1074 $(MAKE) -C Documentation install-html
1070 1075
diff --git a/tools/perf/arch/common.c b/tools/perf/arch/common.c
new file mode 100644
index 000000000000..2367b253f039
--- /dev/null
+++ b/tools/perf/arch/common.c
@@ -0,0 +1,178 @@
1#include <stdio.h>
2#include <sys/utsname.h>
3#include "common.h"
4#include "../util/debug.h"
5
6const char *const arm_triplets[] = {
7 "arm-eabi-",
8 "arm-linux-androideabi-",
9 "arm-unknown-linux-",
10 "arm-unknown-linux-gnu-",
11 "arm-unknown-linux-gnueabi-",
12 NULL
13};
14
15const char *const powerpc_triplets[] = {
16 "powerpc-unknown-linux-gnu-",
17 "powerpc64-unknown-linux-gnu-",
18 NULL
19};
20
21const char *const s390_triplets[] = {
22 "s390-ibm-linux-",
23 NULL
24};
25
26const char *const sh_triplets[] = {
27 "sh-unknown-linux-gnu-",
28 "sh64-unknown-linux-gnu-",
29 NULL
30};
31
32const char *const sparc_triplets[] = {
33 "sparc-unknown-linux-gnu-",
34 "sparc64-unknown-linux-gnu-",
35 NULL
36};
37
38const char *const x86_triplets[] = {
39 "x86_64-pc-linux-gnu-",
40 "x86_64-unknown-linux-gnu-",
41 "i686-pc-linux-gnu-",
42 "i586-pc-linux-gnu-",
43 "i486-pc-linux-gnu-",
44 "i386-pc-linux-gnu-",
45 "i686-linux-android-",
46 "i686-android-linux-",
47 NULL
48};
49
50const char *const mips_triplets[] = {
51 "mips-unknown-linux-gnu-",
52 "mipsel-linux-android-",
53 NULL
54};
55
56static bool lookup_path(char *name)
57{
58 bool found = false;
59 char *path, *tmp;
60 char buf[PATH_MAX];
61 char *env = getenv("PATH");
62
63 if (!env)
64 return false;
65
66 env = strdup(env);
67 if (!env)
68 return false;
69
70 path = strtok_r(env, ":", &tmp);
71 while (path) {
72 scnprintf(buf, sizeof(buf), "%s/%s", path, name);
73 if (access(buf, F_OK) == 0) {
74 found = true;
75 break;
76 }
77 path = strtok_r(NULL, ":", &tmp);
78 }
79 free(env);
80 return found;
81}
82
83static int lookup_triplets(const char *const *triplets, const char *name)
84{
85 int i;
86 char buf[PATH_MAX];
87
88 for (i = 0; triplets[i] != NULL; i++) {
89 scnprintf(buf, sizeof(buf), "%s%s", triplets[i], name);
90 if (lookup_path(buf))
91 return i;
92 }
93 return -1;
94}
95
96static int perf_session_env__lookup_binutils_path(struct perf_session_env *env,
97 const char *name,
98 const char **path)
99{
100 int idx;
101 char *arch, *cross_env;
102 struct utsname uts;
103 const char *const *path_list;
104 char *buf = NULL;
105
106 if (uname(&uts) < 0)
107 goto out;
108
109 /*
110 * We don't need to try to find objdump path for native system.
111 * Just use default binutils path (e.g.: "objdump").
112 */
113 if (!strcmp(uts.machine, env->arch))
114 goto out;
115
116 cross_env = getenv("CROSS_COMPILE");
117 if (cross_env) {
118 if (asprintf(&buf, "%s%s", cross_env, name) < 0)
119 goto out_error;
120 if (buf[0] == '/') {
121 if (access(buf, F_OK) == 0)
122 goto out;
123 goto out_error;
124 }
125 if (lookup_path(buf))
126 goto out;
127 free(buf);
128 }
129
130 arch = env->arch;
131
132 if (!strcmp(arch, "arm"))
133 path_list = arm_triplets;
134 else if (!strcmp(arch, "powerpc"))
135 path_list = powerpc_triplets;
136 else if (!strcmp(arch, "sh"))
137 path_list = sh_triplets;
138 else if (!strcmp(arch, "s390"))
139 path_list = s390_triplets;
140 else if (!strcmp(arch, "sparc"))
141 path_list = sparc_triplets;
142 else if (!strcmp(arch, "x86") || !strcmp(arch, "i386") ||
143 !strcmp(arch, "i486") || !strcmp(arch, "i586") ||
144 !strcmp(arch, "i686"))
145 path_list = x86_triplets;
146 else if (!strcmp(arch, "mips"))
147 path_list = mips_triplets;
148 else {
149 ui__error("binutils for %s not supported.\n", arch);
150 goto out_error;
151 }
152
153 idx = lookup_triplets(path_list, name);
154 if (idx < 0) {
155 ui__error("Please install %s for %s.\n"
156 "You can add it to PATH, set CROSS_COMPILE or "
157 "override the default using --%s.\n",
158 name, arch, name);
159 goto out_error;
160 }
161
162 if (asprintf(&buf, "%s%s", path_list[idx], name) < 0)
163 goto out_error;
164
165out:
166 *path = buf;
167 return 0;
168out_error:
169 free(buf);
170 *path = NULL;
171 return -1;
172}
173
174int perf_session_env__lookup_objdump(struct perf_session_env *env)
175{
176 return perf_session_env__lookup_binutils_path(env, "objdump",
177 &objdump_path);
178}
diff --git a/tools/perf/arch/common.h b/tools/perf/arch/common.h
new file mode 100644
index 000000000000..ede246eda9be
--- /dev/null
+++ b/tools/perf/arch/common.h
@@ -0,0 +1,10 @@
1#ifndef ARCH_PERF_COMMON_H
2#define ARCH_PERF_COMMON_H
3
4#include "../util/session.h"
5
6extern const char *objdump_path;
7
8int perf_session_env__lookup_objdump(struct perf_session_env *env);
9
10#endif /* ARCH_PERF_COMMON_H */
diff --git a/tools/perf/builtin-annotate.c b/tools/perf/builtin-annotate.c
index 690fa9a54657..c4bb6457b19e 100644
--- a/tools/perf/builtin-annotate.c
+++ b/tools/perf/builtin-annotate.c
@@ -28,6 +28,7 @@
28#include "util/hist.h" 28#include "util/hist.h"
29#include "util/session.h" 29#include "util/session.h"
30#include "util/tool.h" 30#include "util/tool.h"
31#include "arch/common.h"
31 32
32#include <linux/bitmap.h> 33#include <linux/bitmap.h>
33 34
@@ -186,6 +187,12 @@ static int __cmd_annotate(struct perf_annotate *ann)
186 goto out_delete; 187 goto out_delete;
187 } 188 }
188 189
190 if (!objdump_path) {
191 ret = perf_session_env__lookup_objdump(&session->header.env);
192 if (ret)
193 goto out_delete;
194 }
195
189 ret = perf_session__process_events(session, &ann->tool); 196 ret = perf_session__process_events(session, &ann->tool);
190 if (ret) 197 if (ret)
191 goto out_delete; 198 goto out_delete;
diff --git a/tools/perf/builtin-record.c b/tools/perf/builtin-record.c
index 73b5d7f91194..53c9892e96dd 100644
--- a/tools/perf/builtin-record.c
+++ b/tools/perf/builtin-record.c
@@ -317,6 +317,11 @@ try_again:
317 perf_evsel__name(pos)); 317 perf_evsel__name(pos));
318 rc = -err; 318 rc = -err;
319 goto out; 319 goto out;
320 } else if ((err == EOPNOTSUPP) && (attr->precise_ip)) {
321 ui__error("\'precise\' request may not be supported. "
322 "Try removing 'p' modifier\n");
323 rc = -err;
324 goto out;
320 } 325 }
321 326
322 printf("\n"); 327 printf("\n");
diff --git a/tools/perf/builtin-report.c b/tools/perf/builtin-report.c
index 5104a40af563..90d1162bb8b8 100644
--- a/tools/perf/builtin-report.c
+++ b/tools/perf/builtin-report.c
@@ -33,6 +33,7 @@
33#include "util/thread.h" 33#include "util/thread.h"
34#include "util/sort.h" 34#include "util/sort.h"
35#include "util/hist.h" 35#include "util/hist.h"
36#include "arch/common.h"
36 37
37#include <linux/bitmap.h> 38#include <linux/bitmap.h>
38 39
@@ -672,6 +673,12 @@ int cmd_report(int argc, const char **argv, const char *prefix __maybe_unused)
672 has_br_stack = perf_header__has_feat(&session->header, 673 has_br_stack = perf_header__has_feat(&session->header,
673 HEADER_BRANCH_STACK); 674 HEADER_BRANCH_STACK);
674 675
676 if (!objdump_path) {
677 ret = perf_session_env__lookup_objdump(&session->header.env);
678 if (ret)
679 goto error;
680 }
681
675 if (sort__branch_mode == -1 && has_br_stack) 682 if (sort__branch_mode == -1 && has_br_stack)
676 sort__branch_mode = 1; 683 sort__branch_mode = 1;
677 684
diff --git a/tools/perf/builtin-test.c b/tools/perf/builtin-test.c
index e2d9872de3d7..a04276e81f40 100644
--- a/tools/perf/builtin-test.c
+++ b/tools/perf/builtin-test.c
@@ -6,6 +6,7 @@
6#include "builtin.h" 6#include "builtin.h"
7 7
8#include "util/cache.h" 8#include "util/cache.h"
9#include "util/color.h"
9#include "util/debug.h" 10#include "util/debug.h"
10#include "util/debugfs.h" 11#include "util/debugfs.h"
11#include "util/evlist.h" 12#include "util/evlist.h"
@@ -1485,18 +1486,31 @@ static bool perf_test__matches(int curr, int argc, const char *argv[])
1485static int __cmd_test(int argc, const char *argv[]) 1486static int __cmd_test(int argc, const char *argv[])
1486{ 1487{
1487 int i = 0; 1488 int i = 0;
1489 int width = 0;
1488 1490
1489 while (tests[i].func) { 1491 while (tests[i].func) {
1492 int len = strlen(tests[i].desc);
1493
1494 if (width < len)
1495 width = len;
1496 ++i;
1497 }
1498
1499 i = 0;
1500 while (tests[i].func) {
1490 int curr = i++, err; 1501 int curr = i++, err;
1491 1502
1492 if (!perf_test__matches(curr, argc, argv)) 1503 if (!perf_test__matches(curr, argc, argv))
1493 continue; 1504 continue;
1494 1505
1495 pr_info("%2d: %s:", i, tests[curr].desc); 1506 pr_info("%2d: %-*s:", i, width, tests[curr].desc);
1496 pr_debug("\n--- start ---\n"); 1507 pr_debug("\n--- start ---\n");
1497 err = tests[curr].func(); 1508 err = tests[curr].func();
1498 pr_debug("---- end ----\n%s:", tests[curr].desc); 1509 pr_debug("---- end ----\n%s:", tests[curr].desc);
1499 pr_info(" %s\n", err ? "FAILED!\n" : "Ok"); 1510 if (err)
1511 color_fprintf(stderr, PERF_COLOR_RED, " FAILED!\n");
1512 else
1513 pr_info(" Ok\n");
1500 } 1514 }
1501 1515
1502 return 0; 1516 return 0;
diff --git a/tools/perf/builtin-top.c b/tools/perf/builtin-top.c
index fb9da71eba1f..f2ecd498c72d 100644
--- a/tools/perf/builtin-top.c
+++ b/tools/perf/builtin-top.c
@@ -977,6 +977,10 @@ try_again:
977 ui__error("Too many events are opened.\n" 977 ui__error("Too many events are opened.\n"
978 "Try again after reducing the number of events\n"); 978 "Try again after reducing the number of events\n");
979 goto out_err; 979 goto out_err;
980 } else if ((err == EOPNOTSUPP) && (attr->precise_ip)) {
981 ui__error("\'precise\' request may not be supported. "
982 "Try removing 'p' modifier\n");
983 goto out_err;
980 } 984 }
981 985
982 ui__error("The sys_perf_event_open() syscall " 986 ui__error("The sys_perf_event_open() syscall "
diff --git a/tools/perf/builtin-trace.c b/tools/perf/builtin-trace.c
index 14b322961807..ba055103b525 100644
--- a/tools/perf/builtin-trace.c
+++ b/tools/perf/builtin-trace.c
@@ -1,5 +1,8 @@
1#include "builtin.h" 1#include "builtin.h"
2#include "util/color.h"
2#include "util/evlist.h" 3#include "util/evlist.h"
4#include "util/machine.h"
5#include "util/thread.h"
3#include "util/parse-options.h" 6#include "util/parse-options.h"
4#include "util/thread_map.h" 7#include "util/thread_map.h"
5#include "event-parse.h" 8#include "event-parse.h"
@@ -13,15 +16,18 @@ static struct syscall_fmt {
13 bool errmsg; 16 bool errmsg;
14 bool timeout; 17 bool timeout;
15} syscall_fmts[] = { 18} syscall_fmts[] = {
19 { .name = "access", .errmsg = true, },
16 { .name = "arch_prctl", .errmsg = true, .alias = "prctl", }, 20 { .name = "arch_prctl", .errmsg = true, .alias = "prctl", },
17 { .name = "fstat", .errmsg = true, .alias = "newfstat", }, 21 { .name = "fstat", .errmsg = true, .alias = "newfstat", },
18 { .name = "fstatat", .errmsg = true, .alias = "newfstatat", }, 22 { .name = "fstatat", .errmsg = true, .alias = "newfstatat", },
19 { .name = "futex", .errmsg = true, }, 23 { .name = "futex", .errmsg = true, },
24 { .name = "open", .errmsg = true, },
20 { .name = "poll", .errmsg = true, .timeout = true, }, 25 { .name = "poll", .errmsg = true, .timeout = true, },
21 { .name = "ppoll", .errmsg = true, .timeout = true, }, 26 { .name = "ppoll", .errmsg = true, .timeout = true, },
22 { .name = "read", .errmsg = true, }, 27 { .name = "read", .errmsg = true, },
23 { .name = "recvfrom", .errmsg = true, }, 28 { .name = "recvfrom", .errmsg = true, },
24 { .name = "select", .errmsg = true, .timeout = true, }, 29 { .name = "select", .errmsg = true, .timeout = true, },
30 { .name = "socket", .errmsg = true, },
25 { .name = "stat", .errmsg = true, .alias = "newstat", }, 31 { .name = "stat", .errmsg = true, .alias = "newstat", },
26}; 32};
27 33
@@ -43,6 +49,50 @@ struct syscall {
43 struct syscall_fmt *fmt; 49 struct syscall_fmt *fmt;
44}; 50};
45 51
52static size_t fprintf_duration(unsigned long t, FILE *fp)
53{
54 double duration = (double)t / NSEC_PER_MSEC;
55 size_t printed = fprintf(fp, "(");
56
57 if (duration >= 1.0)
58 printed += color_fprintf(fp, PERF_COLOR_RED, "%6.3f ms", duration);
59 else if (duration >= 0.01)
60 printed += color_fprintf(fp, PERF_COLOR_YELLOW, "%6.3f ms", duration);
61 else
62 printed += color_fprintf(fp, PERF_COLOR_NORMAL, "%6.3f ms", duration);
63 return printed + fprintf(stdout, "): ");
64}
65
66struct thread_trace {
67 u64 entry_time;
68 u64 exit_time;
69 bool entry_pending;
70 char *entry_str;
71};
72
73static struct thread_trace *thread_trace__new(void)
74{
75 return zalloc(sizeof(struct thread_trace));
76}
77
78static struct thread_trace *thread__trace(struct thread *thread)
79{
80 if (thread == NULL)
81 goto fail;
82
83 if (thread->priv == NULL)
84 thread->priv = thread_trace__new();
85
86 if (thread->priv == NULL)
87 goto fail;
88
89 return thread->priv;
90fail:
91 color_fprintf(stdout, PERF_COLOR_RED,
92 "WARNING: not enough memory, dropping samples!\n");
93 return NULL;
94}
95
46struct trace { 96struct trace {
47 int audit_machine; 97 int audit_machine;
48 struct { 98 struct {
@@ -50,8 +100,24 @@ struct trace {
50 struct syscall *table; 100 struct syscall *table;
51 } syscalls; 101 } syscalls;
52 struct perf_record_opts opts; 102 struct perf_record_opts opts;
103 struct machine host;
104 u64 base_time;
105 bool multiple_threads;
106 double duration_filter;
53}; 107};
54 108
109static bool trace__filter_duration(struct trace *trace, double t)
110{
111 return t < (trace->duration_filter * NSEC_PER_MSEC);
112}
113
114static size_t trace__fprintf_tstamp(struct trace *trace, u64 tstamp, FILE *fp)
115{
116 double ts = (double)(tstamp - trace->base_time) / NSEC_PER_MSEC;
117
118 return fprintf(fp, "%10.3f ", ts);
119}
120
55static bool done = false; 121static bool done = false;
56 122
57static void sig_handler(int sig __maybe_unused) 123static void sig_handler(int sig __maybe_unused)
@@ -59,6 +125,68 @@ static void sig_handler(int sig __maybe_unused)
59 done = true; 125 done = true;
60} 126}
61 127
128static size_t trace__fprintf_entry_head(struct trace *trace, struct thread *thread,
129 u64 duration, u64 tstamp, FILE *fp)
130{
131 size_t printed = trace__fprintf_tstamp(trace, tstamp, fp);
132 printed += fprintf_duration(duration, fp);
133
134 if (trace->multiple_threads)
135 printed += fprintf(fp, "%d ", thread->pid);
136
137 return printed;
138}
139
140static int trace__process_event(struct machine *machine, union perf_event *event)
141{
142 int ret = 0;
143
144 switch (event->header.type) {
145 case PERF_RECORD_LOST:
146 color_fprintf(stdout, PERF_COLOR_RED,
147 "LOST %" PRIu64 " events!\n", event->lost.lost);
148 ret = machine__process_lost_event(machine, event);
149 default:
150 ret = machine__process_event(machine, event);
151 break;
152 }
153
154 return ret;
155}
156
157static int trace__tool_process(struct perf_tool *tool __maybe_unused,
158 union perf_event *event,
159 struct perf_sample *sample __maybe_unused,
160 struct machine *machine)
161{
162 return trace__process_event(machine, event);
163}
164
165static int trace__symbols_init(struct trace *trace, struct perf_evlist *evlist)
166{
167 int err = symbol__init();
168
169 if (err)
170 return err;
171
172 machine__init(&trace->host, "", HOST_KERNEL_ID);
173 machine__create_kernel_maps(&trace->host);
174
175 if (perf_target__has_task(&trace->opts.target)) {
176 err = perf_event__synthesize_thread_map(NULL, evlist->threads,
177 trace__tool_process,
178 &trace->host);
179 } else {
180 err = perf_event__synthesize_threads(NULL, trace__tool_process,
181 &trace->host);
182 }
183
184 if (err)
185 symbol__exit();
186
187 return err;
188}
189
62static int trace__read_syscall_info(struct trace *trace, int id) 190static int trace__read_syscall_info(struct trace *trace, int id)
63{ 191{
64 char tp_name[128]; 192 char tp_name[128];
@@ -100,7 +228,8 @@ static int trace__read_syscall_info(struct trace *trace, int id)
100 return sc->tp_format != NULL ? 0 : -1; 228 return sc->tp_format != NULL ? 0 : -1;
101} 229}
102 230
103static size_t syscall__fprintf_args(struct syscall *sc, unsigned long *args, FILE *fp) 231static size_t syscall__scnprintf_args(struct syscall *sc, char *bf, size_t size,
232 unsigned long *args)
104{ 233{
105 int i = 0; 234 int i = 0;
106 size_t printed = 0; 235 size_t printed = 0;
@@ -109,12 +238,15 @@ static size_t syscall__fprintf_args(struct syscall *sc, unsigned long *args, FIL
109 struct format_field *field; 238 struct format_field *field;
110 239
111 for (field = sc->tp_format->format.fields->next; field; field = field->next) { 240 for (field = sc->tp_format->format.fields->next; field; field = field->next) {
112 printed += fprintf(fp, "%s%s: %ld", printed ? ", " : "", 241 printed += scnprintf(bf + printed, size - printed,
113 field->name, args[i++]); 242 "%s%s: %ld", printed ? ", " : "",
243 field->name, args[i++]);
114 } 244 }
115 } else { 245 } else {
116 while (i < 6) { 246 while (i < 6) {
117 printed += fprintf(fp, "%sarg%d: %ld", printed ? ", " : "", i, args[i]); 247 printed += scnprintf(bf + printed, size - printed,
248 "%sarg%d: %ld",
249 printed ? ", " : "", i, args[i]);
118 ++i; 250 ++i;
119 } 251 }
120 } 252 }
@@ -146,17 +278,24 @@ static struct syscall *trace__syscall_info(struct trace *trace,
146 return &trace->syscalls.table[id]; 278 return &trace->syscalls.table[id];
147 279
148out_cant_read: 280out_cant_read:
149 printf("Problems reading syscall %d information\n", id); 281 printf("Problems reading syscall %d", id);
282 if (id <= trace->syscalls.max && trace->syscalls.table[id].name != NULL)
283 printf("(%s)", trace->syscalls.table[id].name);
284 puts(" information");
150 return NULL; 285 return NULL;
151} 286}
152 287
153static int trace__sys_enter(struct trace *trace, struct perf_evsel *evsel, 288static int trace__sys_enter(struct trace *trace, struct perf_evsel *evsel,
154 struct perf_sample *sample) 289 struct perf_sample *sample)
155{ 290{
291 char *msg;
156 void *args; 292 void *args;
293 size_t printed = 0;
294 struct thread *thread = machine__findnew_thread(&trace->host, sample->tid);
157 struct syscall *sc = trace__syscall_info(trace, evsel, sample); 295 struct syscall *sc = trace__syscall_info(trace, evsel, sample);
296 struct thread_trace *ttrace = thread__trace(thread);
158 297
159 if (sc == NULL) 298 if (ttrace == NULL || sc == NULL)
160 return -1; 299 return -1;
161 300
162 args = perf_evsel__rawptr(evsel, sample, "args"); 301 args = perf_evsel__rawptr(evsel, sample, "args");
@@ -165,8 +304,27 @@ static int trace__sys_enter(struct trace *trace, struct perf_evsel *evsel,
165 return -1; 304 return -1;
166 } 305 }
167 306
168 printf("%s(", sc->name); 307 ttrace = thread->priv;
169 syscall__fprintf_args(sc, args, stdout); 308
309 if (ttrace->entry_str == NULL) {
310 ttrace->entry_str = malloc(1024);
311 if (!ttrace->entry_str)
312 return -1;
313 }
314
315 ttrace->entry_time = sample->time;
316 msg = ttrace->entry_str;
317 printed += scnprintf(msg + printed, 1024 - printed, "%s(", sc->name);
318
319 printed += syscall__scnprintf_args(sc, msg + printed, 1024 - printed, args);
320
321 if (!strcmp(sc->name, "exit_group") || !strcmp(sc->name, "exit")) {
322 if (!trace->duration_filter) {
323 trace__fprintf_entry_head(trace, thread, 1, sample->time, stdout);
324 printf("%-70s\n", ttrace->entry_str);
325 }
326 } else
327 ttrace->entry_pending = true;
170 328
171 return 0; 329 return 0;
172} 330}
@@ -175,13 +333,37 @@ static int trace__sys_exit(struct trace *trace, struct perf_evsel *evsel,
175 struct perf_sample *sample) 333 struct perf_sample *sample)
176{ 334{
177 int ret; 335 int ret;
336 u64 duration = 0;
337 struct thread *thread = machine__findnew_thread(&trace->host, sample->tid);
338 struct thread_trace *ttrace = thread__trace(thread);
178 struct syscall *sc = trace__syscall_info(trace, evsel, sample); 339 struct syscall *sc = trace__syscall_info(trace, evsel, sample);
179 340
180 if (sc == NULL) 341 if (ttrace == NULL || sc == NULL)
181 return -1; 342 return -1;
182 343
183 ret = perf_evsel__intval(evsel, sample, "ret"); 344 ret = perf_evsel__intval(evsel, sample, "ret");
184 345
346 ttrace = thread->priv;
347
348 ttrace->exit_time = sample->time;
349
350 if (ttrace->entry_time) {
351 duration = sample->time - ttrace->entry_time;
352 if (trace__filter_duration(trace, duration))
353 goto out;
354 } else if (trace->duration_filter)
355 goto out;
356
357 trace__fprintf_entry_head(trace, thread, duration, sample->time, stdout);
358
359 if (ttrace->entry_pending) {
360 printf("%-70s", ttrace->entry_str);
361 } else {
362 printf(" ... [");
363 color_fprintf(stdout, PERF_COLOR_YELLOW, "continued");
364 printf("]: %s()", sc->name);
365 }
366
185 if (ret < 0 && sc->fmt && sc->fmt->errmsg) { 367 if (ret < 0 && sc->fmt && sc->fmt->errmsg) {
186 char bf[256]; 368 char bf[256];
187 const char *emsg = strerror_r(-ret, bf, sizeof(bf)), 369 const char *emsg = strerror_r(-ret, bf, sizeof(bf)),
@@ -194,6 +376,9 @@ static int trace__sys_exit(struct trace *trace, struct perf_evsel *evsel,
194 printf(") = %d", ret); 376 printf(") = %d", ret);
195 377
196 putchar('\n'); 378 putchar('\n');
379out:
380 ttrace->entry_pending = false;
381
197 return 0; 382 return 0;
198} 383}
199 384
@@ -221,6 +406,12 @@ static int trace__run(struct trace *trace, int argc, const char **argv)
221 goto out_delete_evlist; 406 goto out_delete_evlist;
222 } 407 }
223 408
409 err = trace__symbols_init(trace, evlist);
410 if (err < 0) {
411 printf("Problems initializing symbol libraries!\n");
412 goto out_delete_evlist;
413 }
414
224 perf_evlist__config_attrs(evlist, &trace->opts); 415 perf_evlist__config_attrs(evlist, &trace->opts);
225 416
226 signal(SIGCHLD, sig_handler); 417 signal(SIGCHLD, sig_handler);
@@ -251,6 +442,7 @@ static int trace__run(struct trace *trace, int argc, const char **argv)
251 if (forks) 442 if (forks)
252 perf_evlist__start_workload(evlist); 443 perf_evlist__start_workload(evlist);
253 444
445 trace->multiple_threads = evlist->threads->map[0] == -1 || evlist->threads->nr > 1;
254again: 446again:
255 before = nr_events; 447 before = nr_events;
256 448
@@ -264,32 +456,32 @@ again:
264 456
265 ++nr_events; 457 ++nr_events;
266 458
267 switch (type) {
268 case PERF_RECORD_SAMPLE:
269 break;
270 case PERF_RECORD_LOST:
271 printf("LOST %" PRIu64 " events!\n", event->lost.lost);
272 continue;
273 default:
274 printf("Unexpected %s event, skipping...\n",
275 perf_event__name(type));
276 continue;
277 }
278
279 err = perf_evlist__parse_sample(evlist, event, &sample); 459 err = perf_evlist__parse_sample(evlist, event, &sample);
280 if (err) { 460 if (err) {
281 printf("Can't parse sample, err = %d, skipping...\n", err); 461 printf("Can't parse sample, err = %d, skipping...\n", err);
282 continue; 462 continue;
283 } 463 }
284 464
465 if (trace->base_time == 0)
466 trace->base_time = sample.time;
467
468 if (type != PERF_RECORD_SAMPLE) {
469 trace__process_event(&trace->host, event);
470 continue;
471 }
472
285 evsel = perf_evlist__id2evsel(evlist, sample.id); 473 evsel = perf_evlist__id2evsel(evlist, sample.id);
286 if (evsel == NULL) { 474 if (evsel == NULL) {
287 printf("Unknown tp ID %" PRIu64 ", skipping...\n", sample.id); 475 printf("Unknown tp ID %" PRIu64 ", skipping...\n", sample.id);
288 continue; 476 continue;
289 } 477 }
290 478
291 if (evlist->threads->map[0] == -1 || evlist->threads->nr > 1) 479 if (sample.raw_data == NULL) {
292 printf("%d ", sample.tid); 480 printf("%s sample with no payload for tid: %d, cpu %d, raw_size=%d, skipping...\n",
481 perf_evsel__name(evsel), sample.tid,
482 sample.cpu, sample.raw_size);
483 continue;
484 }
293 485
294 if (sample.raw_data == NULL) { 486 if (sample.raw_data == NULL) {
295 printf("%s sample with no payload for tid: %d, cpu %d, raw_size=%d, skipping...\n", 487 printf("%s sample with no payload for tid: %d, cpu %d, raw_size=%d, skipping...\n",
@@ -321,6 +513,15 @@ out:
321 return err; 513 return err;
322} 514}
323 515
516static int trace__set_duration(const struct option *opt, const char *str,
517 int unset __maybe_unused)
518{
519 struct trace *trace = opt->value;
520
521 trace->duration_filter = atof(str);
522 return 0;
523}
524
324int cmd_trace(int argc, const char **argv, const char *prefix __maybe_unused) 525int cmd_trace(int argc, const char **argv, const char *prefix __maybe_unused)
325{ 526{
326 const char * const trace_usage[] = { 527 const char * const trace_usage[] = {
@@ -359,6 +560,9 @@ int cmd_trace(int argc, const char **argv, const char *prefix __maybe_unused)
359 "number of mmap data pages"), 560 "number of mmap data pages"),
360 OPT_STRING(0, "uid", &trace.opts.target.uid_str, "user", 561 OPT_STRING(0, "uid", &trace.opts.target.uid_str, "user",
361 "user to profile"), 562 "user to profile"),
563 OPT_CALLBACK(0, "duration", &trace, "float",
564 "show only events with duration > N.M ms",
565 trace__set_duration),
362 OPT_END() 566 OPT_END()
363 }; 567 };
364 int err; 568 int err;
diff --git a/tools/perf/config/feature-tests.mak b/tools/perf/config/feature-tests.mak
index 3ef5ec9cdff8..f5ac77485a4f 100644
--- a/tools/perf/config/feature-tests.mak
+++ b/tools/perf/config/feature-tests.mak
@@ -121,7 +121,10 @@ define SOURCE_PYTHON_VERSION
121#if PY_VERSION_HEX >= 0x03000000 121#if PY_VERSION_HEX >= 0x03000000
122 #error 122 #error
123#endif 123#endif
124int main(void){} 124int main(void)
125{
126 return 0;
127}
125endef 128endef
126define SOURCE_PYTHON_EMBED 129define SOURCE_PYTHON_EMBED
127#include <Python.h> 130#include <Python.h>
diff --git a/tools/perf/config/utilities.mak b/tools/perf/config/utilities.mak
index 8046182a19eb..ea853c279b31 100644
--- a/tools/perf/config/utilities.mak
+++ b/tools/perf/config/utilities.mak
@@ -180,9 +180,16 @@ _gea_warn = $(warning The path '$(1)' is not executable.)
180_gea_err = $(if $(1),$(error Please set '$(1)' appropriately)) 180_gea_err = $(if $(1),$(error Please set '$(1)' appropriately))
181 181
182# try-cc 182# try-cc
183# Usage: option = $(call try-cc, source-to-build, cc-options) 183# Usage: option = $(call try-cc, source-to-build, cc-options, msg)
184ifndef V
185TRY_CC_OUTPUT= > /dev/null 2>&1
186else
187TRY_CC_MSG=echo "CHK $(3)" 1>&2;
188endif
189
184try-cc = $(shell sh -c \ 190try-cc = $(shell sh -c \
185 'TMP="$(OUTPUT)$(TMPOUT).$$$$"; \ 191 'TMP="$(OUTPUT)$(TMPOUT).$$$$"; \
192 $(TRY_CC_MSG) \
186 echo "$(1)" | \ 193 echo "$(1)" | \
187 $(CC) -x c - $(2) -o "$$TMP" > /dev/null 2>&1 && echo y; \ 194 $(CC) -x c - $(2) -o "$$TMP" $(TRY_CC_OUTPUT) && echo y; \
188 rm -f "$$TMP"') 195 rm -f "$$TMP"')
diff --git a/tools/perf/util/annotate.h b/tools/perf/util/annotate.h
index 39242dcee8f2..a4dd25a61a07 100644
--- a/tools/perf/util/annotate.h
+++ b/tools/perf/util/annotate.h
@@ -154,6 +154,5 @@ static inline int symbol__tui_annotate(struct symbol *sym __maybe_unused,
154#endif 154#endif
155 155
156extern const char *disassembler_style; 156extern const char *disassembler_style;
157extern const char *objdump_path;
158 157
159#endif /* __PERF_ANNOTATE_H */ 158#endif /* __PERF_ANNOTATE_H */
diff --git a/tools/perf/util/parse-events.c b/tools/perf/util/parse-events.c
index 2fe15874e46e..3a3efcf3e4e9 100644
--- a/tools/perf/util/parse-events.c
+++ b/tools/perf/util/parse-events.c
@@ -1081,7 +1081,7 @@ void print_events(const char *event_glob, bool name_only)
1081 printf(" %-50s [%s]\n", 1081 printf(" %-50s [%s]\n",
1082 "cpu/t1=v1[,t2=v2,t3 ...]/modifier", 1082 "cpu/t1=v1[,t2=v2,t3 ...]/modifier",
1083 event_type_descriptors[PERF_TYPE_RAW]); 1083 event_type_descriptors[PERF_TYPE_RAW]);
1084 printf(" (see 'perf list --help' on how to encode it)\n"); 1084 printf(" (see 'man perf-list' on how to encode it)\n");
1085 printf("\n"); 1085 printf("\n");
1086 1086
1087 printf(" %-50s [%s]\n", 1087 printf(" %-50s [%s]\n",
diff --git a/tools/perf/util/rblist.c b/tools/perf/util/rblist.c
index 0171fb611004..a16cdd2625ad 100644
--- a/tools/perf/util/rblist.c
+++ b/tools/perf/util/rblist.c
@@ -44,6 +44,7 @@ int rblist__add_node(struct rblist *rblist, const void *new_entry)
44void rblist__remove_node(struct rblist *rblist, struct rb_node *rb_node) 44void rblist__remove_node(struct rblist *rblist, struct rb_node *rb_node)
45{ 45{
46 rb_erase(rb_node, &rblist->entries); 46 rb_erase(rb_node, &rblist->entries);
47 --rblist->nr_entries;
47 rblist->node_delete(rblist, rb_node); 48 rblist->node_delete(rblist, rb_node);
48} 49}
49 50
@@ -87,8 +88,7 @@ void rblist__delete(struct rblist *rblist)
87 while (next) { 88 while (next) {
88 pos = next; 89 pos = next;
89 next = rb_next(pos); 90 next = rb_next(pos);
90 rb_erase(pos, &rblist->entries); 91 rblist__remove_node(rblist, pos);
91 rblist->node_delete(rblist, pos);
92 } 92 }
93 free(rblist); 93 free(rblist);
94 } 94 }
diff --git a/tools/perf/util/util.h b/tools/perf/util/util.h
index a6b83f8ebef8..0d85209db8f1 100644
--- a/tools/perf/util/util.h
+++ b/tools/perf/util/util.h
@@ -198,6 +198,10 @@ static inline int has_extension(const char *filename, const char *ext)
198#undef tolower 198#undef tolower
199#undef toupper 199#undef toupper
200 200
201#ifndef NSEC_PER_MSEC
202#define NSEC_PER_MSEC 1000000L
203#endif
204
201extern unsigned char sane_ctype[256]; 205extern unsigned char sane_ctype[256];
202#define GIT_SPACE 0x01 206#define GIT_SPACE 0x01
203#define GIT_DIGIT 0x02 207#define GIT_DIGIT 0x02