perf/urgent fixes
Arnaldo Carvalho de Melo
maintainerHi Ingo,
Please consider pulling,
- Arnaldo
The following changes since commit 6e30437bd42c4d4e9cfc4c40efda00eb83a11cde:
tools/include: Sync kernel ABI headers with tooling headers (2017-05-24 09:00:21 +0200)
are available in the git repository at:
git://git.kernel.org/pub/scm/linux/kernel/git/acme/linux.git tags/perf-urgent-for-mingo-4.12-20170606
for you to fetch changes up to 2538b9e2450ae255337c04356e9e0f8cb9ec48d9:
perf report: Ensure the perf DSO mapping matches what libdw sees (2017-06-05 14:18:05 -0300)
----------------------------------------------------------------
perf/urgent fixes:
- Only print NMI watchdog hint in 'perf stat' when it is enabled (Andi Kleen)
- Fix sys_mmap/sys_old_mmap shandling in s390 in 'perf trace' (Jiri Olsa)
- Disable breakpoint signal tests in powerpc, that lacks the perf kernel glue to set breakpoint events and makes 'perf test' always fail (Jiri Olsa)
- Fix 'perf annotate' for branch instruction with multiple operands (Kim Phillips)
- Add missing powerpc triplet when disassembling with 'objdump' in 'perf annotate' (Kim Phillips)
- Do not trow away partial unwound stacks when using libdw, making callchains produced with it similar to those produced when linked with the other DWARF unwind library supported in perf, libunwind (Milian Wolff)
- Fixes to properly handle kernel modules when processing build-id meta events (Namhyung Kim)
- Fix handling of compressed modules in the build-id cache (Namhyung Kim)
- Fix 'perf annotate' failure when filename has special chars (Ravi Bangoria)
----------------------------------------------------------------
Andi Kleen (1):
perf stat: Only print NMI watchdog hint when enabled
Jiri Olsa (2):
perf trace: Add mmap alias for s390
perf test: Disable breakpoint signal tests for powerpc
Kim Phillips (2):
perf annotate: Fix branch instruction with multiple operands perf annotate: Add missing powerpc triplet
Milian Wolff (2):
perf report: Include partial stacks unwound with libdw perf report: Ensure the perf DSO mapping matches what libdw sees
Namhyung Kim (3):
perf header: Set proper module name when build-id event found perf symbols: Set module info when build-id event found
perf symbols: Use correct filename for compressed modules in build-id cache
Ravi Bangoria (1):
perf annotate: Fix failure when filename has special chars
tools/perf/arch/common.c | 1 + tools/perf/builtin-stat.c | 5 ++++- tools/perf/builtin-trace.c | 4 ++++ tools/perf/tests/bp_signal.c | 14 ++++++++++++++ tools/perf/tests/builtin-test.c | 7 +++++++ tools/perf/tests/tests.h | 3 +++ tools/perf/util/annotate.c | 35 +++++++++++++++++++++++++++++++---- tools/perf/util/dso.c | 15 +++++++++++++++ tools/perf/util/dso.h | 3 +++ tools/perf/util/header.c | 12 ++++++++++-- tools/perf/util/machine.c | 11 +---------- tools/perf/util/symbol-elf.c | 5 +---- tools/perf/util/unwind-libdw.c | 10 +++++++++- 13 files changed, 103 insertions(+), 22 deletions(-)
Arnaldo Carvalho de Melo
maintainerPATCH 1/11 perf annotate: Fix failure when filename has special chars
From: Ravi Bangoria <[email protected]>
When filename contains special chars, perf annotate fails with an error:
$ perf annotate --vmlinux ./vmlinux\(test\) --stdio native_safe_halt
sh: -c: line 0: syntax error near unexpected token `('
sh: -c: line 0: `objdump --start-address=0xffffffff8184e840
--stop-address=0xffffffff8184e848 -l -d --no-show-raw -S -C
./vmlinux(test) 2>/dev/null|grep -v ./vmlinux(test):|expand'Fix it by surrounding filename in double quotes.
--- tools/perf/util/annotate.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
tools/perf/util/annotate.c +1 -1
@@ -1429,7 +1429,7 @@ int symbol__disassemble(struct symbol *sym, struct map *map, const char *arch_na snprintf(command, sizeof(command), "%s %s%s --start-address=0x%016" PRIx64 " --stop-address=0x%016" PRIx64 - " -l -d %s %s -C %s 2>/dev/null|grep -v %s:|expand", + " -l -d %s %s -C \"%s\" 2>/dev/null|grep -v \"%s:\"|expand", objdump_path ? objdump_path : "objdump", disassembler_style ? "-M " : "", disassembler_style ? disassembler_style : "",
Signature · 1 line
2.9.4
Arnaldo Carvalho de Melo
maintainerPATCH 2/11 perf trace: Add mmap alias for s390
In reply to Arnaldo Carvalho de MeloFrom: Jiri Olsa <[email protected]>
The s390 architecture maps sys_mmap (nr 90) into sys_old_mmap. For this reason perf trace can't find the proper syscall event to get args format from and displays it wrongly as 'continued'.
To fix that fill the "alias" field with "old_mmap" for trace's mmap record to get the correct translation.
Before:
0.042 ( 0.011 ms): vest/43052 fstat(statbuf: 0x3ffff89fd90 ) = 0
0.042 ( 0.028 ms): vest/43052 ... [continued]: mmap()) = 0x3fffd6e2000
0.072 ( 0.025 ms): vest/43052 read(buf: 0x3fffd6e2000, count: 4096 ) = 6After:
0.045 ( 0.011 ms): fstat(statbuf: 0x3ffff8a0930 ) = 0
0.057 ( 0.018 ms): mmap(arg: 0x3ffff8a0858 ) = 0x3fffd14a000
0.076 ( 0.025 ms): read(buf: 0x3fffd14a000, count: 4096 ) = 6--- tools/perf/builtin-trace.c | 4 ++++ 1 file changed, 4 insertions(+)
tools/perf/builtin-trace.c +4 -0
@@ -681,6 +681,10 @@ static struct syscall_fmt { { .name = "mlockall", .errmsg = true, .arg_scnprintf = { [0] = SCA_HEX, /* addr */ }, }, { .name = "mmap", .hexret = true, +/* The standard mmap maps to old_mmap on s390x */ +#if defined(__s390x__) + .alias = "old_mmap", +#endif .arg_scnprintf = { [0] = SCA_HEX, /* addr */ [2] = SCA_MMAP_PROT, /* prot */ [3] = SCA_MMAP_FLAGS, /* flags */ }, },
Signature · 1 line
2.9.4
Arnaldo Carvalho de Melo
maintainerPATCH 3/11 perf annotate: Fix branch instruction with multiple operands
In reply to Arnaldo Carvalho de MeloFrom: Kim Phillips <[email protected]>
'perf annotate' is dropping the cr* fields from branch instructions.
Fix it by adding support to display branch instructions having multiple operands.
Power Arch objdump of int_sqrt:
20.36 | c0000000004d2694: subf r10,r10,r3
| c0000000004d2698: v bgt cr6,c0000000004d26a0 <int_sqrt+0x40>
1.82 | c0000000004d269c: mr r3,r10
29.18 | c0000000004d26a0: mr r10,r8
| c0000000004d26a4: v bgt cr7,c0000000004d26ac <int_sqrt+0x4c>
| c0000000004d26a8: mr r10,r7Power Arch Before Patch:
20.36 | subf r10,r10,r3
| v bgt 40
1.82 | mr r3,r10
29.18 | 40: mr r10,r8
| v bgt 4c
| mr r10,r7Power Arch After patch:
20.36 | subf r10,r10,r3
| v bgt cr6,40
1.82 | mr r3,r10
29.18 | 40: mr r10,r8
| v bgt cr7,4c
| mr r10,r7Also support AArch64 conditional branch instructions, which can have up to three operands:
Aarch64 Non-simplified (raw objdump) view:
│ffff0000083cd11c: ↑ cbz w0, ffff0000083cd100 <security_fil▒
...
4.44 │ffff000│083cd134: ↓ tbnz w0, #26, ffff0000083cd190 <securit▒
...
1.37 │ffff000│083cd144: ↓ tbnz w22, #5, ffff0000083cd1a4 <securit▒
│ffff000│083cd148: mov w19, #0x20000 //▒
1.02 │ffff000│083cd14c: ↓ tbz w22, #2, ffff0000083cd1ac <securit▒...
0.68 │ffff000└──3cd16c: ↑ cbnz w0, ffff0000083cd120 <security_fil▒
Aarch64 Simplified, before this patch:
│ ↑ cbz 40
...
4.44 │ │↓ tbnz w0, #26, ffff0000083cd190 <security_file_permiss▒
...
1.37 │ │↓ tbnz w22, #5, ffff0000083cd1a4 <security_file_permiss▒
│ │ mov w19, #0x20000 // #131072
1.02 │ │↓ tbz w22, #2, ffff0000083cd1ac <security_file_permiss▒...
0.68 │ └──cbnz 60
the cbz operand is missing, and the tbz doesn't get simplified processing at all because the parsing function failed to match an address.
Aarch64 Simplified, After this patch applied:
│ ↑ cbz w0, 40
...
4.44 │ │↓ tbnz w0, #26, d0
...
1.37 │ │↓ tbnz w22, #5, e4
│ │ mov w19, #0x20000 // #131072
1.02 │ │↓ tbz w22, #2, ec...
0.68 │ └──cbnz w0, 60
--- tools/perf/util/annotate.c | 33 ++++++++++++++++++++++++++++++--- 1 file changed, 30 insertions(+), 3 deletions(-)
tools/perf/util/annotate.c +30 -3
@@ -239,10 +239,20 @@ static int jump__parse(struct arch *arch __maybe_unused, struct ins_operands *opconst char *s =strchr (ops->raw,'+' );const char *c =strchr (ops->raw,',' ); -if (c++ !=NULL ) +/* +* skip over possible up to 2 operands to get to address, e.g.: +* tbnz w0, #26, ffff0000083cd190 <security_file_permission+0xd0> +*/ +if (c++ !=NULL ) { ops->target.addr =strtoull (c,NULL ,16 ); -else +if (!ops->target.addr) { + c =strchr (c,',' ); +if (c++ !=NULL ) + ops->target.addr =strtoull (c,NULL ,16 ); + } + }else { ops->target.addr =strtoull (ops->raw,NULL ,16 ); + }if (s++ !=NULL ) { ops->target.offset =strtoull (s,NULL ,16 );
@@ -257,10 +267,27 @@ static int jump__parse(struct arch *arch __maybe_unused, struct ins_operands *opstatic int jump__scnprintf (struct ins *ins,char *bf,size_t size,struct ins_operands *ops) { +const char *c =strchr (ops->raw,',' ); +if (!ops->target.addr || ops->target.offset <0 )return ins__raw_scnprintf (ins, bf, size, ops); -return scnprintf (bf, size,"%-6.6s %" PRIx64, ins->name, ops->target.offset); +if (c !=NULL ) { +const char *c2 =strchr (c +1 ,',' ); + +/* check for 3-op insn */ +if (c2 !=NULL ) + c = c2; + c++; + +/* mirror arch objdump's space-after-comma style */ +if (*c ==' ' ) + c++; + } + +return scnprintf (bf, size,"%-6.6s %.*s%" PRIx64, + ins->name, c ? c - ops->raw :0 , ops->raw, + ops->target.offset); }static struct ins_ops jump_ops = {
Signature · 1 line
2.9.4
Arnaldo Carvalho de Melo
maintainerPATCH 4/11 perf stat: Only print NMI watchdog hint when enabled
In reply to Arnaldo Carvalho de MeloFrom: Andi Kleen <[email protected]>
Only print the NMI watchdog hint when that watchdog it actually enabled.
This avoids printing these unnecessarily.
--- tools/perf/builtin-stat.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-)
tools/perf/builtin-stat.c +4 -1
@@ -1578,6 +1578,7 @@ static void print_header(int argc, const char **argv)static void print_footer (void ) {FILE *output = stat_config.output; +int n;if (!null_run)fprintf (output,"\n" );
@@ -1590,7 +1591,9 @@ static void print_footer(void) }fprintf (output,"\n\n" ); -if (print_free_counters_hint) +if (print_free_counters_hint && +sysctl__read_int ("kernel/nmi_watchdog" , &n) >=0 && + n >0 )fprintf (output,"Some events weren't counted. Try disabling the NMI watchdog:\n" " echo 0 > /proc/sys/kernel/nmi_watchdog\n"
Signature · 1 line
2.9.4
Arnaldo Carvalho de Melo
maintainerPATCH 5/11 perf header: Set proper module name when build-id event found
In reply to Arnaldo Carvalho de MeloFrom: Namhyung Kim <[email protected]>
When perf processes build-id event, it creates DSOs with the build-id. But it didn't set the module short name (like '[module-name]') so when processing a kernel mmap event of the module, it cannot found the DSO as it only checks the short names.
That leads for perf to create a same DSO without the build-id info and it'll lookup the system path even if the DSO is already in the build-id cache. After kernel was updated, perf cannot find the DSO and cannot show symbols in it anymore.
You can see this if you have an old data file (w/ old kernel version):
$ perf report -i perf.data.old -v |& grep scsi_mod build id event received for /lib/modules/3.19.2-1-ARCH/kernel/drivers/scsi/scsi_mod.ko.gz : cafe1ce6ca13a98a5d9ed3425cde249e57a27fc1 Failed to open /lib/modules/3.19.2-1-ARCH/kernel/drivers/scsi/scsi_mod.ko.gz, continuing without symbols ...
The second message didn't show the build-id. With this patch:
$ perf report -i perf.data.old -v |& grep scsi_mod build id event received for /lib/modules/3.19.2-1-ARCH/kernel/drivers/scsi/scsi_mod.ko.gz: cafe1ce6ca13a98a5d9ed3425cde249e57a27fc1 /lib/modules/3.19.2-1-ARCH/kernel/drivers/scsi/scsi_mod.ko.gz with build id cafe1ce6ca13a98a5d9ed3425cde249e57a27fc1 not found, continuing without symbols ...
Now it shows the build-id but still cannot load the symbol table. This is a different problem which will be fixed in the next patch.
--- tools/perf/util/header.c | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-)
tools/perf/util/header.c +10 -2
@@ -1469,8 +1469,16 @@ static int __event_process_build_id(struct build_id_event *bev,dso__set_build_id (dso, &bev->build_id); -if (!is_kernel_module (filename, cpumode)) - dso->kernel = dso_type; +if (dso_type !=DSO_TYPE_USER ) { +struct kmod_path m = { .name =NULL , }; + +if (!kmod_path__parse_name (&m, filename) && m.kmod) +dso__set_short_name (dso,strdup (m.name), true); +else + dso->kernel = dso_type; + +free (m.name); + }build_id__sprintf (dso->build_id,sizeof (dso->build_id), sbuild_id);
Signature · 1 line
2.9.4
Arnaldo Carvalho de Melo
maintainerPATCH 6/11 perf symbols: Set module info when build-id event found
In reply to Arnaldo Carvalho de MeloFrom: Namhyung Kim <[email protected]>
Like machine__findnew_module_dso(), it should set necessary info for kernel modules to find symbol info from the file. Factor out dso__set_module_info() to do it.
This is needed for dso__needs_decompress() to detect such DSOs.
--- tools/perf/util/dso.c | 15 +++++++++++++++ tools/perf/util/dso.h | 3 +++ tools/perf/util/header.c | 2 +- tools/perf/util/machine.c | 11 +---------- 4 files changed, 20 insertions(+), 11 deletions(-)
tools/perf/util/dso.c +15 -0
@@ -335,6 +335,21 @@ int __kmod_path__parse(struct kmod_path *m, const char *path,return 0 ; } +void dso__set_module_info (struct dso *dso,struct kmod_path *m, +struct machine *machine) +{ +if (machine__is_host (machine)) + dso->symtab_type =DSO_BINARY_TYPE__SYSTEM_PATH_KMODULE ; +else + dso->symtab_type =DSO_BINARY_TYPE__GUEST_KMODULE ; + +/* _KMODULE_COMP should be next to _KMODULE */ +if (m->kmod && m->comp) + dso->symtab_type++; + +dso__set_short_name (dso,strdup (m->name), true); +} +/* * Global list of open DSOs and the counter. */
tools/perf/util/dso.h +3 -0
@@ -259,6 +259,9 @@ int __kmod_path__parse(struct kmod_path *m, const char *path,#define kmod_path__parse_name (__m, __p) __kmod_path__parse(__m, __p, true , false)#define kmod_path__parse_ext (__m, __p) __kmod_path__parse(__m, __p, false, true) +void dso__set_module_info (struct dso *dso,struct kmod_path *m, +struct machine *machine); +/* * The dso__data_* external interface provides following functions: * dso__data_get_fd
tools/perf/util/header.c +1 -1
@@ -1473,7 +1473,7 @@ static int __event_process_build_id(struct build_id_event *bev,struct kmod_path m = { .name =NULL , };if (!kmod_path__parse_name (&m, filename) && m.kmod) -dso__set_short_name (dso,strdup (m.name), true); +dso__set_module_info (dso, &m, machine);else dso->kernel = dso_type;
tools/perf/util/machine.c +1 -10
@@ -572,16 +572,7 @@ static struct dso *machine__findnew_module_dso(struct machine *machine,if (dso ==NULL ) goto out_unlock; -if (machine__is_host (machine)) - dso->symtab_type =DSO_BINARY_TYPE__SYSTEM_PATH_KMODULE ; -else - dso->symtab_type =DSO_BINARY_TYPE__GUEST_KMODULE ; - -/* _KMODULE_COMP should be next to _KMODULE */ -if (m->kmod && m->comp) - dso->symtab_type++; - -dso__set_short_name (dso,strdup (m->name), true); +dso__set_module_info (dso, m, machine);dso__set_long_name (dso,strdup (filename), true); }
Signature · 1 line
2.9.4
Arnaldo Carvalho de Melo
maintainerPATCH 7/11 perf symbols: Use correct filename for compressed modules in build-id cache
In reply to Arnaldo Carvalho de MeloFrom: Namhyung Kim <[email protected]>
The decompress_kmodule() decompresses kernel modules in order to load symbols from it. In the DSO_BINARY_TYPE__BUILD_ID_CACHE case, it needs the full file path to extract the file extension to determine the decompression method. But overwriting 'name' will fail the decompression since it might point to a non-existing old file.
Instead, use dso->long_name for having the correct extension and use the real filename to decompress.
In the DSO_BINARY_TYPE__SYSTEM_PATH_KMODULE_COMP case, both names should be the same. This allows resolving symbols in the old modules.
Before:
$ perf report -i perf.data.old | grep scsi_mod
0.00% cc1 [scsi_mod] [k] 0x0000000000004aa6
0.00% as [scsi_mod] [k] 0x00000000000099e1
0.00% cc1 [scsi_mod] [k] 0x0000000000009830
0.00% cc1 [scsi_mod] [k] 0x0000000000001b8fAfter:
0.00% cc1 [scsi_mod] [k] scsi_handle_queue_ramp_up
0.00% as [scsi_mod] [k] scsi_sg_alloc
0.00% cc1 [scsi_mod] [k] scsi_setup_cmnd
0.00% cc1 [scsi_mod] [k] scsi_get_command--- tools/perf/util/symbol-elf.c | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-)
tools/perf/util/symbol-elf.c +1 -4
@@ -649,10 +649,7 @@ static int decompress_kmodule(struct dso *dso, const char *name, type != DSO_BINARY_TYPE__BUILD_ID_CACHE)return -1 ; -if (type ==DSO_BINARY_TYPE__BUILD_ID_CACHE ) - name = dso->long_name; - -if (kmod_path__parse_ext (&m, name) || !m.comp) +if (kmod_path__parse_ext (&m, dso->long_name) || !m.comp)return -1 ; fd =mkstemp (tmpbuf);
Signature · 1 line
2.9.4
Arnaldo Carvalho de Melo
maintainerPATCH 8/11 perf test: Disable breakpoint signal tests for powerpc
In reply to Arnaldo Carvalho de MeloFrom: Jiri Olsa <[email protected]>
The following tests are failing on powerpc:
# perf test break 18: Breakpoint overflow signal handler : FAILED! 19: Breakpoint overflow sampling : FAILED!
The powerpc kenel so far does not have support to even create instruction breakpoints using the perf event interface, so those tests fail early in the config phase.
I added a '->is_supported()' callback to test struct to be able to disable specific tests. It seems better than putting ifdefs directly to the test array.
--- tools/perf/tests/bp_signal.c | 14 ++++++++++++++ tools/perf/tests/builtin-test.c | 7 +++++++ tools/perf/tests/tests.h | 3 +++ 3 files changed, 24 insertions(+)
tools/perf/tests/bp_signal.c +14 -0
@@ -288,3 +288,17 @@ int test__bp_signal(int subtest __maybe_unused)return count1 ==1 && overflows ==3 && count2 ==3 && overflows_2 ==3 && count3 ==2 ?TEST_OK :TEST_FAIL ; } + +bool test__bp_signal_is_supported (void ) +{ +/* +* The powerpc so far does not have support to even create +* instruction breakpoint using the perf event interface. +* Once it's there we can release this. +*/ +#ifdef __powerpc__ +return false; +#else +return true; +#endif +}
tools/perf/tests/builtin-test.c +7 -0
@@ -97,10 +97,12 @@ static struct test generic_tests[] = { { .desc = "Breakpoint overflow signal handler", .func = test__bp_signal, + .is_supported = test__bp_signal_is_supported, }, { .desc = "Breakpoint overflow sampling", .func = test__bp_signal_overflow, + .is_supported = test__bp_signal_is_supported, }, { .desc = "Number of exit events of a simple workload",
@@ -401,6 +403,11 @@ static int __cmd_test(int argc, const char *argv[], struct intlist *skiplist)if (!perf_test__matches (t, curr, argc, argv))continue ; +if (t->is_supported && !t->is_supported ()) { +pr_debug ("%2d: %-*s: Disabled\n" , i, width, t->desc); +continue ; + } +pr_info ("%2d: %-*s:" , i, width, t->desc);if (intlist__find (skiplist, i)) {
tools/perf/tests/tests.h +3 -0
@@ -34,6 +34,7 @@ struct test {int (*get_nr)(void );const char *(*get_desc)(int subtest); } subtest; +bool (*is_supported)(void ); };/* Tests */
@@ -99,6 +100,8 @@ const char *test__clang_subtest_get_desc(int subtest);int test__clang_subtest_get_nr (void );int test__unit_number__scnprint (int subtest); +bool test__bp_signal_is_supported (void ); +#if defined(__arm__) || defined(__aarch64__)#ifdef HAVE_DWARF_UNWIND_SUPPORT struct thread ;
Signature · 1 line
2.9.4
Arnaldo Carvalho de Melo
maintainerPATCH 9/11 perf annotate: Add missing powerpc triplet
In reply to Arnaldo Carvalho de MeloFrom: Kim Phillips <[email protected]>
On an Ubuntu xenial system, 'perf annotate' says to install powerpc objdump on a system that already has binutils-powerpc-linux-gnu installed. Make perf aware of the missing triplet for the powerpc-linux-gnu target.
--- tools/perf/arch/common.c | 1 + 1 file changed, 1 insertion(+)
tools/perf/arch/common.c +1 -0
@@ -26,6 +26,7 @@ const char *const arm64_triplets[] = {const char *const powerpc_triplets[] = {"powerpc-unknown-linux-gnu-" , +"powerpc-linux-gnu-" ,"powerpc64-unknown-linux-gnu-" ,"powerpc64-linux-gnu-" ,"powerpc64le-linux-gnu-" ,
Signature · 1 line
2.9.4
Arnaldo Carvalho de Melo
maintainerPATCH 10/11 perf report: Include partial stacks unwound with libdw
In reply to Arnaldo Carvalho de MeloFrom: Milian Wolff <[email protected]>
So far the whole stack was thrown away when any error occurred before the maximum stack depth was unwound. This is actually a very common scenario though. The stacks that got unwound so far are still interesting. This removes a large chunk of differences when comparing perf script output for libunwind and libdw perf unwinding.
E.g. with libunwind:
~~~~~heaptrack_gui 2228 135073.388524: 479408 cycles:
ffffffff811749ed perf_iterate_ctx ([kernel.kallsyms])
ffffffff81181662 perf_event_mmap ([kernel.kallsyms])
ffffffff811cf5ed mmap_region ([kernel.kallsyms])
ffffffff811cfe6b do_mmap ([kernel.kallsyms])
ffffffff811b0dca vm_mmap_pgoff ([kernel.kallsyms])
ffffffff811cdb0c sys_mmap_pgoff ([kernel.kallsyms])
ffffffff81033acb sys_mmap ([kernel.kallsyms])
ffffffff81631d37 entry_SYSCALL_64_fastpath ([kernel.kallsyms])
192ca mmap64 (/usr/lib/ld-2.25.so)
59a9 _dl_map_object_from_fd (/usr/lib/ld-2.25.so)
83d0 _dl_map_object (/usr/lib/ld-2.25.so)
cda1 openaux (/usr/lib/ld-2.25.so)
1834f _dl_catch_error (/usr/lib/ld-2.25.so)
cfe2 _dl_map_object_deps (/usr/lib/ld-2.25.so)
3481 dl_main (/usr/lib/ld-2.25.so)
17387 _dl_sysdep_start (/usr/lib/ld-2.25.so)
4d37 _dl_start (/usr/lib/ld-2.25.so)
d87 _start (/usr/lib/ld-2.25.so)heaptrack_gui 2228 135073.388677: 611329 cycles:
1a3e0 strcmp (/usr/lib/ld-2.25.so)
82b2 _dl_map_object (/usr/lib/ld-2.25.so)
cda1 openaux (/usr/lib/ld-2.25.so)
1834f _dl_catch_error (/usr/lib/ld-2.25.so)
cfe2 _dl_map_object_deps (/usr/lib/ld-2.25.so)
3481 dl_main (/usr/lib/ld-2.25.so)
17387 _dl_sysdep_start (/usr/lib/ld-2.25.so)
4d37 _dl_start (/usr/lib/ld-2.25.so)
d87 _start (/usr/lib/ld-2.25.so)~~~~~
With libdw without this patch:
~~~~~heaptrack_gui 2228 135073.388524: 479408 cycles:
ffffffff811749ed perf_iterate_ctx ([kernel.kallsyms]) ffffffff81181662 perf_event_mmap ([kernel.kallsyms]) ffffffff811cf5ed mmap_region ([kernel.kallsyms]) ffffffff811cfe6b do_mmap ([kernel.kallsyms]) ffffffff811b0dca vm_mmap_pgoff ([kernel.kallsyms]) ffffffff811cdb0c sys_mmap_pgoff ([kernel.kallsyms]) ffffffff81033acb sys_mmap ([kernel.kallsyms]) ffffffff81631d37 entry_SYSCALL_64_fastpath ([kernel.kallsyms])
heaptrack_gui 2228 135073.388677: 611329 cycles:
~~~~~
With this patch applied, the libdw unwinder will produce the same output as the libunwind unwinder.
--- tools/perf/util/unwind-libdw.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
tools/perf/util/unwind-libdw.c +1 -1
@@ -224,7 +224,7 @@ int unwind__get_entries(unwind_entry_cb_t cb, void *arg, err =dwfl_getthread_frames (ui->dwfl, thread->tid, frame_callback, ui); -if (err && !ui->max_stack) +if (err && ui->max_stack != max_stack) err =0 ;/*
Signature · 1 line
2.9.4
Arnaldo Carvalho de Melo
maintainerPATCH 11/11 perf report: Ensure the perf DSO mapping matches what libdw sees
In reply to Arnaldo Carvalho de MeloFrom: Milian Wolff <[email protected]>
In some situations the libdw unwinder stopped working properly. I.e. with libunwind we see:
~~~~~heaptrack_gui 2228 135073.400112: 641314 cycles:
e8ed _dl_fixup (/usr/lib/ld-2.25.so) 15f06 _dl_runtime_resolve_sse_vex (/usr/lib/ld-2.25.so) ed94c KDynamicJobTracker::KDynamicJobTracker (/home/milian/projects/compiled/kf5/lib64/libKF5KIOWidgets.so.5.35.0) 608f3 _GLOBAL__sub_I_kdynamicjobtracker.cpp (/home/milian/projects/compiled/kf5/lib64/libKF5KIOWidgets.so.5.35.0) f199 call_init.part.0 (/usr/lib/ld-2.25.so) f2a5 _dl_init (/usr/lib/ld-2.25.so) db9 _dl_start_user (/usr/lib/ld-2.25.so)
~~~~~
But with libdw and without this patch this sample is not properly unwound:
~~~~~heaptrack_gui 2228 135073.400112: 641314 cycles:
e8ed _dl_fixup (/usr/lib/ld-2.25.so) 15f06 _dl_runtime_resolve_sse_vex (/usr/lib/ld-2.25.so) ed94c KDynamicJobTracker::KDynamicJobTracker (/home/milian/projects/compiled/kf5/lib64/libKF5KIOWidgets.so.5.35.0)
~~~~~
Debug output showed me that libdw found a module for the last frame address, but it thinks it belongs to /usr/lib/ld-2.25.so. This patch double-checks what libdw sees and what perf knows. If the mappings mismatch, we now report the elf known to perf. This fixes the situation above, and the libdw unwinder produces the same stack as libunwind.
--- tools/perf/util/unwind-libdw.c | 8 ++++++++ 1 file changed, 8 insertions(+)
tools/perf/util/unwind-libdw.c +8 -0
@@ -39,6 +39,14 @@ static int __report_module(struct addr_location *al, u64 ip,return 0 ; mod =dwfl_addrmodule (ui->dwfl, ip); +if (mod) { +Dwarf_Addr s; + +dwfl_module_info (mod,NULL , &s,NULL ,NULL ,NULL ,NULL ,NULL ); +if (s != al->map->start) + mod =0 ; + } +if (!mod) mod = dwfl_report_elf(ui->dwfl, dso->short_name, dso->long_name, -1, al->map->start,
Signature · 1 line
2.9.4
Quoted 70 lines · Arnaldo Carvalho de Melo
Hi Ingo,
Please consider pulling,
- Arnaldo
The following changes since commit
6e30437bd42c4d4e9cfc4c40efda00eb83a11cde:
tools/include: Sync kernel ABI headers with tooling headers (2017-05-24 09:00:21 +0200)are available in the git repository at:
git://git.kernel.org/pub/scm/linux/kernel/git/acme/linux.gittags/perf-urgent-for-mingo-4.12-20170606for you to fetch changes up to
2538b9e2450ae255337c04356e9e0f8cb9ec48d9:perf report: Ensure the perf DSO mapping matches what libdw sees (2017-06-05 14:18:05 -0300)
----------------------------------------------------------------
perf/urgent fixes:- Only print NMI watchdog hint in 'perf stat' when it is enabled (Andi Kleen)
- Fix sys_mmap/sys_old_mmap shandling in s390 in 'perf trace' (Jiri Olsa)
- Disable breakpoint signal tests in powerpc, that lacks the perf kernel glue to set breakpoint events and makes 'perf test' always fail (Jiri Olsa)
- Fix 'perf annotate' for branch instruction with multiple operands (Kim Phillips)
- Add missing powerpc triplet when disassembling with 'objdump' in 'perf annotate' (Kim Phillips)
- Do not trow away partial unwound stacks when using libdw, making callchains produced with it similar to those produced when linked with the other DWARF unwind library supported in perf, libunwind (Milian Wolff)
- Fixes to properly handle kernel modules when processing build-id meta events (Namhyung Kim)
- Fix handling of compressed modules in the build-id cache (Namhyung Kim)
- Fix 'perf annotate' failure when filename has special chars (Ravi Bangoria)
Signed-off-by Arnaldo Carvalho de Melo <[email protected]>----------------------------------------------------------------
Andi Kleen (1):
perf stat: Only print NMI watchdog hint when enabledJiri Olsa (2):
perf trace: Add mmap alias for s390
perf test: Disable breakpoint signal tests for powerpcKim Phillips (2):
perf annotate: Fix branch instruction with multiple operands perf annotate: Add missing powerpc tripletMilian Wolff (2):
perf report: Include partial stacks unwound with libdw perf report: Ensure the perf DSO mapping matches what libdw seesNamhyung Kim (3):
perf header: Set proper module name when build-id event found perf symbols: Set module info when build-id event found
perf symbols: Use correct filename for compressed modules in build-id cacheRavi Bangoria (1):
perf annotate: Fix failure when filename has special chars
Quoted 14 lines
tools/perf/arch/common.c | 1 + tools/perf/builtin-stat.c | 5 ++++- tools/perf/builtin-trace.c | 4 ++++ tools/perf/tests/bp_signal.c | 14 ++++++++++++++ tools/perf/tests/builtin-test.c | 7 +++++++ tools/perf/tests/tests.h | 3 +++ tools/perf/util/annotate.c | 35 +++++++++++++++++++++++++++++++---- tools/perf/util/dso.c | 15 +++++++++++++++ tools/perf/util/dso.h | 3 +++ tools/perf/util/header.c | 12 ++++++++++-- tools/perf/util/machine.c | 11 +---------- tools/perf/util/symbol-elf.c | 5 +---- tools/perf/util/unwind-libdw.c | 10 +++++++++- 13 files changed, 103 insertions(+), 22 deletions(-)
Pulled, thanks a lot Arnaldo!
Ingo