diff options
author | Ulf Hermann <ulf.hermann@theqtcompany.com> | 2015-11-05 15:25:14 +0100 |
---|---|---|
committer | Ulf Hermann <ulf.hermann@theqtcompany.com> | 2015-11-10 11:02:05 +0000 |
commit | 3e6026766b4f518d4c5631686a4c2b21316f1acb (patch) | |
tree | 5f175aca5497f22a78f786a4c4262715e1a00928 | |
parent | 93e621c8d7bf1edce6f1617bc149bfe5ce8f2643 (diff) |
Force samples to be sent, even if they are uselessv3.6.1v3.6.0-rc1v3.6.03.6
Otherwise we can get grossly misrepresented durations for function
calls in the visualization.
Change-Id: I568fadabff3d21cfeae6700405dc09a3e505a11e
Reviewed-by: Christian Kandeler <christian.kandeler@theqtcompany.com>
-rw-r--r-- | app/perfunwind.cpp | 30 |
1 files changed, 18 insertions, 12 deletions
diff --git a/app/perfunwind.cpp b/app/perfunwind.cpp index fbc7f1c..a5d288a 100644 --- a/app/perfunwind.cpp +++ b/app/perfunwind.cpp @@ -293,7 +293,7 @@ static const Dwfl_Thread_Callbacks callbacks = { static PerfUnwind::Frame lookupSymbol(PerfUnwind::UnwindInfo *ui, Dwfl *dwfl, Dwarf_Addr ip, bool isKernel) { - Dwfl_Module *mod = dwfl_addrmodule (dwfl, ip); + Dwfl_Module *mod = dwfl ? dwfl_addrmodule(dwfl, ip) : 0; const char *symname = NULL; const char *elfFile = NULL; const char *srcFile = NULL; @@ -302,7 +302,7 @@ static PerfUnwind::Frame lookupSymbol(PerfUnwind::UnwindInfo *ui, Dwfl *dwfl, Dw GElf_Sym sym; GElf_Off off; - if (!mod) { + if (dwfl && !mod) { const PerfUnwind::ElfInfo *elfInfo = 0; mod = ui->unwind->reportElf(ip, isKernel ? PerfUnwind::s_kernelPid : ui->sample->pid(), &elfInfo); @@ -426,6 +426,11 @@ void PerfUnwind::sample(const PerfRecordSample &sample) void PerfUnwind::analyze(const PerfRecordSample &sample) { + currentUnwind.broken = false; + currentUnwind.isInterworking = false; + currentUnwind.sample = &sample; + currentUnwind.frames.clear(); + if (!dwfl || static_cast<pid_t>(sample.pid()) != dwfl_pid(dwfl)) { dwfl_end(dwfl); dwfl = dwfl_begin(&offlineCallbacks); @@ -433,24 +438,25 @@ void PerfUnwind::analyze(const PerfRecordSample &sample) if (!dwfl) { qWarning() << "failed to initialize dwfl" << dwfl_errmsg(dwfl_errno()); - return; - } - if (!dwfl_attach_state(dwfl, 0, sample.pid(), &callbacks, ¤tUnwind)) { - return; + currentUnwind.broken = true; + } else if (!dwfl_attach_state(dwfl, 0, sample.pid(), &callbacks, ¤tUnwind)) { + qWarning() << "failed to attach state" << dwfl_errmsg(dwfl_errno()); + currentUnwind.broken = true; } } else { if (!dwfl_addrmodule (dwfl, sample.ip())) reportElf(sample.ip(), sample.pid()); } - currentUnwind.broken = false; - currentUnwind.isInterworking = false; - currentUnwind.sample = &sample; - currentUnwind.frames.clear(); if (sample.callchain().length() > 0) resolveCallchain(); - if (sample.registerAbi() != 0 && sample.userStack().length() > 0) - unwindStack(); + if (sample.registerAbi() != 0) { + if (dwfl && sample.userStack().length() > 0) + unwindStack(); + // If nothing was found, at least look up the IP + if (currentUnwind.frames.isEmpty()) + currentUnwind.frames.append(lookupSymbol(¤tUnwind, dwfl, sample.ip(), false)); + } QByteArray buffer; QDataStream(&buffer, QIODevice::WriteOnly) |