forked from KDAB/hotspot
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add integration tests for perf parser.
Also add supporting class for perf record so hotspot can generate perf.data files for existing test-clients (cpp-inlining, cpp-recursion). Fixes KDAB#32
- Loading branch information
Showing
8 changed files
with
513 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -27,6 +27,7 @@ set(hotspot_SRCS | |
util.cpp | ||
|
||
parsers/perf/perfparser.cpp | ||
perfrecord.cpp | ||
|
||
mainwindow.cpp | ||
flamegraph.cpp | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,69 @@ | ||
/* | ||
perfrecord.cpp | ||
This file is part of Hotspot, the Qt GUI for performance analysis. | ||
Copyright (C) 2017 Klarälvdalens Datakonsult AB, a KDAB Group company, [email protected] | ||
Author: Nate Rogers <[email protected]> | ||
Licensees holding valid commercial KDAB Hotspot licenses may use this file in | ||
accordance with Hotspot Commercial License Agreement provided with the Software. | ||
Contact [email protected] if any conditions of this licensing are not clear to you. | ||
This program is free software; you can redistribute it and/or modify | ||
it under the terms of the GNU General Public License as published by | ||
the Free Software Foundation, either version 2 of the License, or | ||
(at your option) any later version. | ||
This program is distributed in the hope that it will be useful, | ||
but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
GNU General Public License for more details. | ||
You should have received a copy of the GNU General Public License | ||
along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
*/ | ||
|
||
#include <QDebug> | ||
#include <QFileInfo> | ||
|
||
#include "perfrecord.h" | ||
|
||
PerfRecord::PerfRecord(QObject* parent) | ||
: QObject(parent) | ||
, m_PerfRecordProcess(new QProcess(this)) | ||
, m_perfCommand() | ||
, m_outputPath() | ||
{ | ||
connect(m_PerfRecordProcess, (void (QProcess::*)(int,QProcess::ExitStatus))&QProcess::finished, this, &PerfRecord::perfRecordFinished); | ||
} | ||
|
||
PerfRecord::~PerfRecord() = default; | ||
|
||
void PerfRecord::record(QStringList perfOptions, const QString &outputPath, const QString &exePath) | ||
{ | ||
m_outputPath = outputPath; | ||
|
||
// Add in -F 99: sample at 99 Hertz (samples per second). I'll sometimes sample faster than this (up to 999 Hertz), but that also costs overhead. 99 Hertz should be negligible. Also, the value '99' and not '100' is to avoid lockstep sampling, which can produce skewed results. | ||
m_perfCommand = QLatin1String("perf record ") + perfOptions.join(QLatin1Char(' ')) + (perfOptions.size() > 0 ? QLatin1String(" ") : QLatin1String("")) + QLatin1String("-F 999 -o ") + m_outputPath + QLatin1Char(' ') + exePath; | ||
|
||
m_PerfRecordProcess->start(m_perfCommand);//QLatin1String("ping localhost -c 1"));// | ||
} | ||
|
||
void PerfRecord::perfRecordFinished(int exitCode, QProcess::ExitStatus exitStatus) | ||
{ | ||
Q_UNUSED(exitCode); | ||
Q_UNUSED(exitStatus); | ||
|
||
if (QFileInfo::exists(m_outputPath)) { | ||
emit recordingFinished(m_outputPath); | ||
} else { | ||
emit recordingFailed(tr("Failed to record perf data.")); | ||
} | ||
} | ||
|
||
QString PerfRecord::getPerfCommand() | ||
{ | ||
return m_perfCommand; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,123 @@ | ||
/* | ||
perfrecord.cpp | ||
This file is part of Hotspot, the Qt GUI for performance analysis. | ||
Copyright (C) 2017 Klarälvdalens Datakonsult AB, a KDAB Group company, [email protected] | ||
Author: Nate Rogers <[email protected]> | ||
Licensees holding valid commercial KDAB Hotspot licenses may use this file in | ||
accordance with Hotspot Commercial License Agreement provided with the Software. | ||
Contact [email protected] if any conditions of this licensing are not clear to you. | ||
This program is free software; you can redistribute it and/or modify | ||
it under the terms of the GNU General Public License as published by | ||
the Free Software Foundation, either version 2 of the License, or | ||
(at your option) any later version. | ||
This program is distributed in the hope that it will be useful, | ||
but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
GNU General Public License for more details. | ||
You should have received a copy of the GNU General Public License | ||
along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
*/ | ||
|
||
#pragma once | ||
|
||
#include <QObject> | ||
#include <QProcess> | ||
|
||
class PerfRecord : public QObject | ||
{ | ||
Q_OBJECT | ||
public: | ||
PerfRecord(QObject* parent = nullptr); | ||
~PerfRecord(); | ||
|
||
void record(QStringList perfOptions, const QString &outputPath, const QString &exePath); | ||
QString getPerfCommand(); | ||
|
||
signals: | ||
void recordingFinished(const QString &fileLocation); | ||
void recordingFailed(const QString &errorMessage); | ||
|
||
public slots: | ||
void perfRecordFinished(int exitCode, QProcess::ExitStatus exitStatus); | ||
|
||
private: | ||
QProcess *m_PerfRecordProcess; | ||
QString m_perfCommand; | ||
QString m_outputPath; | ||
}; | ||
|
||
/* | ||
-e, --event= | ||
Select the PMU event. Selection can be a symbolic event name (use perf list to list all events) or a raw PMU event (eventsel+umask) in the form of rNNN where NNN is a hexadecimal event descriptor. | ||
--filter=<filter> | ||
Event filter. | ||
-a, --all-cpus | ||
System-wide collection from all CPUs. | ||
-l | ||
Scale counter values. | ||
-p, --pid= | ||
Record events on existing process ID (comma separated list). | ||
-t, --tid= | ||
Record events on existing thread ID (comma separated list). | ||
-u, --uid= | ||
Record events in threads owned by uid. Name or number. | ||
-r, --realtime= | ||
Collect data with this RT SCHED_FIFO priority. | ||
-D, --no-delay | ||
Collect data without buffering. | ||
-A, --append | ||
Append to the output file to do incremental profiling. | ||
-f, --force | ||
Overwrite existing data file. (deprecated) | ||
-c, --count= | ||
Event period to sample. | ||
-o, --output= | ||
Output file name. | ||
-i, --no-inherit | ||
Child tasks do not inherit counters. | ||
-F, --freq= | ||
Profile at this frequency. | ||
-m, --mmap-pages= | ||
Number of mmap data pages. Must be a power of two. | ||
-g, --call-graph | ||
Do call-graph (stack chain/backtrace) recording. | ||
-q, --quiet | ||
Don't print any message, useful for scripting. | ||
-v, --verbose | ||
Be more verbose (show counter open errors, etc). | ||
-s, --stat | ||
Per thread counts. | ||
-d, --data | ||
Sample addresses. | ||
-T, --timestamp | ||
Sample timestamps. Use it with perf report -D to see the timestamps, for instance. | ||
-n, --no-samples | ||
Don't sample. | ||
-R, --raw-samples | ||
Collect raw sample records from all opened counters (default for tracepoint counters). | ||
-C, --cpu | ||
Collect samples only on the list of CPUs provided. Multiple CPUs can be provided as a comma-separated list with no space: 0,1. Ranges of CPUs are specified with -: 0-2. In per-thread mode with inheritance mode on (default), samples are captured only when the thread executes on the designated CPUs. Default is to monitor all CPUs. | ||
-N, --no-buildid-cache | ||
Do not update the builid cache. This saves some overhead in situations where the information in the perf.data file (which includes buildids) is sufficient. | ||
-G name,..., --cgroup name,... | ||
monitor only in the container (cgroup) called "name". This option is available only in per-cpu mode. The cgroup filesystem must be mounted. All threads belonging to container "name" are monitored when they run on the monitored CPUs. Multiple cgroups can be provided. Each cgroup is applied to the corresponding event, i.e., first cgroup to first event, second cgroup to second event and so on. It is possible to provide an empty cgroup (monitor all the time) using, e.g., -G foo,,bar. Cgroups must have corresponding events, i.e., they always refer to events defined earlier on the command line. | ||
-b, --branch-any | ||
Enable taken branch stack sampling. Any type of taken branch may be sampled. This is a shortcut for --branch-filter any. See --branch-filter for more infos. | ||
-j, --branch-filter | ||
Enable taken branch stack sampling. Each sample captures a series of consecutive taken branches. The number of branches captured with each sample depends on the underlying hardware, the type of branches of interest, and the executed code. It is possible to select the types of branches captured by enabling filters. The following filters are defined: | ||
• any: any type of branches | ||
• any_call: any function call or system call | ||
• any_ret: any function return or system call return | ||
• ind_call: any indirect branch | ||
• u: only when the branch target is at the user level | ||
• k: only when the branch target is in the kernel | ||
• hv: only when the target is at the hypervisor level | ||
The option requires at least one branch type among any, any_call, any_ret, ind_call. The privilege levels may be ommitted, in which case, the privilege levels of the associated event are applied to the branch filter. Both kernel (k) and hypervisor (hv) privilege levels are subject to permissions. When sampling on multiple events, branch stack sampling is enabled for all the sampling events. The sampled branch type is the same for all events. The various filters must be specified as a comma separated list: --branch-filter any_ret,u,k Note that this feature may not be available on all processors. | ||
*/ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,2 +1,3 @@ | ||
add_subdirectory(test-clients) | ||
add_subdirectory(modeltests) | ||
add_subdirectory(integrationtests) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
include_directories(../../src) | ||
include_directories(../../src/models) | ||
include_directories(../../src/parsers/perf) | ||
|
||
ecm_add_test( | ||
../../src/perfrecord.cpp | ||
../../src/util.cpp | ||
../../src/models/data.cpp | ||
../../src/parsers/perf/perfparser.cpp | ||
tst_perfparser.cpp | ||
LINK_LIBRARIES | ||
Qt5::Core | ||
Qt5::Test | ||
KF5::ThreadWeaver | ||
TEST_NAME | ||
tst_perfparser | ||
) |
Oops, something went wrong.