diff options
author | Ulf Hermann <ulf.hermann@qt.io> | 2018-01-25 11:29:22 +0100 |
---|---|---|
committer | Ulf Hermann <ulf.hermann@qt.io> | 2018-01-25 12:11:15 +0000 |
commit | df0d8d59bb1b78c169822c244ddccbb046945dd9 (patch) | |
tree | e5ff77fdcc3d3a2964abeb9167a2eacfba24e07f | |
parent | c7a2d7623825ec0d514dabb44c4729f79ac5ab6c (diff) |
Use dwfl_report_begin/_end correctly
The documentation states that you cannot use dwfl until dwfl_report_end
returns 0. In fact you can, but then you run into strange corner cases
where dwfl doesn't find certain modules that have been reported before.
So far it was assumed that we cannot report additional modules while
unwinding a stack, but in fact I don't see a reason why. So, whenever we
want to report an additional module we call dwfl_report_begin_add before
and dwfl_report_end afterwards. In addition, to make our dwfl initially
usable we do one round of dwfl_report_begin and dwfl_report_end when
creating it, and we have to change the order of begin and end on clear
because the usual state of the dwfl is now "closed for reporting".
Change-Id: I7468204c8f48a8a0c8f68f78e81f5c4aeb8fb8d4
Reviewed-by: Milian Wolff <milian.wolff@kdab.com>
-rw-r--r-- | app/perfsymboltable.cpp | 11 |
1 files changed, 10 insertions, 1 deletions
diff --git a/app/perfsymboltable.cpp b/app/perfsymboltable.cpp index 3a1b451..8787b73 100644 --- a/app/perfsymboltable.cpp +++ b/app/perfsymboltable.cpp @@ -75,6 +75,11 @@ PerfSymbolTable::PerfSymbolTable(qint32 pid, Dwfl_Callbacks *callbacks, PerfUnwi m_pid(pid) { m_dwfl = dwfl_begin(m_callbacks); + dwfl_report_begin(m_dwfl); + + // "DWFL can not be used until this function returns 0" + const int reportEnd = dwfl_report_end(m_dwfl, NULL, NULL); + Q_ASSERT(reportEnd == 0); } PerfSymbolTable::~PerfSymbolTable() @@ -484,6 +489,7 @@ Dwfl_Module *PerfSymbolTable::reportElf(const PerfElfMap::ElfInfo& info) return nullptr; } + dwfl_report_begin_add(m_dwfl); Dwfl_Module *ret = dwfl_report_elf( m_dwfl, info.originalFileName.constData(), info.localFile.absoluteFilePath().toLocal8Bit().constData(), -1, info.addr, @@ -498,6 +504,8 @@ Dwfl_Module *PerfSymbolTable::reportElf(const PerfElfMap::ElfInfo& info) nullptr, nullptr); *userData = this; } + const int reportEnd = dwfl_report_end(m_dwfl, NULL, NULL); + Q_ASSERT(reportEnd == 0); return ret; } @@ -756,8 +764,9 @@ void PerfSymbolTable::clearCache() m_perfMapFile.reset(); // Throw out the dwfl state - dwfl_report_end(m_dwfl, NULL, NULL); dwfl_report_begin(m_dwfl); + const int reportEnd = dwfl_report_end(m_dwfl, NULL, NULL); + Q_ASSERT(reportEnd == 0); m_cacheIsDirty = false; } |