Commit 6ca2a9c6 authored by Ingo Molnar's avatar Ingo Molnar

Merge tag 'perf-core-for-mingo' of...

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: default avatarArnaldo Carvalho de Melo <acme@redhat.com>
parents ce37f400 af3df2cf
include ../config/utilities.mak
OUTPUT := ./ OUTPUT := ./
ifeq ("$(origin O)", "command line") ifeq ("$(origin O)", "command line")
ifneq ($(O),) ifneq ($(O),)
...@@ -64,6 +66,7 @@ MAKEINFO=makeinfo ...@@ -64,6 +66,7 @@ MAKEINFO=makeinfo
INSTALL_INFO=install-info INSTALL_INFO=install-info
DOCBOOK2X_TEXI=docbook2x-texi DOCBOOK2X_TEXI=docbook2x-texi
DBLATEX=dblatex DBLATEX=dblatex
XMLTO=xmlto
ifndef PERL_PATH ifndef PERL_PATH
PERL_PATH = /usr/bin/perl PERL_PATH = /usr/bin/perl
endif endif
...@@ -71,6 +74,16 @@ endif ...@@ -71,6 +74,16 @@ endif
-include ../config.mak.autogen -include ../config.mak.autogen
-include ../config.mak -include ../config.mak
_tmp_tool_path := $(call get-executable,$(ASCIIDOC))
ifeq ($(_tmp_tool_path),)
missing_tools = $(ASCIIDOC)
endif
_tmp_tool_path := $(call get-executable,$(XMLTO))
ifeq ($(_tmp_tool_path),)
missing_tools += $(XMLTO)
endif
# #
# For asciidoc ... # For asciidoc ...
# -7.1.2, no extra settings are needed. # -7.1.2, no extra settings are needed.
...@@ -170,7 +183,12 @@ pdf: $(OUTPUT)user-manual.pdf ...@@ -170,7 +183,12 @@ pdf: $(OUTPUT)user-manual.pdf
install: install-man install: install-man
install-man: man check-man-tools:
ifdef missing_tools
$(error "You need to install $(missing_tools) for man pages")
endif
do-install-man: man
$(INSTALL) -d -m 755 $(DESTDIR)$(man1dir) $(INSTALL) -d -m 755 $(DESTDIR)$(man1dir)
# $(INSTALL) -d -m 755 $(DESTDIR)$(man5dir) # $(INSTALL) -d -m 755 $(DESTDIR)$(man5dir)
# $(INSTALL) -d -m 755 $(DESTDIR)$(man7dir) # $(INSTALL) -d -m 755 $(DESTDIR)$(man7dir)
...@@ -178,6 +196,15 @@ install-man: man ...@@ -178,6 +196,15 @@ install-man: man
# $(INSTALL) -m 644 $(DOC_MAN5) $(DESTDIR)$(man5dir) # $(INSTALL) -m 644 $(DOC_MAN5) $(DESTDIR)$(man5dir)
# $(INSTALL) -m 644 $(DOC_MAN7) $(DESTDIR)$(man7dir) # $(INSTALL) -m 644 $(DOC_MAN7) $(DESTDIR)$(man7dir)
install-man: check-man-tools man
try-install-man:
ifdef missing_tools
$(warning Please install $(missing_tools) to have the man pages installed)
else
$(MAKE) do-install-man
endif
install-info: info install-info: info
$(INSTALL) -d -m 755 $(DESTDIR)$(infodir) $(INSTALL) -d -m 755 $(DESTDIR)$(infodir)
$(INSTALL) -m 644 $(OUTPUT)perf.info $(OUTPUT)perfman.info $(DESTDIR)$(infodir) $(INSTALL) -m 644 $(OUTPUT)perf.info $(OUTPUT)perfman.info $(DESTDIR)$(infodir)
...@@ -246,7 +273,7 @@ $(MAN_HTML): $(OUTPUT)%.html : %.txt ...@@ -246,7 +273,7 @@ $(MAN_HTML): $(OUTPUT)%.html : %.txt
$(OUTPUT)%.1 $(OUTPUT)%.5 $(OUTPUT)%.7 : $(OUTPUT)%.xml $(OUTPUT)%.1 $(OUTPUT)%.5 $(OUTPUT)%.7 : $(OUTPUT)%.xml
$(QUIET_XMLTO)$(RM) $@ && \ $(QUIET_XMLTO)$(RM) $@ && \
xmlto -o $(OUTPUT) -m $(MANPAGE_XSL) $(XMLTO_EXTRA) man $< $(XMLTO) -o $(OUTPUT) -m $(MANPAGE_XSL) $(XMLTO_EXTRA) man $<
$(OUTPUT)%.xml : %.txt $(OUTPUT)%.xml : %.txt
$(QUIET_ASCIIDOC)$(RM) $@+ $@ && \ $(QUIET_ASCIIDOC)$(RM) $@+ $@ && \
......
...@@ -48,6 +48,9 @@ comma-separated list with no space: 0,1. Ranges of CPUs are specified with -: 0- ...@@ -48,6 +48,9 @@ comma-separated list with no space: 0,1. Ranges of CPUs are specified with -: 0-
In per-thread mode with inheritance mode on (default), Events are captured only when In per-thread mode with inheritance mode on (default), Events are captured only when
the thread executes on the designated CPUs. Default is to monitor all CPUs. the thread executes on the designated CPUs. Default is to monitor all CPUs.
--duration:
Show only events that had a duration greater than N.M ms.
SEE ALSO SEE ALSO
-------- --------
linkperf:perf-record[1], linkperf:perf-script[1] linkperf:perf-record[1], linkperf:perf-script[1]
...@@ -155,15 +155,15 @@ SPARSE_FLAGS = -D__BIG_ENDIAN__ -D__powerpc__ ...@@ -155,15 +155,15 @@ SPARSE_FLAGS = -D__BIG_ENDIAN__ -D__powerpc__
-include config/feature-tests.mak -include config/feature-tests.mak
ifeq ($(call try-cc,$(SOURCE_HELLO),$(CFLAGS) -Werror -fstack-protector-all),y) ifeq ($(call try-cc,$(SOURCE_HELLO),$(CFLAGS) -Werror -fstack-protector-all,-fstack-protector-all),y)
CFLAGS := $(CFLAGS) -fstack-protector-all CFLAGS := $(CFLAGS) -fstack-protector-all
endif endif
ifeq ($(call try-cc,$(SOURCE_HELLO),$(CFLAGS) -Werror -Wstack-protector),y) ifeq ($(call try-cc,$(SOURCE_HELLO),$(CFLAGS) -Werror -Wstack-protector,-Wstack-protector),y)
CFLAGS := $(CFLAGS) -Wstack-protector CFLAGS := $(CFLAGS) -Wstack-protector
endif endif
ifeq ($(call try-cc,$(SOURCE_HELLO),$(CFLAGS) -Werror -Wvolatile-register-var),y) ifeq ($(call try-cc,$(SOURCE_HELLO),$(CFLAGS) -Werror -Wvolatile-register-var,-Wvolatile-register-var),y)
CFLAGS := $(CFLAGS) -Wvolatile-register-var CFLAGS := $(CFLAGS) -Wvolatile-register-var
endif endif
...@@ -172,7 +172,7 @@ endif ...@@ -172,7 +172,7 @@ endif
BASIC_CFLAGS = -Iutil/include -Iarch/$(ARCH)/include -I$(OUTPUT)util -I$(TRACE_EVENT_DIR) -D_LARGEFILE64_SOURCE -D_FILE_OFFSET_BITS=64 -D_GNU_SOURCE BASIC_CFLAGS = -Iutil/include -Iarch/$(ARCH)/include -I$(OUTPUT)util -I$(TRACE_EVENT_DIR) -D_LARGEFILE64_SOURCE -D_FILE_OFFSET_BITS=64 -D_GNU_SOURCE
BASIC_LDFLAGS = BASIC_LDFLAGS =
ifeq ($(call try-cc,$(SOURCE_BIONIC),$(CFLAGS)),y) ifeq ($(call try-cc,$(SOURCE_BIONIC),$(CFLAGS),bionic),y)
BIONIC := 1 BIONIC := 1
EXTLIBS := $(filter-out -lrt,$(EXTLIBS)) EXTLIBS := $(filter-out -lrt,$(EXTLIBS))
EXTLIBS := $(filter-out -lpthread,$(EXTLIBS)) EXTLIBS := $(filter-out -lpthread,$(EXTLIBS))
...@@ -426,6 +426,8 @@ LIB_OBJS += $(OUTPUT)ui/helpline.o ...@@ -426,6 +426,8 @@ LIB_OBJS += $(OUTPUT)ui/helpline.o
LIB_OBJS += $(OUTPUT)ui/hist.o LIB_OBJS += $(OUTPUT)ui/hist.o
LIB_OBJS += $(OUTPUT)ui/stdio/hist.o LIB_OBJS += $(OUTPUT)ui/stdio/hist.o
LIB_OBJS += $(OUTPUT)arch/common.o
BUILTIN_OBJS += $(OUTPUT)builtin-annotate.o BUILTIN_OBJS += $(OUTPUT)builtin-annotate.o
BUILTIN_OBJS += $(OUTPUT)builtin-bench.o BUILTIN_OBJS += $(OUTPUT)builtin-bench.o
# Benchmark modules # Benchmark modules
...@@ -477,9 +479,9 @@ ifdef NO_LIBELF ...@@ -477,9 +479,9 @@ ifdef NO_LIBELF
NO_LIBUNWIND := 1 NO_LIBUNWIND := 1
else else
FLAGS_LIBELF=$(ALL_CFLAGS) $(ALL_LDFLAGS) $(EXTLIBS) FLAGS_LIBELF=$(ALL_CFLAGS) $(ALL_LDFLAGS) $(EXTLIBS)
ifneq ($(call try-cc,$(SOURCE_LIBELF),$(FLAGS_LIBELF)),y) ifneq ($(call try-cc,$(SOURCE_LIBELF),$(FLAGS_LIBELF),libelf),y)
FLAGS_GLIBC=$(ALL_CFLAGS) $(ALL_LDFLAGS) FLAGS_GLIBC=$(ALL_CFLAGS) $(ALL_LDFLAGS)
ifeq ($(call try-cc,$(SOURCE_GLIBC),$(FLAGS_GLIBC)),y) ifeq ($(call try-cc,$(SOURCE_GLIBC),$(FLAGS_GLIBC),glibc),y)
LIBC_SUPPORT := 1 LIBC_SUPPORT := 1
endif endif
ifeq ($(BIONIC),1) ifeq ($(BIONIC),1)
...@@ -494,7 +496,7 @@ ifneq ($(call try-cc,$(SOURCE_LIBELF),$(FLAGS_LIBELF)),y) ...@@ -494,7 +496,7 @@ ifneq ($(call try-cc,$(SOURCE_LIBELF),$(FLAGS_LIBELF)),y)
endif endif
else else
FLAGS_DWARF=$(ALL_CFLAGS) -ldw -lelf $(ALL_LDFLAGS) $(EXTLIBS) FLAGS_DWARF=$(ALL_CFLAGS) -ldw -lelf $(ALL_LDFLAGS) $(EXTLIBS)
ifneq ($(call try-cc,$(SOURCE_DWARF),$(FLAGS_DWARF)),y) ifneq ($(call try-cc,$(SOURCE_DWARF),$(FLAGS_DWARF),libdw),y)
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); 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);
NO_DWARF := 1 NO_DWARF := 1
endif # Dwarf support endif # Dwarf support
...@@ -510,7 +512,7 @@ ifdef LIBUNWIND_DIR ...@@ -510,7 +512,7 @@ ifdef LIBUNWIND_DIR
endif endif
FLAGS_UNWIND=$(LIBUNWIND_CFLAGS) $(ALL_CFLAGS) $(LIBUNWIND_LDFLAGS) $(ALL_LDFLAGS) $(EXTLIBS) $(LIBUNWIND_LIBS) FLAGS_UNWIND=$(LIBUNWIND_CFLAGS) $(ALL_CFLAGS) $(LIBUNWIND_LDFLAGS) $(ALL_LDFLAGS) $(EXTLIBS) $(LIBUNWIND_LIBS)
ifneq ($(call try-cc,$(SOURCE_LIBUNWIND),$(FLAGS_UNWIND)),y) ifneq ($(call try-cc,$(SOURCE_LIBUNWIND),$(FLAGS_UNWIND),libunwind),y)
msg := $(warning No libunwind found, disabling post unwind support. Please install libunwind-dev[el] >= 0.99); msg := $(warning No libunwind found, disabling post unwind support. Please install libunwind-dev[el] >= 0.99);
NO_LIBUNWIND := 1 NO_LIBUNWIND := 1
endif # Libunwind support endif # Libunwind support
...@@ -539,7 +541,7 @@ LIB_OBJS += $(OUTPUT)util/symbol-minimal.o ...@@ -539,7 +541,7 @@ LIB_OBJS += $(OUTPUT)util/symbol-minimal.o
else # NO_LIBELF else # NO_LIBELF
BASIC_CFLAGS += -DLIBELF_SUPPORT BASIC_CFLAGS += -DLIBELF_SUPPORT
ifeq ($(call try-cc,$(SOURCE_ELF_MMAP),$(FLAGS_COMMON)),y) ifeq ($(call try-cc,$(SOURCE_ELF_MMAP),$(FLAGS_COMMON),-DLIBELF_MMAP),y)
BASIC_CFLAGS += -DLIBELF_MMAP BASIC_CFLAGS += -DLIBELF_MMAP
endif endif
...@@ -565,7 +567,7 @@ endif ...@@ -565,7 +567,7 @@ endif
ifndef NO_LIBAUDIT ifndef NO_LIBAUDIT
FLAGS_LIBAUDIT = $(ALL_CFLAGS) $(ALL_LDFLAGS) -laudit FLAGS_LIBAUDIT = $(ALL_CFLAGS) $(ALL_LDFLAGS) -laudit
ifneq ($(call try-cc,$(SOURCE_LIBAUDIT),$(FLAGS_LIBAUDIT)),y) ifneq ($(call try-cc,$(SOURCE_LIBAUDIT),$(FLAGS_LIBAUDIT),libaudit),y)
msg := $(warning No libaudit.h found, disables 'trace' tool, please install audit-libs-devel or libaudit-dev); msg := $(warning No libaudit.h found, disables 'trace' tool, please install audit-libs-devel or libaudit-dev);
else else
BASIC_CFLAGS += -DLIBAUDIT_SUPPORT BASIC_CFLAGS += -DLIBAUDIT_SUPPORT
...@@ -576,7 +578,7 @@ endif ...@@ -576,7 +578,7 @@ endif
ifndef NO_NEWT ifndef NO_NEWT
FLAGS_NEWT=$(ALL_CFLAGS) $(ALL_LDFLAGS) $(EXTLIBS) -lnewt FLAGS_NEWT=$(ALL_CFLAGS) $(ALL_LDFLAGS) $(EXTLIBS) -lnewt
ifneq ($(call try-cc,$(SOURCE_NEWT),$(FLAGS_NEWT)),y) ifneq ($(call try-cc,$(SOURCE_NEWT),$(FLAGS_NEWT),libnewt),y)
msg := $(warning newt not found, disables TUI support. Please install newt-devel or libnewt-dev); msg := $(warning newt not found, disables TUI support. Please install newt-devel or libnewt-dev);
else else
# Fedora has /usr/include/slang/slang.h, but ubuntu /usr/include/slang.h # Fedora has /usr/include/slang/slang.h, but ubuntu /usr/include/slang.h
...@@ -605,10 +607,10 @@ endif ...@@ -605,10 +607,10 @@ endif
ifndef NO_GTK2 ifndef NO_GTK2
FLAGS_GTK2=$(ALL_CFLAGS) $(ALL_LDFLAGS) $(EXTLIBS) $(shell pkg-config --libs --cflags gtk+-2.0 2>/dev/null) FLAGS_GTK2=$(ALL_CFLAGS) $(ALL_LDFLAGS) $(EXTLIBS) $(shell pkg-config --libs --cflags gtk+-2.0 2>/dev/null)
ifneq ($(call try-cc,$(SOURCE_GTK2),$(FLAGS_GTK2)),y) ifneq ($(call try-cc,$(SOURCE_GTK2),$(FLAGS_GTK2),gtk2),y)
msg := $(warning GTK2 not found, disables GTK2 support. Please install gtk2-devel or libgtk2.0-dev); msg := $(warning GTK2 not found, disables GTK2 support. Please install gtk2-devel or libgtk2.0-dev);
else else
ifeq ($(call try-cc,$(SOURCE_GTK2_INFOBAR),$(FLAGS_GTK2)),y) ifeq ($(call try-cc,$(SOURCE_GTK2_INFOBAR),$(FLAGS_GTK2),-DHAVE_GTK_INFO_BAR),y)
BASIC_CFLAGS += -DHAVE_GTK_INFO_BAR BASIC_CFLAGS += -DHAVE_GTK_INFO_BAR
endif endif
BASIC_CFLAGS += -DGTK2_SUPPORT BASIC_CFLAGS += -DGTK2_SUPPORT
...@@ -635,7 +637,7 @@ else ...@@ -635,7 +637,7 @@ else
PERL_EMBED_CCOPTS = `perl -MExtUtils::Embed -e ccopts 2>/dev/null` PERL_EMBED_CCOPTS = `perl -MExtUtils::Embed -e ccopts 2>/dev/null`
FLAGS_PERL_EMBED=$(PERL_EMBED_CCOPTS) $(PERL_EMBED_LDOPTS) FLAGS_PERL_EMBED=$(PERL_EMBED_CCOPTS) $(PERL_EMBED_LDOPTS)
ifneq ($(call try-cc,$(SOURCE_PERL_EMBED),$(FLAGS_PERL_EMBED)),y) ifneq ($(call try-cc,$(SOURCE_PERL_EMBED),$(FLAGS_PERL_EMBED),perl),y)
BASIC_CFLAGS += -DNO_LIBPERL BASIC_CFLAGS += -DNO_LIBPERL
else else
ALL_LDFLAGS += $(PERL_EMBED_LDFLAGS) ALL_LDFLAGS += $(PERL_EMBED_LDFLAGS)
...@@ -689,11 +691,11 @@ else ...@@ -689,11 +691,11 @@ else
PYTHON_EMBED_CCOPTS := $(shell $(PYTHON_CONFIG_SQ) --cflags 2>/dev/null) PYTHON_EMBED_CCOPTS := $(shell $(PYTHON_CONFIG_SQ) --cflags 2>/dev/null)
FLAGS_PYTHON_EMBED := $(PYTHON_EMBED_CCOPTS) $(PYTHON_EMBED_LDOPTS) FLAGS_PYTHON_EMBED := $(PYTHON_EMBED_CCOPTS) $(PYTHON_EMBED_LDOPTS)
ifneq ($(call try-cc,$(SOURCE_PYTHON_EMBED),$(FLAGS_PYTHON_EMBED)),y) ifneq ($(call try-cc,$(SOURCE_PYTHON_EMBED),$(FLAGS_PYTHON_EMBED),python),y)
$(call disable-python,Python.h (for Python 2.x)) $(call disable-python,Python.h (for Python 2.x))
else else
ifneq ($(call try-cc,$(SOURCE_PYTHON_VERSION),$(FLAGS_PYTHON_EMBED)),y) ifneq ($(call try-cc,$(SOURCE_PYTHON_VERSION),$(FLAGS_PYTHON_EMBED),python version),y)
$(warning Python 3 is not yet supported; please set) $(warning Python 3 is not yet supported; please set)
$(warning PYTHON and/or PYTHON_CONFIG appropriately.) $(warning PYTHON and/or PYTHON_CONFIG appropriately.)
$(warning If you also have Python 2 installed, then) $(warning If you also have Python 2 installed, then)
...@@ -727,22 +729,22 @@ else ...@@ -727,22 +729,22 @@ else
BASIC_CFLAGS += -DHAVE_CPLUS_DEMANGLE BASIC_CFLAGS += -DHAVE_CPLUS_DEMANGLE
else else
FLAGS_BFD=$(ALL_CFLAGS) $(ALL_LDFLAGS) $(EXTLIBS) -DPACKAGE='perf' -lbfd FLAGS_BFD=$(ALL_CFLAGS) $(ALL_LDFLAGS) $(EXTLIBS) -DPACKAGE='perf' -lbfd
has_bfd := $(call try-cc,$(SOURCE_BFD),$(FLAGS_BFD)) has_bfd := $(call try-cc,$(SOURCE_BFD),$(FLAGS_BFD),libbfd)
ifeq ($(has_bfd),y) ifeq ($(has_bfd),y)
EXTLIBS += -lbfd EXTLIBS += -lbfd
else else
FLAGS_BFD_IBERTY=$(FLAGS_BFD) -liberty FLAGS_BFD_IBERTY=$(FLAGS_BFD) -liberty
has_bfd_iberty := $(call try-cc,$(SOURCE_BFD),$(FLAGS_BFD_IBERTY)) has_bfd_iberty := $(call try-cc,$(SOURCE_BFD),$(FLAGS_BFD_IBERTY),liberty)
ifeq ($(has_bfd_iberty),y) ifeq ($(has_bfd_iberty),y)
EXTLIBS += -lbfd -liberty EXTLIBS += -lbfd -liberty
else else
FLAGS_BFD_IBERTY_Z=$(FLAGS_BFD_IBERTY) -lz FLAGS_BFD_IBERTY_Z=$(FLAGS_BFD_IBERTY) -lz
has_bfd_iberty_z := $(call try-cc,$(SOURCE_BFD),$(FLAGS_BFD_IBERTY_Z)) has_bfd_iberty_z := $(call try-cc,$(SOURCE_BFD),$(FLAGS_BFD_IBERTY_Z),libz)
ifeq ($(has_bfd_iberty_z),y) ifeq ($(has_bfd_iberty_z),y)
EXTLIBS += -lbfd -liberty -lz EXTLIBS += -lbfd -liberty -lz
else else
FLAGS_CPLUS_DEMANGLE=$(ALL_CFLAGS) $(ALL_LDFLAGS) $(EXTLIBS) -liberty FLAGS_CPLUS_DEMANGLE=$(ALL_CFLAGS) $(ALL_LDFLAGS) $(EXTLIBS) -liberty
has_cplus_demangle := $(call try-cc,$(SOURCE_CPLUS_DEMANGLE),$(FLAGS_CPLUS_DEMANGLE)) has_cplus_demangle := $(call try-cc,$(SOURCE_CPLUS_DEMANGLE),$(FLAGS_CPLUS_DEMANGLE),demangle)
ifeq ($(has_cplus_demangle),y) ifeq ($(has_cplus_demangle),y)
EXTLIBS += -liberty EXTLIBS += -liberty
BASIC_CFLAGS += -DHAVE_CPLUS_DEMANGLE BASIC_CFLAGS += -DHAVE_CPLUS_DEMANGLE
...@@ -764,19 +766,19 @@ ifeq ($(NO_PERF_REGS),0) ...@@ -764,19 +766,19 @@ ifeq ($(NO_PERF_REGS),0)
endif endif
ifndef NO_STRLCPY ifndef NO_STRLCPY
ifeq ($(call try-cc,$(SOURCE_STRLCPY),),y) ifeq ($(call try-cc,$(SOURCE_STRLCPY),,-DHAVE_STRLCPY),y)
BASIC_CFLAGS += -DHAVE_STRLCPY BASIC_CFLAGS += -DHAVE_STRLCPY
endif endif
endif endif
ifndef NO_ON_EXIT ifndef NO_ON_EXIT
ifeq ($(call try-cc,$(SOURCE_ON_EXIT),),y) ifeq ($(call try-cc,$(SOURCE_ON_EXIT),,-DHAVE_ON_EXIT),y)
BASIC_CFLAGS += -DHAVE_ON_EXIT BASIC_CFLAGS += -DHAVE_ON_EXIT
endif endif
endif endif
ifndef NO_BACKTRACE ifndef NO_BACKTRACE
ifeq ($(call try-cc,$(SOURCE_BACKTRACE),),y) ifeq ($(call try-cc,$(SOURCE_BACKTRACE),,-DBACKTRACE_SUPPORT),y)
BASIC_CFLAGS += -DBACKTRACE_SUPPORT BASIC_CFLAGS += -DBACKTRACE_SUPPORT
endif endif
endif endif
...@@ -1039,7 +1041,7 @@ perfexec_instdir = $(prefix)/$(perfexecdir) ...@@ -1039,7 +1041,7 @@ perfexec_instdir = $(prefix)/$(perfexecdir)
endif endif
perfexec_instdir_SQ = $(subst ','\'',$(perfexec_instdir)) perfexec_instdir_SQ = $(subst ','\'',$(perfexec_instdir))
install: all install: all try-install-man
$(INSTALL) -d -m 755 '$(DESTDIR_SQ)$(bindir_SQ)' $(INSTALL) -d -m 755 '$(DESTDIR_SQ)$(bindir_SQ)'
$(INSTALL) $(OUTPUT)perf '$(DESTDIR_SQ)$(bindir_SQ)' $(INSTALL) $(OUTPUT)perf '$(DESTDIR_SQ)$(bindir_SQ)'
$(INSTALL) -d -m 755 '$(DESTDIR_SQ)$(perfexec_instdir_SQ)/scripts/perl/Perf-Trace-Util/lib/Perf/Trace' $(INSTALL) -d -m 755 '$(DESTDIR_SQ)$(perfexec_instdir_SQ)/scripts/perl/Perf-Trace-Util/lib/Perf/Trace'
...@@ -1065,6 +1067,9 @@ install-doc: ...@@ -1065,6 +1067,9 @@ install-doc:
install-man: install-man:
$(MAKE) -C Documentation install-man $(MAKE) -C Documentation install-man
try-install-man:
$(MAKE) -C Documentation try-install-man
install-html: install-html:
$(MAKE) -C Documentation install-html $(MAKE) -C Documentation install-html
......
#include <stdio.h>
#include <sys/utsname.h>
#include "common.h"
#include "../util/debug.h"
const char *const arm_triplets[] = {
"arm-eabi-",
"arm-linux-androideabi-",
"arm-unknown-linux-",
"arm-unknown-linux-gnu-",
"arm-unknown-linux-gnueabi-",
NULL
};
const char *const powerpc_triplets[] = {
"powerpc-unknown-linux-gnu-",
"powerpc64-unknown-linux-gnu-",
NULL
};
const char *const s390_triplets[] = {
"s390-ibm-linux-",
NULL
};
const char *const sh_triplets[] = {
"sh-unknown-linux-gnu-",
"sh64-unknown-linux-gnu-",
NULL
};
const char *const sparc_triplets[] = {
"sparc-unknown-linux-gnu-",
"sparc64-unknown-linux-gnu-",
NULL
};
const char *const x86_triplets[] = {
"x86_64-pc-linux-gnu-",
"x86_64-unknown-linux-gnu-",
"i686-pc-linux-gnu-",
"i586-pc-linux-gnu-",
"i486-pc-linux-gnu-",
"i386-pc-linux-gnu-",
"i686-linux-android-",
"i686-android-linux-",
NULL
};
const char *const mips_triplets[] = {
"mips-unknown-linux-gnu-",
"mipsel-linux-android-",
NULL
};
static bool lookup_path(char *name)
{
bool found = false;
char *path, *tmp;
char buf[PATH_MAX];
char *env = getenv("PATH");
if (!env)
return false;
env = strdup(env);
if (!env)
return false;
path = strtok_r(env, ":", &tmp);
while (path) {
scnprintf(buf, sizeof(buf), "%s/%s", path, name);
if (access(buf, F_OK) == 0) {
found = true;
break;
}
path = strtok_r(NULL, ":", &tmp);
}
free(env);
return found;
}
static int lookup_triplets(const char *const *triplets, const char *name)
{
int i;
char buf[PATH_MAX];
for (i = 0; triplets[i] != NULL; i++) {
scnprintf(buf, sizeof(buf), "%s%s", triplets[i], name);
if (lookup_path(buf))
return i;
}
return -1;
}
static int perf_session_env__lookup_binutils_path(struct perf_session_env *env,
const char *name,
const char **path)
{
int idx;
char *arch, *cross_env;
struct utsname uts;
const char *const *path_list;
char *buf = NULL;
if (uname(&uts) < 0)
goto out;
/*
* We don't need to try to find objdump path for native system.
* Just use default binutils path (e.g.: "objdump").
*/
if (!strcmp(uts.machine, env->arch))
goto out;
cross_env = getenv("CROSS_COMPILE");
if (cross_env) {
if (asprintf(&buf, "%s%s", cross_env, name) < 0)
goto out_error;
if (buf[0] == '/') {
if (access(buf, F_OK) == 0)
goto out;
goto out_error;
}
if (lookup_path(buf))
goto out;
free(buf);
}
arch = env->arch;
if (!strcmp(arch, "arm"))
path_list = arm_triplets;
else if (!strcmp(arch, "powerpc"))
path_list = powerpc_triplets;
else if (!strcmp(arch, "sh"))
path_list = sh_triplets;
else if (!strcmp(arch, "s390"))
path_list = s390_triplets;
else if (!strcmp(arch, "sparc"))
path_list = sparc_triplets;
else if (!strcmp(arch, "x86") || !strcmp(arch, "i386") ||
!strcmp(arch, "i486") || !strcmp(arch, "i586") ||
!strcmp(arch, "i686"))
path_list = x86_triplets;
else if (!strcmp(arch, "mips"))
path_list = mips_triplets;
else {
ui__error("binutils for %s not supported.\n", arch);
goto out_error;
}
idx = lookup_triplets(path_list, name);
if (idx < 0) {
ui__error("Please install %s for %s.\n"
"You can add it to PATH, set CROSS_COMPILE or "
"override the default using --%s.\n",
name, arch, name);
goto out_error;
}
if (asprintf(&buf, "%s%s", path_list[idx], name) < 0)
goto out_error;
out:
*path = buf;
return 0;
out_error:
free(buf);
*path = NULL;
return -1;
}
int perf_session_env__lookup_objdump(struct perf_session_env *env)
{
return perf_session_env__lookup_binutils_path(env, "objdump",
&objdump_path);
}
#ifndef ARCH_PERF_COMMON_H
#define ARCH_PERF_COMMON_H
#include "../util/session.h"
extern const char *objdump_path;
int perf_session_env__lookup_objdump(struct perf_session_env *env);
#endif /* ARCH_PERF_COMMON_H */
...@@ -28,6 +28,7 @@ ...@@ -28,6 +28,7 @@
#include "util/hist.h" #include "util/hist.h"
#include "util/session.h" #include "util/session.h"
#include "util/tool.h" #include "util/tool.h"
#include "arch/common.h"
#include <linux/bitmap.h> #include <linux/bitmap.h>
...@@ -186,6 +187,12 @@ static int __cmd_annotate(struct perf_annotate *ann) ...@@ -186,6 +187,12 @@ static int __cmd_annotate(struct perf_annotate *ann)
goto out_delete; goto out_delete;
} }
if (!objdump_path) {
ret = perf_session_env__lookup_objdump(&session->header.env);
if (ret)
goto out_delete;
}
ret = perf_session__process_events(session, &ann->tool); ret = perf_session__process_events(session, &ann->tool);
if (ret) if (ret)
goto out_delete; goto out_delete;
......
...@@ -317,6 +317,11 @@ static int perf_record__open(struct perf_record *rec) ...@@ -317,6 +317,11 @@ static int perf_record__open(struct perf_record *rec)
perf_evsel__name(pos)); perf_evsel__name(pos));
rc = -err; rc = -err;
goto out; goto out;
} else if ((err == EOPNOTSUPP) && (attr->precise_ip)) {
ui__error("\'precise\' request may not be supported. "
"Try removing 'p' modifier\n");
rc = -err;
goto out;
} }
printf("\n"); printf("\n");
......
...@@ -33,6 +33,7 @@ ...@@ -33,6 +33,7 @@
#include "util/thread.h" #include "util/thread.h"
#include "util/sort.h" #include "util/sort.h"
#include "util/hist.h" #include "util/hist.h"
#include "arch/common.h"
#include <linux/bitmap.h> #include <linux/bitmap.h>
...@@ -672,6 +673,12 @@ int cmd_report(int argc, const char **argv, const char *prefix __maybe_unused) ...@@ -672,6 +673,12 @@ int cmd_report(int argc, const char **argv, const char *prefix __maybe_unused)
has_br_stack = perf_header__has_feat(&session->header, has_br_stack = perf_header__has_feat(&session->header,
HEADER_BRANCH_STACK); HEADER_BRANCH_STACK);
if (!objdump_path) {
ret = perf_session_env__lookup_objdump(&session->header.env);
if (ret)
goto error;
}
if (sort__branch_mode == -1 && has_br_stack) if (sort__branch_mode == -1 && has_br_stack)
sort__branch_mode = 1; sort__branch_mode = 1;
......
...@@ -6,6 +6,7 @@ ...@@ -6,6 +6,7 @@
#include "builtin.h" #include "builtin.h"
#include "util/cache.h" #include "util/cache.h"
#include "util/color.h"
#include "util/debug.h" #include "util/debug.h"
#include "util/debugfs.h" #include "util/debugfs.h"
#include "util/evlist.h" #include "util/evlist.h"
...@@ -1485,18 +1486,31 @@ static bool perf_test__matches(int curr, int argc, const char *argv[]) ...@@ -1485,18 +1486,31 @@ static bool perf_test__matches(int curr, int argc, const char *argv[])
static int __cmd_test(int argc, const char *argv[]) static int __cmd_test(int argc, const char *argv[])
{ {
int i = 0; int i = 0;
int width = 0;
while (tests[i].func) {
int len = strlen(tests[i].desc);
if (width < len)
width = len;
++i;
}
i = 0;
while (tests[i].func) { while (tests[i].func) {
int curr = i++, err; int curr = i++, err;
if (!perf_test__matches(curr, argc, argv)) if (!perf_test__matches(curr, argc, argv))
continue; continue;
pr_info("%2d: %s:", i, tests[curr].desc); pr_info("%2d: %-*s:", i, width, tests[curr].desc);
pr_debug("\n--- start ---\n"); pr_debug("\n--- start ---\n");
err = tests[curr].func(); err = tests[curr].func();
pr_debug("---- end ----\n%s:", tests[curr].desc); pr_debug("---- end ----\n%s:", tests[curr].desc);
pr_info(" %s\n", err ? "FAILED!\n" : "Ok"); if (err)
color_fprintf(stderr, PERF_COLOR_RED, " FAILED!\n");
else
pr_info(" Ok\n");
} }
return 0; return 0;
......
...@@ -977,6 +977,10 @@ static void perf_top__start_counters(struct perf_top *top) ...@@ -977,6 +977,10 @@ static void perf_top__start_counters(struct perf_top *top)
ui__error("Too many events are opened.\n" ui__error("Too many events are opened.\n"
"Try again after reducing the number of events\n"); "Try again after reducing the number of events\n");
goto out_err; goto out_err;
} else if ((err == EOPNOTSUPP) && (attr->precise_ip)) {
ui__error("\'precise\' request may not be supported. "
"Try removing 'p' modifier\n");
goto out_err;
} }
ui__error("The sys_perf_event_open() syscall " ui__error("The sys_perf_event_open() syscall "
......
#include "builtin.h" #include "builtin.h"
#include "util/color.h"
#include "util/evlist.h" #include "util/evlist.h"
#include "util/machine.h"
#include "util/thread.h"
#include "util/parse-options.h" #include "util/parse-options.h"
#include "util/thread_map.h" #include "util/thread_map.h"
#include "event-parse.h" #include "event-parse.h"
...@@ -13,15 +16,18 @@ static struct syscall_fmt { ...@@ -13,15 +16,18 @@ static struct syscall_fmt {
bool errmsg; bool errmsg;
bool timeout; bool timeout;
} syscall_fmts[] = { } syscall_fmts[] = {
{ .name = "access", .errmsg = true, },
{ .name = "arch_prctl", .errmsg = true, .alias = "prctl", }, { .name = "arch_prctl", .errmsg = true, .alias = "prctl", },
{ .name = "fstat", .errmsg = true, .alias = "newfstat", }, { .name = "fstat", .errmsg = true, .alias = "newfstat", },
{ .name = "fstatat", .errmsg = true, .alias = "newfstatat", }, { .name = "fstatat", .errmsg = true, .alias = "newfstatat", },
{ .name = "futex", .errmsg = true, }, { .name = "futex", .errmsg = true, },
{ .name = "open", .errmsg = true, },
{ .name = "poll", .errmsg = true, .timeout = true, }, { .name = "poll", .errmsg = true, .timeout = true, },
{ .name = "ppoll", .errmsg = true, .timeout = true, }, { .name = "ppoll", .errmsg = true, .timeout = true, },
{ .name = "read", .errmsg = true, }, { .name = "read", .errmsg = true, },
{ .name = "recvfrom", .errmsg = true, }, { .name = "recvfrom", .errmsg = true, },
{ .name = "select", .errmsg = true, .timeout = true, }, { .name = "select", .errmsg = true, .timeout = true, },
{ .name = "socket", .errmsg = true, },
{ .name = "stat", .errmsg = true, .alias = "newstat", }, { .name = "stat", .errmsg = true, .alias = "newstat", },
}; };
...@@ -43,6 +49,50 @@ struct syscall { ...@@ -43,6 +49,50 @@ struct syscall {
struct syscall_fmt *fmt; struct syscall_fmt *fmt;
}; };
static size_t fprintf_duration(unsigned long t, FILE *fp)
{
double duration = (double)t / NSEC_PER_MSEC;
size_t printed = fprintf(fp, "(");
if (duration >= 1.0)
printed += color_fprintf(fp, PERF_COLOR_RED, "%6.3f ms", duration);
else if (duration >= 0.01)
printed += color_fprintf(fp, PERF_COLOR_YELLOW, "%6.3f ms", duration);
else
printed += color_fprintf(fp, PERF_COLOR_NORMAL, "%6.3f ms", duration);
return printed + fprintf(stdout, "): ");
}
struct thread_trace {
u64 entry_time;
u64 exit_time;
bool entry_pending;
char *entry_str;
};
static struct thread_trace *thread_trace__new(void)
{
return zalloc(sizeof(struct thread_trace));
}
static struct thread_trace *thread__trace(struct thread *thread)
{
if (thread == NULL)
goto fail;
if (thread->priv == NULL)
thread->priv = thread_trace__new();
if (thread->priv == NULL)
goto fail;
return thread->priv;
fail:
color_fprintf(stdout, PERF_COLOR_RED,
"WARNING: not enough memory, dropping samples!\n");
return NULL;
}
struct trace { struct trace {
int audit_machine; int audit_machine;
struct { struct {
...@@ -50,8 +100,24 @@ struct trace { ...@@ -50,8 +100,24 @@ struct trace {
struct syscall *table; struct syscall *table;
} syscalls; } syscalls;
struct perf_record_opts opts; struct perf_record_opts opts;
struct machine host;
u64 base_time;
bool multiple_threads;
double duration_filter;
}; };
static bool trace__filter_duration(struct trace *trace, double t)
{
return t < (trace->duration_filter * NSEC_PER_MSEC);
}
static size_t trace__fprintf_tstamp(struct trace *trace, u64 tstamp, FILE *fp)
{
double ts = (double)(tstamp - trace->base_time) / NSEC_PER_MSEC;
return fprintf(fp, "%10.3f ", ts);
}
static bool done = false; static bool done = false;
static void sig_handler(int sig __maybe_unused) static void sig_handler(int sig __maybe_unused)
...@@ -59,6 +125,68 @@ static void sig_handler(int sig __maybe_unused) ...@@ -59,6 +125,68 @@ static void sig_handler(int sig __maybe_unused)
done = true; done = true;
} }
static size_t trace__fprintf_entry_head(struct trace *trace, struct thread *thread,
u64 duration, u64 tstamp, FILE *fp)
{
size_t printed = trace__fprintf_tstamp(trace, tstamp, fp);
printed += fprintf_duration(duration, fp);
if (trace->multiple_threads)
printed += fprintf(fp, "%d ", thread->pid);
return printed;
}
static int trace__process_event(struct machine *machine, union perf_event *event)
{
int ret = 0;
switch (event->header.type) {
case PERF_RECORD_LOST:
color_fprintf(stdout, PERF_COLOR_RED,
"LOST %" PRIu64 " events!\n", event->lost.lost);
ret = machine__process_lost_event(machine, event);
default:
ret = machine__process_event(machine, event);
break;
}
return ret;
}
static int trace__tool_process(struct perf_tool *tool __maybe_unused,
union perf_event *event,
struct perf_sample *sample __maybe_unused,
struct machine *machine)
{
return trace__process_event(machine, event);
}
static int trace__symbols_init(struct trace *trace, struct perf_evlist *evlist)
{
int err = symbol__init();
if (err)
return err;
machine__init(&trace->host, "", HOST_KERNEL_ID);
machine__create_kernel_maps(&trace->host);
if (perf_target__has_task(&trace->opts.target)) {
err = perf_event__synthesize_thread_map(NULL, evlist->threads,
trace__tool_process,
&trace->host);
} else {
err = perf_event__synthesize_threads(NULL, trace__tool_process,
&trace->host);
}
if (err)
symbol__exit();
return err;
}
static int trace__read_syscall_info(struct trace *trace, int id) static int trace__read_syscall_info(struct trace *trace, int id)
{ {
char tp_name[128]; char tp_name[128];
...@@ -100,7 +228,8 @@ static int trace__read_syscall_info(struct trace *trace, int id) ...@@ -100,7 +228,8 @@ static int trace__read_syscall_info(struct trace *trace, int id)
return sc->tp_format != NULL ? 0 : -1; return sc->tp_format != NULL ? 0 : -1;
} }
static size_t syscall__fprintf_args(struct syscall *sc, unsigned long *args, FILE *fp) static size_t syscall__scnprintf_args(struct syscall *sc, char *bf, size_t size,
unsigned long *args)
{ {
int i = 0; int i = 0;
size_t printed = 0; size_t printed = 0;
...@@ -109,12 +238,15 @@ static size_t syscall__fprintf_args(struct syscall *sc, unsigned long *args, FIL ...@@ -109,12 +238,15 @@ static size_t syscall__fprintf_args(struct syscall *sc, unsigned long *args, FIL
struct format_field *field; struct format_field *field;
for (field = sc->tp_format->format.fields->next; field; field = field->next) { for (field = sc->tp_format->format.fields->next; field; field = field->next) {
printed += fprintf(fp, "%s%s: %ld", printed ? ", " : "", printed += scnprintf(bf + printed, size - printed,
"%s%s: %ld", printed ? ", " : "",
field->name, args[i++]); field->name, args[i++]);
} }
} else { } else {
while (i < 6) { while (i < 6) {
printed += fprintf(fp, "%sarg%d: %ld", printed ? ", " : "", i, args[i]); printed += scnprintf(bf + printed, size - printed,
"%sarg%d: %ld",
printed ? ", " : "", i, args[i]);
++i; ++i;
} }
} }
...@@ -146,17 +278,24 @@ static struct syscall *trace__syscall_info(struct trace *trace, ...@@ -146,17 +278,24 @@ static struct syscall *trace__syscall_info(struct trace *trace,
return &trace->syscalls.table[id]; return &trace->syscalls.table[id];
out_cant_read: out_cant_read:
printf("Problems reading syscall %d information\n", id); printf("Problems reading syscall %d", id);
if (id <= trace->syscalls.max && trace->syscalls.table[id].name != NULL)
printf("(%s)", trace->syscalls.table[id].name);
puts(" information");
return NULL; return NULL;
} }
static int trace__sys_enter(struct trace *trace, struct perf_evsel *evsel, static int trace__sys_enter(struct trace *trace, struct perf_evsel *evsel,
struct perf_sample *sample) struct perf_sample *sample)
{ {
char *msg;
void *args; void *args;
size_t printed = 0;
struct thread *thread = machine__findnew_thread(&trace->host, sample->tid);
struct syscall *sc = trace__syscall_info(trace, evsel, sample); struct syscall *sc = trace__syscall_info(trace, evsel, sample);
struct thread_trace *ttrace = thread__trace(thread);
if (sc == NULL) if (ttrace == NULL || sc == NULL)
return -1; return -1;
args = perf_evsel__rawptr(evsel, sample, "args"); args = perf_evsel__rawptr(evsel, sample, "args");
...@@ -165,8 +304,27 @@ static int trace__sys_enter(struct trace *trace, struct perf_evsel *evsel, ...@@ -165,8 +304,27 @@ static int trace__sys_enter(struct trace *trace, struct perf_evsel *evsel,
return -1; return -1;
} }
printf("%s(", sc->name); ttrace = thread->priv;
syscall__fprintf_args(sc, args, stdout);
if (ttrace->entry_str == NULL) {
ttrace->entry_str = malloc(1024);
if (!ttrace->entry_str)
return -1;
}
ttrace->entry_time = sample->time;
msg = ttrace->entry_str;
printed += scnprintf(msg + printed, 1024 - printed, "%s(", sc->name);
printed += syscall__scnprintf_args(sc, msg + printed, 1024 - printed, args);
if (!strcmp(sc->name, "exit_group") || !strcmp(sc->name, "exit")) {
if (!trace->duration_filter) {
trace__fprintf_entry_head(trace, thread, 1, sample->time, stdout);
printf("%-70s\n", ttrace->entry_str);
}
} else
ttrace->entry_pending = true;
return 0; return 0;
} }
...@@ -175,13 +333,37 @@ static int trace__sys_exit(struct trace *trace, struct perf_evsel *evsel, ...@@ -175,13 +333,37 @@ static int trace__sys_exit(struct trace *trace, struct perf_evsel *evsel,
struct perf_sample *sample) struct perf_sample *sample)
{ {
int ret; int ret;
u64 duration = 0;
struct thread *thread = machine__findnew_thread(&trace->host, sample->tid);
struct thread_trace *ttrace = thread__trace(thread);
struct syscall *sc = trace__syscall_info(trace, evsel, sample); struct syscall *sc = trace__syscall_info(trace, evsel, sample);
if (sc == NULL) if (ttrace == NULL || sc == NULL)
return -1; return -1;
ret = perf_evsel__intval(evsel, sample, "ret"); ret = perf_evsel__intval(evsel, sample, "ret");
ttrace = thread->priv;
ttrace->exit_time = sample->time;
if (ttrace->entry_time) {
duration = sample->time - ttrace->entry_time;
if (trace__filter_duration(trace, duration))
goto out;
} else if (trace->duration_filter)
goto out;
trace__fprintf_entry_head(trace, thread, duration, sample->time, stdout);
if (ttrace->entry_pending) {
printf("%-70s", ttrace->entry_str);
} else {
printf(" ... [");
color_fprintf(stdout, PERF_COLOR_YELLOW, "continued");
printf("]: %s()", sc->name);
}
if (ret < 0 && sc->fmt && sc->fmt->errmsg) { if (ret < 0 && sc->fmt && sc->fmt->errmsg) {
char bf[256]; char bf[256];
const char *emsg = strerror_r(-ret, bf, sizeof(bf)), 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,6 +376,9 @@ static int trace__sys_exit(struct trace *trace, struct perf_evsel *evsel,
printf(") = %d", ret); printf(") = %d", ret);
putchar('\n'); putchar('\n');
out:
ttrace->entry_pending = false;
return 0; return 0;
} }
...@@ -221,6 +406,12 @@ static int trace__run(struct trace *trace, int argc, const char **argv) ...@@ -221,6 +406,12 @@ static int trace__run(struct trace *trace, int argc, const char **argv)
goto out_delete_evlist; goto out_delete_evlist;
} }
err = trace__symbols_init(trace, evlist);
if (err < 0) {
printf("Problems initializing symbol libraries!\n");
goto out_delete_evlist;
}
perf_evlist__config_attrs(evlist, &trace->opts); perf_evlist__config_attrs(evlist, &trace->opts);
signal(SIGCHLD, sig_handler); signal(SIGCHLD, sig_handler);
...@@ -251,6 +442,7 @@ static int trace__run(struct trace *trace, int argc, const char **argv) ...@@ -251,6 +442,7 @@ static int trace__run(struct trace *trace, int argc, const char **argv)
if (forks) if (forks)
perf_evlist__start_workload(evlist); perf_evlist__start_workload(evlist);
trace->multiple_threads = evlist->threads->map[0] == -1 || evlist->threads->nr > 1;
again: again:
before = nr_events; before = nr_events;
...@@ -264,32 +456,32 @@ static int trace__run(struct trace *trace, int argc, const char **argv) ...@@ -264,32 +456,32 @@ static int trace__run(struct trace *trace, int argc, const char **argv)
++nr_events; ++nr_events;
switch (type) {
case PERF_RECORD_SAMPLE:
break;
case PERF_RECORD_LOST:
printf("LOST %" PRIu64 " events!\n", event->lost.lost);
continue;
default:
printf("Unexpected %s event, skipping...\n",
perf_event__name(type));
continue;
}
err = perf_evlist__parse_sample(evlist, event, &sample); err = perf_evlist__parse_sample(evlist, event, &sample);
if (err) { if (err) {
printf("Can't parse sample, err = %d, skipping...\n", err); printf("Can't parse sample, err = %d, skipping...\n", err);
continue; continue;
} }
if (trace->base_time == 0)
trace->base_time = sample.time;
if (type != PERF_RECORD_SAMPLE) {
trace__process_event(&trace->host, event);
continue;
}
evsel = perf_evlist__id2evsel(evlist, sample.id); evsel = perf_evlist__id2evsel(evlist, sample.id);
if (evsel == NULL) { if (evsel == NULL) {
printf("Unknown tp ID %" PRIu64 ", skipping...\n", sample.id); printf("Unknown tp ID %" PRIu64 ", skipping...\n", sample.id);
continue; continue;
} }
if (evlist->threads->map[0] == -1 || evlist->threads->nr > 1) if (sample.raw_data == NULL) {
printf("%d ", sample.tid); printf("%s sample with no payload for tid: %d, cpu %d, raw_size=%d, skipping...\n",
perf_evsel__name(evsel), sample.tid,
sample.cpu, sample.raw_size);
continue;
}
if (sample.raw_data == NULL) { if (sample.raw_data == NULL) {
printf("%s sample with no payload for tid: %d, cpu %d, raw_size=%d, skipping...\n", printf("%s sample with no payload for tid: %d, cpu %d, raw_size=%d, skipping...\n",
...@@ -321,6 +513,15 @@ static int trace__run(struct trace *trace, int argc, const char **argv) ...@@ -321,6 +513,15 @@ static int trace__run(struct trace *trace, int argc, const char **argv)
return err; return err;
} }
static int trace__set_duration(const struct option *opt, const char *str,
int unset __maybe_unused)
{
struct trace *trace = opt->value;
trace->duration_filter = atof(str);
return 0;
}
int cmd_trace(int argc, const char **argv, const char *prefix __maybe_unused) int cmd_trace(int argc, const char **argv, const char *prefix __maybe_unused)
{ {
const char * const trace_usage[] = { const char * const trace_usage[] = {
...@@ -359,6 +560,9 @@ int cmd_trace(int argc, const char **argv, const char *prefix __maybe_unused) ...@@ -359,6 +560,9 @@ int cmd_trace(int argc, const char **argv, const char *prefix __maybe_unused)
"number of mmap data pages"), "number of mmap data pages"),
OPT_STRING(0, "uid", &trace.opts.target.uid_str, "user", OPT_STRING(0, "uid", &trace.opts.target.uid_str, "user",
"user to profile"), "user to profile"),
OPT_CALLBACK(0, "duration", &trace, "float",
"show only events with duration > N.M ms",
trace__set_duration),
OPT_END() OPT_END()
}; };
int err; int err;
......
...@@ -121,7 +121,10 @@ define SOURCE_PYTHON_VERSION ...@@ -121,7 +121,10 @@ define SOURCE_PYTHON_VERSION
#if PY_VERSION_HEX >= 0x03000000 #if PY_VERSION_HEX >= 0x03000000
#error #error
#endif #endif
int main(void){} int main(void)
{
return 0;
}
endef endef
define SOURCE_PYTHON_EMBED define SOURCE_PYTHON_EMBED
#include <Python.h> #include <Python.h>
......
...@@ -180,9 +180,16 @@ _gea_warn = $(warning The path '$(1)' is not executable.) ...@@ -180,9 +180,16 @@ _gea_warn = $(warning The path '$(1)' is not executable.)
_gea_err = $(if $(1),$(error Please set '$(1)' appropriately)) _gea_err = $(if $(1),$(error Please set '$(1)' appropriately))
# try-cc # try-cc
# Usage: option = $(call try-cc, source-to-build, cc-options) # Usage: option = $(call try-cc, source-to-build, cc-options, msg)
ifndef V
TRY_CC_OUTPUT= > /dev/null 2>&1
else
TRY_CC_MSG=echo "CHK $(3)" 1>&2;
endif
try-cc = $(shell sh -c \ try-cc = $(shell sh -c \
'TMP="$(OUTPUT)$(TMPOUT).$$$$"; \ 'TMP="$(OUTPUT)$(TMPOUT).$$$$"; \
$(TRY_CC_MSG) \
echo "$(1)" | \ echo "$(1)" | \
$(CC) -x c - $(2) -o "$$TMP" > /dev/null 2>&1 && echo y; \ $(CC) -x c - $(2) -o "$$TMP" $(TRY_CC_OUTPUT) && echo y; \
rm -f "$$TMP"') rm -f "$$TMP"')
...@@ -154,6 +154,5 @@ static inline int symbol__tui_annotate(struct symbol *sym __maybe_unused, ...@@ -154,6 +154,5 @@ static inline int symbol__tui_annotate(struct symbol *sym __maybe_unused,
#endif #endif
extern const char *disassembler_style; extern const char *disassembler_style;
extern const char *objdump_path;
#endif /* __PERF_ANNOTATE_H */ #endif /* __PERF_ANNOTATE_H */
...@@ -1081,7 +1081,7 @@ void print_events(const char *event_glob, bool name_only) ...@@ -1081,7 +1081,7 @@ void print_events(const char *event_glob, bool name_only)
printf(" %-50s [%s]\n", printf(" %-50s [%s]\n",
"cpu/t1=v1[,t2=v2,t3 ...]/modifier", "cpu/t1=v1[,t2=v2,t3 ...]/modifier",
event_type_descriptors[PERF_TYPE_RAW]); event_type_descriptors[PERF_TYPE_RAW]);
printf(" (see 'perf list --help' on how to encode it)\n"); printf(" (see 'man perf-list' on how to encode it)\n");
printf("\n"); printf("\n");
printf(" %-50s [%s]\n", printf(" %-50s [%s]\n",
......
...@@ -44,6 +44,7 @@ int rblist__add_node(struct rblist *rblist, const void *new_entry) ...@@ -44,6 +44,7 @@ int rblist__add_node(struct rblist *rblist, const void *new_entry)
void rblist__remove_node(struct rblist *rblist, struct rb_node *rb_node) void rblist__remove_node(struct rblist *rblist, struct rb_node *rb_node)
{ {
rb_erase(rb_node, &rblist->entries); rb_erase(rb_node, &rblist->entries);
--rblist->nr_entries;
rblist->node_delete(rblist, rb_node); rblist->node_delete(rblist, rb_node);
} }
...@@ -87,8 +88,7 @@ void rblist__delete(struct rblist *rblist) ...@@ -87,8 +88,7 @@ void rblist__delete(struct rblist *rblist)
while (next) { while (next) {
pos = next; pos = next;
next = rb_next(pos); next = rb_next(pos);
rb_erase(pos, &rblist->entries); rblist__remove_node(rblist, pos);
rblist->node_delete(rblist, pos);
} }
free(rblist); free(rblist);
} }
......
...@@ -198,6 +198,10 @@ static inline int has_extension(const char *filename, const char *ext) ...@@ -198,6 +198,10 @@ static inline int has_extension(const char *filename, const char *ext)
#undef tolower #undef tolower
#undef toupper #undef toupper
#ifndef NSEC_PER_MSEC
#define NSEC_PER_MSEC 1000000L
#endif
extern unsigned char sane_ctype[256]; extern unsigned char sane_ctype[256];
#define GIT_SPACE 0x01 #define GIT_SPACE 0x01
#define GIT_DIGIT 0x02 #define GIT_DIGIT 0x02
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment