Skip to contentSkip to conversation

perf probe: Check if dwarf_getlocations() is available

tip:perf/core tip-bot for Arnaldo Carvalho de Melo 1 participant 1 message Apr 13, 2016 perf events

lore
Share & tools
lore
#0 lore raw
Commit-ID:  bd0419e2a5a9fd9396cb7dc69044f961f52e19f0
Gitweb:     http://git.kernel.org/tip/bd0419e2a5a9fd9396cb7dc69044f961f52e19f0
Author:     Arnaldo Carvalho de Melo <[email protected]>
AuthorDate: Tue, 5 Apr 2016 11:33:41 -0300
Committer:  Arnaldo Carvalho de Melo <[email protected]>
CommitDate: Wed, 6 Apr 2016 10:44:28 -0300

perf probe: Check if dwarf_getlocations() is available

If not, tell the user that:

config/Makefile:273: Old libdw.h, finding variables at given 'perf probe' point will not work, install elfutils-devel/libdw-dev >= 0.157

And return -ENOTSUPP in die_get_var_range(), failing features that need it, like the one pointed out above.

This fixes the build on older systems, such as Ubuntu 12.04.5.

---
 tools/build/Makefile.feature                  |  2 ++
 tools/build/feature/Makefile                  |  4 ++++
 tools/build/feature/test-all.c                |  5 +++++
 tools/build/feature/test-dwarf_getlocations.c | 12 ++++++++++++
 tools/perf/config/Makefile                    |  6 ++++++
 tools/perf/util/dwarf-aux.c                   |  9 +++++++++
 6 files changed, 38 insertions(+)
tools/build/Makefile.feature +2 -0
index 6b77072..9f87861 100644
@@ -30,6 +30,7 @@ endef
 FEATURE_TESTS_BASIC :=			\
 	backtrace			\
 	dwarf				\
+	dwarf_getlocations		\
 	fortify-source			\
 	sync-compare-and-swap		\
 	glibc				\
@@ -78,6 +79,7 @@ endif
 
 FEATURE_DISPLAY ?=			\
 	dwarf				\
+	dwarf_getlocations		\
 	glibc				\
 	gtk2				\
 	libaudit			\
tools/build/feature/Makefile +4 -0
index c5f4c41..4ae94db 100644
@@ -3,6 +3,7 @@ FILES=					\
 	test-backtrace.bin		\
 	test-bionic.bin			\
 	test-dwarf.bin			\
+	test-dwarf_getlocations.bin	\
 	test-fortify-source.bin		\
 	test-sync-compare-and-swap.bin	\
 	test-glibc.bin			\
@@ -82,6 +83,9 @@ endif
 $(OUTPUT)test-dwarf.bin:
 	$(BUILD) $(DWARFLIBS)
 
+$(OUTPUT)test-dwarf_getlocations.bin:
+	$(BUILD) $(DWARFLIBS)
+
 $(OUTPUT)test-libelf-mmap.bin:
 	$(BUILD) -lelf
 
tools/build/feature/test-all.c +5 -0
index e499a36..a282e8c 100644
@@ -41,6 +41,10 @@
 # include "test-dwarf.c"
 #undef main
 
+#define main main_test_dwarf_getlocations
+# include "test-dwarf_getlocations.c"
+#undef main
+
 #define main main_test_libelf_getphdrnum
 # include "test-libelf-getphdrnum.c"
 #undef main
@@ -143,6 +147,7 @@ int main(int argc, char *argv[])
 	main_test_libelf_mmap();
 	main_test_glibc();
 	main_test_dwarf();
+	main_test_dwarf_getlocations();
 	main_test_libelf_getphdrnum();
 	main_test_libunwind();
 	main_test_libaudit();
tools/build/feature/test-dwarf_getlocations.c new file +12 -0
new file mode 100644
index 0000000..7016269
@@ -0,0 +1,12 @@
+#include <stdlib.h>
+#include <elfutils/libdw.h>
+
+int main(void)
+{
+	Dwarf_Addr base, start, end;
+	Dwarf_Attribute attr;
+	Dwarf_Op *op;
+        size_t nops;
+	ptrdiff_t offset = 0;
+        return (int)dwarf_getlocations(&attr, offset, &base, &start, &end, &op, &nops);
+}
tools/perf/config/Makefile +6 -0
index f7d7f5a..6f8f643 100644
@@ -268,6 +268,12 @@ else
     ifneq ($(feature-dwarf), 1)
       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
+    else
+      ifneq ($(feature-dwarf_getlocations), 1)
+        msg := $(warning Old libdw.h, finding variables at given 'perf probe' point will not work, install elfutils-devel/libdw-dev >= 0.157);
+      else
+        CFLAGS += -DHAVE_DWARF_GETLOCATIONS
+      endif # dwarf_getlocations
     endif # Dwarf support
   endif # libelf support
 endif # NO_LIBELF
tools/perf/util/dwarf-aux.c +9 -0
index 577e600..aea189b 100644
@@ -959,6 +959,7 @@ int die_get_varname(Dwarf_Die *vr_die, struct strbuf *buf)
 	return 0;
 }
 
+#ifdef HAVE_DWARF_GETLOCATIONS
 /**
  * die_get_var_innermost_scope - Get innermost scope range of given variable DIE
  * @sp_die: a subprogram DIE
@@ -1080,3 +1081,11 @@ int die_get_var_range(Dwarf_Die *sp_die, Dwarf_Die *vr_die, struct strbuf *buf)
 
 	return ret;
 }
+#else
+int die_get_var_range(Dwarf_Die *sp_die __maybe_unused,
+		      Dwarf_Die *vr_die __maybe_unused,
+		      struct strbuf *buf __maybe_unused)
+{
+	return -ENOTSUP;
+}
+#endif