Callgrind: Support opening last results in KCachegrind

Change-Id: Idb3b08ca6a1837f2456b73bcaf19aced5b83179f
Reviewed-by: hjk <hjk@qt.io>
This commit is contained in:
Orgad Shaneh
2018-11-07 23:55:59 +02:00
committed by Orgad Shaneh
parent 2c212d48a5
commit 7c56b2c310
12 changed files with 168 additions and 17 deletions

View File

@@ -44,13 +44,15 @@ namespace Callgrind {
class ParseData::Private { class ParseData::Private {
Q_DECLARE_TR_FUNCTIONS(Valgrind::Callgrind::ParseData) Q_DECLARE_TR_FUNCTIONS(Valgrind::Callgrind::ParseData)
public: public:
Private(ParseData *q) Private(ParseData *q, const QString &fileName)
: m_q(q) : m_fileName(fileName)
, m_q(q)
{ {
} }
~Private(); ~Private();
QString m_fileName;
QStringList m_events; QStringList m_events;
QStringList m_positions; QStringList m_positions;
QVector<quint64> m_totalCosts; QVector<quint64> m_totalCosts;
@@ -138,10 +140,9 @@ void ParseData::Private::cycleDetection()
//BEGIN ParseData //BEGIN ParseData
ParseData::ParseData() ParseData::ParseData(const QString &fileName)
: d(new Private(this)) : d(new Private(this, fileName))
{ {
} }
ParseData::~ParseData() ParseData::~ParseData()
@@ -149,6 +150,11 @@ ParseData::~ParseData()
delete d; delete d;
} }
QString ParseData::fileName() const
{
return d->m_fileName;
}
QString ParseData::prettyStringForEvent(const QString &event) QString ParseData::prettyStringForEvent(const QString &event)
{ {
/* /*

View File

@@ -44,9 +44,11 @@ class Function;
class ParseData class ParseData
{ {
public: public:
explicit ParseData(); explicit ParseData(const QString &fileName);
~ParseData(); ~ParseData();
QString fileName() const;
static QString prettyStringForEvent(const QString &event); static QString prettyStringForEvent(const QString &event);
/// List of events reported in the data file. /// List of events reported in the data file.
QStringList events() const; QStringList events() const;

View File

@@ -32,6 +32,7 @@
#include <utils/qtcassert.h> #include <utils/qtcassert.h>
#include <QFileDevice>
#include <QHash> #include <QHash>
#include <QVector> #include <QVector>
#include <QStringList> #include <QStringList>
@@ -202,7 +203,10 @@ void Parser::Private::parse(QIODevice *device)
delete data; delete data;
data = nullptr; data = nullptr;
data = new ParseData; QString file;
if (auto fileDevice = qobject_cast<QFileDevice *>(device))
file = fileDevice->fileName();
data = new ParseData(file);
parseHeader(device); parseHeader(device);
while (!device->atEnd()) { while (!device->atEnd()) {
QByteArray line = device->readLine(); QByteArray line = device->readLine();

View File

@@ -186,6 +186,8 @@ public:
QPointer<CostView> m_calleesView; QPointer<CostView> m_calleesView;
QPointer<Visualization> m_visualization; QPointer<Visualization> m_visualization;
QString m_lastFileName;
// Navigation // Navigation
QAction *m_goBack = nullptr; QAction *m_goBack = nullptr;
QAction *m_goNext = nullptr; QAction *m_goNext = nullptr;
@@ -207,6 +209,7 @@ public:
QAction *m_startAction = nullptr; QAction *m_startAction = nullptr;
QAction *m_stopAction = nullptr; QAction *m_stopAction = nullptr;
QAction *m_loadExternalLogFile = nullptr; QAction *m_loadExternalLogFile = nullptr;
QAction *m_startKCachegrind = nullptr;
QAction *m_dumpAction = nullptr; QAction *m_dumpAction = nullptr;
QAction *m_resetAction = nullptr; QAction *m_resetAction = nullptr;
QAction *m_pauseAction = nullptr; QAction *m_pauseAction = nullptr;
@@ -355,6 +358,8 @@ CallgrindTool::CallgrindTool()
updateCostFormat(); updateCostFormat();
ValgrindGlobalSettings *settings = ValgrindPlugin::globalSettings();
// //
// Control Widget // Control Widget
// //
@@ -365,6 +370,16 @@ CallgrindTool::CallgrindTool()
action->setToolTip(tr("Load External Log File")); action->setToolTip(tr("Load External Log File"));
connect(action, &QAction::triggered, this, &CallgrindTool::loadExternalLogFile); connect(action, &QAction::triggered, this, &CallgrindTool::loadExternalLogFile);
action = m_startKCachegrind = new QAction(this);
action->setEnabled(false);
const Utils::Icon kCachegrindIcon({{":/valgrind/images/kcachegrind.png",
Theme::IconsBaseColor}});
action->setIcon(kCachegrindIcon.icon());
action->setToolTip(tr("Open results in KCachegrind."));
connect(action, &QAction::triggered, this, [this, settings] {
QProcess::startDetached(settings->kcachegrindExecutable(), { m_lastFileName });
});
// dump action // dump action
m_dumpAction = action = new QAction(this); m_dumpAction = action = new QAction(this);
action->setDisabled(true); action->setDisabled(true);
@@ -423,6 +438,7 @@ CallgrindTool::CallgrindTool()
m_perspective.addToolBarAction(m_startAction); m_perspective.addToolBarAction(m_startAction);
m_perspective.addToolBarAction(m_stopAction); m_perspective.addToolBarAction(m_stopAction);
m_perspective.addToolBarAction(m_loadExternalLogFile); m_perspective.addToolBarAction(m_loadExternalLogFile);
m_perspective.addToolBarAction(m_startKCachegrind);
m_perspective.addToolBarAction(m_dumpAction); m_perspective.addToolBarAction(m_dumpAction);
m_perspective.addToolBarAction(m_resetAction); m_perspective.addToolBarAction(m_resetAction);
m_perspective.addToolBarAction(m_pauseAction); m_perspective.addToolBarAction(m_pauseAction);
@@ -466,8 +482,6 @@ CallgrindTool::CallgrindTool()
m_perspective.addToolBarWidget(button); m_perspective.addToolBarWidget(button);
} }
ValgrindGlobalSettings *settings = ValgrindPlugin::globalSettings();
// Cycle detection // Cycle detection
//action = new QAction("Cycle Detection", this); ///FIXME: icon //action = new QAction("Cycle Detection", this); ///FIXME: icon
action = m_cycleDetection = new QAction("O", this); ///FIXME: icon action = m_cycleDetection = new QAction("O", this); ///FIXME: icon
@@ -713,6 +727,7 @@ void CallgrindTool::setParseData(ParseData *data)
delete data; delete data;
data = nullptr; data = nullptr;
} }
m_lastFileName = data ? data->fileName() : QString();
m_dataModel.setParseData(data); m_dataModel.setParseData(data);
m_calleesModel.setParseData(data); m_calleesModel.setParseData(data);
m_callersModel.setParseData(data); m_callersModel.setParseData(data);
@@ -919,14 +934,21 @@ void CallgrindTool::takeParserData(ParseData *data)
{ {
showParserResults(data); showParserResults(data);
if (!data) if (!data) {
m_lastFileName.clear();
m_startKCachegrind->setEnabled(false);
return; return;
}
// clear first // clear first
clearTextMarks(); clearTextMarks();
doClear(true); doClear(true);
setParseData(data); setParseData(data);
const QString kcachegrindExecutable = ValgrindPlugin::globalSettings()->kcachegrindExecutable();
const bool kcachegrindExists = !Utils::Environment::systemEnvironment().searchInPath(
kcachegrindExecutable).isEmpty();
m_startKCachegrind->setEnabled(kcachegrindExists && !m_lastFileName.isEmpty());
createTextMarks(); createTextMarks();
} }

Binary file not shown.

After

Width:  |  Height:  |  Size: 247 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 507 B

View File

@@ -2,5 +2,7 @@
<qresource prefix="/valgrind"> <qresource prefix="/valgrind">
<file>images/suppressoverlay.png</file> <file>images/suppressoverlay.png</file>
<file>images/suppressoverlay@2x.png</file> <file>images/suppressoverlay@2x.png</file>
<file>images/kcachegrind.png</file>
<file>images/kcachegrind@2x.png</file>
</qresource> </qresource>
</RCC> </RCC>

View File

@@ -73,6 +73,10 @@ ValgrindConfigWidget::ValgrindConfigWidget(ValgrindBaseSettings *settings, bool
// //
// Callgrind // Callgrind
// //
m_ui->kcachegrindExeChooser->setExpectedKind(Utils::PathChooser::ExistingCommand);
m_ui->kcachegrindExeChooser->setPromptDialogTitle(tr("KCachegrind Command"));
connect(m_ui->kcachegrindExeChooser, &Utils::PathChooser::rawPathChanged,
m_settings, &ValgrindBaseSettings::setKCachegrindExecutable);
connect(m_ui->enableCacheSim, &QCheckBox::toggled, connect(m_ui->enableCacheSim, &QCheckBox::toggled,
m_settings, &ValgrindBaseSettings::setEnableCacheSim); m_settings, &ValgrindBaseSettings::setEnableCacheSim);
connect(m_settings, &ValgrindBaseSettings::enableCacheSimChanged, connect(m_settings, &ValgrindBaseSettings::enableCacheSimChanged,
@@ -168,6 +172,7 @@ void ValgrindConfigWidget::updateUi()
{ {
m_ui->valgrindExeChooser->setPath(m_settings->valgrindExecutable()); m_ui->valgrindExeChooser->setPath(m_settings->valgrindExecutable());
m_ui->smcDetectionComboBox->setCurrentIndex(m_settings->selfModifyingCodeDetection()); m_ui->smcDetectionComboBox->setCurrentIndex(m_settings->selfModifyingCodeDetection());
m_ui->kcachegrindExeChooser->setPath(m_settings->kcachegrindExecutable());
m_ui->enableCacheSim->setChecked(m_settings->enableCacheSim()); m_ui->enableCacheSim->setChecked(m_settings->enableCacheSim());
m_ui->enableBranchSim->setChecked(m_settings->enableBranchSim()); m_ui->enableBranchSim->setChecked(m_settings->enableBranchSim());
m_ui->collectSystime->setChecked(m_settings->collectSystime()); m_ui->collectSystime->setChecked(m_settings->collectSystime());

View File

@@ -6,8 +6,8 @@
<rect> <rect>
<x>0</x> <x>0</x>
<y>0</y> <y>0</y>
<width>655</width> <width>708</width>
<height>364</height> <height>397</height>
</rect> </rect>
</property> </property>
<layout class="QGridLayout" name="gridLayout"> <layout class="QGridLayout" name="gridLayout">
@@ -106,7 +106,7 @@
<string>Profiling Options</string> <string>Profiling Options</string>
</property> </property>
<layout class="QFormLayout" name="formLayout_2"> <layout class="QFormLayout" name="formLayout_2">
<item row="0" column="0"> <item row="1" column="0">
<widget class="QLabel" name="minimumInclusiveCostRatioLabel"> <widget class="QLabel" name="minimumInclusiveCostRatioLabel">
<property name="toolTip"> <property name="toolTip">
<string>Limits the amount of results the profiler gives you. A lower limit will likely increase performance.</string> <string>Limits the amount of results the profiler gives you. A lower limit will likely increase performance.</string>
@@ -119,7 +119,7 @@
</property> </property>
</widget> </widget>
</item> </item>
<item row="0" column="1"> <item row="1" column="1">
<widget class="QDoubleSpinBox" name="minimumInclusiveCostRatio"> <widget class="QDoubleSpinBox" name="minimumInclusiveCostRatio">
<property name="suffix"> <property name="suffix">
<string>%</string> <string>%</string>
@@ -135,7 +135,7 @@
</property> </property>
</widget> </widget>
</item> </item>
<item row="2" column="0" colspan="2"> <item row="3" column="0" colspan="2">
<widget class="QGroupBox" name="enableEventToolTips"> <widget class="QGroupBox" name="enableEventToolTips">
<property name="title"> <property name="title">
<string>Show additional information for events in tooltips</string> <string>Show additional information for events in tooltips</string>
@@ -203,14 +203,14 @@ With cache simulation, further event counters are enabled:
</layout> </layout>
</widget> </widget>
</item> </item>
<item row="1" column="0"> <item row="2" column="0">
<widget class="QLabel" name="visualisationMinimumInclusiveCostRatioLabel"> <widget class="QLabel" name="visualisationMinimumInclusiveCostRatioLabel">
<property name="text"> <property name="text">
<string>Visualization: Minimum event cost:</string> <string>Visualization: Minimum event cost:</string>
</property> </property>
</widget> </widget>
</item> </item>
<item row="1" column="1"> <item row="2" column="1">
<widget class="QDoubleSpinBox" name="visualisationMinimumInclusiveCostRatio"> <widget class="QDoubleSpinBox" name="visualisationMinimumInclusiveCostRatio">
<property name="prefix"> <property name="prefix">
<string/> <string/>
@@ -226,6 +226,23 @@ With cache simulation, further event counters are enabled:
</property> </property>
</widget> </widget>
</item> </item>
<item row="0" column="0">
<widget class="QLabel" name="label_2">
<property name="text">
<string>KCachegrind executable:</string>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="Utils::PathChooser" name="kcachegrindExeChooser" native="true">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
<horstretch>1</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
</widget>
</item>
</layout> </layout>
</widget> </widget>
</item> </item>

View File

@@ -49,6 +49,7 @@ const char visibleErrorKindsC[] = "Analyzer.Valgrind.VisibleErrorKinds";
const char lastSuppressionDirectoryC[] = "Analyzer.Valgrind.LastSuppressionDirectory"; const char lastSuppressionDirectoryC[] = "Analyzer.Valgrind.LastSuppressionDirectory";
const char lastSuppressionHistoryC[] = "Analyzer.Valgrind.LastSuppressionHistory"; const char lastSuppressionHistoryC[] = "Analyzer.Valgrind.LastSuppressionHistory";
const char kcachegrindExeC[] = "Analyzer.Valgrind.KCachegrindExecutable";
const char callgrindEnableCacheSimC[] = "Analyzer.Valgrind.Callgrind.EnableCacheSim"; const char callgrindEnableCacheSimC[] = "Analyzer.Valgrind.Callgrind.EnableCacheSim";
const char callgrindEnableBranchSimC[] = "Analyzer.Valgrind.Callgrind.EnableBranchSim"; const char callgrindEnableBranchSimC[] = "Analyzer.Valgrind.Callgrind.EnableBranchSim";
const char callgrindCollectSystimeC[] = "Analyzer.Valgrind.Callgrind.CollectSystime"; const char callgrindCollectSystimeC[] = "Analyzer.Valgrind.Callgrind.CollectSystime";
@@ -105,6 +106,7 @@ void ValgrindBaseSettings::fromMap(const QVariantMap &map)
} }
// Callgrind // Callgrind
setIfPresent(map, kcachegrindExeC, &m_kcachegrindExecutable);
setIfPresent(map, callgrindEnableCacheSimC, &m_enableCacheSim); setIfPresent(map, callgrindEnableCacheSimC, &m_enableCacheSim);
setIfPresent(map, callgrindEnableBranchSimC, &m_enableBranchSim); setIfPresent(map, callgrindEnableBranchSimC, &m_enableBranchSim);
setIfPresent(map, callgrindCollectSystimeC, &m_collectSystime); setIfPresent(map, callgrindCollectSystimeC, &m_collectSystime);
@@ -135,6 +137,7 @@ void ValgrindBaseSettings::toMap(QVariantMap &map) const
map.insert(visibleErrorKindsC, errorKinds); map.insert(visibleErrorKindsC, errorKinds);
// Callgrind // Callgrind
map.insert(kcachegrindExeC, m_kcachegrindExecutable);
map.insert(callgrindEnableCacheSimC, m_enableCacheSim); map.insert(callgrindEnableCacheSimC, m_enableCacheSim);
map.insert(callgrindEnableBranchSimC, m_enableBranchSim); map.insert(callgrindEnableBranchSimC, m_enableBranchSim);
map.insert(callgrindCollectSystimeC, m_collectSystime); map.insert(callgrindCollectSystimeC, m_collectSystime);
@@ -216,6 +219,16 @@ void ValgrindBaseSettings::setVisibleErrorKinds(const QList<int> &visibleErrorKi
} }
} }
QString ValgrindBaseSettings::kcachegrindExecutable() const
{
return m_kcachegrindExecutable;
}
void ValgrindBaseSettings::setKCachegrindExecutable(const QString &exec)
{
m_kcachegrindExecutable = exec;
}
void ValgrindBaseSettings::setEnableCacheSim(bool enable) void ValgrindBaseSettings::setEnableCacheSim(bool enable)
{ {
if (m_enableCacheSim == enable) if (m_enableCacheSim == enable)
@@ -394,6 +407,7 @@ void ValgrindGlobalSettings::readSettings()
defaults.insert(lastSuppressionHistoryC, QStringList()); defaults.insert(lastSuppressionHistoryC, QStringList());
// Callgrind // Callgrind
defaults.insert(kcachegrindExeC, "kcachegrind");
defaults.insert(callgrindEnableCacheSimC, false); defaults.insert(callgrindEnableCacheSimC, false);
defaults.insert(callgrindEnableBranchSimC, false); defaults.insert(callgrindEnableBranchSimC, false);
defaults.insert(callgrindCollectSystimeC, false); defaults.insert(callgrindCollectSystimeC, false);

View File

@@ -129,6 +129,8 @@ protected:
* Base callgrind settings * Base callgrind settings
*/ */
public: public:
QString kcachegrindExecutable() const;
bool enableCacheSim() const { return m_enableCacheSim; } bool enableCacheSim() const { return m_enableCacheSim; }
bool enableBranchSim() const { return m_enableBranchSim; } bool enableBranchSim() const { return m_enableBranchSim; }
bool collectSystime() const { return m_collectSystime; } bool collectSystime() const { return m_collectSystime; }
@@ -141,6 +143,7 @@ public:
/// \return Minimum cost ratio, range [0.0..100.0] /// \return Minimum cost ratio, range [0.0..100.0]
double visualisationMinimumInclusiveCostRatio() const { return m_visualisationMinimumInclusiveCostRatio; } double visualisationMinimumInclusiveCostRatio() const { return m_visualisationMinimumInclusiveCostRatio; }
void setKCachegrindExecutable(const QString &exec);
void setEnableCacheSim(bool enable); void setEnableCacheSim(bool enable);
void setEnableBranchSim(bool enable); void setEnableBranchSim(bool enable);
void setCollectSystime(bool collect); void setCollectSystime(bool collect);
@@ -163,6 +166,7 @@ signals:
void visualisationMinimumInclusiveCostRatioChanged(double); void visualisationMinimumInclusiveCostRatioChanged(double);
private: private:
QString m_kcachegrindExecutable;
bool m_enableCacheSim; bool m_enableCacheSim;
bool m_collectSystime; bool m_collectSystime;
bool m_collectBusEvents; bool m_collectBusEvents;

View File

@@ -3188,6 +3188,81 @@
width="100%" width="100%"
height="100%" /> height="100%" />
</g> </g>
<g
id="src/plugins/valgrind/images/kcachegrind"
transform="translate(112)">
<use
x="0"
y="0"
xlink:href="#backgroundRect"
id="use5933-0-2"
width="100%"
height="100%"
transform="translate(1740,132)" />
<circle
style="fill:none;stroke:#000000"
id="path3156"
cx="1732.5"
cy="575.5"
r="3" />
<circle
style="fill:none;stroke:#000000"
id="path3156-7"
cx="1732.5"
cy="575.5"
r="5" />
<path
style="fill:none;stroke:#000000"
id="path3156-7-6"
sodipodi:type="arc"
sodipodi:cx="1732.5"
sodipodi:cy="575.5"
sodipodi:rx="5.5"
sodipodi:ry="5.5"
sodipodi:start="1.0821041"
sodipodi:end="4.118977"
d="m 1735.0821,580.35621 a 5.5,5.5 0 0 1 -7.2965,-2.0235 5.5,5.5 0 0 1 1.6388,-7.39242"
sodipodi:open="true" />
<path
style="fill:none;stroke:#000000"
d="m 1735,580 c 1,2 2.5,3.5 3.5,2.5 1,-1 -0.5,-2.5 -2.5,-3.5"
id="path7714"
inkscape:connector-curvature="0"
sodipodi:nodetypes="czc" />
<rect
style="fill:#000000"
id="rect7716"
width="3"
height="3"
x="1731"
y="580" />
<use
style="display:inline"
x="0"
y="0"
xlink:href="#rect7716"
id="use7718-4"
transform="rotate(45,1732.2679,575.40407)"
width="100%"
height="100%" />
<use
x="0"
y="0"
xlink:href="#rect7716"
id="use7718"
transform="rotate(90,1732.5,575.5)"
width="100%"
height="100%" />
<use
style="display:inline"
x="0"
y="0"
xlink:href="#rect7716"
id="use7718-4-4"
transform="rotate(135,1732.4602,575.4038)"
width="100%"
height="100%" />
</g>
</g> </g>
<g <g
inkscape:groupmode="layer" inkscape:groupmode="layer"

Before

Width:  |  Height:  |  Size: 351 KiB

After

Width:  |  Height:  |  Size: 353 KiB