summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorUlf Hermann <ulf.hermann@theqtcompany.com>2015-11-05 15:25:14 +0100
committerUlf Hermann <ulf.hermann@theqtcompany.com>2015-11-10 11:02:05 +0000
commit3e6026766b4f518d4c5631686a4c2b21316f1acb (patch)
tree5f175aca5497f22a78f786a4c4262715e1a00928
parent93e621c8d7bf1edce6f1617bc149bfe5ce8f2643 (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.cpp30
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, &currentUnwind)) {
- return;
+ currentUnwind.broken = true;
+ } else if (!dwfl_attach_state(dwfl, 0, sample.pid(), &callbacks, &currentUnwind)) {
+ 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(&currentUnwind, dwfl, sample.ip(), false));
+ }
QByteArray buffer;
QDataStream(&buffer, QIODevice::WriteOnly)