Commit-ID:  9126cbbacecb8917bd0418809ef1d26616b2061e
Gitweb:     http://git.kernel.org/tip/9126cbbacecb8917bd0418809ef1d26616b2061e
Author:     Milian Wolff <[email protected]>
AuthorDate: Fri, 2 Jun 2017 16:37:53 +0200
Committer:  Arnaldo Carvalho de Melo <[email protected]>
CommitDate: Fri, 16 Jun 2017 14:37:30 -0300

perf unwind: Report module before querying isactivation in dwfl unwind

The PC returned by dwfl_frame_pc() may map into a not-yet-reported
module. We have to report it before we continue unwinding. But when we
query for the isactivation flag in dwfl_frame_pc, libdw will actually do
one more unwinding step internally which can then break and lead to
missed frames or broken stacks.

With libunwind we get e.g.:

~~~~~
  heaptrack_gui  2228 135073.400474:     613969 cycles:
                  108c8e [unknown] (/usr/lib/libQt5Core.so.5.8.0)
                  1093bc [unknown] (/usr/lib/libQt5Core.so.5.8.0)
                  109e7b QLocale::QLocale (/usr/lib/libQt5Core.so.5.8.0)
                  1470ff [unknown] (/usr/lib/libQt5Core.so.5.8.0)
                  147f67 QSystemLocale::query (/usr/lib/libQt5Core.so.5.8.0)
                  109fbf QLocalePrivate::updateSystemPrivate 
(/usr/lib/libQt5Core.so.5.8.0)
                  10aa27 QLocale::QLocale (/usr/lib/libQt5Core.so.5.8.0)
                  1e02c3 [unknown] (/usr/lib/libQt5Core.so.5.8.0)
                  2113bb [unknown] (/usr/lib/libQt5Core.so.5.8.0)
                  211505 [unknown] (/usr/lib/libQt5Core.so.5.8.0)
                  1b5df0 QFileInfo::exists (/usr/lib/libQt5Core.so.5.8.0)
                   92eb2 [unknown] (/usr/lib/libQt5Core.so.5.8.0)
                   93423 [unknown] (/usr/lib/libQt5Core.so.5.8.0)
                   93d2a QLibraryInfo::location (/usr/lib/libQt5Core.so.5.8.0)
                  2170af [unknown] (/usr/lib/libQt5Core.so.5.8.0)
                  297c53 QCoreApplicationPrivate::init 
(/usr/lib/libQt5Core.so.5.8.0)
                   f7cde QGuiApplicationPrivate::init 
(/usr/lib/libQt5Gui.so.5.8.0)
                  1589e8 QApplicationPrivate::init 
(/usr/lib/libQt5Widgets.so.5.8.0)
                   78622 main 
(/home/milian/projects/compiled/other/bin/heaptrack_gui)
                   20439 __libc_start_main (/usr/lib/libc-2.25.so)
                   78299 _start 
(/home/milian/projects/compiled/other/bin/heaptrack_gui)

  heaptrack_gui  2228 135073.401156:     569521 cycles:
                  131633 QString::endsWith (/usr/lib/libQt5Core.so.5.8.0)
                  1a0701 QDir::cleanPath (/usr/lib/libQt5Core.so.5.8.0)
                  21b82d [unknown] (/usr/lib/libQt5Core.so.5.8.0)
                  1b3727 QFileInfo::canonicalFilePath 
(/usr/lib/libQt5Core.so.5.8.0)
                  2780c7 QFactoryLoader::update (/usr/lib/libQt5Core.so.5.8.0)
                  279525 QFactoryLoader::QFactoryLoader 
(/usr/lib/libQt5Core.so.5.8.0)
                   e5bd0 QPlatformIntegrationFactory::create 
(/usr/lib/libQt5Gui.so.5.8.0)
                   f5a1c QGuiApplicationPrivate::createPlatformIntegration 
(/usr/lib/libQt5Gui.so.5.8.0)
                   f650c QGuiApplicationPrivate::createEventDispatcher 
(/usr/lib/libQt5Gui.so.5.8.0)
                  298524 QCoreApplicationPrivate::init 
(/usr/lib/libQt5Core.so.5.8.0)
                   f7cde QGuiApplicationPrivate::init 
(/usr/lib/libQt5Gui.so.5.8.0)
                  1589e8 QApplicationPrivate::init 
(/usr/lib/libQt5Widgets.so.5.8.0)
                   78622 main 
(/home/milian/projects/compiled/other/bin/heaptrack_gui)
                   20439 __libc_start_main (/usr/lib/libc-2.25.so)
                   78299 _start 
(/home/milian/projects/compiled/other/bin/heaptrack_gui)
~~~~~

Note the two frames 1589e8 and 78622 in the first sample. These are
missing when unwinding with libdw. The second sample's breakage is
more obvious:

~~~~~
  heaptrack_gui  2228 135073.400474:     613969 cycles:
                  108c8e [unknown] (/usr/lib/libQt5Core.so.5.8.0)
                  1093bc [unknown] (/usr/lib/libQt5Core.so.5.8.0)
                  109e7b QLocale::QLocale (/usr/lib/libQt5Core.so.5.8.0)
                  1470ff [unknown] (/usr/lib/libQt5Core.so.5.8.0)
                  147f67 QSystemLocale::query (/usr/lib/libQt5Core.so.5.8.0)
                  109fbf QLocalePrivate::updateSystemPrivate 
(/usr/lib/libQt5Core.so.5.8.0)
                  10aa27 QLocale::QLocale (/usr/lib/libQt5Core.so.5.8.0)
                  1e02c3 [unknown] (/usr/lib/libQt5Core.so.5.8.0)
                  2113bb [unknown] (/usr/lib/libQt5Core.so.5.8.0)
                  211505 [unknown] (/usr/lib/libQt5Core.so.5.8.0)
                  1b5df0 QFileInfo::exists (/usr/lib/libQt5Core.so.5.8.0)
                   92eb2 [unknown] (/usr/lib/libQt5Core.so.5.8.0)
                   93423 [unknown] (/usr/lib/libQt5Core.so.5.8.0)
                   93d2a QLibraryInfo::location (/usr/lib/libQt5Core.so.5.8.0)
                  2170af [unknown] (/usr/lib/libQt5Core.so.5.8.0)
                  297c53 QCoreApplicationPrivate::init 
(/usr/lib/libQt5Core.so.5.8.0)
                   f7cde QGuiApplicationPrivate::init 
(/usr/lib/libQt5Gui.so.5.8.0)
                   20439 __libc_start_main (/usr/lib/libc-2.25.so)
                   78299 _start 
(/home/milian/projects/compiled/other/bin/heaptrack_gui)

heaptrack_gui  2228 135073.401156:     569521 cycles:
                  131633 QString::endsWith (/usr/lib/libQt5Core.so.5.8.0)
                  1a0701 QDir::cleanPath (/usr/lib/libQt5Core.so.5.8.0)
                  21b82d [unknown] (/usr/lib/libQt5Core.so.5.8.0)
                  1b3727 QFileInfo::canonicalFilePath 
(/usr/lib/libQt5Core.so.5.8.0)
                  2780c7 QFactoryLoader::update (/usr/lib/libQt5Core.so.5.8.0)
                  279525 QFactoryLoader::QFactoryLoader 
(/usr/lib/libQt5Core.so.5.8.0)
                   e5bd0 QPlatformIntegrationFactory::create 
(/usr/lib/libQt5Gui.so.5.8.0)
                  723dbf [unknown] ([unknown])
~~~~~

This patch fixes this issue and the libdw unwinder mimicks the libunwind
behavior more closely.

Signed-off-by: Milian Wolff <[email protected]>
Acked-by: Jan Kratochvil <[email protected]>
Cc: Jiri Olsa <[email protected]>
Cc: Namhyung Kim <[email protected]>
Link: http://lkml.kernel.org/r/[email protected]
Signed-off-by: Arnaldo Carvalho de Melo <[email protected]>
---
 tools/perf/util/unwind-libdw.c | 8 ++++++++
 1 file changed, 8 insertions(+)

diff --git a/tools/perf/util/unwind-libdw.c b/tools/perf/util/unwind-libdw.c
index da45c4b..7755a5e0 100644
--- a/tools/perf/util/unwind-libdw.c
+++ b/tools/perf/util/unwind-libdw.c
@@ -178,6 +178,14 @@ frame_callback(Dwfl_Frame *state, void *arg)
        Dwarf_Addr pc;
        bool isactivation;
 
+       if (!dwfl_frame_pc(state, &pc, NULL)) {
+               pr_err("%s", dwfl_errmsg(-1));
+               return DWARF_CB_ABORT;
+       }
+
+       // report the module before we query for isactivation
+       report_module(pc, ui);
+
        if (!dwfl_frame_pc(state, &pc, &isactivation)) {
                pr_err("%s", dwfl_errmsg(-1));
                return DWARF_CB_ABORT;

Reply via email to