All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 0/8] Add support for remote unwind
@ 2016-05-06  8:59 He Kuang
  2016-05-06  8:59 ` [PATCH 1/8] perf tools: Omit DWARF judgement when recording dwarf callchain He Kuang
                   ` (8 more replies)
  0 siblings, 9 replies; 22+ messages in thread
From: He Kuang @ 2016-05-06  8:59 UTC (permalink / raw)
  To: peterz, mingo, acme, alexander.shishkin, jolsa, wangnan0,
	hekuang, jpoimboe, ak, eranian, namhyung, adrian.hunter, sukadev,
	masami.hiramatsu.pt, tumanova, kan.liang, penberg, dsahern
  Cc: linux-kernel

Currently, perf script uses host unwind methods to parse perf.data
callchain info regardless of the target architecture. So we get wrong
result and no promotion when do remote unwind on other
platforms/machines.

This patch set adds build tests for the supported platforms for remote
unwinding, and checks the map elf info for each thread, use remote
unwind methods instead.

Only x86 and aarch64 is added in this patch set to show the work flow,
other platforms can be added easily.

We can see the right result for unwind infos on different machines,
for example: we record perf.data on i686 qemu with '-g' option and
parse it on x86_64 machine.

before this patchset:

  hello  1071 [000]   417.567832: probe:sys_close: (c1169d60)
                  c1169d61 sys_close ([kernel.kallsyms])
                  c189c0d7 sysenter_past_esp ([kernel.kallsyms])
                  b77c8ba9 [unknown] ([vdso32])
  
after:

  hello  1071 [000]   417.567832: probe:sys_close: (c1169d60)
                  c1169d61 sys_close ([kernel.kallsyms])
                  c189c0d7 sysenter_past_esp ([kernel.kallsyms])
                  b77c8ba9 [unknown] ([vdso32])
                  b76e51cc close (/lib/libc-2.22.so)
                   804842e fib (/tmp/hello)
                   804849d main (/tmp/hello)
                  b762546e __libc_start_main (/lib/libc-2.22.so)
                   8048341 _start (/tmp/hello)

Thanks, discussion welcomed.

He Kuang (8):
  perf tools: Omit DWARF judgement when recording dwarf callchain
  perf script: Add options for custom vdso name
  perf build: Add build-test for libunwind cross-platforms support
  perf build: Add build-test for debug-frame on arm/arm64
  perf tools: Promote proper messages for cross-platform unwind
  perf callchain: Add support for cross-platform unwind
  perf callchain: Support x86 target platform
  perf callchain: Support aarch64 cross-platform

 tools/build/Makefile.feature                       | 11 +++-
 tools/build/feature/Makefile                       | 26 +++++++-
 tools/build/feature/test-libunwind-aarch64.c       | 26 ++++++++
 tools/build/feature/test-libunwind-arm.c           | 27 +++++++++
 .../feature/test-libunwind-debug-frame-aarch64.c   | 16 +++++
 .../build/feature/test-libunwind-debug-frame-arm.c | 16 +++++
 tools/build/feature/test-libunwind-debug-frame.c   | 16 -----
 tools/build/feature/test-libunwind-x86.c           | 27 +++++++++
 tools/build/feature/test-libunwind-x86_64.c        | 27 +++++++++
 .../arch/arm64/include/libunwind/libunwind-arch.h  | 18 ++++++
 tools/perf/arch/arm64/util/unwind-libunwind.c      |  5 +-
 .../arch/x86/include/libunwind/libunwind-arch.h    | 18 ++++++
 tools/perf/arch/x86/util/unwind-libunwind.c        | 42 +++++++++++++
 tools/perf/builtin-script.c                        |  2 +
 tools/perf/config/Makefile                         | 35 ++++++++++-
 tools/perf/util/Build                              | 13 +++-
 tools/perf/util/dso.c                              |  7 +++
 tools/perf/util/dso.h                              |  1 +
 tools/perf/util/symbol-elf.c                       | 16 +++++
 tools/perf/util/symbol.c                           | 50 ++++++++++++++++
 tools/perf/util/symbol.h                           |  3 +
 tools/perf/util/thread.c                           | 70 ++++++++++++++++++++--
 tools/perf/util/thread.h                           | 14 ++++-
 tools/perf/util/unwind-libunwind.c                 | 50 +++++++++++++---
 tools/perf/util/unwind-libunwind_common.c          | 60 +++++++++++++++++++
 tools/perf/util/unwind.h                           | 30 ++++++++++
 tools/perf/util/util.c                             |  2 -
 27 files changed, 589 insertions(+), 39 deletions(-)
 create mode 100644 tools/build/feature/test-libunwind-aarch64.c
 create mode 100644 tools/build/feature/test-libunwind-arm.c
 create mode 100644 tools/build/feature/test-libunwind-debug-frame-aarch64.c
 create mode 100644 tools/build/feature/test-libunwind-debug-frame-arm.c
 delete mode 100644 tools/build/feature/test-libunwind-debug-frame.c
 create mode 100644 tools/build/feature/test-libunwind-x86.c
 create mode 100644 tools/build/feature/test-libunwind-x86_64.c
 create mode 100644 tools/perf/arch/arm64/include/libunwind/libunwind-arch.h
 create mode 100644 tools/perf/arch/x86/include/libunwind/libunwind-arch.h
 create mode 100644 tools/perf/util/unwind-libunwind_common.c

-- 
1.8.5.2

^ permalink raw reply	[flat|nested] 22+ messages in thread

* [PATCH 1/8] perf tools: Omit DWARF judgement when recording dwarf callchain
  2016-05-06  8:59 [PATCH 0/8] Add support for remote unwind He Kuang
@ 2016-05-06  8:59 ` He Kuang
  2016-05-06 11:47   ` Arnaldo Carvalho de Melo
                     ` (2 more replies)
  2016-05-06  8:59 ` [PATCH 2/8] perf script: Add options for custom vdso name He Kuang
                   ` (7 subsequent siblings)
  8 siblings, 3 replies; 22+ messages in thread
From: He Kuang @ 2016-05-06  8:59 UTC (permalink / raw)
  To: peterz, mingo, acme, alexander.shishkin, jolsa, wangnan0,
	hekuang, jpoimboe, ak, eranian, namhyung, adrian.hunter, sukadev,
	masami.hiramatsu.pt, tumanova, kan.liang, penberg, dsahern
  Cc: linux-kernel

There's no need for dwarf support when perf recording with callchain.

Signed-off-by: He Kuang <hekuang@huawei.com>
---
 tools/perf/util/util.c | 2 --
 1 file changed, 2 deletions(-)

diff --git a/tools/perf/util/util.c b/tools/perf/util/util.c
index b7766c5..e5ebfd4 100644
--- a/tools/perf/util/util.c
+++ b/tools/perf/util/util.c
@@ -471,7 +471,6 @@ int parse_callchain_record(const char *arg, struct callchain_param *param)
 				       "needed for --call-graph fp\n");
 			break;
 
-#ifdef HAVE_DWARF_UNWIND_SUPPORT
 		/* Dwarf style */
 		} else if (!strncmp(name, "dwarf", sizeof("dwarf"))) {
 			const unsigned long default_stack_dump_size = 8192;
@@ -487,7 +486,6 @@ int parse_callchain_record(const char *arg, struct callchain_param *param)
 				ret = get_stack_size(tok, &size);
 				param->dump_size = size;
 			}
-#endif /* HAVE_DWARF_UNWIND_SUPPORT */
 		} else if (!strncmp(name, "lbr", sizeof("lbr"))) {
 			if (!strtok_r(NULL, ",", &saveptr)) {
 				param->record_mode = CALLCHAIN_LBR;
-- 
1.8.5.2

^ permalink raw reply related	[flat|nested] 22+ messages in thread

* [PATCH 2/8] perf script: Add options for custom vdso name
  2016-05-06  8:59 [PATCH 0/8] Add support for remote unwind He Kuang
  2016-05-06  8:59 ` [PATCH 1/8] perf tools: Omit DWARF judgement when recording dwarf callchain He Kuang
@ 2016-05-06  8:59 ` He Kuang
  2016-05-06 11:49   ` Arnaldo Carvalho de Melo
  2016-05-07 18:14   ` Jiri Olsa
  2016-05-06  8:59 ` [PATCH 3/8] perf build: Add build-test for libunwind cross-platforms support He Kuang
                   ` (6 subsequent siblings)
  8 siblings, 2 replies; 22+ messages in thread
From: He Kuang @ 2016-05-06  8:59 UTC (permalink / raw)
  To: peterz, mingo, acme, alexander.shishkin, jolsa, wangnan0,
	hekuang, jpoimboe, ak, eranian, namhyung, adrian.hunter, sukadev,
	masami.hiramatsu.pt, tumanova, kan.liang, penberg, dsahern
  Cc: linux-kernel

When unwinding callchain on different machine, vdso info should be
provided so the unwind process won't be interrupted if address fell
into vdso region.

Signed-off-by: He Kuang <hekuang@huawei.com>
---
 tools/perf/builtin-script.c | 2 ++
 tools/perf/util/dso.c       | 7 +++++++
 tools/perf/util/dso.h       | 1 +
 tools/perf/util/symbol.c    | 1 +
 tools/perf/util/symbol.h    | 1 +
 5 files changed, 12 insertions(+)

diff --git a/tools/perf/builtin-script.c b/tools/perf/builtin-script.c
index 8f6ab2a..c88b547 100644
--- a/tools/perf/builtin-script.c
+++ b/tools/perf/builtin-script.c
@@ -2001,6 +2001,8 @@ int cmd_script(int argc, const char **argv, const char *prefix __maybe_unused)
 		   "file", "vmlinux pathname"),
 	OPT_STRING(0, "kallsyms", &symbol_conf.kallsyms_name,
 		   "file", "kallsyms pathname"),
+	OPT_STRING(0, "vdso", &symbol_conf.vdso_name,
+		   "file", "vdso pathname"),
 	OPT_BOOLEAN('G', "hide-call-graph", &no_callchain,
 		    "When printing symbols do not display call chain"),
 	OPT_STRING(0, "symfs", &symbol_conf.symfs, "directory",
diff --git a/tools/perf/util/dso.c b/tools/perf/util/dso.c
index 8e639543..344db10 100644
--- a/tools/perf/util/dso.c
+++ b/tools/perf/util/dso.c
@@ -21,6 +21,7 @@ char dso__symtab_origin(const struct dso *dso)
 		[DSO_BINARY_TYPE__OPENEMBEDDED_DEBUGINFO]	= 'o',
 		[DSO_BINARY_TYPE__BUILDID_DEBUGINFO]		= 'b',
 		[DSO_BINARY_TYPE__SYSTEM_PATH_DSO]		= 'd',
+		[DSO_BINARY_TYPE__SYSTEM_PATH_DSO_CUSTOM]	= 'r',
 		[DSO_BINARY_TYPE__SYSTEM_PATH_KMODULE]		= 'K',
 		[DSO_BINARY_TYPE__SYSTEM_PATH_KMODULE_COMP]	= 'm',
 		[DSO_BINARY_TYPE__GUEST_KALLSYMS]		= 'g',
@@ -113,6 +114,11 @@ int dso__read_binary_type_filename(const struct dso *dso,
 			 build_id_hex, build_id_hex + 2);
 		break;
 
+	case DSO_BINARY_TYPE__SYSTEM_PATH_DSO_CUSTOM:
+	{
+		snprintf(filename, size, "%s", symbol_conf.vdso_name);
+		break;
+	}
 	case DSO_BINARY_TYPE__VMLINUX:
 	case DSO_BINARY_TYPE__GUEST_VMLINUX:
 	case DSO_BINARY_TYPE__SYSTEM_PATH_DSO:
@@ -487,6 +493,7 @@ static void try_to_open_dso(struct dso *dso, struct machine *machine)
 	enum dso_binary_type binary_type_data[] = {
 		DSO_BINARY_TYPE__BUILD_ID_CACHE,
 		DSO_BINARY_TYPE__SYSTEM_PATH_DSO,
+		DSO_BINARY_TYPE__SYSTEM_PATH_DSO_CUSTOM,
 		DSO_BINARY_TYPE__NOT_FOUND,
 	};
 	int i = 0;
diff --git a/tools/perf/util/dso.h b/tools/perf/util/dso.h
index 0953280..f55ce5b 100644
--- a/tools/perf/util/dso.h
+++ b/tools/perf/util/dso.h
@@ -23,6 +23,7 @@ enum dso_binary_type {
 	DSO_BINARY_TYPE__UBUNTU_DEBUGINFO,
 	DSO_BINARY_TYPE__BUILDID_DEBUGINFO,
 	DSO_BINARY_TYPE__SYSTEM_PATH_DSO,
+	DSO_BINARY_TYPE__SYSTEM_PATH_DSO_CUSTOM,
 	DSO_BINARY_TYPE__GUEST_KMODULE,
 	DSO_BINARY_TYPE__GUEST_KMODULE_COMP,
 	DSO_BINARY_TYPE__SYSTEM_PATH_KMODULE,
diff --git a/tools/perf/util/symbol.c b/tools/perf/util/symbol.c
index e7588dc..93f348f 100644
--- a/tools/perf/util/symbol.c
+++ b/tools/perf/util/symbol.c
@@ -1359,6 +1359,7 @@ static bool dso__is_compatible_symtab_type(struct dso *dso, bool kmod,
 	case DSO_BINARY_TYPE__JAVA_JIT:
 	case DSO_BINARY_TYPE__DEBUGLINK:
 	case DSO_BINARY_TYPE__SYSTEM_PATH_DSO:
+	case DSO_BINARY_TYPE__SYSTEM_PATH_DSO_CUSTOM:
 	case DSO_BINARY_TYPE__FEDORA_DEBUGINFO:
 	case DSO_BINARY_TYPE__UBUNTU_DEBUGINFO:
 	case DSO_BINARY_TYPE__BUILDID_DEBUGINFO:
diff --git a/tools/perf/util/symbol.h b/tools/perf/util/symbol.h
index c8b7544..4e6910e 100644
--- a/tools/perf/util/symbol.h
+++ b/tools/perf/util/symbol.h
@@ -114,6 +114,7 @@ struct symbol_conf {
 			report_hierarchy;
 	const char	*vmlinux_name,
 			*kallsyms_name,
+			*vdso_name,
 			*source_prefix,
 			*field_sep;
 	const char	*default_guest_vmlinux_name,
-- 
1.8.5.2

^ permalink raw reply related	[flat|nested] 22+ messages in thread

* [PATCH 3/8] perf build: Add build-test for libunwind cross-platforms support
  2016-05-06  8:59 [PATCH 0/8] Add support for remote unwind He Kuang
  2016-05-06  8:59 ` [PATCH 1/8] perf tools: Omit DWARF judgement when recording dwarf callchain He Kuang
  2016-05-06  8:59 ` [PATCH 2/8] perf script: Add options for custom vdso name He Kuang
@ 2016-05-06  8:59 ` He Kuang
  2016-05-07 18:20   ` Jiri Olsa
  2016-05-06  8:59 ` [PATCH 4/8] perf build: Add build-test for debug-frame on arm/arm64 He Kuang
                   ` (5 subsequent siblings)
  8 siblings, 1 reply; 22+ messages in thread
From: He Kuang @ 2016-05-06  8:59 UTC (permalink / raw)
  To: peterz, mingo, acme, alexander.shishkin, jolsa, wangnan0,
	hekuang, jpoimboe, ak, eranian, namhyung, adrian.hunter, sukadev,
	masami.hiramatsu.pt, tumanova, kan.liang, penberg, dsahern
  Cc: linux-kernel

Currently only test for local libunwind. We should check all supported
platforms so we can use them to parse perf.data with callchain info on
different machines.

Signed-off-by: He Kuang <hekuang@huawei.com>
---
 tools/build/Makefile.feature                 |  8 ++++++++
 tools/build/feature/Makefile                 | 16 ++++++++++++++++
 tools/build/feature/test-libunwind-aarch64.c | 26 ++++++++++++++++++++++++++
 tools/build/feature/test-libunwind-arm.c     | 27 +++++++++++++++++++++++++++
 tools/build/feature/test-libunwind-x86.c     | 27 +++++++++++++++++++++++++++
 tools/build/feature/test-libunwind-x86_64.c  | 27 +++++++++++++++++++++++++++
 6 files changed, 131 insertions(+)
 create mode 100644 tools/build/feature/test-libunwind-aarch64.c
 create mode 100644 tools/build/feature/test-libunwind-arm.c
 create mode 100644 tools/build/feature/test-libunwind-x86.c
 create mode 100644 tools/build/feature/test-libunwind-x86_64.c

diff --git a/tools/build/Makefile.feature b/tools/build/Makefile.feature
index 9f87861..139e99c 100644
--- a/tools/build/Makefile.feature
+++ b/tools/build/Makefile.feature
@@ -49,6 +49,10 @@ FEATURE_TESTS_BASIC :=			\
 	libslang			\
 	libcrypto			\
 	libunwind			\
+	libunwind-x86			\
+	libunwind-x86_64		\
+	libunwind-arm			\
+	libunwind-aarch64		\
 	pthread-attr-setaffinity-np	\
 	stackprotector-all		\
 	timerfd				\
@@ -92,6 +96,10 @@ FEATURE_DISPLAY ?=			\
 	libslang			\
 	libcrypto			\
 	libunwind			\
+	libunwind-x86			\
+	libunwind-x86_64		\
+	libunwind-arm			\
+	libunwind-aarch64		\
 	libdw-dwarf-unwind		\
 	zlib				\
 	lzma				\
diff --git a/tools/build/feature/Makefile b/tools/build/feature/Makefile
index 4ae94db..f4fe3bc 100644
--- a/tools/build/feature/Makefile
+++ b/tools/build/feature/Makefile
@@ -27,6 +27,10 @@ FILES=					\
 	test-libcrypto.bin		\
 	test-libunwind.bin		\
 	test-libunwind-debug-frame.bin	\
+	test-libunwind-x86.bin		\
+	test-libunwind-x86_64.bin	\
+	test-libunwind-arm.bin		\
+	test-libunwind-aarch64.bin	\
 	test-pthread-attr-setaffinity-np.bin	\
 	test-stackprotector-all.bin	\
 	test-timerfd.bin		\
@@ -103,6 +107,18 @@ $(OUTPUT)test-libunwind.bin:
 
 $(OUTPUT)test-libunwind-debug-frame.bin:
 	$(BUILD) -lelf
+$(OUTPUT)test-libunwind-x86.bin:
+	$(BUILD) -lelf -lunwind-x86
+
+$(OUTPUT)test-libunwind-x86_64.bin:
+	$(BUILD) -lelf -lunwind-x86_64
+
+$(OUTPUT)test-libunwind-arm.bin:
+	$(BUILD) -lelf -lunwind-arm
+
+$(OUTPUT)test-libunwind-aarch64.bin:
+	$(BUILD) -lelf -lunwind-aarch64
+
 
 $(OUTPUT)test-libaudit.bin:
 	$(BUILD) -laudit
diff --git a/tools/build/feature/test-libunwind-aarch64.c b/tools/build/feature/test-libunwind-aarch64.c
new file mode 100644
index 0000000..fc03fb6
--- /dev/null
+++ b/tools/build/feature/test-libunwind-aarch64.c
@@ -0,0 +1,26 @@
+#include <libunwind-aarch64.h>
+#include <stdlib.h>
+
+extern int UNW_OBJ(dwarf_search_unwind_table) (unw_addr_space_t as,
+					       unw_word_t ip,
+					       unw_dyn_info_t *di,
+					       unw_proc_info_t *pi,
+					       int need_unwind_info, void *arg);
+
+#define dwarf_search_unwind_table UNW_OBJ(dwarf_search_unwind_table)
+
+static unw_accessors_t accessors;
+
+int main(void)
+{
+	unw_addr_space_t addr_space;
+
+	addr_space = unw_create_addr_space(&accessors, 0);
+	if (addr_space)
+		return 0;
+
+	unw_init_remote(NULL, addr_space, NULL);
+	dwarf_search_unwind_table(addr_space, 0, NULL, NULL, 0, NULL);
+
+	return 0;
+}
diff --git a/tools/build/feature/test-libunwind-arm.c b/tools/build/feature/test-libunwind-arm.c
new file mode 100644
index 0000000..632d95e
--- /dev/null
+++ b/tools/build/feature/test-libunwind-arm.c
@@ -0,0 +1,27 @@
+#include <libunwind-arm.h>
+#include <stdlib.h>
+
+extern int UNW_OBJ(dwarf_search_unwind_table) (unw_addr_space_t as,
+					       unw_word_t ip,
+					       unw_dyn_info_t *di,
+					       unw_proc_info_t *pi,
+					       int need_unwind_info, void *arg);
+
+
+#define dwarf_search_unwind_table UNW_OBJ(dwarf_search_unwind_table)
+
+static unw_accessors_t accessors;
+
+int main(void)
+{
+	unw_addr_space_t addr_space;
+
+	addr_space = unw_create_addr_space(&accessors, 0);
+	if (addr_space)
+		return 0;
+
+	unw_init_remote(NULL, addr_space, NULL);
+	dwarf_search_unwind_table(addr_space, 0, NULL, NULL, 0, NULL);
+
+	return 0;
+}
diff --git a/tools/build/feature/test-libunwind-x86.c b/tools/build/feature/test-libunwind-x86.c
new file mode 100644
index 0000000..3561edc
--- /dev/null
+++ b/tools/build/feature/test-libunwind-x86.c
@@ -0,0 +1,27 @@
+#include <libunwind-x86.h>
+#include <stdlib.h>
+
+extern int UNW_OBJ(dwarf_search_unwind_table) (unw_addr_space_t as,
+					       unw_word_t ip,
+					       unw_dyn_info_t *di,
+					       unw_proc_info_t *pi,
+					       int need_unwind_info, void *arg);
+
+
+#define dwarf_search_unwind_table UNW_OBJ(dwarf_search_unwind_table)
+
+static unw_accessors_t accessors;
+
+int main(void)
+{
+	unw_addr_space_t addr_space;
+
+	addr_space = unw_create_addr_space(&accessors, 0);
+	if (addr_space)
+		return 0;
+
+	unw_init_remote(NULL, addr_space, NULL);
+	dwarf_search_unwind_table(addr_space, 0, NULL, NULL, 0, NULL);
+
+	return 0;
+}
diff --git a/tools/build/feature/test-libunwind-x86_64.c b/tools/build/feature/test-libunwind-x86_64.c
new file mode 100644
index 0000000..5add251
--- /dev/null
+++ b/tools/build/feature/test-libunwind-x86_64.c
@@ -0,0 +1,27 @@
+#include <libunwind-x86_64.h>
+#include <stdlib.h>
+
+extern int UNW_OBJ(dwarf_search_unwind_table) (unw_addr_space_t as,
+					       unw_word_t ip,
+					       unw_dyn_info_t *di,
+					       unw_proc_info_t *pi,
+					       int need_unwind_info, void *arg);
+
+
+#define dwarf_search_unwind_table UNW_OBJ(dwarf_search_unwind_table)
+
+static unw_accessors_t accessors;
+
+int main(void)
+{
+	unw_addr_space_t addr_space;
+
+	addr_space = unw_create_addr_space(&accessors, 0);
+	if (addr_space)
+		return 0;
+
+	unw_init_remote(NULL, addr_space, NULL);
+	dwarf_search_unwind_table(addr_space, 0, NULL, NULL, 0, NULL);
+
+	return 0;
+}
-- 
1.8.5.2

^ permalink raw reply related	[flat|nested] 22+ messages in thread

* [PATCH 4/8] perf build: Add build-test for debug-frame on arm/arm64
  2016-05-06  8:59 [PATCH 0/8] Add support for remote unwind He Kuang
                   ` (2 preceding siblings ...)
  2016-05-06  8:59 ` [PATCH 3/8] perf build: Add build-test for libunwind cross-platforms support He Kuang
@ 2016-05-06  8:59 ` He Kuang
  2016-05-07 18:24   ` Jiri Olsa
  2016-05-06  8:59 ` [PATCH 5/8] perf tools: Promote proper messages for cross-platform unwind He Kuang
                   ` (4 subsequent siblings)
  8 siblings, 1 reply; 22+ messages in thread
From: He Kuang @ 2016-05-06  8:59 UTC (permalink / raw)
  To: peterz, mingo, acme, alexander.shishkin, jolsa, wangnan0,
	hekuang, jpoimboe, ak, eranian, namhyung, adrian.hunter, sukadev,
	masami.hiramatsu.pt, tumanova, kan.liang, penberg, dsahern
  Cc: linux-kernel

Debug-frame for remote platforms is not related to the host platform,
so we should test each platform separately.

Signed-off-by: He Kuang <hekuang@huawei.com>
---
 tools/build/Makefile.feature                             |  3 ++-
 tools/build/feature/Makefile                             | 10 +++++++---
 tools/build/feature/test-libunwind-debug-frame-aarch64.c | 16 ++++++++++++++++
 tools/build/feature/test-libunwind-debug-frame-arm.c     | 16 ++++++++++++++++
 tools/build/feature/test-libunwind-debug-frame.c         | 16 ----------------
 5 files changed, 41 insertions(+), 20 deletions(-)
 create mode 100644 tools/build/feature/test-libunwind-debug-frame-aarch64.c
 create mode 100644 tools/build/feature/test-libunwind-debug-frame-arm.c
 delete mode 100644 tools/build/feature/test-libunwind-debug-frame.c

diff --git a/tools/build/Makefile.feature b/tools/build/Makefile.feature
index 139e99c..87dd96b9 100644
--- a/tools/build/Makefile.feature
+++ b/tools/build/Makefile.feature
@@ -73,7 +73,8 @@ FEATURE_TESTS_EXTRA :=			\
 	libbabeltrace			\
 	liberty				\
 	liberty-z			\
-	libunwind-debug-frame
+	libunwind-debug-frame-arm	\
+	libunwind-debug-frame-aarch64
 
 FEATURE_TESTS ?= $(FEATURE_TESTS_BASIC)
 
diff --git a/tools/build/feature/Makefile b/tools/build/feature/Makefile
index f4fe3bc..38a9896 100644
--- a/tools/build/feature/Makefile
+++ b/tools/build/feature/Makefile
@@ -26,11 +26,12 @@ FILES=					\
 	test-libslang.bin		\
 	test-libcrypto.bin		\
 	test-libunwind.bin		\
-	test-libunwind-debug-frame.bin	\
 	test-libunwind-x86.bin		\
 	test-libunwind-x86_64.bin	\
 	test-libunwind-arm.bin		\
 	test-libunwind-aarch64.bin	\
+	test-libunwind-debug-frame-arm.bin	\
+	test-libunwind-debug-frame-aarch64.bin	\
 	test-pthread-attr-setaffinity-np.bin	\
 	test-stackprotector-all.bin	\
 	test-timerfd.bin		\
@@ -105,8 +106,6 @@ $(OUTPUT)test-numa_num_possible_cpus.bin:
 $(OUTPUT)test-libunwind.bin:
 	$(BUILD) -lelf
 
-$(OUTPUT)test-libunwind-debug-frame.bin:
-	$(BUILD) -lelf
 $(OUTPUT)test-libunwind-x86.bin:
 	$(BUILD) -lelf -lunwind-x86
 
@@ -119,6 +118,11 @@ $(OUTPUT)test-libunwind-arm.bin:
 $(OUTPUT)test-libunwind-aarch64.bin:
 	$(BUILD) -lelf -lunwind-aarch64
 
+$(OUTPUT)test-libunwind-debug-frame-arm.bin:
+	$(BUILD) -lelf -lunwind-arm
+
+$(OUTPUT)test-libunwind-debug-frame-aarch64.bin:
+	$(BUILD) -lelf -lunwind-aarch64
 
 $(OUTPUT)test-libaudit.bin:
 	$(BUILD) -laudit
diff --git a/tools/build/feature/test-libunwind-debug-frame-aarch64.c b/tools/build/feature/test-libunwind-debug-frame-aarch64.c
new file mode 100644
index 0000000..2284467
--- /dev/null
+++ b/tools/build/feature/test-libunwind-debug-frame-aarch64.c
@@ -0,0 +1,16 @@
+#include <libunwind-aarch64.h>
+#include <stdlib.h>
+
+extern int
+UNW_OBJ(dwarf_find_debug_frame) (int found, unw_dyn_info_t *di_debug,
+				 unw_word_t ip, unw_word_t segbase,
+				 const char *obj_name, unw_word_t start,
+				 unw_word_t end);
+
+#define dwarf_find_debug_frame UNW_OBJ(dwarf_find_debug_frame)
+
+int main(void)
+{
+	dwarf_find_debug_frame(0, NULL, 0, 0, NULL, 0, 0);
+	return 0;
+}
diff --git a/tools/build/feature/test-libunwind-debug-frame-arm.c b/tools/build/feature/test-libunwind-debug-frame-arm.c
new file mode 100644
index 0000000..f988596
--- /dev/null
+++ b/tools/build/feature/test-libunwind-debug-frame-arm.c
@@ -0,0 +1,16 @@
+#include <libunwind-arm.h>
+#include <stdlib.h>
+
+extern int
+UNW_OBJ(dwarf_find_debug_frame) (int found, unw_dyn_info_t *di_debug,
+				 unw_word_t ip, unw_word_t segbase,
+				 const char *obj_name, unw_word_t start,
+				 unw_word_t end);
+
+#define dwarf_find_debug_frame UNW_OBJ(dwarf_find_debug_frame)
+
+int main(void)
+{
+	dwarf_find_debug_frame(0, NULL, 0, 0, NULL, 0, 0);
+	return 0;
+}
diff --git a/tools/build/feature/test-libunwind-debug-frame.c b/tools/build/feature/test-libunwind-debug-frame.c
deleted file mode 100644
index 0ef8087..0000000
--- a/tools/build/feature/test-libunwind-debug-frame.c
+++ /dev/null
@@ -1,16 +0,0 @@
-#include <libunwind.h>
-#include <stdlib.h>
-
-extern int
-UNW_OBJ(dwarf_find_debug_frame) (int found, unw_dyn_info_t *di_debug,
-				 unw_word_t ip, unw_word_t segbase,
-				 const char *obj_name, unw_word_t start,
-				 unw_word_t end);
-
-#define dwarf_find_debug_frame UNW_OBJ(dwarf_find_debug_frame)
-
-int main(void)
-{
-	dwarf_find_debug_frame(0, NULL, 0, 0, NULL, 0, 0);
-	return 0;
-}
-- 
1.8.5.2

^ permalink raw reply related	[flat|nested] 22+ messages in thread

* [PATCH 5/8] perf tools: Promote proper messages for cross-platform unwind
  2016-05-06  8:59 [PATCH 0/8] Add support for remote unwind He Kuang
                   ` (3 preceding siblings ...)
  2016-05-06  8:59 ` [PATCH 4/8] perf build: Add build-test for debug-frame on arm/arm64 He Kuang
@ 2016-05-06  8:59 ` He Kuang
  2016-05-07 18:41   ` Jiri Olsa
  2016-05-07 18:42   ` Jiri Olsa
  2016-05-06  8:59 ` [PATCH 6/8] perf callchain: Add support " He Kuang
                   ` (3 subsequent siblings)
  8 siblings, 2 replies; 22+ messages in thread
From: He Kuang @ 2016-05-06  8:59 UTC (permalink / raw)
  To: peterz, mingo, acme, alexander.shishkin, jolsa, wangnan0,
	hekuang, jpoimboe, ak, eranian, namhyung, adrian.hunter, sukadev,
	masami.hiramatsu.pt, tumanova, kan.liang, penberg, dsahern
  Cc: linux-kernel

Currently, perf script uses host unwind methods to parse perf.data
callchain info regardless of the target architecture. So we get wrong
result and no promotion when unwinding callchains of x86(32bit) on
x86(64bit) machine.

This patch shows proper error messages when we do remote unwind
x86(32bit) on other machines.

Same thing for other platforms will be added in next patches.

Signed-off-by: He Kuang <hekuang@huawei.com>
---
 tools/perf/config/Makefile   |  6 ++++++
 tools/perf/util/symbol-elf.c | 16 +++++++++++++++
 tools/perf/util/symbol.c     | 49 ++++++++++++++++++++++++++++++++++++++++++++
 tools/perf/util/symbol.h     |  2 ++
 tools/perf/util/thread.c     | 31 ++++++++++++++++++++++++++++
 5 files changed, 104 insertions(+)

diff --git a/tools/perf/config/Makefile b/tools/perf/config/Makefile
index 1e46277..a86b864 100644
--- a/tools/perf/config/Makefile
+++ b/tools/perf/config/Makefile
@@ -345,6 +345,12 @@ ifeq ($(ARCH),powerpc)
 endif
 
 ifndef NO_LIBUNWIND
+  ifeq ($(feature-libunwind-x86), 1)
+    LIBUNWIND_LIBS += -lunwind-x86
+    $(call detected,CONFIG_LIBUNWIND_X86)
+    CFLAGS += -DHAVE_LIBUNWIND_X86_SUPPORT
+  endif
+
   ifneq ($(feature-libunwind), 1)
     msg := $(warning No libunwind found. Please install libunwind-dev[el] >= 1.1 and/or set LIBUNWIND_DIR);
     NO_LIBUNWIND := 1
diff --git a/tools/perf/util/symbol-elf.c b/tools/perf/util/symbol-elf.c
index 3f9d679..9f290b9 100644
--- a/tools/perf/util/symbol-elf.c
+++ b/tools/perf/util/symbol-elf.c
@@ -636,6 +636,22 @@ bool __weak elf__needs_adjust_symbols(GElf_Ehdr ehdr)
 	return ehdr.e_type == ET_EXEC || ehdr.e_type == ET_REL;
 }
 
+int elf_is_64_bit(char *name)
+{
+	Elf *elf;
+	int fd;
+
+	fd = open(name, O_RDONLY);
+	if (fd < 0)
+		return -1;
+
+	elf = elf_begin(fd, PERF_ELF_C_READ_MMAP, NULL);
+	if (elf == NULL)
+		return -1;
+
+	return (gelf_getclass(elf) == ELFCLASS64);
+}
+
 int symsrc__init(struct symsrc *ss, struct dso *dso, const char *name,
 		 enum dso_binary_type type)
 {
diff --git a/tools/perf/util/symbol.c b/tools/perf/util/symbol.c
index 93f348f..c33aa5a 100644
--- a/tools/perf/util/symbol.c
+++ b/tools/perf/util/symbol.c
@@ -1395,6 +1395,55 @@ static bool dso__is_compatible_symtab_type(struct dso *dso, bool kmod,
 	}
 }
 
+int dso_is_64_bit(struct dso *dso, struct map *map)
+{
+	char *name;
+	u_int i;
+	bool kmod;
+	char *root_dir = (char *) "";
+	struct machine *machine;
+
+	if (map->groups && map->groups->machine)
+		machine = map->groups->machine;
+	else
+		machine = NULL;
+
+	if (machine)
+		root_dir = machine->root_dir;
+
+	name = malloc(PATH_MAX);
+	if (!name)
+		return -1;
+
+	kmod = dso->symtab_type == DSO_BINARY_TYPE__SYSTEM_PATH_KMODULE ||
+		dso->symtab_type == DSO_BINARY_TYPE__SYSTEM_PATH_KMODULE_COMP ||
+		dso->symtab_type == DSO_BINARY_TYPE__GUEST_KMODULE ||
+		dso->symtab_type == DSO_BINARY_TYPE__GUEST_KMODULE_COMP;
+
+	/*
+	 * Iterate over candidate debug images.
+	 * Keep track of "interesting" ones (those which have a symtab, dynsym,
+	 * and/or opd section) for processing.
+	 */
+	for (i = 0; i < DSO_BINARY_TYPE__SYMTAB_CNT; i++) {
+		enum dso_binary_type symtab_type = binary_type_symtab[i];
+
+		if (!dso__is_compatible_symtab_type(dso, kmod, symtab_type))
+			continue;
+
+		if (dso__read_binary_type_filename(dso, symtab_type,
+						   root_dir, name, PATH_MAX))
+			continue;
+
+		if (!is_regular_file(name))
+			continue;
+
+		return elf_is_64_bit(name);
+	}
+
+	return -1;
+}
+
 int dso__load(struct dso *dso, struct map *map, symbol_filter_t filter)
 {
 	char *name;
diff --git a/tools/perf/util/symbol.h b/tools/perf/util/symbol.h
index 4e6910e..d33fbf4 100644
--- a/tools/perf/util/symbol.h
+++ b/tools/perf/util/symbol.h
@@ -308,6 +308,8 @@ int setup_list(struct strlist **list, const char *list_str,
 	       const char *list_name);
 int setup_intlist(struct intlist **list, const char *list_str,
 		  const char *list_name);
+int elf_is_64_bit(char *name);
+int dso_is_64_bit(struct dso *dso, struct map *map);
 
 #ifdef HAVE_LIBELF_SUPPORT
 bool elf__needs_adjust_symbols(GElf_Ehdr ehdr);
diff --git a/tools/perf/util/thread.c b/tools/perf/util/thread.c
index dfd00c6..e0cdcf7 100644
--- a/tools/perf/util/thread.c
+++ b/tools/perf/util/thread.c
@@ -184,8 +184,39 @@ size_t thread__fprintf(struct thread *thread, FILE *fp)
 
 void thread__insert_map(struct thread *thread, struct map *map)
 {
+	char * __maybe_unused arch;
+	int __maybe_unused is_64_bit;
+
 	map_groups__fixup_overlappings(thread->mg, map, stderr);
 	map_groups__insert(thread->mg, map);
+
+#ifdef HAVE_LIBUNWIND_SUPPORT
+	if (!thread->mg->machine->env)
+		return;
+
+	is_64_bit = dso_is_64_bit(map->dso, map);
+	if (is_64_bit < 0)
+		return;
+
+	if (thread->addr_space)
+		pr_debug("Thread map already set, 64bit is %d, dso=%s\n",
+			 is_64_bit, map->dso->name);
+
+	arch = thread->mg->machine->env->arch;
+
+	if (!strcmp(arch, "x86_64")
+		   || !strcmp(arch, "x86")
+		   || !strcmp(arch, "i686")) {
+		pr_debug("Thread map is X86, 64bit is %d\n", is_64_bit);
+		if (!is_64_bit)
+#ifdef HAVE_LIBUNWIND_X86_SUPPORT
+			pr_err("target platform=%s is not implemented!\n",
+			       arch);
+#else
+			pr_err("target platform=%s is not supported!\n", arch);
+#endif
+	}
+#endif
 }
 
 static int thread__clone_map_groups(struct thread *thread,
-- 
1.8.5.2

^ permalink raw reply related	[flat|nested] 22+ messages in thread

* [PATCH 6/8] perf callchain: Add support for cross-platform unwind
  2016-05-06  8:59 [PATCH 0/8] Add support for remote unwind He Kuang
                   ` (4 preceding siblings ...)
  2016-05-06  8:59 ` [PATCH 5/8] perf tools: Promote proper messages for cross-platform unwind He Kuang
@ 2016-05-06  8:59 ` He Kuang
  2016-05-06 11:56   ` Arnaldo Carvalho de Melo
  2016-05-06  8:59 ` [PATCH 7/8] perf callchain: Support x86 target platform He Kuang
                   ` (2 subsequent siblings)
  8 siblings, 1 reply; 22+ messages in thread
From: He Kuang @ 2016-05-06  8:59 UTC (permalink / raw)
  To: peterz, mingo, acme, alexander.shishkin, jolsa, wangnan0,
	hekuang, jpoimboe, ak, eranian, namhyung, adrian.hunter, sukadev,
	masami.hiramatsu.pt, tumanova, kan.liang, penberg, dsahern
  Cc: linux-kernel

Use thread specific unwind ops to unwind cross-platform callchains.

Before this patch, unwind methods is suitable for local unwind, this
patch changes the fixed methods to thread/map related. Each time a map
is inserted, we find the target arch and see if this platform can be
remote unwind. In this patch, we test for x86 platform and only show
proper messages. The real unwind methods are not implemented, will be
introduced in next patch.

Signed-off-by: He Kuang <hekuang@huawei.com>
---
 tools/perf/config/Makefile                | 19 ++++++++--
 tools/perf/util/Build                     |  3 +-
 tools/perf/util/thread.c                  | 29 +++++++++++----
 tools/perf/util/thread.h                  | 14 +++++++-
 tools/perf/util/unwind-libunwind.c        | 48 +++++++++++++++++++++----
 tools/perf/util/unwind-libunwind_common.c | 60 +++++++++++++++++++++++++++++++
 tools/perf/util/unwind.h                  | 22 ++++++++++++
 7 files changed, 178 insertions(+), 17 deletions(-)
 create mode 100644 tools/perf/util/unwind-libunwind_common.c

diff --git a/tools/perf/config/Makefile b/tools/perf/config/Makefile
index a86b864..16f14b1 100644
--- a/tools/perf/config/Makefile
+++ b/tools/perf/config/Makefile
@@ -345,14 +345,24 @@ ifeq ($(ARCH),powerpc)
 endif
 
 ifndef NO_LIBUNWIND
+  have_libunwind =
   ifeq ($(feature-libunwind-x86), 1)
-    LIBUNWIND_LIBS += -lunwind-x86
     $(call detected,CONFIG_LIBUNWIND_X86)
     CFLAGS += -DHAVE_LIBUNWIND_X86_SUPPORT
+    LDFLAGS += -lunwind -lunwind-x86
+    have_libunwind = 1
   endif
 
   ifneq ($(feature-libunwind), 1)
     msg := $(warning No libunwind found. Please install libunwind-dev[el] >= 1.1 and/or set LIBUNWIND_DIR);
+    NO_LOCAL_LIBUNWIND := 1
+  else
+    have_libunwind = 1
+    CFLAGS += -DHAVE_LIBUNWIND_LOCAL_SUPPORT
+    $(call detected,CONFIG_LOCAL_LIBUNWIND)
+  endif
+
+  ifneq ($(have_libunwind), 1)
     NO_LIBUNWIND := 1
   endif
 endif
@@ -392,7 +402,7 @@ else
   NO_DWARF_UNWIND := 1
 endif
 
-ifndef NO_LIBUNWIND
+ifndef NO_LOCAL_LIBUNWIND
   ifeq ($(ARCH),$(filter $(ARCH),arm arm64))
     $(call feature_check,libunwind-debug-frame)
     ifneq ($(feature-libunwind-debug-frame), 1)
@@ -403,12 +413,15 @@ ifndef NO_LIBUNWIND
     # non-ARM has no dwarf_find_debug_frame() function:
     CFLAGS += -DNO_LIBUNWIND_DEBUG_FRAME
   endif
-  CFLAGS  += -DHAVE_LIBUNWIND_SUPPORT
   EXTLIBS += $(LIBUNWIND_LIBS)
   CFLAGS  += $(LIBUNWIND_CFLAGS)
   LDFLAGS += $(LIBUNWIND_LDFLAGS)
 endif
 
+ifndef NO_LIBUNWIND
+  CFLAGS  += -DHAVE_LIBUNWIND_SUPPORT
+endif
+
 ifndef NO_LIBAUDIT
   ifneq ($(feature-libaudit), 1)
     msg := $(warning No libaudit.h found, disables 'trace' tool, please install audit-libs-devel or libaudit-dev);
diff --git a/tools/perf/util/Build b/tools/perf/util/Build
index ea4ac03..2e21529 100644
--- a/tools/perf/util/Build
+++ b/tools/perf/util/Build
@@ -97,7 +97,8 @@ libperf-$(CONFIG_DWARF) += probe-finder.o
 libperf-$(CONFIG_DWARF) += dwarf-aux.o
 
 libperf-$(CONFIG_LIBDW_DWARF_UNWIND) += unwind-libdw.o
-libperf-$(CONFIG_LIBUNWIND)          += unwind-libunwind.o
+libperf-$(CONFIG_LOCAL_LIBUNWIND)    += unwind-libunwind.o
+libperf-$(CONFIG_LIBUNWIND)          += unwind-libunwind_common.o
 
 libperf-$(CONFIG_LIBBABELTRACE) += data-convert-bt.o
 
diff --git a/tools/perf/util/thread.c b/tools/perf/util/thread.c
index e0cdcf7..cf60db1 100644
--- a/tools/perf/util/thread.c
+++ b/tools/perf/util/thread.c
@@ -41,9 +41,6 @@ struct thread *thread__new(pid_t pid, pid_t tid)
 		thread->cpu = -1;
 		INIT_LIST_HEAD(&thread->comm_list);
 
-		if (unwind__prepare_access(thread) < 0)
-			goto err_thread;
-
 		comm_str = malloc(32);
 		if (!comm_str)
 			goto err_thread;
@@ -57,6 +54,9 @@ struct thread *thread__new(pid_t pid, pid_t tid)
 		list_add(&comm->list, &thread->comm_list);
 		atomic_set(&thread->refcnt, 1);
 		RB_CLEAR_NODE(&thread->rb_node);
+#ifdef HAVE_LIBUNWIND_SUPPORT
+		register_null_unwind_libunwind_ops(thread);
+#endif
 	}
 
 	return thread;
@@ -82,7 +82,9 @@ void thread__delete(struct thread *thread)
 		list_del(&comm->list);
 		comm__free(comm);
 	}
-	unwind__finish_access(thread);
+#ifdef HAVE_LIBUNWIND_SUPPORT
+	thread->unwind_libunwind_ops->finish_access(thread);
+#endif
 
 	free(thread);
 }
@@ -144,8 +146,10 @@ int __thread__set_comm(struct thread *thread, const char *str, u64 timestamp,
 			return -ENOMEM;
 		list_add(&new->list, &thread->comm_list);
 
+#ifdef HAVE_LIBUNWIND_SUPPORT
 		if (exec)
-			unwind__flush_access(thread);
+			thread->unwind_libunwind_ops->flush_access(thread);
+#endif
 	}
 
 	thread->comm_set = true;
@@ -208,14 +212,27 @@ void thread__insert_map(struct thread *thread, struct map *map)
 		   || !strcmp(arch, "x86")
 		   || !strcmp(arch, "i686")) {
 		pr_debug("Thread map is X86, 64bit is %d\n", is_64_bit);
-		if (!is_64_bit)
+		if (!is_64_bit) {
 #ifdef HAVE_LIBUNWIND_X86_SUPPORT
 			pr_err("target platform=%s is not implemented!\n",
 			       arch);
 #else
 			pr_err("target platform=%s is not supported!\n", arch);
 #endif
+			goto err;
+		}
+	} else {
+		register_local_unwind_libunwind_ops(thread);
 	}
+
+	if (thread->unwind_libunwind_ops->prepare_access(thread) < 0)
+		return;
+
+	return;
+
+err: __maybe_unused
+	register_null_unwind_libunwind_ops(thread);
+	return;
 #endif
 }
 
diff --git a/tools/perf/util/thread.h b/tools/perf/util/thread.h
index e214207..6f2d4cd 100644
--- a/tools/perf/util/thread.h
+++ b/tools/perf/util/thread.h
@@ -15,6 +15,17 @@
 
 struct thread_stack;
 
+struct unwind_entry;
+typedef int (*unwind_entry_cb_t)(struct unwind_entry *entry, void *arg);
+struct unwind_libunwind_ops {
+	int (*prepare_access)(struct thread *thread);
+	void (*flush_access)(struct thread *thread);
+	void (*finish_access)(struct thread *thread);
+	int (*get_entries)(unwind_entry_cb_t cb, void *arg,
+			   struct thread *thread,
+			   struct perf_sample *data, int max_stack);
+};
+
 struct thread {
 	union {
 		struct rb_node	 rb_node;
@@ -36,7 +47,8 @@ struct thread {
 	void			*priv;
 	struct thread_stack	*ts;
 #ifdef HAVE_LIBUNWIND_SUPPORT
-	unw_addr_space_t	addr_space;
+	unw_addr_space_t		addr_space;
+	struct unwind_libunwind_ops	*unwind_libunwind_ops;
 #endif
 };
 
diff --git a/tools/perf/util/unwind-libunwind.c b/tools/perf/util/unwind-libunwind.c
index 63687d3..2558bf3 100644
--- a/tools/perf/util/unwind-libunwind.c
+++ b/tools/perf/util/unwind-libunwind.c
@@ -22,6 +22,9 @@
 #include <unistd.h>
 #include <sys/mman.h>
 #include <linux/list.h>
+#ifdef ARCH_UNWIND_LIBUNWIND
+#include "libunwind-arch.h"
+#endif
 #include <libunwind.h>
 #include <libunwind-ptrace.h>
 #include "callchain.h"
@@ -34,6 +37,22 @@
 #include "debug.h"
 #include "asm/bug.h"
 
+#ifndef ARCH_UNWIND_LIBUNWIND
+  #define LIBUNWIND__ARCH_REG_ID libunwind__arch_reg_id
+  #define LOCAL_UNWIND_LIBUNWIND
+  #undef UNWT_OBJ
+  #define UNWT_OBJ(x) _##x
+#else
+  #undef NO_LIBUNWIND_DEBUG_FRAME
+  #if defined(LIBUNWIND_ARM) && !defined(NO_LIBUNWIND_DEBUG_FRAME_ARM)
+  #elif defined(LIBUNWIND_AARCH64) &&                    \
+	  defined(NO_LIBUNWIND_DEBUG_FRAME_ARM_AARCH64)
+  #else
+    #define NO_LIBUNWIND_DEBUG_FRAME
+  #endif
+#endif
+
+
 extern int
 UNW_OBJ(dwarf_search_unwind_table) (unw_addr_space_t as,
 				    unw_word_t ip,
@@ -579,7 +598,7 @@ static unw_accessors_t accessors = {
 	.get_proc_name		= get_proc_name,
 };
 
-int unwind__prepare_access(struct thread *thread)
+static int UNWT_OBJ(_unwind__prepare_access)(struct thread *thread)
 {
 	if (callchain_param.record_mode != CALLCHAIN_DWARF)
 		return 0;
@@ -594,7 +613,7 @@ int unwind__prepare_access(struct thread *thread)
 	return 0;
 }
 
-void unwind__flush_access(struct thread *thread)
+static void UNWT_OBJ(_unwind__flush_access)(struct thread *thread)
 {
 	if (callchain_param.record_mode != CALLCHAIN_DWARF)
 		return;
@@ -602,7 +621,7 @@ void unwind__flush_access(struct thread *thread)
 	unw_flush_cache(thread->addr_space, 0, 0);
 }
 
-void unwind__finish_access(struct thread *thread)
+static void UNWT_OBJ(_unwind__finish_access)(struct thread *thread)
 {
 	if (callchain_param.record_mode != CALLCHAIN_DWARF)
 		return;
@@ -662,9 +681,10 @@ static int get_entries(struct unwind_info *ui, unwind_entry_cb_t cb,
 	return ret;
 }
 
-int unwind__get_entries(unwind_entry_cb_t cb, void *arg,
-			struct thread *thread,
-			struct perf_sample *data, int max_stack)
+static int UNWT_OBJ(_unwind__get_entries)(unwind_entry_cb_t cb, void *arg,
+					 struct thread *thread,
+					 struct perf_sample *data,
+					 int max_stack)
 {
 	struct unwind_info ui = {
 		.sample       = data,
@@ -680,3 +700,19 @@ int unwind__get_entries(unwind_entry_cb_t cb, void *arg,
 
 	return get_entries(&ui, cb, arg, max_stack);
 }
+
+struct unwind_libunwind_ops
+UNWT_OBJ(unwind_libunwind_ops) = {
+	.prepare_access = UNWT_OBJ(_unwind__prepare_access),
+	.flush_access   = UNWT_OBJ(_unwind__flush_access),
+	.finish_access  = UNWT_OBJ(_unwind__finish_access),
+	.get_entries    = UNWT_OBJ(_unwind__get_entries),
+};
+
+#ifdef LOCAL_UNWIND_LIBUNWIND
+int register_local_unwind_libunwind_ops(struct thread *thread)
+{
+	thread->unwind_libunwind_ops = &UNWT_OBJ(unwind_libunwind_ops);
+	return 0;
+}
+#endif
diff --git a/tools/perf/util/unwind-libunwind_common.c b/tools/perf/util/unwind-libunwind_common.c
new file mode 100644
index 0000000..47433a4
--- /dev/null
+++ b/tools/perf/util/unwind-libunwind_common.c
@@ -0,0 +1,60 @@
+#include <elf.h>
+#include <gelf.h>
+#include <fcntl.h>
+#include <string.h>
+#include <unistd.h>
+#include <sys/mman.h>
+#include <linux/list.h>
+#include <libunwind.h>
+#include <libunwind-ptrace.h>
+#include "callchain.h"
+#include "thread.h"
+#include "session.h"
+#include "perf_regs.h"
+#include "unwind.h"
+#include "symbol.h"
+#include "util.h"
+#include "debug.h"
+#include "asm/bug.h"
+
+static int __null__prepare_access(struct thread *thread __maybe_unused)
+{
+	return 0;
+}
+
+static void __null__flush_access(struct thread *thread __maybe_unused)
+{
+}
+
+static void __null__finish_access(struct thread *thread __maybe_unused)
+{
+}
+
+static int __null__get_entries(unwind_entry_cb_t cb __maybe_unused,
+			       void *arg __maybe_unused,
+			       struct thread *thread __maybe_unused,
+			       struct perf_sample *data __maybe_unused,
+			       int max_stack __maybe_unused)
+{
+	return 0;
+}
+
+static struct unwind_libunwind_ops null_unwind_libunwind_ops = {
+	.prepare_access = __null__prepare_access,
+	.flush_access   = __null__flush_access,
+	.finish_access  = __null__finish_access,
+	.get_entries    = __null__get_entries,
+};
+
+int register_null_unwind_libunwind_ops(struct thread *thread)
+{
+	thread->unwind_libunwind_ops = &null_unwind_libunwind_ops;
+	return 0;
+}
+
+int register_unwind_libunwind_ops(struct unwind_libunwind_ops *ops,
+				  struct thread *thread)
+{
+	thread->unwind_libunwind_ops = ops;
+	return 0;
+}
diff --git a/tools/perf/util/unwind.h b/tools/perf/util/unwind.h
index 12790cf..61b44a6 100644
--- a/tools/perf/util/unwind.h
+++ b/tools/perf/util/unwind.h
@@ -24,6 +24,28 @@ int libunwind__arch_reg_id(int regnum);
 int unwind__prepare_access(struct thread *thread);
 void unwind__flush_access(struct thread *thread);
 void unwind__finish_access(struct thread *thread);
+int register_unwind_libunwind_ops(struct unwind_libunwind_ops *ops,
+				  struct thread *thread);
+int register_null_unwind_libunwind_ops(struct thread *thread);
+
+#ifndef HAVE_LIBUNWIND_LOCAL_SUPPORT
+static inline int
+register_local_unwind_libunwind_ops(struct thread *thread) {
+	return register_null_unwind_libunwind_ops(thread);
+}
+#else
+int register_local_unwind_libunwind_ops(struct thread *thread);
+#endif
+
+#define unwind__get_entries(cb, arg,					\
+			    thread,					\
+			    data, max_stack)				\
+	thread->unwind_libunwind_ops->get_entries(cb,			\
+						  arg,			\
+						  thread,		\
+						  data,			\
+						  max_stack)
+
 #else
 static inline int unwind__prepare_access(struct thread *thread __maybe_unused)
 {
-- 
1.8.5.2

^ permalink raw reply related	[flat|nested] 22+ messages in thread

* [PATCH 7/8] perf callchain: Support x86 target platform
  2016-05-06  8:59 [PATCH 0/8] Add support for remote unwind He Kuang
                   ` (5 preceding siblings ...)
  2016-05-06  8:59 ` [PATCH 6/8] perf callchain: Add support " He Kuang
@ 2016-05-06  8:59 ` He Kuang
  2016-05-06  8:59 ` [PATCH 8/8] perf callchain: Support aarch64 cross-platform He Kuang
  2016-05-06 11:58 ` [PATCH 0/8] Add support for remote unwind Arnaldo Carvalho de Melo
  8 siblings, 0 replies; 22+ messages in thread
From: He Kuang @ 2016-05-06  8:59 UTC (permalink / raw)
  To: peterz, mingo, acme, alexander.shishkin, jolsa, wangnan0,
	hekuang, jpoimboe, ak, eranian, namhyung, adrian.hunter, sukadev,
	masami.hiramatsu.pt, tumanova, kan.liang, penberg, dsahern
  Cc: linux-kernel

Support x86(32bit) cross platform callchain unwind.

Signed-off-by: He Kuang <hekuang@huawei.com>
---
 .../arch/x86/include/libunwind/libunwind-arch.h    | 18 ++++++++++
 tools/perf/arch/x86/util/unwind-libunwind.c        | 42 ++++++++++++++++++++++
 tools/perf/util/Build                              |  6 ++++
 tools/perf/util/thread.c                           | 10 +++---
 tools/perf/util/unwind-libunwind.c                 |  2 +-
 tools/perf/util/unwind.h                           |  5 +++
 6 files changed, 77 insertions(+), 6 deletions(-)
 create mode 100644 tools/perf/arch/x86/include/libunwind/libunwind-arch.h

diff --git a/tools/perf/arch/x86/include/libunwind/libunwind-arch.h b/tools/perf/arch/x86/include/libunwind/libunwind-arch.h
new file mode 100644
index 0000000..265f14d
--- /dev/null
+++ b/tools/perf/arch/x86/include/libunwind/libunwind-arch.h
@@ -0,0 +1,18 @@
+#ifndef _LIBUNWIND_ARCH_H
+#define _LIBUNWIND_ARCH_H
+
+#include <libunwind-x86.h>
+#include <../perf_regs.h>
+#include <../../../../../../arch/x86/include/uapi/asm/perf_regs.h>
+
+#define LIBUNWIND_X86_32
+int libunwind__x86_reg_id(int regnum);
+
+#include <../../../x86/util/unwind-libunwind.c>
+
+#define LIBUNWIND__ARCH_REG_ID libunwind__x86_reg_id
+
+#define UNWT_PREFIX	UNW_PASTE(UNW_PASTE(_U, x86), _)
+#define UNWT_OBJ(fn)	UNW_PASTE(UNWT_PREFIX, fn)
+
+#endif /* _LIBUNWIND_ARCH_H */
diff --git a/tools/perf/arch/x86/util/unwind-libunwind.c b/tools/perf/arch/x86/util/unwind-libunwind.c
index db25e93..d422fbf 100644
--- a/tools/perf/arch/x86/util/unwind-libunwind.c
+++ b/tools/perf/arch/x86/util/unwind-libunwind.c
@@ -5,6 +5,7 @@
 #include "../../util/unwind.h"
 #include "../../util/debug.h"
 
+#ifndef LIBUNWIND_X86_32
 #ifdef HAVE_ARCH_X86_64_SUPPORT
 int libunwind__arch_reg_id(int regnum)
 {
@@ -110,3 +111,44 @@ int libunwind__arch_reg_id(int regnum)
 	return id;
 }
 #endif /* HAVE_ARCH_X86_64_SUPPORT */
+#else
+int libunwind__x86_reg_id(int regnum)
+{
+	int id;
+
+	switch (regnum) {
+	case UNW_X86_EAX:
+		id = PERF_REG_X86_AX;
+		break;
+	case UNW_X86_EDX:
+		id = PERF_REG_X86_DX;
+		break;
+	case UNW_X86_ECX:
+		id = PERF_REG_X86_CX;
+		break;
+	case UNW_X86_EBX:
+		id = PERF_REG_X86_BX;
+		break;
+	case UNW_X86_ESI:
+		id = PERF_REG_X86_SI;
+		break;
+	case UNW_X86_EDI:
+		id = PERF_REG_X86_DI;
+		break;
+	case UNW_X86_EBP:
+		id = PERF_REG_X86_BP;
+		break;
+	case UNW_X86_ESP:
+		id = PERF_REG_X86_SP;
+		break;
+	case UNW_X86_EIP:
+		id = PERF_REG_X86_IP;
+		break;
+	default:
+		pr_err("unwind: invalid reg id %d\n", regnum);
+		return -EINVAL;
+	}
+
+	return id;
+}
+#endif /* LIBUNWIND_X86_32 */
diff --git a/tools/perf/util/Build b/tools/perf/util/Build
index 2e21529..2dd3939 100644
--- a/tools/perf/util/Build
+++ b/tools/perf/util/Build
@@ -1,3 +1,5 @@
+include ../scripts/Makefile.include
+
 libperf-y += alias.o
 libperf-y += annotate.o
 libperf-y += build-id.o
@@ -99,6 +101,10 @@ libperf-$(CONFIG_DWARF) += dwarf-aux.o
 libperf-$(CONFIG_LIBDW_DWARF_UNWIND) += unwind-libdw.o
 libperf-$(CONFIG_LOCAL_LIBUNWIND)    += unwind-libunwind.o
 libperf-$(CONFIG_LIBUNWIND)          += unwind-libunwind_common.o
+libperf-$(CONFIG_LIBUNWIND_X86)      += unwind-libunwind_x86_32.o
+
+$(OUTPUT)util/unwind-libunwind_x86_32.o: util/unwind-libunwind.c arch/x86/util/unwind-libunwind.c
+	$(QUIET_CC)$(CC) $(CFLAGS) -DARCH_UNWIND_LIBUNWIND -Iarch/x86/include/libunwind -c -o $@ util/unwind-libunwind.c
 
 libperf-$(CONFIG_LIBBABELTRACE) += data-convert-bt.o
 
diff --git a/tools/perf/util/thread.c b/tools/perf/util/thread.c
index cf60db1..2b93856 100644
--- a/tools/perf/util/thread.c
+++ b/tools/perf/util/thread.c
@@ -214,12 +214,12 @@ void thread__insert_map(struct thread *thread, struct map *map)
 		pr_debug("Thread map is X86, 64bit is %d\n", is_64_bit);
 		if (!is_64_bit) {
 #ifdef HAVE_LIBUNWIND_X86_SUPPORT
-			pr_err("target platform=%s is not implemented!\n",
-			       arch);
+			register_unwind_libunwind_ops(
+				&_Ux86_unwind_libunwind_ops, thread);
 #else
-			pr_err("target platform=%s is not supported!\n", arch);
-#endif
+			register_null_unwind_libunwind_ops(thread);
 			goto err;
+#endif
 		}
 	} else {
 		register_local_unwind_libunwind_ops(thread);
@@ -231,7 +231,7 @@ void thread__insert_map(struct thread *thread, struct map *map)
 	return;
 
 err: __maybe_unused
-	register_null_unwind_libunwind_ops(thread);
+	pr_err("target platform=%s not support!\n", arch);
 	return;
 #endif
 }
diff --git a/tools/perf/util/unwind-libunwind.c b/tools/perf/util/unwind-libunwind.c
index 2558bf3..a195b56 100644
--- a/tools/perf/util/unwind-libunwind.c
+++ b/tools/perf/util/unwind-libunwind.c
@@ -527,7 +527,7 @@ static int access_reg(unw_addr_space_t __maybe_unused as,
 		return 0;
 	}
 
-	id = libunwind__arch_reg_id(regnum);
+	id = LIBUNWIND__ARCH_REG_ID(regnum);
 	if (id < 0)
 		return -EINVAL;
 
diff --git a/tools/perf/util/unwind.h b/tools/perf/util/unwind.h
index 61b44a6..98d40bd 100644
--- a/tools/perf/util/unwind.h
+++ b/tools/perf/util/unwind.h
@@ -55,6 +55,11 @@ static inline int unwind__prepare_access(struct thread *thread __maybe_unused)
 static inline void unwind__flush_access(struct thread *thread __maybe_unused) {}
 static inline void unwind__finish_access(struct thread *thread __maybe_unused) {}
 #endif
+
+#ifdef HAVE_LIBUNWIND_X86_SUPPORT
+extern struct unwind_libunwind_ops _Ux86_unwind_libunwind_ops;
+#endif
+
 #else
 static inline int
 unwind__get_entries(unwind_entry_cb_t cb __maybe_unused,
-- 
1.8.5.2

^ permalink raw reply related	[flat|nested] 22+ messages in thread

* [PATCH 8/8] perf callchain: Support aarch64 cross-platform
  2016-05-06  8:59 [PATCH 0/8] Add support for remote unwind He Kuang
                   ` (6 preceding siblings ...)
  2016-05-06  8:59 ` [PATCH 7/8] perf callchain: Support x86 target platform He Kuang
@ 2016-05-06  8:59 ` He Kuang
  2016-05-06 11:58 ` [PATCH 0/8] Add support for remote unwind Arnaldo Carvalho de Melo
  8 siblings, 0 replies; 22+ messages in thread
From: He Kuang @ 2016-05-06  8:59 UTC (permalink / raw)
  To: peterz, mingo, acme, alexander.shishkin, jolsa, wangnan0,
	hekuang, jpoimboe, ak, eranian, namhyung, adrian.hunter, sukadev,
	masami.hiramatsu.pt, tumanova, kan.liang, penberg, dsahern
  Cc: linux-kernel

Support aarch64 cross platform callchain unwind.

Signed-off-by: He Kuang <hekuang@huawei.com>
---
 .../perf/arch/arm64/include/libunwind/libunwind-arch.h | 18 ++++++++++++++++++
 tools/perf/arch/arm64/util/unwind-libunwind.c          |  5 ++++-
 tools/perf/config/Makefile                             | 12 ++++++++++++
 tools/perf/util/Build                                  |  4 ++++
 tools/perf/util/thread.c                               | 12 ++++++++++++
 tools/perf/util/unwind.h                               |  3 +++
 6 files changed, 53 insertions(+), 1 deletion(-)
 create mode 100644 tools/perf/arch/arm64/include/libunwind/libunwind-arch.h

diff --git a/tools/perf/arch/arm64/include/libunwind/libunwind-arch.h b/tools/perf/arch/arm64/include/libunwind/libunwind-arch.h
new file mode 100644
index 0000000..7bc8a00
--- /dev/null
+++ b/tools/perf/arch/arm64/include/libunwind/libunwind-arch.h
@@ -0,0 +1,18 @@
+#ifndef _LIBUNWIND_ARCH_H
+#define _LIBUNWIND_ARCH_H
+
+#include <libunwind-aarch64.h>
+#include <../perf_regs.h>
+#include <../../../../../../arch/arm64/include/uapi/asm/perf_regs.h>
+
+#define LIBUNWIND_AARCH64
+int libunwind__aarch64_reg_id(int regnum);
+
+#include <../../../arm64/util/unwind-libunwind.c>
+
+#define LIBUNWIND__ARCH_REG_ID libunwind__aarch64_reg_id
+
+#define UNWT_PREFIX	UNW_PASTE(UNW_PASTE(_U, aarch64), _)
+#define UNWT_OBJ(fn)	UNW_PASTE(UNWT_PREFIX, fn)
+
+#endif /* _LIBUNWIND_ARCH_H */
diff --git a/tools/perf/arch/arm64/util/unwind-libunwind.c b/tools/perf/arch/arm64/util/unwind-libunwind.c
index a87afa9..5b557a5 100644
--- a/tools/perf/arch/arm64/util/unwind-libunwind.c
+++ b/tools/perf/arch/arm64/util/unwind-libunwind.c
@@ -1,11 +1,14 @@
 
 #include <errno.h>
-#include <libunwind.h>
 #include "perf_regs.h"
 #include "../../util/unwind.h"
 #include "../../util/debug.h"
 
+#ifndef LIBUNWIND_AARCH64
 int libunwind__arch_reg_id(int regnum)
+#else
+int libunwind__aarch64_reg_id(int regnum)
+#endif
 {
 	switch (regnum) {
 	case UNW_AARCH64_X0:
diff --git a/tools/perf/config/Makefile b/tools/perf/config/Makefile
index 16f14b1..c1bfc5e 100644
--- a/tools/perf/config/Makefile
+++ b/tools/perf/config/Makefile
@@ -353,6 +353,18 @@ ifndef NO_LIBUNWIND
     have_libunwind = 1
   endif
 
+  ifeq ($(feature-libunwind-aarch64), 1)
+    $(call detected,CONFIG_LIBUNWIND_AARCH64)
+    CFLAGS += -DHAVE_LIBUNWIND_AARCH64_SUPPORT
+    LDFLAGS += -lunwind -lunwind-aarch64
+    have_libunwind = 1
+    $(call feature_check,libunwind-debug-frame-aarch64)
+    ifneq ($(feature-libunwind-debug-frame-aarch64), 1)
+      msg := $(warning No debug_frame support found in libunwind-aarch64);
+      CFLAGS += -DNO_LIBUNWIND_DEBUG_FRAME_AARCH64
+    endif
+  endif
+
   ifneq ($(feature-libunwind), 1)
     msg := $(warning No libunwind found. Please install libunwind-dev[el] >= 1.1 and/or set LIBUNWIND_DIR);
     NO_LOCAL_LIBUNWIND := 1
diff --git a/tools/perf/util/Build b/tools/perf/util/Build
index 2dd3939..10e42ad 100644
--- a/tools/perf/util/Build
+++ b/tools/perf/util/Build
@@ -102,10 +102,14 @@ libperf-$(CONFIG_LIBDW_DWARF_UNWIND) += unwind-libdw.o
 libperf-$(CONFIG_LOCAL_LIBUNWIND)    += unwind-libunwind.o
 libperf-$(CONFIG_LIBUNWIND)          += unwind-libunwind_common.o
 libperf-$(CONFIG_LIBUNWIND_X86)      += unwind-libunwind_x86_32.o
+libperf-$(CONFIG_LIBUNWIND_AARCH64)  += unwind-libunwind_arm64.o
 
 $(OUTPUT)util/unwind-libunwind_x86_32.o: util/unwind-libunwind.c arch/x86/util/unwind-libunwind.c
 	$(QUIET_CC)$(CC) $(CFLAGS) -DARCH_UNWIND_LIBUNWIND -Iarch/x86/include/libunwind -c -o $@ util/unwind-libunwind.c
 
+$(OUTPUT)util/unwind-libunwind_arm64.o: util/unwind-libunwind.c arch/arm64/util/unwind-libunwind.c
+	$(QUIET_CC)$(CC) $(CFLAGS) -DARCH_UNWIND_LIBUNWIND -Iarch/arm64/include/libunwind -c -o $@ util/unwind-libunwind.c
+
 libperf-$(CONFIG_LIBBABELTRACE) += data-convert-bt.o
 
 libperf-y += scripting-engines/
diff --git a/tools/perf/util/thread.c b/tools/perf/util/thread.c
index 2b93856..ba3e597 100644
--- a/tools/perf/util/thread.c
+++ b/tools/perf/util/thread.c
@@ -221,6 +221,18 @@ void thread__insert_map(struct thread *thread, struct map *map)
 			goto err;
 #endif
 		}
+	} else if (!strcmp(arch, "aarch64") || !strncmp(arch, "arm", 3)) {
+		pr_debug("Thread map is ARM, 64bit is %d, dso=%s\n",
+			 is_64_bit, map->dso->name);
+		if (is_64_bit) {
+#ifdef HAVE_LIBUNWIND_AARCH64_SUPPORT
+			register_unwind_libunwind_ops(
+				&_Uaarch64_unwind_libunwind_ops, thread);
+#else
+			register_null_unwind_libunwind_ops(thread);
+			goto err;
+#endif
+		}
 	} else {
 		register_local_unwind_libunwind_ops(thread);
 	}
diff --git a/tools/perf/util/unwind.h b/tools/perf/util/unwind.h
index 98d40bd..d215717 100644
--- a/tools/perf/util/unwind.h
+++ b/tools/perf/util/unwind.h
@@ -59,6 +59,9 @@ static inline void unwind__finish_access(struct thread *thread __maybe_unused) {
 #ifdef HAVE_LIBUNWIND_X86_SUPPORT
 extern struct unwind_libunwind_ops _Ux86_unwind_libunwind_ops;
 #endif
+#ifdef HAVE_LIBUNWIND_AARCH64_SUPPORT
+extern struct unwind_libunwind_ops _Uaarch64_unwind_libunwind_ops;
+#endif
 
 #else
 static inline int
-- 
1.8.5.2

^ permalink raw reply related	[flat|nested] 22+ messages in thread

* Re: [PATCH 1/8] perf tools: Omit DWARF judgement when recording dwarf callchain
  2016-05-06  8:59 ` [PATCH 1/8] perf tools: Omit DWARF judgement when recording dwarf callchain He Kuang
@ 2016-05-06 11:47   ` Arnaldo Carvalho de Melo
  2016-05-07 18:03   ` Jiri Olsa
  2016-05-10 20:30   ` [tip:perf/core] perf callchain: Recording 'dwarf' callchains do not need DWARF unwinding support tip-bot for He Kuang
  2 siblings, 0 replies; 22+ messages in thread
From: Arnaldo Carvalho de Melo @ 2016-05-06 11:47 UTC (permalink / raw)
  To: He Kuang
  Cc: peterz, mingo, alexander.shishkin, jolsa, wangnan0, jpoimboe, ak,
	eranian, namhyung, adrian.hunter, sukadev, masami.hiramatsu.pt,
	tumanova, kan.liang, penberg, dsahern, linux-kernel

Em Fri, May 06, 2016 at 08:59:07AM +0000, He Kuang escreveu:
> There's no need for dwarf support when perf recording with callchain.

Can you rewrite this? We do need to have support for dwarf when
processing "dwarf style" callchains.

- Arnaldo
 
> Signed-off-by: He Kuang <hekuang@huawei.com>
> ---
>  tools/perf/util/util.c | 2 --
>  1 file changed, 2 deletions(-)
> 
> diff --git a/tools/perf/util/util.c b/tools/perf/util/util.c
> index b7766c5..e5ebfd4 100644
> --- a/tools/perf/util/util.c
> +++ b/tools/perf/util/util.c
> @@ -471,7 +471,6 @@ int parse_callchain_record(const char *arg, struct callchain_param *param)
>  				       "needed for --call-graph fp\n");
>  			break;
>  
> -#ifdef HAVE_DWARF_UNWIND_SUPPORT
>  		/* Dwarf style */
>  		} else if (!strncmp(name, "dwarf", sizeof("dwarf"))) {
>  			const unsigned long default_stack_dump_size = 8192;
> @@ -487,7 +486,6 @@ int parse_callchain_record(const char *arg, struct callchain_param *param)
>  				ret = get_stack_size(tok, &size);
>  				param->dump_size = size;
>  			}
> -#endif /* HAVE_DWARF_UNWIND_SUPPORT */
>  		} else if (!strncmp(name, "lbr", sizeof("lbr"))) {
>  			if (!strtok_r(NULL, ",", &saveptr)) {
>  				param->record_mode = CALLCHAIN_LBR;
> -- 
> 1.8.5.2

^ permalink raw reply	[flat|nested] 22+ messages in thread

* Re: [PATCH 2/8] perf script: Add options for custom vdso name
  2016-05-06  8:59 ` [PATCH 2/8] perf script: Add options for custom vdso name He Kuang
@ 2016-05-06 11:49   ` Arnaldo Carvalho de Melo
  2016-05-07 18:14   ` Jiri Olsa
  1 sibling, 0 replies; 22+ messages in thread
From: Arnaldo Carvalho de Melo @ 2016-05-06 11:49 UTC (permalink / raw)
  To: He Kuang
  Cc: peterz, mingo, alexander.shishkin, jolsa, wangnan0, jpoimboe, ak,
	eranian, namhyung, adrian.hunter, sukadev, masami.hiramatsu.pt,
	tumanova, kan.liang, penberg, dsahern, linux-kernel

Em Fri, May 06, 2016 at 08:59:08AM +0000, He Kuang escreveu:
> When unwinding callchain on different machine, vdso info should be
> provided so the unwind process won't be interrupted if address fell
> into vdso region.
> 
> Signed-off-by: He Kuang <hekuang@huawei.com>
> ---
>  tools/perf/builtin-script.c | 2 ++
>  tools/perf/util/dso.c       | 7 +++++++
>  tools/perf/util/dso.h       | 1 +
>  tools/perf/util/symbol.c    | 1 +
>  tools/perf/util/symbol.h    | 1 +
>  5 files changed, 12 insertions(+)
> 
> diff --git a/tools/perf/builtin-script.c b/tools/perf/builtin-script.c
> index 8f6ab2a..c88b547 100644
> --- a/tools/perf/builtin-script.c
> +++ b/tools/perf/builtin-script.c
> @@ -2001,6 +2001,8 @@ int cmd_script(int argc, const char **argv, const char *prefix __maybe_unused)
>  		   "file", "vmlinux pathname"),
>  	OPT_STRING(0, "kallsyms", &symbol_conf.kallsyms_name,
>  		   "file", "kallsyms pathname"),
> +	OPT_STRING(0, "vdso", &symbol_conf.vdso_name,
> +		   "file", "vdso pathname"),
>  	OPT_BOOLEAN('G', "hide-call-graph", &no_callchain,
>  		    "When printing symbols do not display call chain"),
>  	OPT_STRING(0, "symfs", &symbol_conf.symfs, "directory",
> diff --git a/tools/perf/util/dso.c b/tools/perf/util/dso.c
> index 8e639543..344db10 100644
> --- a/tools/perf/util/dso.c
> +++ b/tools/perf/util/dso.c
> @@ -21,6 +21,7 @@ char dso__symtab_origin(const struct dso *dso)
>  		[DSO_BINARY_TYPE__OPENEMBEDDED_DEBUGINFO]	= 'o',
>  		[DSO_BINARY_TYPE__BUILDID_DEBUGINFO]		= 'b',
>  		[DSO_BINARY_TYPE__SYSTEM_PATH_DSO]		= 'd',
> +		[DSO_BINARY_TYPE__SYSTEM_PATH_DSO_CUSTOM]	= 'r',
>  		[DSO_BINARY_TYPE__SYSTEM_PATH_KMODULE]		= 'K',
>  		[DSO_BINARY_TYPE__SYSTEM_PATH_KMODULE_COMP]	= 'm',
>  		[DSO_BINARY_TYPE__GUEST_KALLSYMS]		= 'g',
> @@ -113,6 +114,11 @@ int dso__read_binary_type_filename(const struct dso *dso,
>  			 build_id_hex, build_id_hex + 2);
>  		break;
>  
> +	case DSO_BINARY_TYPE__SYSTEM_PATH_DSO_CUSTOM:
> +	{
> +		snprintf(filename, size, "%s", symbol_conf.vdso_name);
> +		break;
> +	}

Remove the {}, not needed at all.

>  	case DSO_BINARY_TYPE__VMLINUX:
>  	case DSO_BINARY_TYPE__GUEST_VMLINUX:
>  	case DSO_BINARY_TYPE__SYSTEM_PATH_DSO:
> @@ -487,6 +493,7 @@ static void try_to_open_dso(struct dso *dso, struct machine *machine)
>  	enum dso_binary_type binary_type_data[] = {
>  		DSO_BINARY_TYPE__BUILD_ID_CACHE,
>  		DSO_BINARY_TYPE__SYSTEM_PATH_DSO,
> +		DSO_BINARY_TYPE__SYSTEM_PATH_DSO_CUSTOM,

Why do you call it a "DSO_CUSTOM" in some places while in others you
call it vdso_name?

>  		DSO_BINARY_TYPE__NOT_FOUND,
>  	};
>  	int i = 0;
> diff --git a/tools/perf/util/dso.h b/tools/perf/util/dso.h
> index 0953280..f55ce5b 100644
> --- a/tools/perf/util/dso.h
> +++ b/tools/perf/util/dso.h
> @@ -23,6 +23,7 @@ enum dso_binary_type {
>  	DSO_BINARY_TYPE__UBUNTU_DEBUGINFO,
>  	DSO_BINARY_TYPE__BUILDID_DEBUGINFO,
>  	DSO_BINARY_TYPE__SYSTEM_PATH_DSO,
> +	DSO_BINARY_TYPE__SYSTEM_PATH_DSO_CUSTOM,
>  	DSO_BINARY_TYPE__GUEST_KMODULE,
>  	DSO_BINARY_TYPE__GUEST_KMODULE_COMP,
>  	DSO_BINARY_TYPE__SYSTEM_PATH_KMODULE,
> diff --git a/tools/perf/util/symbol.c b/tools/perf/util/symbol.c
> index e7588dc..93f348f 100644
> --- a/tools/perf/util/symbol.c
> +++ b/tools/perf/util/symbol.c
> @@ -1359,6 +1359,7 @@ static bool dso__is_compatible_symtab_type(struct dso *dso, bool kmod,
>  	case DSO_BINARY_TYPE__JAVA_JIT:
>  	case DSO_BINARY_TYPE__DEBUGLINK:
>  	case DSO_BINARY_TYPE__SYSTEM_PATH_DSO:
> +	case DSO_BINARY_TYPE__SYSTEM_PATH_DSO_CUSTOM:
>  	case DSO_BINARY_TYPE__FEDORA_DEBUGINFO:
>  	case DSO_BINARY_TYPE__UBUNTU_DEBUGINFO:
>  	case DSO_BINARY_TYPE__BUILDID_DEBUGINFO:
> diff --git a/tools/perf/util/symbol.h b/tools/perf/util/symbol.h
> index c8b7544..4e6910e 100644
> --- a/tools/perf/util/symbol.h
> +++ b/tools/perf/util/symbol.h
> @@ -114,6 +114,7 @@ struct symbol_conf {
>  			report_hierarchy;
>  	const char	*vmlinux_name,
>  			*kallsyms_name,
> +			*vdso_name,
>  			*source_prefix,
>  			*field_sep;
>  	const char	*default_guest_vmlinux_name,
> -- 
> 1.8.5.2

^ permalink raw reply	[flat|nested] 22+ messages in thread

* Re: [PATCH 6/8] perf callchain: Add support for cross-platform unwind
  2016-05-06  8:59 ` [PATCH 6/8] perf callchain: Add support " He Kuang
@ 2016-05-06 11:56   ` Arnaldo Carvalho de Melo
  0 siblings, 0 replies; 22+ messages in thread
From: Arnaldo Carvalho de Melo @ 2016-05-06 11:56 UTC (permalink / raw)
  To: He Kuang
  Cc: peterz, mingo, alexander.shishkin, jolsa, wangnan0, jpoimboe, ak,
	eranian, namhyung, adrian.hunter, sukadev, masami.hiramatsu.pt,
	tumanova, kan.liang, penberg, dsahern, linux-kernel

Em Fri, May 06, 2016 at 08:59:12AM +0000, He Kuang escreveu:
> Use thread specific unwind ops to unwind cross-platform callchains.
> 
> Before this patch, unwind methods is suitable for local unwind, this
> patch changes the fixed methods to thread/map related. Each time a map
> is inserted, we find the target arch and see if this platform can be
> remote unwind. In this patch, we test for x86 platform and only show
> proper messages. The real unwind methods are not implemented, will be
> introduced in next patch.
> 
> Signed-off-by: He Kuang <hekuang@huawei.com>
> ---
>  tools/perf/config/Makefile                | 19 ++++++++--
>  tools/perf/util/Build                     |  3 +-
>  tools/perf/util/thread.c                  | 29 +++++++++++----
>  tools/perf/util/thread.h                  | 14 +++++++-
>  tools/perf/util/unwind-libunwind.c        | 48 +++++++++++++++++++++----
>  tools/perf/util/unwind-libunwind_common.c | 60 +++++++++++++++++++++++++++++++
>  tools/perf/util/unwind.h                  | 22 ++++++++++++
>  7 files changed, 178 insertions(+), 17 deletions(-)
>  create mode 100644 tools/perf/util/unwind-libunwind_common.c
> 
> diff --git a/tools/perf/config/Makefile b/tools/perf/config/Makefile
> index a86b864..16f14b1 100644
> --- a/tools/perf/config/Makefile
> +++ b/tools/perf/config/Makefile
> @@ -345,14 +345,24 @@ ifeq ($(ARCH),powerpc)
>  endif
>  
>  ifndef NO_LIBUNWIND
> +  have_libunwind =
>    ifeq ($(feature-libunwind-x86), 1)
> -    LIBUNWIND_LIBS += -lunwind-x86
>      $(call detected,CONFIG_LIBUNWIND_X86)
>      CFLAGS += -DHAVE_LIBUNWIND_X86_SUPPORT
> +    LDFLAGS += -lunwind -lunwind-x86
> +    have_libunwind = 1
>    endif
>  
>    ifneq ($(feature-libunwind), 1)
>      msg := $(warning No libunwind found. Please install libunwind-dev[el] >= 1.1 and/or set LIBUNWIND_DIR);
> +    NO_LOCAL_LIBUNWIND := 1
> +  else
> +    have_libunwind = 1
> +    CFLAGS += -DHAVE_LIBUNWIND_LOCAL_SUPPORT
> +    $(call detected,CONFIG_LOCAL_LIBUNWIND)
> +  endif
> +
> +  ifneq ($(have_libunwind), 1)
>      NO_LIBUNWIND := 1
>    endif
>  endif
> @@ -392,7 +402,7 @@ else
>    NO_DWARF_UNWIND := 1
>  endif
>  
> -ifndef NO_LIBUNWIND
> +ifndef NO_LOCAL_LIBUNWIND
>    ifeq ($(ARCH),$(filter $(ARCH),arm arm64))
>      $(call feature_check,libunwind-debug-frame)
>      ifneq ($(feature-libunwind-debug-frame), 1)
> @@ -403,12 +413,15 @@ ifndef NO_LIBUNWIND
>      # non-ARM has no dwarf_find_debug_frame() function:
>      CFLAGS += -DNO_LIBUNWIND_DEBUG_FRAME
>    endif
> -  CFLAGS  += -DHAVE_LIBUNWIND_SUPPORT
>    EXTLIBS += $(LIBUNWIND_LIBS)
>    CFLAGS  += $(LIBUNWIND_CFLAGS)
>    LDFLAGS += $(LIBUNWIND_LDFLAGS)
>  endif
>  
> +ifndef NO_LIBUNWIND
> +  CFLAGS  += -DHAVE_LIBUNWIND_SUPPORT
> +endif
> +
>  ifndef NO_LIBAUDIT
>    ifneq ($(feature-libaudit), 1)
>      msg := $(warning No libaudit.h found, disables 'trace' tool, please install audit-libs-devel or libaudit-dev);
> diff --git a/tools/perf/util/Build b/tools/perf/util/Build
> index ea4ac03..2e21529 100644
> --- a/tools/perf/util/Build
> +++ b/tools/perf/util/Build
> @@ -97,7 +97,8 @@ libperf-$(CONFIG_DWARF) += probe-finder.o
>  libperf-$(CONFIG_DWARF) += dwarf-aux.o
>  
>  libperf-$(CONFIG_LIBDW_DWARF_UNWIND) += unwind-libdw.o
> -libperf-$(CONFIG_LIBUNWIND)          += unwind-libunwind.o
> +libperf-$(CONFIG_LOCAL_LIBUNWIND)    += unwind-libunwind.o
> +libperf-$(CONFIG_LIBUNWIND)          += unwind-libunwind_common.o
>  
>  libperf-$(CONFIG_LIBBABELTRACE) += data-convert-bt.o
>  
> diff --git a/tools/perf/util/thread.c b/tools/perf/util/thread.c
> index e0cdcf7..cf60db1 100644
> --- a/tools/perf/util/thread.c
> +++ b/tools/perf/util/thread.c
> @@ -41,9 +41,6 @@ struct thread *thread__new(pid_t pid, pid_t tid)
>  		thread->cpu = -1;
>  		INIT_LIST_HEAD(&thread->comm_list);
>  
> -		if (unwind__prepare_access(thread) < 0)
> -			goto err_thread;
> -
>  		comm_str = malloc(32);
>  		if (!comm_str)
>  			goto err_thread;
> @@ -57,6 +54,9 @@ struct thread *thread__new(pid_t pid, pid_t tid)
>  		list_add(&comm->list, &thread->comm_list);
>  		atomic_set(&thread->refcnt, 1);
>  		RB_CLEAR_NODE(&thread->rb_node);
> +#ifdef HAVE_LIBUNWIND_SUPPORT
> +		register_null_unwind_libunwind_ops(thread);
> +#endif

Could you please avoid having all those ifdefs sprinkled in the .c file?
For instance, the above ifdef/endif should be dropped and instead, at a
central place, a header probably, or at most at the start of the .c
file, you should have one ifdef block, the else should just make the
above function, for instance, be:

#ifdef HAVE_LIBUNWIND_SUPPORT
void register_null_unwind_libunwind_ops(struct thread *thread);
#else
static inline
void register_null_unwind_libunwind_ops(struct thread *thread __maybe_unused)
{
}
#endif

>  	}
>  
>  	return thread;
> @@ -82,7 +82,9 @@ void thread__delete(struct thread *thread)
>  		list_del(&comm->list);
>  		comm__free(comm);
>  	}
> -	unwind__finish_access(thread);
> +#ifdef HAVE_LIBUNWIND_SUPPORT
> +	thread->unwind_libunwind_ops->finish_access(thread);
> +#endif
>  
>  	free(thread);
>  }
> @@ -144,8 +146,10 @@ int __thread__set_comm(struct thread *thread, const char *str, u64 timestamp,
>  			return -ENOMEM;
>  		list_add(&new->list, &thread->comm_list);
>  
> +#ifdef HAVE_LIBUNWIND_SUPPORT
>  		if (exec)
> -			unwind__flush_access(thread);
> +			thread->unwind_libunwind_ops->flush_access(thread);
> +#endif

You see, here the original code should be left untouched and you would
change unwind__flush_access() instead to be:

#ifdef HAVE_LIBUNWIND_SUPPORT
void unwind__flush_access(struct thread *thread)
{
	thread->unwind_libunwind_ops->flush_access(thread);
}
#else
void unwind__flush_access(struct thread *thread __maybe_unused)
{
}
#endif

combine the above if/else/endif with the previous and with all the
others, please.

>  	}
>  
>  	thread->comm_set = true;
> @@ -208,14 +212,27 @@ void thread__insert_map(struct thread *thread, struct map *map)
>  		   || !strcmp(arch, "x86")
>  		   || !strcmp(arch, "i686")) {
>  		pr_debug("Thread map is X86, 64bit is %d\n", is_64_bit);
> -		if (!is_64_bit)
> +		if (!is_64_bit) {
>  #ifdef HAVE_LIBUNWIND_X86_SUPPORT
>  			pr_err("target platform=%s is not implemented!\n",
>  			       arch);
>  #else
>  			pr_err("target platform=%s is not supported!\n", arch);
>  #endif
> +			goto err;
> +		}
> +	} else {
> +		register_local_unwind_libunwind_ops(thread);
>  	}
> +
> +	if (thread->unwind_libunwind_ops->prepare_access(thread) < 0)
> +		return;
> +
> +	return;
> +
> +err: __maybe_unused
> +	register_null_unwind_libunwind_ops(thread);
> +	return;
>  #endif
>  }
>  
> diff --git a/tools/perf/util/thread.h b/tools/perf/util/thread.h
> index e214207..6f2d4cd 100644
> --- a/tools/perf/util/thread.h
> +++ b/tools/perf/util/thread.h
> @@ -15,6 +15,17 @@
>  
>  struct thread_stack;
>  
> +struct unwind_entry;
> +typedef int (*unwind_entry_cb_t)(struct unwind_entry *entry, void *arg);
> +struct unwind_libunwind_ops {
> +	int (*prepare_access)(struct thread *thread);
> +	void (*flush_access)(struct thread *thread);
> +	void (*finish_access)(struct thread *thread);
> +	int (*get_entries)(unwind_entry_cb_t cb, void *arg,
> +			   struct thread *thread,
> +			   struct perf_sample *data, int max_stack);
> +};
> +
>  struct thread {
>  	union {
>  		struct rb_node	 rb_node;
> @@ -36,7 +47,8 @@ struct thread {
>  	void			*priv;
>  	struct thread_stack	*ts;
>  #ifdef HAVE_LIBUNWIND_SUPPORT
> -	unw_addr_space_t	addr_space;
> +	unw_addr_space_t		addr_space;
> +	struct unwind_libunwind_ops	*unwind_libunwind_ops;
>  #endif
>  };
>  
> diff --git a/tools/perf/util/unwind-libunwind.c b/tools/perf/util/unwind-libunwind.c
> index 63687d3..2558bf3 100644
> --- a/tools/perf/util/unwind-libunwind.c
> +++ b/tools/perf/util/unwind-libunwind.c
> @@ -22,6 +22,9 @@
>  #include <unistd.h>
>  #include <sys/mman.h>
>  #include <linux/list.h>
> +#ifdef ARCH_UNWIND_LIBUNWIND
> +#include "libunwind-arch.h"
> +#endif
>  #include <libunwind.h>
>  #include <libunwind-ptrace.h>
>  #include "callchain.h"
> @@ -34,6 +37,22 @@
>  #include "debug.h"
>  #include "asm/bug.h"
>  
> +#ifndef ARCH_UNWIND_LIBUNWIND
> +  #define LIBUNWIND__ARCH_REG_ID libunwind__arch_reg_id
> +  #define LOCAL_UNWIND_LIBUNWIND
> +  #undef UNWT_OBJ
> +  #define UNWT_OBJ(x) _##x
> +#else
> +  #undef NO_LIBUNWIND_DEBUG_FRAME
> +  #if defined(LIBUNWIND_ARM) && !defined(NO_LIBUNWIND_DEBUG_FRAME_ARM)
> +  #elif defined(LIBUNWIND_AARCH64) &&                    \
> +	  defined(NO_LIBUNWIND_DEBUG_FRAME_ARM_AARCH64)
> +  #else
> +    #define NO_LIBUNWIND_DEBUG_FRAME
> +  #endif
> +#endif
> +
> +
>  extern int
>  UNW_OBJ(dwarf_search_unwind_table) (unw_addr_space_t as,
>  				    unw_word_t ip,
> @@ -579,7 +598,7 @@ static unw_accessors_t accessors = {
>  	.get_proc_name		= get_proc_name,
>  };
>  
> -int unwind__prepare_access(struct thread *thread)
> +static int UNWT_OBJ(_unwind__prepare_access)(struct thread *thread)
>  {
>  	if (callchain_param.record_mode != CALLCHAIN_DWARF)
>  		return 0;
> @@ -594,7 +613,7 @@ int unwind__prepare_access(struct thread *thread)
>  	return 0;
>  }
>  
> -void unwind__flush_access(struct thread *thread)
> +static void UNWT_OBJ(_unwind__flush_access)(struct thread *thread)
>  {
>  	if (callchain_param.record_mode != CALLCHAIN_DWARF)
>  		return;
> @@ -602,7 +621,7 @@ void unwind__flush_access(struct thread *thread)
>  	unw_flush_cache(thread->addr_space, 0, 0);
>  }
>  
> -void unwind__finish_access(struct thread *thread)
> +static void UNWT_OBJ(_unwind__finish_access)(struct thread *thread)
>  {
>  	if (callchain_param.record_mode != CALLCHAIN_DWARF)
>  		return;
> @@ -662,9 +681,10 @@ static int get_entries(struct unwind_info *ui, unwind_entry_cb_t cb,
>  	return ret;
>  }
>  
> -int unwind__get_entries(unwind_entry_cb_t cb, void *arg,
> -			struct thread *thread,
> -			struct perf_sample *data, int max_stack)
> +static int UNWT_OBJ(_unwind__get_entries)(unwind_entry_cb_t cb, void *arg,
> +					 struct thread *thread,
> +					 struct perf_sample *data,
> +					 int max_stack)
>  {
>  	struct unwind_info ui = {
>  		.sample       = data,
> @@ -680,3 +700,19 @@ int unwind__get_entries(unwind_entry_cb_t cb, void *arg,
>  
>  	return get_entries(&ui, cb, arg, max_stack);
>  }
> +
> +struct unwind_libunwind_ops
> +UNWT_OBJ(unwind_libunwind_ops) = {
> +	.prepare_access = UNWT_OBJ(_unwind__prepare_access),
> +	.flush_access   = UNWT_OBJ(_unwind__flush_access),
> +	.finish_access  = UNWT_OBJ(_unwind__finish_access),
> +	.get_entries    = UNWT_OBJ(_unwind__get_entries),
> +};
> +
> +#ifdef LOCAL_UNWIND_LIBUNWIND
> +int register_local_unwind_libunwind_ops(struct thread *thread)
> +{
> +	thread->unwind_libunwind_ops = &UNWT_OBJ(unwind_libunwind_ops);
> +	return 0;
> +}
> +#endif
> diff --git a/tools/perf/util/unwind-libunwind_common.c b/tools/perf/util/unwind-libunwind_common.c
> new file mode 100644
> index 0000000..47433a4
> --- /dev/null
> +++ b/tools/perf/util/unwind-libunwind_common.c
> @@ -0,0 +1,60 @@
> +#include <elf.h>
> +#include <gelf.h>
> +#include <fcntl.h>
> +#include <string.h>
> +#include <unistd.h>
> +#include <sys/mman.h>
> +#include <linux/list.h>
> +#include <libunwind.h>
> +#include <libunwind-ptrace.h>
> +#include "callchain.h"
> +#include "thread.h"
> +#include "session.h"
> +#include "perf_regs.h"
> +#include "unwind.h"
> +#include "symbol.h"
> +#include "util.h"
> +#include "debug.h"
> +#include "asm/bug.h"
> +
> +static int __null__prepare_access(struct thread *thread __maybe_unused)
> +{
> +	return 0;
> +}
> +
> +static void __null__flush_access(struct thread *thread __maybe_unused)
> +{
> +}
> +
> +static void __null__finish_access(struct thread *thread __maybe_unused)
> +{
> +}
> +
> +static int __null__get_entries(unwind_entry_cb_t cb __maybe_unused,
> +			       void *arg __maybe_unused,
> +			       struct thread *thread __maybe_unused,
> +			       struct perf_sample *data __maybe_unused,
> +			       int max_stack __maybe_unused)
> +{
> +	return 0;
> +}
> +
> +static struct unwind_libunwind_ops null_unwind_libunwind_ops = {
> +	.prepare_access = __null__prepare_access,
> +	.flush_access   = __null__flush_access,
> +	.finish_access  = __null__finish_access,
> +	.get_entries    = __null__get_entries,
> +};
> +
> +int register_null_unwind_libunwind_ops(struct thread *thread)
> +{
> +	thread->unwind_libunwind_ops = &null_unwind_libunwind_ops;
> +	return 0;
> +}
> +
> +int register_unwind_libunwind_ops(struct unwind_libunwind_ops *ops,
> +				  struct thread *thread)
> +{
> +	thread->unwind_libunwind_ops = ops;
> +	return 0;
> +}
> diff --git a/tools/perf/util/unwind.h b/tools/perf/util/unwind.h
> index 12790cf..61b44a6 100644
> --- a/tools/perf/util/unwind.h
> +++ b/tools/perf/util/unwind.h
> @@ -24,6 +24,28 @@ int libunwind__arch_reg_id(int regnum);
>  int unwind__prepare_access(struct thread *thread);
>  void unwind__flush_access(struct thread *thread);
>  void unwind__finish_access(struct thread *thread);
> +int register_unwind_libunwind_ops(struct unwind_libunwind_ops *ops,
> +				  struct thread *thread);
> +int register_null_unwind_libunwind_ops(struct thread *thread);
> +
> +#ifndef HAVE_LIBUNWIND_LOCAL_SUPPORT
> +static inline int
> +register_local_unwind_libunwind_ops(struct thread *thread) {
> +	return register_null_unwind_libunwind_ops(thread);
> +}
> +#else
> +int register_local_unwind_libunwind_ops(struct thread *thread);
> +#endif
> +
> +#define unwind__get_entries(cb, arg,					\
> +			    thread,					\
> +			    data, max_stack)				\
> +	thread->unwind_libunwind_ops->get_entries(cb,			\
> +						  arg,			\
> +						  thread,		\
> +						  data,			\
> +						  max_stack)
> +
>  #else
>  static inline int unwind__prepare_access(struct thread *thread __maybe_unused)
>  {
> -- 
> 1.8.5.2

^ permalink raw reply	[flat|nested] 22+ messages in thread

* Re: [PATCH 0/8] Add support for remote unwind
  2016-05-06  8:59 [PATCH 0/8] Add support for remote unwind He Kuang
                   ` (7 preceding siblings ...)
  2016-05-06  8:59 ` [PATCH 8/8] perf callchain: Support aarch64 cross-platform He Kuang
@ 2016-05-06 11:58 ` Arnaldo Carvalho de Melo
  8 siblings, 0 replies; 22+ messages in thread
From: Arnaldo Carvalho de Melo @ 2016-05-06 11:58 UTC (permalink / raw)
  To: He Kuang, Jiri Olsa
  Cc: peterz, Ingo Molnar, alexander.shishkin, jolsa, wangnan0,
	jpoimboe, ak, eranian, namhyung, adrian.hunter, sukadev,
	masami.hiramatsu.pt, tumanova, kan.liang, penberg, dsahern,
	linux-kernel

Em Fri, May 06, 2016 at 08:59:06AM +0000, He Kuang escreveu:
> Currently, perf script uses host unwind methods to parse perf.data
> callchain info regardless of the target architecture. So we get wrong
> result and no promotion when do remote unwind on other
> platforms/machines.

Thanks for working on this, being able to record on one machine and do
analysis in another, of a different hw architectures is indeed a goal
for the perf tools!

Jiri, if you could please take a look, that would be really great!

- Arnaldo
 
> This patch set adds build tests for the supported platforms for remote
> unwinding, and checks the map elf info for each thread, use remote
> unwind methods instead.
> 
> Only x86 and aarch64 is added in this patch set to show the work flow,
> other platforms can be added easily.
> 
> We can see the right result for unwind infos on different machines,
> for example: we record perf.data on i686 qemu with '-g' option and
> parse it on x86_64 machine.
> 
> before this patchset:
> 
>   hello  1071 [000]   417.567832: probe:sys_close: (c1169d60)
>                   c1169d61 sys_close ([kernel.kallsyms])
>                   c189c0d7 sysenter_past_esp ([kernel.kallsyms])
>                   b77c8ba9 [unknown] ([vdso32])
>   
> after:
> 
>   hello  1071 [000]   417.567832: probe:sys_close: (c1169d60)
>                   c1169d61 sys_close ([kernel.kallsyms])
>                   c189c0d7 sysenter_past_esp ([kernel.kallsyms])
>                   b77c8ba9 [unknown] ([vdso32])
>                   b76e51cc close (/lib/libc-2.22.so)
>                    804842e fib (/tmp/hello)
>                    804849d main (/tmp/hello)
>                   b762546e __libc_start_main (/lib/libc-2.22.so)
>                    8048341 _start (/tmp/hello)
> 
> Thanks, discussion welcomed.
> 
> He Kuang (8):
>   perf tools: Omit DWARF judgement when recording dwarf callchain
>   perf script: Add options for custom vdso name
>   perf build: Add build-test for libunwind cross-platforms support
>   perf build: Add build-test for debug-frame on arm/arm64
>   perf tools: Promote proper messages for cross-platform unwind
>   perf callchain: Add support for cross-platform unwind
>   perf callchain: Support x86 target platform
>   perf callchain: Support aarch64 cross-platform
> 
>  tools/build/Makefile.feature                       | 11 +++-
>  tools/build/feature/Makefile                       | 26 +++++++-
>  tools/build/feature/test-libunwind-aarch64.c       | 26 ++++++++
>  tools/build/feature/test-libunwind-arm.c           | 27 +++++++++
>  .../feature/test-libunwind-debug-frame-aarch64.c   | 16 +++++
>  .../build/feature/test-libunwind-debug-frame-arm.c | 16 +++++
>  tools/build/feature/test-libunwind-debug-frame.c   | 16 -----
>  tools/build/feature/test-libunwind-x86.c           | 27 +++++++++
>  tools/build/feature/test-libunwind-x86_64.c        | 27 +++++++++
>  .../arch/arm64/include/libunwind/libunwind-arch.h  | 18 ++++++
>  tools/perf/arch/arm64/util/unwind-libunwind.c      |  5 +-
>  .../arch/x86/include/libunwind/libunwind-arch.h    | 18 ++++++
>  tools/perf/arch/x86/util/unwind-libunwind.c        | 42 +++++++++++++
>  tools/perf/builtin-script.c                        |  2 +
>  tools/perf/config/Makefile                         | 35 ++++++++++-
>  tools/perf/util/Build                              | 13 +++-
>  tools/perf/util/dso.c                              |  7 +++
>  tools/perf/util/dso.h                              |  1 +
>  tools/perf/util/symbol-elf.c                       | 16 +++++
>  tools/perf/util/symbol.c                           | 50 ++++++++++++++++
>  tools/perf/util/symbol.h                           |  3 +
>  tools/perf/util/thread.c                           | 70 ++++++++++++++++++++--
>  tools/perf/util/thread.h                           | 14 ++++-
>  tools/perf/util/unwind-libunwind.c                 | 50 +++++++++++++---
>  tools/perf/util/unwind-libunwind_common.c          | 60 +++++++++++++++++++
>  tools/perf/util/unwind.h                           | 30 ++++++++++
>  tools/perf/util/util.c                             |  2 -
>  27 files changed, 589 insertions(+), 39 deletions(-)
>  create mode 100644 tools/build/feature/test-libunwind-aarch64.c
>  create mode 100644 tools/build/feature/test-libunwind-arm.c
>  create mode 100644 tools/build/feature/test-libunwind-debug-frame-aarch64.c
>  create mode 100644 tools/build/feature/test-libunwind-debug-frame-arm.c
>  delete mode 100644 tools/build/feature/test-libunwind-debug-frame.c
>  create mode 100644 tools/build/feature/test-libunwind-x86.c
>  create mode 100644 tools/build/feature/test-libunwind-x86_64.c
>  create mode 100644 tools/perf/arch/arm64/include/libunwind/libunwind-arch.h
>  create mode 100644 tools/perf/arch/x86/include/libunwind/libunwind-arch.h
>  create mode 100644 tools/perf/util/unwind-libunwind_common.c
> 
> -- 
> 1.8.5.2

^ permalink raw reply	[flat|nested] 22+ messages in thread

* Re: [PATCH 1/8] perf tools: Omit DWARF judgement when recording dwarf callchain
  2016-05-06  8:59 ` [PATCH 1/8] perf tools: Omit DWARF judgement when recording dwarf callchain He Kuang
  2016-05-06 11:47   ` Arnaldo Carvalho de Melo
@ 2016-05-07 18:03   ` Jiri Olsa
  2016-05-09 16:16     ` Arnaldo Carvalho de Melo
  2016-05-10 20:30   ` [tip:perf/core] perf callchain: Recording 'dwarf' callchains do not need DWARF unwinding support tip-bot for He Kuang
  2 siblings, 1 reply; 22+ messages in thread
From: Jiri Olsa @ 2016-05-07 18:03 UTC (permalink / raw)
  To: He Kuang
  Cc: peterz, mingo, acme, alexander.shishkin, wangnan0, jpoimboe, ak,
	eranian, namhyung, adrian.hunter, sukadev, masami.hiramatsu.pt,
	tumanova, kan.liang, penberg, dsahern, linux-kernel

On Fri, May 06, 2016 at 08:59:07AM +0000, He Kuang wrote:
> There's no need for dwarf support when perf recording with callchain.
> 
> Signed-off-by: He Kuang <hekuang@huawei.com>

Acked-by: Jiri Olsa <jolsa@kernel.org>

thanks,
jirka

> ---
>  tools/perf/util/util.c | 2 --
>  1 file changed, 2 deletions(-)
> 
> diff --git a/tools/perf/util/util.c b/tools/perf/util/util.c
> index b7766c5..e5ebfd4 100644
> --- a/tools/perf/util/util.c
> +++ b/tools/perf/util/util.c
> @@ -471,7 +471,6 @@ int parse_callchain_record(const char *arg, struct callchain_param *param)
>  				       "needed for --call-graph fp\n");
>  			break;
>  
> -#ifdef HAVE_DWARF_UNWIND_SUPPORT
>  		/* Dwarf style */
>  		} else if (!strncmp(name, "dwarf", sizeof("dwarf"))) {
>  			const unsigned long default_stack_dump_size = 8192;
> @@ -487,7 +486,6 @@ int parse_callchain_record(const char *arg, struct callchain_param *param)
>  				ret = get_stack_size(tok, &size);
>  				param->dump_size = size;
>  			}
> -#endif /* HAVE_DWARF_UNWIND_SUPPORT */
>  		} else if (!strncmp(name, "lbr", sizeof("lbr"))) {
>  			if (!strtok_r(NULL, ",", &saveptr)) {
>  				param->record_mode = CALLCHAIN_LBR;
> -- 
> 1.8.5.2
> 

^ permalink raw reply	[flat|nested] 22+ messages in thread

* Re: [PATCH 2/8] perf script: Add options for custom vdso name
  2016-05-06  8:59 ` [PATCH 2/8] perf script: Add options for custom vdso name He Kuang
  2016-05-06 11:49   ` Arnaldo Carvalho de Melo
@ 2016-05-07 18:14   ` Jiri Olsa
  1 sibling, 0 replies; 22+ messages in thread
From: Jiri Olsa @ 2016-05-07 18:14 UTC (permalink / raw)
  To: He Kuang
  Cc: peterz, mingo, acme, alexander.shishkin, wangnan0, jpoimboe, ak,
	eranian, namhyung, adrian.hunter, sukadev, masami.hiramatsu.pt,
	tumanova, kan.liang, penberg, dsahern, linux-kernel

On Fri, May 06, 2016 at 08:59:08AM +0000, He Kuang wrote:
> When unwinding callchain on different machine, vdso info should be
> provided so the unwind process won't be interrupted if address fell
> into vdso region.
> 
> Signed-off-by: He Kuang <hekuang@huawei.com>
> ---
>  tools/perf/builtin-script.c | 2 ++
>  tools/perf/util/dso.c       | 7 +++++++
>  tools/perf/util/dso.h       | 1 +
>  tools/perf/util/symbol.c    | 1 +
>  tools/perf/util/symbol.h    | 1 +
>  5 files changed, 12 insertions(+)
> 
> diff --git a/tools/perf/builtin-script.c b/tools/perf/builtin-script.c
> index 8f6ab2a..c88b547 100644
> --- a/tools/perf/builtin-script.c
> +++ b/tools/perf/builtin-script.c
> @@ -2001,6 +2001,8 @@ int cmd_script(int argc, const char **argv, const char *prefix __maybe_unused)
>  		   "file", "vmlinux pathname"),
>  	OPT_STRING(0, "kallsyms", &symbol_conf.kallsyms_name,
>  		   "file", "kallsyms pathname"),
> +	OPT_STRING(0, "vdso", &symbol_conf.vdso_name,
> +		   "file", "vdso pathname"),
>  	OPT_BOOLEAN('G', "hide-call-graph", &no_callchain,
>  		    "When printing symbols do not display call chain"),
>  	OPT_STRING(0, "symfs", &symbol_conf.symfs, "directory",
> diff --git a/tools/perf/util/dso.c b/tools/perf/util/dso.c
> index 8e639543..344db10 100644
> --- a/tools/perf/util/dso.c
> +++ b/tools/perf/util/dso.c
> @@ -21,6 +21,7 @@ char dso__symtab_origin(const struct dso *dso)
>  		[DSO_BINARY_TYPE__OPENEMBEDDED_DEBUGINFO]	= 'o',
>  		[DSO_BINARY_TYPE__BUILDID_DEBUGINFO]		= 'b',
>  		[DSO_BINARY_TYPE__SYSTEM_PATH_DSO]		= 'd',
> +		[DSO_BINARY_TYPE__SYSTEM_PATH_DSO_CUSTOM]	= 'r',
>  		[DSO_BINARY_TYPE__SYSTEM_PATH_KMODULE]		= 'K',
>  		[DSO_BINARY_TYPE__SYSTEM_PATH_KMODULE_COMP]	= 'm',
>  		[DSO_BINARY_TYPE__GUEST_KALLSYMS]		= 'g',
> @@ -113,6 +114,11 @@ int dso__read_binary_type_filename(const struct dso *dso,
>  			 build_id_hex, build_id_hex + 2);
>  		break;
>  
> +	case DSO_BINARY_TYPE__SYSTEM_PATH_DSO_CUSTOM:
> +	{
> +		snprintf(filename, size, "%s", symbol_conf.vdso_name);
> +		break;
> +	}
>  	case DSO_BINARY_TYPE__VMLINUX:
>  	case DSO_BINARY_TYPE__GUEST_VMLINUX:
>  	case DSO_BINARY_TYPE__SYSTEM_PATH_DSO:
> @@ -487,6 +493,7 @@ static void try_to_open_dso(struct dso *dso, struct machine *machine)
>  	enum dso_binary_type binary_type_data[] = {
>  		DSO_BINARY_TYPE__BUILD_ID_CACHE,
>  		DSO_BINARY_TYPE__SYSTEM_PATH_DSO,
> +		DSO_BINARY_TYPE__SYSTEM_PATH_DSO_CUSTOM,

could you please elaborate on how this one gets set?
don't we already store it under .debug?

also it seems fairly vdso specific, we shouldn't call it DSO_CUSTOM

thanks,
jirka

^ permalink raw reply	[flat|nested] 22+ messages in thread

* Re: [PATCH 3/8] perf build: Add build-test for libunwind cross-platforms support
  2016-05-06  8:59 ` [PATCH 3/8] perf build: Add build-test for libunwind cross-platforms support He Kuang
@ 2016-05-07 18:20   ` Jiri Olsa
  0 siblings, 0 replies; 22+ messages in thread
From: Jiri Olsa @ 2016-05-07 18:20 UTC (permalink / raw)
  To: He Kuang
  Cc: peterz, mingo, acme, alexander.shishkin, wangnan0, jpoimboe, ak,
	eranian, namhyung, adrian.hunter, sukadev, masami.hiramatsu.pt,
	tumanova, kan.liang, penberg, dsahern, linux-kernel

On Fri, May 06, 2016 at 08:59:09AM +0000, He Kuang wrote:
> Currently only test for local libunwind. We should check all supported
> platforms so we can use them to parse perf.data with callchain info on
> different machines.
> 
> Signed-off-by: He Kuang <hekuang@huawei.com>
> ---
>  tools/build/Makefile.feature                 |  8 ++++++++
>  tools/build/feature/Makefile                 | 16 ++++++++++++++++
>  tools/build/feature/test-libunwind-aarch64.c | 26 ++++++++++++++++++++++++++
>  tools/build/feature/test-libunwind-arm.c     | 27 +++++++++++++++++++++++++++
>  tools/build/feature/test-libunwind-x86.c     | 27 +++++++++++++++++++++++++++
>  tools/build/feature/test-libunwind-x86_64.c  | 27 +++++++++++++++++++++++++++
>  6 files changed, 131 insertions(+)
>  create mode 100644 tools/build/feature/test-libunwind-aarch64.c
>  create mode 100644 tools/build/feature/test-libunwind-arm.c
>  create mode 100644 tools/build/feature/test-libunwind-x86.c
>  create mode 100644 tools/build/feature/test-libunwind-x86_64.c
> 
> diff --git a/tools/build/Makefile.feature b/tools/build/Makefile.feature
> index 9f87861..139e99c 100644
> --- a/tools/build/Makefile.feature
> +++ b/tools/build/Makefile.feature
> @@ -49,6 +49,10 @@ FEATURE_TESTS_BASIC :=			\
>  	libslang			\
>  	libcrypto			\
>  	libunwind			\
> +	libunwind-x86			\
> +	libunwind-x86_64		\
> +	libunwind-arm			\
> +	libunwind-aarch64		\
>  	pthread-attr-setaffinity-np	\
>  	stackprotector-all		\
>  	timerfd				\
> @@ -92,6 +96,10 @@ FEATURE_DISPLAY ?=			\
>  	libslang			\
>  	libcrypto			\
>  	libunwind			\
> +	libunwind-x86			\
> +	libunwind-x86_64		\
> +	libunwind-arm			\
> +	libunwind-aarch64		\

I dont think we should display status of libs needed only for cross builds
it'll be OFF for most of the people and create unnecessary tension ;-)

thanks,
jirka

^ permalink raw reply	[flat|nested] 22+ messages in thread

* Re: [PATCH 4/8] perf build: Add build-test for debug-frame on arm/arm64
  2016-05-06  8:59 ` [PATCH 4/8] perf build: Add build-test for debug-frame on arm/arm64 He Kuang
@ 2016-05-07 18:24   ` Jiri Olsa
  0 siblings, 0 replies; 22+ messages in thread
From: Jiri Olsa @ 2016-05-07 18:24 UTC (permalink / raw)
  To: He Kuang
  Cc: peterz, mingo, acme, alexander.shishkin, wangnan0, jpoimboe, ak,
	eranian, namhyung, adrian.hunter, sukadev, masami.hiramatsu.pt,
	tumanova, kan.liang, penberg, dsahern, linux-kernel

On Fri, May 06, 2016 at 08:59:10AM +0000, He Kuang wrote:
> Debug-frame for remote platforms is not related to the host platform,
> so we should test each platform separately.

SNIP

> diff --git a/tools/build/feature/test-libunwind-debug-frame.c b/tools/build/feature/test-libunwind-debug-frame.c
> deleted file mode 100644
> index 0ef8087..0000000
> --- a/tools/build/feature/test-libunwind-debug-frame.c
> +++ /dev/null
> @@ -1,16 +0,0 @@
> -#include <libunwind.h>
> -#include <stdlib.h>
> -
> -extern int
> -UNW_OBJ(dwarf_find_debug_frame) (int found, unw_dyn_info_t *di_debug,
> -				 unw_word_t ip, unw_word_t segbase,
> -				 const char *obj_name, unw_word_t start,
> -				 unw_word_t end);
> -
> -#define dwarf_find_debug_frame UNW_OBJ(dwarf_find_debug_frame)

hum but we still use this in standard libdw unwind
from find_proc_info in util/unwind-libunwind.c

should we keep the generic version as well?

thanks,
jirka

^ permalink raw reply	[flat|nested] 22+ messages in thread

* Re: [PATCH 5/8] perf tools: Promote proper messages for cross-platform unwind
  2016-05-06  8:59 ` [PATCH 5/8] perf tools: Promote proper messages for cross-platform unwind He Kuang
@ 2016-05-07 18:41   ` Jiri Olsa
  2016-05-07 18:42   ` Jiri Olsa
  1 sibling, 0 replies; 22+ messages in thread
From: Jiri Olsa @ 2016-05-07 18:41 UTC (permalink / raw)
  To: He Kuang
  Cc: peterz, mingo, acme, alexander.shishkin, wangnan0, jpoimboe, ak,
	eranian, namhyung, adrian.hunter, sukadev, masami.hiramatsu.pt,
	tumanova, kan.liang, penberg, dsahern, linux-kernel

On Fri, May 06, 2016 at 08:59:11AM +0000, He Kuang wrote:
> Currently, perf script uses host unwind methods to parse perf.data
> callchain info regardless of the target architecture. So we get wrong
> result and no promotion when unwinding callchains of x86(32bit) on
> x86(64bit) machine.
> 
> This patch shows proper error messages when we do remote unwind
> x86(32bit) on other machines.
> 
> Same thing for other platforms will be added in next patches.
> 
> Signed-off-by: He Kuang <hekuang@huawei.com>
> ---
>  tools/perf/config/Makefile   |  6 ++++++
>  tools/perf/util/symbol-elf.c | 16 +++++++++++++++
>  tools/perf/util/symbol.c     | 49 ++++++++++++++++++++++++++++++++++++++++++++
>  tools/perf/util/symbol.h     |  2 ++
>  tools/perf/util/thread.c     | 31 ++++++++++++++++++++++++++++
>  5 files changed, 104 insertions(+)
> 
> diff --git a/tools/perf/config/Makefile b/tools/perf/config/Makefile
> index 1e46277..a86b864 100644
> --- a/tools/perf/config/Makefile
> +++ b/tools/perf/config/Makefile
> @@ -345,6 +345,12 @@ ifeq ($(ARCH),powerpc)
>  endif
>  
>  ifndef NO_LIBUNWIND
> +  ifeq ($(feature-libunwind-x86), 1)
> +    LIBUNWIND_LIBS += -lunwind-x86
> +    $(call detected,CONFIG_LIBUNWIND_X86)
> +    CFLAGS += -DHAVE_LIBUNWIND_X86_SUPPORT
> +  endif
> +
>    ifneq ($(feature-libunwind), 1)
>      msg := $(warning No libunwind found. Please install libunwind-dev[el] >= 1.1 and/or set LIBUNWIND_DIR);
>      NO_LIBUNWIND := 1
> diff --git a/tools/perf/util/symbol-elf.c b/tools/perf/util/symbol-elf.c
> index 3f9d679..9f290b9 100644
> --- a/tools/perf/util/symbol-elf.c
> +++ b/tools/perf/util/symbol-elf.c
> @@ -636,6 +636,22 @@ bool __weak elf__needs_adjust_symbols(GElf_Ehdr ehdr)
>  	return ehdr.e_type == ET_EXEC || ehdr.e_type == ET_REL;
>  }
>  
> +int elf_is_64_bit(char *name)
> +{
> +	Elf *elf;
> +	int fd;
> +
> +	fd = open(name, O_RDONLY);
> +	if (fd < 0)
> +		return -1;
> +
> +	elf = elf_begin(fd, PERF_ELF_C_READ_MMAP, NULL);
> +	if (elf == NULL)
> +		return -1;
> +
> +	return (gelf_getclass(elf) == ELFCLASS64);
> +}
> +
>  int symsrc__init(struct symsrc *ss, struct dso *dso, const char *name,
>  		 enum dso_binary_type type)
>  {
> diff --git a/tools/perf/util/symbol.c b/tools/perf/util/symbol.c
> index 93f348f..c33aa5a 100644
> --- a/tools/perf/util/symbol.c
> +++ b/tools/perf/util/symbol.c
> @@ -1395,6 +1395,55 @@ static bool dso__is_compatible_symtab_type(struct dso *dso, bool kmod,
>  	}
>  }
>  
> +int dso_is_64_bit(struct dso *dso, struct map *map)
> +{
> +	char *name;
> +	u_int i;
> +	bool kmod;
> +	char *root_dir = (char *) "";
> +	struct machine *machine;
> +
> +	if (map->groups && map->groups->machine)
> +		machine = map->groups->machine;
> +	else
> +		machine = NULL;
> +
> +	if (machine)
> +		root_dir = machine->root_dir;
> +
> +	name = malloc(PATH_MAX);
> +	if (!name)
> +		return -1;
> +
> +	kmod = dso->symtab_type == DSO_BINARY_TYPE__SYSTEM_PATH_KMODULE ||
> +		dso->symtab_type == DSO_BINARY_TYPE__SYSTEM_PATH_KMODULE_COMP ||
> +		dso->symtab_type == DSO_BINARY_TYPE__GUEST_KMODULE ||
> +		dso->symtab_type == DSO_BINARY_TYPE__GUEST_KMODULE_COMP;
> +
> +	/*
> +	 * Iterate over candidate debug images.
> +	 * Keep track of "interesting" ones (those which have a symtab, dynsym,
> +	 * and/or opd section) for processing.
> +	 */
> +	for (i = 0; i < DSO_BINARY_TYPE__SYMTAB_CNT; i++) {
> +		enum dso_binary_type symtab_type = binary_type_symtab[i];
> +
> +		if (!dso__is_compatible_symtab_type(dso, kmod, symtab_type))
> +			continue;
> +
> +		if (dso__read_binary_type_filename(dso, symtab_type,
> +						   root_dir, name, PATH_MAX))
> +			continue;
> +
> +		if (!is_regular_file(name))
> +			continue;
> +
> +		return elf_is_64_bit(name);
> +	}
> +
> +	return -1;
> +}
> +
>  int dso__load(struct dso *dso, struct map *map, symbol_filter_t filter)
>  {
>  	char *name;
> diff --git a/tools/perf/util/symbol.h b/tools/perf/util/symbol.h
> index 4e6910e..d33fbf4 100644
> --- a/tools/perf/util/symbol.h
> +++ b/tools/perf/util/symbol.h
> @@ -308,6 +308,8 @@ int setup_list(struct strlist **list, const char *list_str,
>  	       const char *list_name);
>  int setup_intlist(struct intlist **list, const char *list_str,
>  		  const char *list_name);
> +int elf_is_64_bit(char *name);
> +int dso_is_64_bit(struct dso *dso, struct map *map);
>  
>  #ifdef HAVE_LIBELF_SUPPORT
>  bool elf__needs_adjust_symbols(GElf_Ehdr ehdr);
> diff --git a/tools/perf/util/thread.c b/tools/perf/util/thread.c
> index dfd00c6..e0cdcf7 100644
> --- a/tools/perf/util/thread.c
> +++ b/tools/perf/util/thread.c
> @@ -184,8 +184,39 @@ size_t thread__fprintf(struct thread *thread, FILE *fp)
>  
>  void thread__insert_map(struct thread *thread, struct map *map)
>  {
> +	char * __maybe_unused arch;
> +	int __maybe_unused is_64_bit;
> +
>  	map_groups__fixup_overlappings(thread->mg, map, stderr);
>  	map_groups__insert(thread->mg, map);
> +
> +#ifdef HAVE_LIBUNWIND_SUPPORT
> +	if (!thread->mg->machine->env)
> +		return;
> +
> +	is_64_bit = dso_is_64_bit(map->dso, map);
> +	if (is_64_bit < 0)
> +		return;
> +
> +	if (thread->addr_space)
> +		pr_debug("Thread map already set, 64bit is %d, dso=%s\n",
> +			 is_64_bit, map->dso->name);
> +
> +	arch = thread->mg->machine->env->arch;
> +
> +	if (!strcmp(arch, "x86_64")
> +		   || !strcmp(arch, "x86")
> +		   || !strcmp(arch, "i686")) {
> +		pr_debug("Thread map is X86, 64bit is %d\n", is_64_bit);
> +		if (!is_64_bit)
> +#ifdef HAVE_LIBUNWIND_X86_SUPPORT
> +			pr_err("target platform=%s is not implemented!\n",
> +			       arch);
> +#else
> +			pr_err("target platform=%s is not supported!\n", arch);
> +#endif
> +	}
> +#endif

could you please move above code under unwind object,
like we do with unwind__prepare_access in thread__new?

also we could unite both names somehome now we have 2 callbacks
to unwind code from generic code

thanks,
jirka

^ permalink raw reply	[flat|nested] 22+ messages in thread

* Re: [PATCH 5/8] perf tools: Promote proper messages for cross-platform unwind
  2016-05-06  8:59 ` [PATCH 5/8] perf tools: Promote proper messages for cross-platform unwind He Kuang
  2016-05-07 18:41   ` Jiri Olsa
@ 2016-05-07 18:42   ` Jiri Olsa
  1 sibling, 0 replies; 22+ messages in thread
From: Jiri Olsa @ 2016-05-07 18:42 UTC (permalink / raw)
  To: He Kuang
  Cc: peterz, mingo, acme, alexander.shishkin, wangnan0, jpoimboe, ak,
	eranian, namhyung, adrian.hunter, sukadev, masami.hiramatsu.pt,
	tumanova, kan.liang, penberg, dsahern, linux-kernel

On Fri, May 06, 2016 at 08:59:11AM +0000, He Kuang wrote:

SNIP

> +	if (machine)
> +		root_dir = machine->root_dir;
> +
> +	name = malloc(PATH_MAX);
> +	if (!name)
> +		return -1;
> +
> +	kmod = dso->symtab_type == DSO_BINARY_TYPE__SYSTEM_PATH_KMODULE ||
> +		dso->symtab_type == DSO_BINARY_TYPE__SYSTEM_PATH_KMODULE_COMP ||
> +		dso->symtab_type == DSO_BINARY_TYPE__GUEST_KMODULE ||
> +		dso->symtab_type == DSO_BINARY_TYPE__GUEST_KMODULE_COMP;
> +
> +	/*
> +	 * Iterate over candidate debug images.
> +	 * Keep track of "interesting" ones (those which have a symtab, dynsym,
> +	 * and/or opd section) for processing.
> +	 */
> +	for (i = 0; i < DSO_BINARY_TYPE__SYMTAB_CNT; i++) {
> +		enum dso_binary_type symtab_type = binary_type_symtab[i];
> +
> +		if (!dso__is_compatible_symtab_type(dso, kmod, symtab_type))
> +			continue;
> +
> +		if (dso__read_binary_type_filename(dso, symtab_type,
> +						   root_dir, name, PATH_MAX))
> +			continue;
> +
> +		if (!is_regular_file(name))
> +			continue;
> +
> +		return elf_is_64_bit(name);
> +	}
> +
> +	return -1;
> +}
> +
>  int dso__load(struct dso *dso, struct map *map, symbol_filter_t filter)
>  {
>  	char *name;
> diff --git a/tools/perf/util/symbol.h b/tools/perf/util/symbol.h
> index 4e6910e..d33fbf4 100644
> --- a/tools/perf/util/symbol.h
> +++ b/tools/perf/util/symbol.h
> @@ -308,6 +308,8 @@ int setup_list(struct strlist **list, const char *list_str,
>  	       const char *list_name);
>  int setup_intlist(struct intlist **list, const char *list_str,
>  		  const char *list_name);
> +int elf_is_64_bit(char *name);
> +int dso_is_64_bit(struct dso *dso, struct map *map);

please put above 2 functions addition into separate patch

thanks,
jirka

^ permalink raw reply	[flat|nested] 22+ messages in thread

* Re: [PATCH 1/8] perf tools: Omit DWARF judgement when recording dwarf callchain
  2016-05-07 18:03   ` Jiri Olsa
@ 2016-05-09 16:16     ` Arnaldo Carvalho de Melo
  2016-05-10  1:44       ` Hekuang
  0 siblings, 1 reply; 22+ messages in thread
From: Arnaldo Carvalho de Melo @ 2016-05-09 16:16 UTC (permalink / raw)
  To: Jiri Olsa
  Cc: He Kuang, peterz, mingo, alexander.shishkin, wangnan0, jpoimboe,
	ak, eranian, namhyung, adrian.hunter, sukadev,
	masami.hiramatsu.pt, tumanova, kan.liang, penberg, dsahern,
	linux-kernel

Em Sat, May 07, 2016 at 08:03:46PM +0200, Jiri Olsa escreveu:
> On Fri, May 06, 2016 at 08:59:07AM +0000, He Kuang wrote:
> > There's no need for dwarf support when perf recording with callchain.
> > 
> > Signed-off-by: He Kuang <hekuang@huawei.com>
> 
> Acked-by: Jiri Olsa <jolsa@kernel.org>

Ok, due to your Ack I went on to read the code and indeed, with this
changeset description:

"There is no need to check for DWARF unwinding support when using the
'dwarf' callchain record method, as this will only ask the kernel to
collect stack dumps for later DWARF CFI processing, which can be done
in another machine, where the support for DWARF unwinding need to be
present."

Thanks,

- Arnaldo
 
> thanks,
> jirka
> 
> > ---
> >  tools/perf/util/util.c | 2 --
> >  1 file changed, 2 deletions(-)
> > 
> > diff --git a/tools/perf/util/util.c b/tools/perf/util/util.c
> > index b7766c5..e5ebfd4 100644
> > --- a/tools/perf/util/util.c
> > +++ b/tools/perf/util/util.c
> > @@ -471,7 +471,6 @@ int parse_callchain_record(const char *arg, struct callchain_param *param)
> >  				       "needed for --call-graph fp\n");
> >  			break;
> >  
> > -#ifdef HAVE_DWARF_UNWIND_SUPPORT
> >  		/* Dwarf style */
> >  		} else if (!strncmp(name, "dwarf", sizeof("dwarf"))) {
> >  			const unsigned long default_stack_dump_size = 8192;
> > @@ -487,7 +486,6 @@ int parse_callchain_record(const char *arg, struct callchain_param *param)
> >  				ret = get_stack_size(tok, &size);
> >  				param->dump_size = size;
> >  			}
> > -#endif /* HAVE_DWARF_UNWIND_SUPPORT */
> >  		} else if (!strncmp(name, "lbr", sizeof("lbr"))) {
> >  			if (!strtok_r(NULL, ",", &saveptr)) {
> >  				param->record_mode = CALLCHAIN_LBR;
> > -- 
> > 1.8.5.2
> > 

^ permalink raw reply	[flat|nested] 22+ messages in thread

* Re: [PATCH 1/8] perf tools: Omit DWARF judgement when recording dwarf callchain
  2016-05-09 16:16     ` Arnaldo Carvalho de Melo
@ 2016-05-10  1:44       ` Hekuang
  0 siblings, 0 replies; 22+ messages in thread
From: Hekuang @ 2016-05-10  1:44 UTC (permalink / raw)
  To: Arnaldo Carvalho de Melo, Jiri Olsa
  Cc: peterz, mingo, alexander.shishkin, wangnan0, jpoimboe, ak,
	eranian, namhyung, adrian.hunter, sukadev, masami.hiramatsu.pt,
	tumanova, kan.liang, penberg, dsahern, linux-kernel

ok

在 2016/5/10 0:16, Arnaldo Carvalho de Melo 写道:
> Em Sat, May 07, 2016 at 08:03:46PM +0200, Jiri Olsa escreveu:
>> On Fri, May 06, 2016 at 08:59:07AM +0000, He Kuang wrote:
>>> There's no need for dwarf support when perf recording with callchain.
>>>
>>> Signed-off-by: He Kuang <hekuang@huawei.com>
>> Acked-by: Jiri Olsa <jolsa@kernel.org>
> Ok, due to your Ack I went on to read the code and indeed, with this
> changeset description:
>
> "There is no need to check for DWARF unwinding support when using the
> 'dwarf' callchain record method, as this will only ask the kernel to
> collect stack dumps for later DWARF CFI processing, which can be done
> in another machine, where the support for DWARF unwinding need to be
> present."
>
> Thanks,
>
> - Arnaldo
>   
>> thanks,
>> jirka
>>
>>> ---
>>>   tools/perf/util/util.c | 2 --
>>>   1 file changed, 2 deletions(-)
>>>
>>> diff --git a/tools/perf/util/util.c b/tools/perf/util/util.c
>>> index b7766c5..e5ebfd4 100644
>>> --- a/tools/perf/util/util.c
>>> +++ b/tools/perf/util/util.c
>>> @@ -471,7 +471,6 @@ int parse_callchain_record(const char *arg, struct callchain_param *param)
>>>   				       "needed for --call-graph fp\n");
>>>   			break;
>>>   
>>> -#ifdef HAVE_DWARF_UNWIND_SUPPORT
>>>   		/* Dwarf style */
>>>   		} else if (!strncmp(name, "dwarf", sizeof("dwarf"))) {
>>>   			const unsigned long default_stack_dump_size = 8192;
>>> @@ -487,7 +486,6 @@ int parse_callchain_record(const char *arg, struct callchain_param *param)
>>>   				ret = get_stack_size(tok, &size);
>>>   				param->dump_size = size;
>>>   			}
>>> -#endif /* HAVE_DWARF_UNWIND_SUPPORT */
>>>   		} else if (!strncmp(name, "lbr", sizeof("lbr"))) {
>>>   			if (!strtok_r(NULL, ",", &saveptr)) {
>>>   				param->record_mode = CALLCHAIN_LBR;
>>> -- 
>>> 1.8.5.2
>>>

^ permalink raw reply	[flat|nested] 22+ messages in thread

* [tip:perf/core] perf callchain: Recording 'dwarf' callchains do not need DWARF unwinding support
  2016-05-06  8:59 ` [PATCH 1/8] perf tools: Omit DWARF judgement when recording dwarf callchain He Kuang
  2016-05-06 11:47   ` Arnaldo Carvalho de Melo
  2016-05-07 18:03   ` Jiri Olsa
@ 2016-05-10 20:30   ` tip-bot for He Kuang
  2 siblings, 0 replies; 22+ messages in thread
From: tip-bot for He Kuang @ 2016-05-10 20:30 UTC (permalink / raw)
  To: linux-tip-commits
  Cc: dsahern, hpa, alexander.shishkin, tumanova, kan.liang, wangnan0,
	linux-kernel, namhyung, hekuang, eranian, acme, adrian.hunter,
	sukadev, tglx, peterz, ak, mhiramat, jpoimboe, mingo, penberg,
	jolsa

Commit-ID:  841e3558b2de6d8c53dae4f01c7a81cd53e42e5c
Gitweb:     http://git.kernel.org/tip/841e3558b2de6d8c53dae4f01c7a81cd53e42e5c
Author:     He Kuang <hekuang@huawei.com>
AuthorDate: Fri, 6 May 2016 08:59:07 +0000
Committer:  Arnaldo Carvalho de Melo <acme@redhat.com>
CommitDate: Mon, 9 May 2016 13:29:36 -0300

perf callchain: Recording 'dwarf' callchains do not need DWARF unwinding support

There is no need to check for DWARF unwinding support when using the
'dwarf' callchain record method, as this will only ask the kernel to
collect stack dumps for later DWARF CFI processing, which can be done in
another machine, where the support for DWARF unwinding need to be
present.

Signed-off-by: He Kuang <hekuang@huawei.com>
Acked-by: Jiri Olsa <jolsa@kernel.org>
Cc: Adrian Hunter <adrian.hunter@intel.com>
Cc: Alexander Shishkin <alexander.shishkin@linux.intel.com>
Cc: Andi Kleen <ak@linux.intel.com>
Cc: David Ahern <dsahern@gmail.com>
Cc: Ekaterina Tumanova <tumanova@linux.vnet.ibm.com>
Cc: Josh Poimboeuf <jpoimboe@redhat.com>
Cc: Kan Liang <kan.liang@intel.com>
Cc: Masami Hiramatsu <mhiramat@kernel.org>
Cc: Namhyung Kim <namhyung@kernel.org>
Cc: Pekka Enberg <penberg@kernel.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Stephane Eranian <eranian@google.com>
Cc: Sukadev Bhattiprolu <sukadev@linux.vnet.ibm.com>
Cc: Wang Nan <wangnan0@huawei.com>
Link: http://lkml.kernel.org/r/1462525154-125656-2-git-send-email-hekuang@huawei.com
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
---
 tools/perf/util/util.c | 2 --
 1 file changed, 2 deletions(-)

diff --git a/tools/perf/util/util.c b/tools/perf/util/util.c
index 619ba20..01c9433 100644
--- a/tools/perf/util/util.c
+++ b/tools/perf/util/util.c
@@ -507,7 +507,6 @@ int parse_callchain_record(const char *arg, struct callchain_param *param)
 				       "needed for --call-graph fp\n");
 			break;
 
-#ifdef HAVE_DWARF_UNWIND_SUPPORT
 		/* Dwarf style */
 		} else if (!strncmp(name, "dwarf", sizeof("dwarf"))) {
 			const unsigned long default_stack_dump_size = 8192;
@@ -523,7 +522,6 @@ int parse_callchain_record(const char *arg, struct callchain_param *param)
 				ret = get_stack_size(tok, &size);
 				param->dump_size = size;
 			}
-#endif /* HAVE_DWARF_UNWIND_SUPPORT */
 		} else if (!strncmp(name, "lbr", sizeof("lbr"))) {
 			if (!strtok_r(NULL, ",", &saveptr)) {
 				param->record_mode = CALLCHAIN_LBR;

^ permalink raw reply related	[flat|nested] 22+ messages in thread

end of thread, other threads:[~2016-05-10 20:31 UTC | newest]

Thread overview: 22+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2016-05-06  8:59 [PATCH 0/8] Add support for remote unwind He Kuang
2016-05-06  8:59 ` [PATCH 1/8] perf tools: Omit DWARF judgement when recording dwarf callchain He Kuang
2016-05-06 11:47   ` Arnaldo Carvalho de Melo
2016-05-07 18:03   ` Jiri Olsa
2016-05-09 16:16     ` Arnaldo Carvalho de Melo
2016-05-10  1:44       ` Hekuang
2016-05-10 20:30   ` [tip:perf/core] perf callchain: Recording 'dwarf' callchains do not need DWARF unwinding support tip-bot for He Kuang
2016-05-06  8:59 ` [PATCH 2/8] perf script: Add options for custom vdso name He Kuang
2016-05-06 11:49   ` Arnaldo Carvalho de Melo
2016-05-07 18:14   ` Jiri Olsa
2016-05-06  8:59 ` [PATCH 3/8] perf build: Add build-test for libunwind cross-platforms support He Kuang
2016-05-07 18:20   ` Jiri Olsa
2016-05-06  8:59 ` [PATCH 4/8] perf build: Add build-test for debug-frame on arm/arm64 He Kuang
2016-05-07 18:24   ` Jiri Olsa
2016-05-06  8:59 ` [PATCH 5/8] perf tools: Promote proper messages for cross-platform unwind He Kuang
2016-05-07 18:41   ` Jiri Olsa
2016-05-07 18:42   ` Jiri Olsa
2016-05-06  8:59 ` [PATCH 6/8] perf callchain: Add support " He Kuang
2016-05-06 11:56   ` Arnaldo Carvalho de Melo
2016-05-06  8:59 ` [PATCH 7/8] perf callchain: Support x86 target platform He Kuang
2016-05-06  8:59 ` [PATCH 8/8] perf callchain: Support aarch64 cross-platform He Kuang
2016-05-06 11:58 ` [PATCH 0/8] Add support for remote unwind Arnaldo Carvalho de Melo

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.