Valgrind: Aspectify settings

Change-Id: I2fbf8244a05ffb1b642843c6471f92e2b154cf8a
Reviewed-by: Christian Stenger <christian.stenger@qt.io>
This commit is contained in:
hjk
2021-02-18 14:18:34 +01:00
parent 8cfc053c2d
commit 0e2445bc54
13 changed files with 396 additions and 1309 deletions

View File

@@ -443,7 +443,6 @@ QVariant BaseAspect::volatileValue() const
void BaseAspect::setVolatileValue(const QVariant &val) void BaseAspect::setVolatileValue(const QVariant &val)
{ {
Q_UNUSED(val); Q_UNUSED(val);
QTC_CHECK(false);
} }
void BaseAspect::registerSubWidget(QWidget *widget) void BaseAspect::registerSubWidget(QWidget *widget)
@@ -1100,7 +1099,6 @@ QVariant StringAspect::volatileValue() const
void StringAspect::setVolatileValue(const QVariant &val) void StringAspect::setVolatileValue(const QVariant &val)
{ {
QTC_CHECK(!isAutoApply());
switch (d->m_displayStyle) { switch (d->m_displayStyle) {
case PathChooserDisplay: case PathChooserDisplay:
if (d->m_pathChooserDisplay) if (d->m_pathChooserDisplay)
@@ -2084,6 +2082,12 @@ void AspectContainer::reset()
aspect->setValueQuietly(aspect->defaultValue()); aspect->setValueQuietly(aspect->defaultValue());
} }
void AspectContainer::setAutoApply(bool on)
{
for (BaseAspect *aspect : qAsConst(d->m_items))
aspect->setAutoApply(on);
}
void AspectContainer::fromMap(const QString &prefix, const QVariantMap &map) void AspectContainer::fromMap(const QString &prefix, const QVariantMap &map)
{ {
for (BaseAspect *aspect : qAsConst(d->m_items)) for (BaseAspect *aspect : qAsConst(d->m_items))

View File

@@ -538,6 +538,7 @@ public:
void toMap(const QString &prefix, QVariantMap &map) const; void toMap(const QString &prefix, QVariantMap &map) const;
bool equals(const AspectContainer &other) const; bool equals(const AspectContainer &other) const;
void copyFrom(const AspectContainer &other); void copyFrom(const AspectContainer &other);
void setAutoApply(bool on);
void forEachAspect(const std::function<void(BaseAspect *)> &run) const; void forEachAspect(const std::function<void(BaseAspect *)> &run) const;

View File

@@ -27,7 +27,7 @@ add_qtc_plugin(Valgrind
memchecktool.cpp memchecktool.h memchecktool.cpp memchecktool.h
suppressiondialog.cpp suppressiondialog.h suppressiondialog.cpp suppressiondialog.h
valgrind.qrc valgrind.qrc
valgrindconfigwidget.cpp valgrindconfigwidget.h valgrindconfigwidget.ui valgrindconfigwidget.cpp valgrindconfigwidget.h
valgrindengine.cpp valgrindengine.h valgrindengine.cpp valgrindengine.h
valgrindplugin.cpp valgrindplugin.h valgrindplugin.cpp valgrindplugin.h
valgrindrunner.cpp valgrindrunner.h valgrindrunner.cpp valgrindrunner.h

View File

@@ -78,16 +78,16 @@ QStringList CallgrindToolRunner::toolArguments() const
{ {
QStringList arguments = {"--tool=callgrind"}; QStringList arguments = {"--tool=callgrind"};
if (m_settings.enableCacheSim()) if (m_settings.enableCacheSim.value())
arguments << "--cache-sim=yes"; arguments << "--cache-sim=yes";
if (m_settings.enableBranchSim()) if (m_settings.enableBranchSim.value())
arguments << "--branch-sim=yes"; arguments << "--branch-sim=yes";
if (m_settings.collectBusEvents()) if (m_settings.collectBusEvents.value())
arguments << "--collect-bus=yes"; arguments << "--collect-bus=yes";
if (m_settings.collectSystime()) if (m_settings.collectSystime.value())
arguments << "--collect-systime=yes"; arguments << "--collect-systime=yes";
if (m_markAsPaused) if (m_markAsPaused)
@@ -97,7 +97,7 @@ QStringList CallgrindToolRunner::toolArguments() const
if (!m_argumentForToggleCollect.isEmpty()) if (!m_argumentForToggleCollect.isEmpty())
arguments << m_argumentForToggleCollect; arguments << m_argumentForToggleCollect;
arguments << Utils::QtcProcess::splitArgs(m_settings.callgrindArguments()); arguments << Utils::QtcProcess::splitArgs(m_settings.callgrindArguments.value());
return arguments; return arguments;
} }

View File

@@ -133,8 +133,6 @@ public:
void selectFunction(const Function *); void selectFunction(const Function *);
void setCostFormat(CostDelegate::CostFormat format); void setCostFormat(CostDelegate::CostFormat format);
void enableCycleDetection(bool enabled);
void shortenTemplates(bool enabled);
void setCostEvent(int index); void setCostEvent(int index);
/// This function will add custom text marks to the editor /// This function will add custom text marks to the editor
@@ -198,8 +196,6 @@ public:
QAction *m_costAbsolute = nullptr; QAction *m_costAbsolute = nullptr;
QAction *m_costRelative = nullptr; QAction *m_costRelative = nullptr;
QAction *m_costRelativeToParent = nullptr; QAction *m_costRelativeToParent = nullptr;
QAction *m_cycleDetection = nullptr;
QAction *m_shortenTemplates = nullptr;
QComboBox *m_eventCombo = nullptr; QComboBox *m_eventCombo = nullptr;
QTimer m_updateTimer; QTimer m_updateTimer;
@@ -382,7 +378,7 @@ CallgrindToolPrivate::CallgrindToolPrivate()
action->setIcon(kCachegrindIcon.icon()); action->setIcon(kCachegrindIcon.icon());
action->setToolTip(CallgrindTool::tr("Open results in KCachegrind.")); action->setToolTip(CallgrindTool::tr("Open results in KCachegrind."));
connect(action, &QAction::triggered, this, [this, settings] { connect(action, &QAction::triggered, this, [this, settings] {
QProcess::startDetached(settings->kcachegrindExecutable(), { m_lastFileName }); QProcess::startDetached(settings->kcachegrindExecutable.value(), { m_lastFileName });
}); });
// dump action // dump action
@@ -488,40 +484,20 @@ CallgrindToolPrivate::CallgrindToolPrivate()
m_perspective.addToolBarWidget(button); m_perspective.addToolBarWidget(button);
} }
// Cycle detection
//action = new QAction("Cycle Detection", this); ///FIXME: icon
action = m_cycleDetection = new QAction("O", this); ///FIXME: icon
action->setToolTip(CallgrindTool::tr("Enable cycle detection to properly handle recursive or circular function calls."));
action->setCheckable(true);
connect(action, &QAction::toggled, &m_dataModel, &DataModel::enableCycleDetection);
connect(action, &QAction::toggled, settings, &ValgrindGlobalSettings::setDetectCycles);
// Shorter template signature
action = m_shortenTemplates = new QAction("<>", this);
action->setToolTip(CallgrindTool::tr("Remove template parameter lists when displaying function names."));
action->setCheckable(true);
connect(action, &QAction::toggled, &m_dataModel, &DataModel::setShortenTemplates);
connect(action, &QAction::toggled, settings, &ValgrindGlobalSettings::setShortenTemplates);
// Filtering // Filtering
action = m_filterProjectCosts = new QAction(CallgrindTool::tr("Show Project Costs Only"), this); action = m_filterProjectCosts = settings->filterExternalIssues.action();
action->setIcon(Utils::Icons::FILTER.icon());
action->setToolTip(CallgrindTool::tr("Show only profiling info that originated from this project source."));
action->setCheckable(true);
connect(action, &QAction::toggled, this, &CallgrindToolPrivate::handleFilterProjectCosts); connect(action, &QAction::toggled, this, &CallgrindToolPrivate::handleFilterProjectCosts);
// Filter // Filter
///FIXME: find workaround for https://bugreports.qt.io/browse/QTCREATORBUG-3247
m_searchFilter = new QLineEdit; m_searchFilter = new QLineEdit;
m_searchFilter->setPlaceholderText(CallgrindTool::tr("Filter...")); m_searchFilter->setPlaceholderText(CallgrindTool::tr("Filter..."));
connect(m_searchFilter, &QLineEdit::textChanged, connect(m_searchFilter, &QLineEdit::textChanged,
&m_updateTimer, QOverload<>::of(&QTimer::start)); &m_updateTimer, QOverload<>::of(&QTimer::start));
setCostFormat(settings->costFormat()); setCostFormat(CostDelegate::CostFormat(settings->costFormat.value()));
enableCycleDetection(settings->detectCycles());
m_perspective.addToolBarAction(m_cycleDetection); m_perspective.addToolBarAction(settings->detectCycles.action());
m_perspective.addToolBarAction(m_shortenTemplates); m_perspective.addToolBarAction(settings->shortenTemplates.action());
m_perspective.addToolBarAction(m_filterProjectCosts); m_perspective.addToolBarAction(m_filterProjectCosts);
m_perspective.addToolBarWidget(m_searchFilter); m_perspective.addToolBarWidget(m_searchFilter);
@@ -640,16 +616,6 @@ void CallgrindToolPrivate::setCostEvent(int index)
m_callersModel.setCostEvent(index); m_callersModel.setCostEvent(index);
} }
void CallgrindToolPrivate::enableCycleDetection(bool enabled)
{
m_cycleDetection->setChecked(enabled);
}
void CallgrindToolPrivate::shortenTemplates(bool enabled)
{
m_shortenTemplates->setChecked(enabled);
}
// Following functions can be called with actions=0 or widgets=0 // Following functions can be called with actions=0 or widgets=0
// depending on initialization sequence (whether callgrind was current). // depending on initialization sequence (whether callgrind was current).
CostDelegate::CostFormat CallgrindToolPrivate::costFormat() const CostDelegate::CostFormat CallgrindToolPrivate::costFormat() const
@@ -671,7 +637,7 @@ void CallgrindToolPrivate::updateCostFormat()
m_callersView->setCostFormat(format); m_callersView->setCostFormat(format);
} }
if (ValgrindGlobalSettings *settings = ValgrindGlobalSettings::instance()) if (ValgrindGlobalSettings *settings = ValgrindGlobalSettings::instance())
settings->setCostFormat(format); settings->costFormat.setValue(format);
} }
void CallgrindToolPrivate::handleFilterProjectCosts() void CallgrindToolPrivate::handleFilterProjectCosts()
@@ -789,9 +755,9 @@ void CallgrindToolPrivate::setupRunner(CallgrindToolRunner *toolRunner)
// apply project settings // apply project settings
ValgrindProjectSettings settings; ValgrindProjectSettings settings;
settings.fromMap(runControl->settingsData(ANALYZER_VALGRIND_SETTINGS)); settings.fromMap(runControl->settingsData(ANALYZER_VALGRIND_SETTINGS));
m_visualization->setMinimumInclusiveCostRatio(settings.visualisationMinimumInclusiveCostRatio() / 100.0); m_visualization->setMinimumInclusiveCostRatio(settings.visualizationMinimumInclusiveCostRatio.value() / 100.0);
m_proxyModel.setMinimumInclusiveCostRatio(settings.minimumInclusiveCostRatio() / 100.0); m_proxyModel.setMinimumInclusiveCostRatio(settings.minimumInclusiveCostRatio.value() / 100.0);
m_dataModel.setVerboseToolTipsEnabled(settings.enableEventToolTips()); m_dataModel.setVerboseToolTipsEnabled(settings.enableEventToolTips.value());
m_toolBusy = true; m_toolBusy = true;
updateRunActions(); updateRunActions();
@@ -949,7 +915,8 @@ void CallgrindToolPrivate::takeParserData(ParseData *data)
doClear(true); doClear(true);
setParseData(data); setParseData(data);
const QString kcachegrindExecutable = ValgrindGlobalSettings::instance()->kcachegrindExecutable(); const QString kcachegrindExecutable =
ValgrindGlobalSettings::instance()->kcachegrindExecutable.value();
const bool kcachegrindExists = !Utils::Environment::systemEnvironment().searchInPath( const bool kcachegrindExists = !Utils::Environment::systemEnvironment().searchInPath(
kcachegrindExecutable).isEmpty(); kcachegrindExecutable).isEmpty();
m_startKCachegrind->setEnabled(kcachegrindExists && !m_lastFileName.isEmpty()); m_startKCachegrind->setEnabled(kcachegrindExists && !m_lastFileName.isEmpty());

View File

@@ -191,14 +191,14 @@ QStringList MemcheckToolRunner::toolArguments() const
{ {
QStringList arguments = {"--tool=memcheck", "--gen-suppressions=all"}; QStringList arguments = {"--tool=memcheck", "--gen-suppressions=all"};
if (m_settings.trackOrigins()) if (m_settings.trackOrigins.value())
arguments << "--track-origins=yes"; arguments << "--track-origins=yes";
if (m_settings.showReachable()) if (m_settings.showReachable.value())
arguments << "--show-reachable=yes"; arguments << "--show-reachable=yes";
QString leakCheckValue; QString leakCheckValue;
switch (m_settings.leakCheckOnFinish()) { switch (m_settings.leakCheckOnFinish.value()) {
case ValgrindBaseSettings::LeakCheckOnFinishNo: case ValgrindBaseSettings::LeakCheckOnFinishNo:
leakCheckValue = "no"; leakCheckValue = "no";
break; break;
@@ -215,12 +215,12 @@ QStringList MemcheckToolRunner::toolArguments() const
foreach (const QString &file, m_settings.suppressionFiles()) foreach (const QString &file, m_settings.suppressionFiles())
arguments << QString("--suppressions=%1").arg(file); arguments << QString("--suppressions=%1").arg(file);
arguments << QString("--num-callers=%1").arg(m_settings.numCallers()); arguments << QString("--num-callers=%1").arg(m_settings.numCallers.value());
if (m_withGdb) if (m_withGdb)
arguments << "--vgdb=yes" << "--vgdb-error=0"; arguments << "--vgdb=yes" << "--vgdb-error=0";
arguments << Utils::QtcProcess::splitArgs(m_settings.memcheckArguments()); arguments << Utils::QtcProcess::splitArgs(m_settings.memcheckArguments.value());
return arguments; return arguments;
} }
@@ -916,22 +916,22 @@ void MemcheckToolPrivate::updateFromSettings()
foreach (const QVariant &v, action->data().toList()) { foreach (const QVariant &v, action->data().toList()) {
bool ok; bool ok;
int kind = v.toInt(&ok); int kind = v.toInt(&ok);
if (ok && !m_settings->visibleErrorKinds().contains(kind)) if (ok && !m_settings->visibleErrorKinds.value().contains(kind))
contained = false; contained = false;
} }
action->setChecked(contained); action->setChecked(contained);
} }
m_filterProjectAction->setChecked(!m_settings->filterExternalIssues()); m_filterProjectAction->setChecked(!m_settings->filterExternalIssues.value());
m_errorView->settingsChanged(m_settings); m_errorView->settingsChanged(m_settings);
connect(m_settings, &ValgrindBaseSettings::visibleErrorKindsChanged, connect(&m_settings->visibleErrorKinds, &IntegersAspect::valueChanged,
&m_errorProxyModel, &MemcheckErrorFilterProxyModel::setAcceptedKinds); &m_errorProxyModel, &MemcheckErrorFilterProxyModel::setAcceptedKinds);
m_errorProxyModel.setAcceptedKinds(m_settings->visibleErrorKinds()); m_errorProxyModel.setAcceptedKinds(m_settings->visibleErrorKinds.value());
connect(m_settings, &ValgrindBaseSettings::filterExternalIssuesChanged, connect(&m_settings->filterExternalIssues, &BoolAspect::valueChanged,
&m_errorProxyModel, &MemcheckErrorFilterProxyModel::setFilterExternalIssues); &m_errorProxyModel, &MemcheckErrorFilterProxyModel::setFilterExternalIssues);
m_errorProxyModel.setFilterExternalIssues(m_settings->filterExternalIssues()); m_errorProxyModel.setFilterExternalIssues(m_settings->filterExternalIssues.value());
} }
void MemcheckToolPrivate::maybeActiveRunConfigurationChanged() void MemcheckToolPrivate::maybeActiveRunConfigurationChanged()
@@ -1006,7 +1006,7 @@ void MemcheckToolPrivate::setupRunner(MemcheckToolRunner *runTool)
void MemcheckToolPrivate::loadShowXmlLogFile(const QString &filePath, const QString &exitMsg) void MemcheckToolPrivate::loadShowXmlLogFile(const QString &filePath, const QString &exitMsg)
{ {
clearErrorView(); clearErrorView();
m_settings->setFilterExternalIssues(false); m_settings->filterExternalIssues.setValue(false);
m_filterProjectAction->setChecked(true); m_filterProjectAction->setChecked(true);
m_perspective.select(); m_perspective.select();
Core::ModeManager::activateMode(Debugger::Constants::MODE_DEBUG); Core::ModeManager::activateMode(Debugger::Constants::MODE_DEBUG);
@@ -1092,7 +1092,7 @@ void MemcheckToolPrivate::updateErrorFilter()
QTC_ASSERT(m_errorView, return); QTC_ASSERT(m_errorView, return);
QTC_ASSERT(m_settings, return); QTC_ASSERT(m_settings, return);
m_settings->setFilterExternalIssues(!m_filterProjectAction->isChecked()); m_settings->filterExternalIssues.setValue(!m_filterProjectAction->isChecked());
QList<int> errorKinds; QList<int> errorKinds;
foreach (QAction *a, m_errorFilterActions) { foreach (QAction *a, m_errorFilterActions) {
@@ -1105,7 +1105,7 @@ void MemcheckToolPrivate::updateErrorFilter()
errorKinds << kind; errorKinds << kind;
} }
} }
m_settings->setVisibleErrorKinds(errorKinds); m_settings->visibleErrorKinds.setValue(errorKinds);
} }
int MemcheckToolPrivate::updateUiAfterFinishedHelper() int MemcheckToolPrivate::updateUiAfterFinishedHelper()

View File

@@ -41,9 +41,6 @@ SOURCES += \
memcheckerrorview.cpp \ memcheckerrorview.cpp \
suppressiondialog.cpp suppressiondialog.cpp
FORMS += \
valgrindconfigwidget.ui
RESOURCES += \ RESOURCES += \
valgrind.qrc valgrind.qrc

View File

@@ -31,7 +31,7 @@ QtcPlugin {
"memchecktool.cpp", "memchecktool.h", "memchecktool.cpp", "memchecktool.h",
"suppressiondialog.cpp", "suppressiondialog.h", "suppressiondialog.cpp", "suppressiondialog.h",
"valgrind.qrc", "valgrind.qrc",
"valgrindconfigwidget.cpp", "valgrindconfigwidget.h", "valgrindconfigwidget.ui", "valgrindconfigwidget.cpp", "valgrindconfigwidget.h",
"valgrindengine.cpp", "valgrindengine.h", "valgrindengine.cpp", "valgrindengine.h",
"valgrindplugin.cpp", "valgrindplugin.h", "valgrindplugin.cpp", "valgrindplugin.h",
"valgrindrunner.cpp", "valgrindrunner.h", "valgrindrunner.cpp", "valgrindrunner.h",

View File

@@ -28,20 +28,23 @@
#include "valgrindsettings.h" #include "valgrindsettings.h"
#include "valgrindplugin.h" #include "valgrindplugin.h"
#include "ui_valgrindconfigwidget.h"
#include <debugger/analyzer/analyzericons.h> #include <debugger/analyzer/analyzericons.h>
#include <utils/algorithm.h> #include <utils/algorithm.h>
#include <utils/hostosinfo.h> #include <utils/hostosinfo.h>
#include <utils/layoutbuilder.h>
#include <utils/qtcassert.h> #include <utils/qtcassert.h>
#include <QDebug> #include <QDebug>
#include <QStandardItemModel>
#include <QFileDialog> #include <QFileDialog>
#include <QListView>
#include <QPushButton>
#include <QStandardItemModel>
#include <functional> #include <functional>
using namespace Utils;
namespace Valgrind { namespace Valgrind {
namespace Internal { namespace Internal {
@@ -53,10 +56,10 @@ class ValgrindConfigWidget : public Core::IOptionsPageWidget
public: public:
explicit ValgrindConfigWidget(ValgrindBaseSettings *settings); explicit ValgrindConfigWidget(ValgrindBaseSettings *settings);
~ValgrindConfigWidget() override;
void apply() final void apply() final
{ {
ValgrindGlobalSettings::instance()->group.apply();
ValgrindGlobalSettings::instance()->writeSettings(); ValgrindGlobalSettings::instance()->writeSettings();
} }
@@ -73,172 +76,102 @@ private:
void updateUi(); void updateUi();
ValgrindBaseSettings *m_settings; ValgrindBaseSettings *m_settings;
Ui::ValgrindConfigWidget *m_ui;
QStandardItemModel *m_model; QPushButton *addSuppression;
QPushButton *removeSuppression;
QListView *suppressionList;
QStandardItemModel m_model;
}; };
ValgrindConfigWidget::ValgrindConfigWidget(ValgrindBaseSettings *settings) ValgrindConfigWidget::ValgrindConfigWidget(ValgrindBaseSettings *settings)
: m_settings(settings), : m_settings(settings)
m_ui(new Ui::ValgrindConfigWidget)
{ {
m_ui->setupUi(this); addSuppression = new QPushButton(tr("Add..."));
m_model = new QStandardItemModel(this); removeSuppression = new QPushButton(tr("Remove"));
suppressionList = new QListView;
suppressionList->setModel(&m_model);
suppressionList->setSelectionMode(QAbstractItemView::MultiSelection);
using namespace Layouting;
const Break nl;
ValgrindBaseSettings &s = *settings;
Grid generic {
s.valgrindExecutable, nl,
s.valgrindArguments, nl,
s.selfModifyingCodeDetection, nl
};
Grid memcheck {
s.memcheckArguments, nl,
s.trackOrigins, nl,
s.showReachable, nl,
s.leakCheckOnFinish, nl,
s.numCallers, nl,
s.filterExternalIssues, nl,
Item {
Group {
Title(tr("Suppression files:")),
Row {
suppressionList,
Column { addSuppression, removeSuppression, Stretch() }
}
},
2 // Span.
}
};
Grid callgrind {
s.callgrindArguments, nl,
s.kcachegrindExecutable, nl,
s.minimumInclusiveCostRatio, nl,
s.visualizationMinimumInclusiveCostRatio, nl,
s.enableEventToolTips, nl,
Item {
Group {
s.enableCacheSim,
s.enableBranchSim,
s.collectSystime,
s.collectBusEvents,
},
2 // Span.
}
};
Column {
Group { Title(tr("Valgrind Generic Settings")), generic },
Group { Title(tr("MemCheck Memory Analysis Options")), memcheck },
Group { Title(tr("CallGrind Profiling Options")), callgrind },
Stretch(),
}.attachTo(this);
m_ui->valgrindExeChooser->setExpectedKind(Utils::PathChooser::ExistingCommand);
m_ui->valgrindExeChooser->setHistoryCompleter("Valgrind.Command.History");
m_ui->valgrindExeChooser->setPromptDialogTitle(tr("Valgrind Command"));
updateUi(); updateUi();
connect(m_settings, &ValgrindBaseSettings::changed, this, &ValgrindConfigWidget::updateUi); connect(m_settings, &ValgrindBaseSettings::changed, this, &ValgrindConfigWidget::updateUi);
connect(m_ui->valgrindExeChooser, &Utils::PathChooser::rawPathChanged, connect(addSuppression, &QPushButton::clicked,
m_settings, &ValgrindBaseSettings::setValgrindExecutable); this, &ValgrindConfigWidget::slotAddSuppression);
connect(removeSuppression, &QPushButton::clicked,
this, &ValgrindConfigWidget::slotRemoveSuppression);
connect(m_ui->valgrindArgumentsLineEdit, &QLineEdit::textChanged, connect(&s, &ValgrindBaseSettings::suppressionFilesRemoved,
m_settings, &ValgrindBaseSettings::setValgrindArguments);
connect(m_settings, &ValgrindBaseSettings::valgrindArgumentsChanged,
m_ui->valgrindArgumentsLineEdit, &QLineEdit::setText);
connect(m_ui->smcDetectionComboBox, QOverload<int>::of(&QComboBox::currentIndexChanged),
m_settings, &ValgrindBaseSettings::setSelfModifyingCodeDetection);
if (Utils::HostOsInfo::isWindowsHost()) {
// FIXME: On Window we know that we don't have a local valgrind
// executable, so having the "Browse" button in the path chooser
// (which is needed for the remote executable) is confusing.
m_ui->valgrindExeChooser->buttonAtIndex(0)->hide();
}
//
// Callgrind
//
m_ui->kcachegrindExeChooser->setExpectedKind(Utils::PathChooser::ExistingCommand);
m_ui->kcachegrindExeChooser->setPromptDialogTitle(tr("KCachegrind Command"));
connect(m_ui->callgrindArgumentsLineEdit, &QLineEdit::textChanged,
m_settings, &ValgrindBaseSettings::setCallgrindArguments);
connect(m_settings, &ValgrindBaseSettings::callgrindArgumentsChanged,
m_ui->callgrindArgumentsLineEdit, &QLineEdit::setText);
connect(m_ui->kcachegrindExeChooser, &Utils::PathChooser::rawPathChanged,
m_settings, &ValgrindBaseSettings::setKCachegrindExecutable);
connect(m_ui->enableCacheSim, &QCheckBox::toggled,
m_settings, &ValgrindBaseSettings::setEnableCacheSim);
connect(m_settings, &ValgrindBaseSettings::enableCacheSimChanged,
m_ui->enableCacheSim, &QAbstractButton::setChecked);
connect(m_ui->enableBranchSim, &QCheckBox::toggled,
m_settings, &ValgrindBaseSettings::setEnableBranchSim);
connect(m_settings, &ValgrindBaseSettings::enableBranchSimChanged,
m_ui->enableBranchSim, &QAbstractButton::setChecked);
connect(m_ui->collectSystime, &QCheckBox::toggled,
m_settings, &ValgrindBaseSettings::setCollectSystime);
connect(m_settings, &ValgrindBaseSettings::collectSystimeChanged,
m_ui->collectSystime, &QAbstractButton::setChecked);
connect(m_ui->collectBusEvents, &QCheckBox::toggled,
m_settings, &ValgrindBaseSettings::setCollectBusEvents);
connect(m_settings, &ValgrindBaseSettings::collectBusEventsChanged,
m_ui->collectBusEvents, &QAbstractButton::setChecked);
connect(m_ui->enableEventToolTips, &QGroupBox::toggled,
m_settings, &ValgrindBaseSettings::setEnableEventToolTips);
connect(m_settings, &ValgrindBaseSettings::enableEventToolTipsChanged,
m_ui->enableEventToolTips, &QGroupBox::setChecked);
connect(m_ui->minimumInclusiveCostRatio, QOverload<double>::of(&QDoubleSpinBox::valueChanged),
m_settings, &ValgrindBaseSettings::setMinimumInclusiveCostRatio);
connect(m_settings, &ValgrindBaseSettings::minimumInclusiveCostRatioChanged,
m_ui->minimumInclusiveCostRatio, &QDoubleSpinBox::setValue);
connect(m_ui->visualisationMinimumInclusiveCostRatio, QOverload<double>::of(&QDoubleSpinBox::valueChanged),
m_settings, &ValgrindBaseSettings::setVisualisationMinimumInclusiveCostRatio);
connect(m_settings, &ValgrindBaseSettings::visualisationMinimumInclusiveCostRatioChanged,
m_ui->visualisationMinimumInclusiveCostRatio, &QDoubleSpinBox::setValue);
//
// Memcheck
//
m_ui->suppressionList->setModel(m_model);
m_ui->suppressionList->setSelectionMode(QAbstractItemView::MultiSelection);
connect(m_ui->memcheckArgumentsLineEdit, &QLineEdit::textChanged,
m_settings, &ValgrindBaseSettings::setMemcheckArguments);
connect(m_settings, &ValgrindBaseSettings::memcheckArgumentsChanged,
m_ui->memcheckArgumentsLineEdit, &QLineEdit::setText);
connect(m_ui->addSuppression, &QPushButton::clicked, this, &ValgrindConfigWidget::slotAddSuppression);
connect(m_ui->removeSuppression, &QPushButton::clicked, this, &ValgrindConfigWidget::slotRemoveSuppression);
connect(m_ui->numCallers, QOverload<int>::of(&QSpinBox::valueChanged),
m_settings, &ValgrindBaseSettings::setNumCallers);
connect(m_settings, &ValgrindBaseSettings::numCallersChanged,
m_ui->numCallers, &QSpinBox::setValue);
connect(m_ui->leakCheckOnFinish, QOverload<int>::of(&QComboBox::currentIndexChanged),
m_settings, &ValgrindBaseSettings::setLeakCheckOnFinish);
connect(m_settings, &ValgrindBaseSettings::leakCheckOnFinishChanged,
m_ui->leakCheckOnFinish, &QComboBox::setCurrentIndex);
connect(m_ui->showReachable, &QCheckBox::toggled,
m_settings, &ValgrindBaseSettings::setShowReachable);
connect(m_settings, &ValgrindBaseSettings::showReachableChanged,
m_ui->showReachable, &QAbstractButton::setChecked);
connect(m_ui->trackOrigins, &QCheckBox::toggled, m_settings, &ValgrindBaseSettings::setTrackOrigins);
connect(m_settings, &ValgrindBaseSettings::trackOriginsChanged,
m_ui->trackOrigins, &QAbstractButton::setChecked);
connect(m_settings, &ValgrindBaseSettings::suppressionFilesRemoved,
this, &ValgrindConfigWidget::slotSuppressionsRemoved); this, &ValgrindConfigWidget::slotSuppressionsRemoved);
connect(m_settings, &ValgrindBaseSettings::suppressionFilesAdded, connect(&s, &ValgrindBaseSettings::suppressionFilesAdded,
this, &ValgrindConfigWidget::slotSuppressionsAdded); this, &ValgrindConfigWidget::slotSuppressionsAdded);
connect(m_ui->suppressionList->selectionModel(), &QItemSelectionModel::selectionChanged, connect(suppressionList->selectionModel(), &QItemSelectionModel::selectionChanged,
this, &ValgrindConfigWidget::slotSuppressionSelectionChanged); this, &ValgrindConfigWidget::slotSuppressionSelectionChanged);
slotSuppressionSelectionChanged(); slotSuppressionSelectionChanged();
if (settings != ValgrindGlobalSettings::instance()) {
// In project settings we want a flat vertical list.
auto l = new QVBoxLayout;
while (layout()->count()) {
QLayoutItem *item = layout()->takeAt(0);
if (QWidget *w = item->widget())
l->addWidget(w);
delete item;
}
delete layout();
setLayout(l);
}
}
ValgrindConfigWidget::~ValgrindConfigWidget()
{
delete m_ui;
} }
void ValgrindConfigWidget::updateUi() void ValgrindConfigWidget::updateUi()
{ {
m_ui->valgrindExeChooser->setPath(m_settings->valgrindExecutable()); m_model.clear();
m_ui->valgrindArgumentsLineEdit->setText(m_settings->valgrindArguments());
m_ui->memcheckArgumentsLineEdit->setText(m_settings->memcheckArguments());
m_ui->callgrindArgumentsLineEdit->setText(m_settings->callgrindArguments());
m_ui->smcDetectionComboBox->setCurrentIndex(m_settings->selfModifyingCodeDetection());
m_ui->kcachegrindExeChooser->setPath(m_settings->kcachegrindExecutable());
m_ui->enableCacheSim->setChecked(m_settings->enableCacheSim());
m_ui->enableBranchSim->setChecked(m_settings->enableBranchSim());
m_ui->collectSystime->setChecked(m_settings->collectSystime());
m_ui->collectBusEvents->setChecked(m_settings->collectBusEvents());
m_ui->enableEventToolTips->setChecked(m_settings->enableEventToolTips());
m_ui->minimumInclusiveCostRatio->setValue(m_settings->minimumInclusiveCostRatio());
m_ui->visualisationMinimumInclusiveCostRatio->setValue(m_settings->visualisationMinimumInclusiveCostRatio());
m_ui->numCallers->setValue(m_settings->numCallers());
m_ui->leakCheckOnFinish->setCurrentIndex(m_settings->leakCheckOnFinish());
m_ui->showReachable->setChecked(m_settings->showReachable());
m_ui->trackOrigins->setChecked(m_settings->trackOrigins());
m_model->clear();
foreach (const QString &file, m_settings->suppressionFiles()) foreach (const QString &file, m_settings->suppressionFiles())
m_model->appendRow(new QStandardItem(file)); m_model.appendRow(new QStandardItem(file));
} }
void ValgrindConfigWidget::slotAddSuppression() void ValgrindConfigWidget::slotAddSuppression()
@@ -247,14 +180,14 @@ void ValgrindConfigWidget::slotAddSuppression()
QTC_ASSERT(conf, return); QTC_ASSERT(conf, return);
QStringList files = QFileDialog::getOpenFileNames(this, QStringList files = QFileDialog::getOpenFileNames(this,
tr("Valgrind Suppression Files"), tr("Valgrind Suppression Files"),
conf->lastSuppressionDialogDirectory(), conf->lastSuppressionDirectory.value(),
tr("Valgrind Suppression File (*.supp);;All Files (*)")); tr("Valgrind Suppression File (*.supp);;All Files (*)"));
//dialog.setHistory(conf->lastSuppressionDialogHistory()); //dialog.setHistory(conf->lastSuppressionDialogHistory());
if (!files.isEmpty()) { if (!files.isEmpty()) {
foreach (const QString &file, files) foreach (const QString &file, files)
m_model->appendRow(new QStandardItem(file)); m_model.appendRow(new QStandardItem(file));
m_settings->addSuppressionFiles(files); m_settings->addSuppressionFiles(files);
conf->setLastSuppressionDialogDirectory(QFileInfo(files.at(0)).absolutePath()); conf->lastSuppressionDirectory.setValue(QFileInfo(files.at(0)).absolutePath());
//conf->setLastSuppressionDialogHistory(dialog.history()); //conf->setLastSuppressionDialogHistory(dialog.history());
} }
} }
@@ -262,11 +195,11 @@ void ValgrindConfigWidget::slotAddSuppression()
void ValgrindConfigWidget::slotSuppressionsAdded(const QStringList &files) void ValgrindConfigWidget::slotSuppressionsAdded(const QStringList &files)
{ {
QStringList filesToAdd = files; QStringList filesToAdd = files;
for (int i = 0, c = m_model->rowCount(); i < c; ++i) for (int i = 0, c = m_model.rowCount(); i < c; ++i)
filesToAdd.removeAll(m_model->item(i)->text()); filesToAdd.removeAll(m_model.item(i)->text());
foreach (const QString &file, filesToAdd) foreach (const QString &file, filesToAdd)
m_model->appendRow(new QStandardItem(file)); m_model.appendRow(new QStandardItem(file));
} }
void ValgrindConfigWidget::slotRemoveSuppression() void ValgrindConfigWidget::slotRemoveSuppression()
@@ -275,7 +208,7 @@ void ValgrindConfigWidget::slotRemoveSuppression()
QList<int> rows; QList<int> rows;
QStringList removed; QStringList removed;
foreach (const QModelIndex &index, m_ui->suppressionList->selectionModel()->selectedIndexes()) { foreach (const QModelIndex &index, suppressionList->selectionModel()->selectedIndexes()) {
rows << index.row(); rows << index.row();
removed << index.data().toString(); removed << index.data().toString();
} }
@@ -283,16 +216,16 @@ void ValgrindConfigWidget::slotRemoveSuppression()
Utils::sort(rows, std::greater<int>()); Utils::sort(rows, std::greater<int>());
foreach (int row, rows) foreach (int row, rows)
m_model->removeRow(row); m_model.removeRow(row);
m_settings->removeSuppressionFiles(removed); m_settings->removeSuppressionFiles(removed);
} }
void ValgrindConfigWidget::slotSuppressionsRemoved(const QStringList &files) void ValgrindConfigWidget::slotSuppressionsRemoved(const QStringList &files)
{ {
for (int i = 0; i < m_model->rowCount(); ++i) { for (int i = 0; i < m_model.rowCount(); ++i) {
if (files.contains(m_model->item(i)->text())) { if (files.contains(m_model.item(i)->text())) {
m_model->removeRow(i); m_model.removeRow(i);
--i; --i;
} }
} }
@@ -300,24 +233,24 @@ void ValgrindConfigWidget::slotSuppressionsRemoved(const QStringList &files)
void ValgrindConfigWidget::setSuppressions(const QStringList &files) void ValgrindConfigWidget::setSuppressions(const QStringList &files)
{ {
m_model->clear(); m_model.clear();
foreach (const QString &file, files) foreach (const QString &file, files)
m_model->appendRow(new QStandardItem(file)); m_model.appendRow(new QStandardItem(file));
} }
QStringList ValgrindConfigWidget::suppressions() const QStringList ValgrindConfigWidget::suppressions() const
{ {
QStringList ret; QStringList ret;
for (int i = 0; i < m_model->rowCount(); ++i) for (int i = 0; i < m_model.rowCount(); ++i)
ret << m_model->item(i)->text(); ret << m_model.item(i)->text();
return ret; return ret;
} }
void ValgrindConfigWidget::slotSuppressionSelectionChanged() void ValgrindConfigWidget::slotSuppressionSelectionChanged()
{ {
m_ui->removeSuppression->setEnabled(m_ui->suppressionList->selectionModel()->hasSelection()); removeSuppression->setEnabled(suppressionList->selectionModel()->hasSelection());
} }
// ValgrindOptionsPage // ValgrindOptionsPage

View File

@@ -1,503 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>Valgrind::Internal::ValgrindConfigWidget</class>
<widget class="QWidget" name="Valgrind::Internal::ValgrindConfigWidget">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>727</width>
<height>658</height>
</rect>
</property>
<layout class="QGridLayout" name="gridLayout">
<item row="0" column="0" colspan="2">
<widget class="QGroupBox" name="commonValgrindOptions">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Expanding">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="title">
<string>Valgrind Generic Settings</string>
</property>
<layout class="QGridLayout" name="gridLayout_2">
<item row="2" column="1">
<layout class="QHBoxLayout" name="horizontalLayout_2">
<item>
<widget class="QComboBox" name="smcDetectionComboBox">
<property name="currentIndex">
<number>1</number>
</property>
<item>
<property name="text">
<string>No</string>
</property>
</item>
<item>
<property name="text">
<string>Only on Stack</string>
</property>
</item>
<item>
<property name="text">
<string>Everywhere</string>
</property>
</item>
<item>
<property name="text">
<string>Everywhere Except in File-backend Mappings</string>
</property>
</item>
</widget>
</item>
<item>
<spacer name="horizontalSpacer">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
</layout>
</item>
<item row="0" column="0">
<widget class="QLabel" name="valgrindExeLabel">
<property name="text">
<string>Valgrind executable:</string>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="Utils::PathChooser" name="valgrindExeChooser" native="true">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
<horstretch>1</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
</widget>
</item>
<item row="2" column="0">
<widget class="QLabel" name="smcDetectionLabel">
<property name="text">
<string>Detect self-modifying code:</string>
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="QLabel" name="valgrindArgumentsLabel">
<property name="text">
<string>Valgrind arguments:</string>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="QLineEdit" name="valgrindArgumentsLineEdit"/>
</item>
</layout>
</widget>
</item>
<item row="3" column="0">
<spacer name="verticalSpacer">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeType">
<enum>QSizePolicy::Expanding</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>1</width>
<height>500</height>
</size>
</property>
</spacer>
</item>
<item row="1" column="0">
<widget class="QGroupBox" name="memcheckOptions">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="title">
<string>MemCheck Memory Analysis Options</string>
</property>
<layout class="QFormLayout" name="formLayout">
<item row="1" column="0" colspan="2">
<widget class="QCheckBox" name="trackOrigins">
<property name="text">
<string>Track origins of uninitialized memory</string>
</property>
<property name="checked">
<bool>true</bool>
</property>
</widget>
</item>
<item row="2" column="0" colspan="2">
<widget class="QCheckBox" name="showReachable">
<property name="text">
<string>Show reachable and indirectly lost blocks</string>
</property>
</widget>
</item>
<item row="3" column="0">
<widget class="QLabel" name="leakCheckOnFinishLabel">
<property name="text">
<string>Check for leaks on finish:</string>
</property>
</widget>
</item>
<item row="3" column="1">
<layout class="QHBoxLayout" name="horizontalLayout_3">
<item>
<widget class="QComboBox" name="leakCheckOnFinish">
<property name="currentIndex">
<number>0</number>
</property>
<item>
<property name="text">
<string>No</string>
</property>
</item>
<item>
<property name="text">
<string>Summary Only</string>
</property>
</item>
<item>
<property name="text">
<string>Full</string>
</property>
</item>
</widget>
</item>
<item>
<spacer name="horizontalSpacer_2">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
</layout>
</item>
<item row="4" column="0">
<widget class="QLabel" name="numCallersLabel">
<property name="text">
<string>Backtrace frame count:</string>
</property>
<property name="buddy">
<cstring>numCallers</cstring>
</property>
</widget>
</item>
<item row="4" column="1">
<layout class="QHBoxLayout" name="horizontalLayout_4">
<item>
<widget class="QSpinBox" name="numCallers">
<property name="minimum">
<number>5</number>
</property>
<property name="maximum">
<number>50</number>
</property>
<property name="value">
<number>12</number>
</property>
</widget>
</item>
<item>
<spacer name="horizontalSpacer_3">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
</layout>
</item>
<item row="5" column="0">
<widget class="QLabel" name="label">
<property name="text">
<string>Suppression files:</string>
</property>
<property name="buddy">
<cstring>suppressionList</cstring>
</property>
</widget>
</item>
<item row="6" column="0" colspan="2">
<layout class="QHBoxLayout" name="horizontalLayout">
<item>
<widget class="QListView" name="suppressionList">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Expanding">
<horstretch>0</horstretch>
<verstretch>1</verstretch>
</sizepolicy>
</property>
</widget>
</item>
<item>
<layout class="QVBoxLayout" name="verticalLayout_2" stretch="0,0,1">
<property name="sizeConstraint">
<enum>QLayout::SetMinimumSize</enum>
</property>
<item>
<widget class="QPushButton" name="addSuppression">
<property name="text">
<string>Add...</string>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="removeSuppression">
<property name="text">
<string>Remove</string>
</property>
<property name="flat">
<bool>false</bool>
</property>
</widget>
</item>
<item>
<spacer name="verticalSpacer_2">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>40</height>
</size>
</property>
</spacer>
</item>
</layout>
</item>
</layout>
</item>
<item row="0" column="0">
<widget class="QLabel" name="memcheckArgumentsLabel">
<property name="text">
<string>Extra MemCheck arguments:</string>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QLineEdit" name="memcheckArgumentsLineEdit"/>
</item>
</layout>
</widget>
</item>
<item row="2" column="0">
<widget class="QGroupBox" name="memcheckOptions_2">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="title">
<string>CallGrind Profiling Options</string>
</property>
<layout class="QFormLayout" name="formLayout_2">
<item row="2" column="0">
<widget class="QLabel" name="minimumInclusiveCostRatioLabel">
<property name="toolTip">
<string>Limits the amount of results the profiler gives you. A lower limit will likely increase performance.</string>
</property>
<property name="text">
<string>Result view: Minimum event cost:</string>
</property>
<property name="buddy">
<cstring>minimumInclusiveCostRatio</cstring>
</property>
</widget>
</item>
<item row="2" column="1">
<widget class="QDoubleSpinBox" name="minimumInclusiveCostRatio">
<property name="suffix">
<string>%</string>
</property>
<property name="decimals">
<number>2</number>
</property>
<property name="maximum">
<double>10.000000000000000</double>
</property>
<property name="singleStep">
<double>0.100000000000000</double>
</property>
</widget>
</item>
<item row="4" column="0" colspan="2">
<widget class="QGroupBox" name="enableEventToolTips">
<property name="title">
<string>Show additional information for events in tooltips</string>
</property>
<property name="checkable">
<bool>true</bool>
</property>
<layout class="QGridLayout" name="gridLayout_3">
<item row="0" column="0">
<widget class="QCheckBox" name="enableCacheSim">
<property name="toolTip">
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;
&lt;p&gt;Does full cache simulation.&lt;/p&gt;
&lt;p&gt;By default, only instruction read accesses will be counted (&quot;Ir&quot;).&lt;/p&gt;
&lt;p&gt;
With cache simulation, further event counters are enabled:
&lt;ul&gt;&lt;li&gt;Cache misses on instruction reads (&quot;I1mr&quot;/&quot;I2mr&quot;).&lt;/li&gt;
&lt;li&gt;Data read accesses (&quot;Dr&quot;) and related cache misses (&quot;D1mr&quot;/&quot;D2mr&quot;).&lt;/li&gt;
&lt;li&gt;Data write accesses (&quot;Dw&quot;) and related cache misses (&quot;D1mw&quot;/&quot;D2mw&quot;).&lt;/li&gt;&lt;/ul&gt;
&lt;/p&gt;
&lt;/body&gt;&lt;/html&gt;</string>
</property>
<property name="text">
<string>Enable cache simulation</string>
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="QCheckBox" name="enableBranchSim">
<property name="toolTip">
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;
&lt;p&gt;Does branch prediction simulation.&lt;/p&gt;
&lt;p&gt;Further event counters are enabled: &lt;/p&gt;
&lt;ul&gt;&lt;li&gt;Number of executed conditional branches and related predictor misses (
&quot;Bc&quot;/&quot;Bcm&quot;).&lt;/li&gt;
&lt;li&gt;Executed indirect jumps and related misses of the jump address predictor (
&quot;Bi&quot;/&quot;Bim&quot;).&lt;/li&gt;&lt;/ul&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
<property name="text">
<string>Enable branch prediction simulation</string>
</property>
</widget>
</item>
<item row="2" column="0">
<widget class="QCheckBox" name="collectSystime">
<property name="toolTip">
<string>Collects information for system call times.</string>
</property>
<property name="text">
<string>Collect system call time</string>
</property>
</widget>
</item>
<item row="3" column="0">
<widget class="QCheckBox" name="collectBusEvents">
<property name="toolTip">
<string>Collect the number of global bus events that are executed. The event type &quot;Ge&quot; is used for these events.</string>
</property>
<property name="text">
<string>Collect global bus events</string>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item row="3" column="0">
<widget class="QLabel" name="visualisationMinimumInclusiveCostRatioLabel">
<property name="text">
<string>Visualization: Minimum event cost:</string>
</property>
</widget>
</item>
<item row="3" column="1">
<widget class="QDoubleSpinBox" name="visualisationMinimumInclusiveCostRatio">
<property name="prefix">
<string/>
</property>
<property name="suffix">
<string>%</string>
</property>
<property name="minimum">
<double>0.000000000000000</double>
</property>
<property name="maximum">
<double>50.000000000000000</double>
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="QLabel" name="kcachgrindExeLabel">
<property name="text">
<string>KCachegrind executable:</string>
</property>
</widget>
</item>
<item row="1" 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>
<item row="0" column="0">
<widget class="QLabel" name="callgrindArgumentsLabel">
<property name="text">
<string>Extra CallGrind arguments:</string>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QLineEdit" name="callgrindArgumentsLineEdit"/>
</item>
</layout>
</widget>
</item>
</layout>
</widget>
<customwidgets>
<customwidget>
<class>Utils::PathChooser</class>
<extends>QWidget</extends>
<header location="global">utils/pathchooser.h</header>
<container>1</container>
</customwidget>
</customwidgets>
<tabstops>
<tabstop>smcDetectionComboBox</tabstop>
<tabstop>trackOrigins</tabstop>
<tabstop>showReachable</tabstop>
<tabstop>leakCheckOnFinish</tabstop>
<tabstop>numCallers</tabstop>
<tabstop>suppressionList</tabstop>
<tabstop>addSuppression</tabstop>
<tabstop>removeSuppression</tabstop>
<tabstop>minimumInclusiveCostRatio</tabstop>
<tabstop>visualisationMinimumInclusiveCostRatio</tabstop>
<tabstop>enableEventToolTips</tabstop>
<tabstop>enableCacheSim</tabstop>
<tabstop>enableBranchSim</tabstop>
<tabstop>collectSystime</tabstop>
<tabstop>collectBusEvents</tabstop>
</tabstops>
<resources/>
<connections/>
</ui>

View File

@@ -77,8 +77,8 @@ void ValgrindToolRunner::start()
emit outputReceived(tr("Command line arguments: %1").arg(runnable().debuggeeArgs), LogMessageFormat); emit outputReceived(tr("Command line arguments: %1").arg(runnable().debuggeeArgs), LogMessageFormat);
#endif #endif
CommandLine valgrind{m_settings.valgrindExecutable()}; CommandLine valgrind{m_settings.valgrindExecutable.value()};
valgrind.addArgs(m_settings.valgrindArguments(), CommandLine::Raw); valgrind.addArgs(m_settings.valgrindArguments.value(), CommandLine::Raw);
valgrind.addArgs(genericToolArguments()); valgrind.addArgs(genericToolArguments());
valgrind.addArgs(toolArguments()); valgrind.addArgs(toolArguments());
@@ -124,7 +124,7 @@ QStringList ValgrindToolRunner::genericToolArguments() const
{ {
QString smcCheckValue; QString smcCheckValue;
switch (m_settings.selfModifyingCodeDetection()) { switch (m_settings.selfModifyingCodeDetection.value()) {
case ValgrindBaseSettings::DetectSmcNo: case ValgrindBaseSettings::DetectSmcNo:
smcCheckValue = "none"; smcCheckValue = "none";
break; break;
@@ -175,7 +175,7 @@ void ValgrindToolRunner::receiveProcessOutput(const QString &output, OutputForma
void ValgrindToolRunner::receiveProcessError(const QString &message, QProcess::ProcessError error) void ValgrindToolRunner::receiveProcessError(const QString &message, QProcess::ProcessError error)
{ {
if (error == QProcess::FailedToStart) { if (error == QProcess::FailedToStart) {
const QString valgrind = m_settings.valgrindExecutable(); const QString valgrind = m_settings.valgrindExecutable.value();
if (!valgrind.isEmpty()) if (!valgrind.isEmpty())
appendMessage(tr("Error: \"%1\" could not be started: %2").arg(valgrind, message), ErrorMessageFormat); appendMessage(tr("Error: \"%1\" could not be started: %2").arg(valgrind, message), ErrorMessageFormat);
else else

View File

@@ -29,43 +29,16 @@
#include "valgrindconfigwidget.h" #include "valgrindconfigwidget.h"
#include <coreplugin/icore.h> #include <coreplugin/icore.h>
#include <utils/qtcassert.h> #include <utils/qtcassert.h>
#include <utils/utilsicons.h>
#include <valgrind/xmlprotocol/error.h> #include <valgrind/xmlprotocol/error.h>
#include <QSettings> #include <QSettings>
#include <QDebug> #include <QDebug>
const char numCallersC[] = "Analyzer.Valgrind.NumCallers"; using namespace Utils;
const char leakCheckOnFinishC[] = "Analyzer.Valgrind.LeakCheckOnFinish";
const char showReachableC[] = "Analyzer.Valgrind.ShowReachable";
const char trackOriginsC[] = "Analyzer.Valgrind.TrackOrigins";
const char selfModifyingCodeDetectionC[] = "Analyzer.Valgrind.SelfModifyingCodeDetection";
const char suppressionFilesC[] = "Analyzer.Valgrind.SupressionFiles";
const char removedSuppressionFilesC[] = "Analyzer.Valgrind.RemovedSuppressionFiles";
const char addedSuppressionFilesC[] = "Analyzer.Valgrind.AddedSuppressionFiles";
const char filterExternalIssuesC[] = "Analyzer.Valgrind.FilterExternalIssues";
const char visibleErrorKindsC[] = "Analyzer.Valgrind.VisibleErrorKinds";
const char memcheckArgumentsC[] = "Analyzer.Valgrind.Memcheck.Arguments";
const char lastSuppressionDirectoryC[] = "Analyzer.Valgrind.LastSuppressionDirectory";
const char lastSuppressionHistoryC[] = "Analyzer.Valgrind.LastSuppressionHistory";
const char kcachegrindExeC[] = "Analyzer.Valgrind.KCachegrindExecutable";
const char callgrindEnableCacheSimC[] = "Analyzer.Valgrind.Callgrind.EnableCacheSim";
const char callgrindEnableBranchSimC[] = "Analyzer.Valgrind.Callgrind.EnableBranchSim";
const char callgrindCollectSystimeC[] = "Analyzer.Valgrind.Callgrind.CollectSystime";
const char callgrindCollectBusEventsC[] = "Analyzer.Valgrind.Callgrind.CollectBusEvents";
const char callgrindEnableEventToolTipsC[] = "Analyzer.Valgrind.Callgrind.EnableEventToolTips";
const char callgrindMinimumCostRatioC[] = "Analyzer.Valgrind.Callgrind.MinimumCostRatio";
const char callgrindVisualisationMinimumCostRatioC[] = "Analyzer.Valgrind.Callgrind.VisualisationMinimumCostRatio";
const char callgrindCycleDetectionC[] = "Analyzer.Valgrind.Callgrind.CycleDetection";
const char callgrindShortenTemplates[] = "Analyzer.Valgrind.Callgrind.ShortenTemplates";
const char callgrindCostFormatC[] = "Analyzer.Valgrind.Callgrind.CostFormat";
const char callgrindArgumentsC[] = "Analyzer.Valgrind.Callgrind.Arguments";
const char valgrindExeC[] = "Analyzer.Valgrind.ValgrindExecutable";
const char valgrindArgumentsC[] = "Analyzer.Valgrind.ValgrindArguments";
namespace Valgrind { namespace Valgrind {
namespace Internal { namespace Internal {
@@ -76,253 +49,181 @@ namespace Internal {
// //
////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////
/** ValgrindBaseSettings::ValgrindBaseSettings()
* Utility function to set @p val if @p key is present in @p map.
*/
template <typename T> void setIfPresent(const QVariantMap &map, const QString &key, T *val)
{ {
if (map.contains(key)) // Note that this is used twice, once for project settings in the .user files
*val = map.value(key).template value<T>(); // and once for global settings in QtCreator.ini. This uses intentionally
// the same key to facilitate copying using fromMap/toMap.
QString base = "Analyzer.Valgrind.";
group.registerAspect(&valgrindExecutable);
valgrindExecutable.setSettingsKey(base + "ValgrindExecutable");
valgrindExecutable.setDefaultValue("valgrind");
valgrindExecutable.setDisplayStyle(StringAspect::PathChooserDisplay);
valgrindExecutable.setExpectedKind(PathChooser::Command);
valgrindExecutable.setHistoryCompleter("Valgrind.Command.History");
valgrindExecutable.setDisplayName(tr("Valgrind Command"));
valgrindExecutable.setLabelText(tr("Valgrind executable:"));
if (Utils::HostOsInfo::isWindowsHost()) {
// On Window we know that we don't have a local valgrind
// executable, so having the "Browse" button in the path chooser
// (which is needed for the remote executable) is confusing.
// FIXME: not deadly, still...
//valgrindExecutable. ... buttonAtIndex(0)->hide();
} }
ValgrindBaseSettings::ValgrindBaseSettings() = default; group.registerAspect(&valgrindArguments);
valgrindArguments.setSettingsKey(base + "ValgrindArguments");
valgrindArguments.setDisplayStyle(StringAspect::LineEditDisplay);
valgrindArguments.setLabelText(tr("Valgrind arguments:"));
group.registerAspect(&selfModifyingCodeDetection);
selfModifyingCodeDetection.setSettingsKey(base + "SelfModifyingCodeDetection");
selfModifyingCodeDetection.setDefaultValue(DetectSmcStackOnly);
selfModifyingCodeDetection.setDisplayStyle(SelectionAspect::DisplayStyle::ComboBox);
selfModifyingCodeDetection.addOption("No");
selfModifyingCodeDetection.addOption("Only on Stack");
selfModifyingCodeDetection.addOption("Everywhere");
selfModifyingCodeDetection.addOption("Everywhere Except in File-backend Mappings");
selfModifyingCodeDetection.setLabelText(tr("Detect self-modifying code:"));
// Memcheck
group.registerAspect(&memcheckArguments);
memcheckArguments.setSettingsKey(base + "Memcheck.Arguments");
memcheckArguments.setDisplayStyle(StringAspect::LineEditDisplay);
memcheckArguments.setLabelText(tr("Extra MemCheck arguments:"));
group.registerAspect(&filterExternalIssues);
filterExternalIssues.setSettingsKey(base + "FilterExternalIssues");
filterExternalIssues.setDefaultValue(true);
filterExternalIssues.setIcon(Icons::FILTER.icon());
filterExternalIssues.setLabelPlacement(BoolAspect::LabelPlacement::AtCheckBoxWithoutDummyLabel);
filterExternalIssues.setLabelText(tr("Show Project Costs Only"));
filterExternalIssues.setToolTip(tr("Show only profiling info that originated from this project source."));
group.registerAspect(&trackOrigins);
trackOrigins.setSettingsKey(base + "TrackOrigins");
trackOrigins.setDefaultValue(true);
trackOrigins.setLabelPlacement(BoolAspect::LabelPlacement::AtCheckBoxWithoutDummyLabel);
trackOrigins.setLabelText(tr("Track origins of uninitialized memory"));
group.registerAspect(&showReachable);
showReachable.setSettingsKey(base + "ShowReachable");
showReachable.setLabelPlacement(BoolAspect::LabelPlacement::AtCheckBoxWithoutDummyLabel);
showReachable.setLabelText(tr("Show reachable and indirectly lost blocks"));
group.registerAspect(&leakCheckOnFinish);
leakCheckOnFinish.setSettingsKey(base + "LeakCheckOnFinish");
leakCheckOnFinish.setDefaultValue(LeakCheckOnFinishSummaryOnly);
leakCheckOnFinish.setDisplayStyle(SelectionAspect::DisplayStyle::ComboBox);
leakCheckOnFinish.addOption(tr("No"));
leakCheckOnFinish.addOption(tr("Summary Only"));
leakCheckOnFinish.addOption(tr("Full"));
leakCheckOnFinish.setLabelText(tr("Check for leaks on finish:"));
group.registerAspect(&numCallers);
numCallers.setSettingsKey(base + "NumCallers");
numCallers.setDefaultValue(25);
numCallers.setLabelText(tr("Backtrace frame count:"));
// Callgrind
group.registerAspect(&kcachegrindExecutable);
kcachegrindExecutable.setSettingsKey(base + "KCachegrindExecutable");
kcachegrindExecutable.setDefaultValue("kcachegrind");
kcachegrindExecutable.setDisplayStyle(StringAspect::PathChooserDisplay);
kcachegrindExecutable.setLabelText(tr("KCachegrind executable:"));
kcachegrindExecutable.setExpectedKind(Utils::PathChooser::Command);
kcachegrindExecutable.setDisplayName(tr("KCachegrind Command"));
group.registerAspect(&callgrindArguments);
callgrindArguments.setSettingsKey(base + "Callgrind.Arguments");
callgrindArguments.setDisplayStyle(StringAspect::LineEditDisplay);
callgrindArguments.setLabelText(tr("Extra CallGrind arguments:"));
group.registerAspect(&enableEventToolTips);
enableEventToolTips.setDefaultValue(true);
enableEventToolTips.setSettingsKey(base + "Callgrind.EnableEventToolTips");
enableEventToolTips.setLabelPlacement(BoolAspect::LabelPlacement::AtCheckBoxWithoutDummyLabel);
enableEventToolTips.setLabelText(tr("Show additional information for events in tooltips"));
group.registerAspect(&enableCacheSim);
enableCacheSim.setSettingsKey(base + "Callgrind.EnableCacheSim");
enableCacheSim.setLabelPlacement(BoolAspect::LabelPlacement::AtCheckBoxWithoutDummyLabel);
enableCacheSim.setLabelText(tr("Enable cache simulation"));
enableCacheSim.setToolTip("<html><head/><body>" + tr(
"<p>Does full cache simulation.</p>\n"
"<p>By default, only instruction read accesses will be counted (\"Ir\").</p>\n"
"<p>\n"
"With cache simulation, further event counters are enabled:\n"
"<ul><li>Cache misses on instruction reads (\"I1mr\"/\"I2mr\").</li>\n"
"<li>Data read accesses (\"Dr\") and related cache misses (\"D1mr\"/\"D2mr\").</li>\n"
"<li>Data write accesses (\"Dw\") and related cache misses (\"D1mw\"/\"D2mw\").</li></ul>\n"
"</p>") + "</body></html>");
group.registerAspect(&enableBranchSim);
enableBranchSim.setSettingsKey(base + "Callgrind.EnableBranchSim");
enableBranchSim.setLabelPlacement(BoolAspect::LabelPlacement::AtCheckBoxWithoutDummyLabel);
enableBranchSim.setLabelText(tr("Enable branch prediction simulation"));
enableBranchSim.setToolTip("<html><head/><body>\n" + tr(
"<p>Does branch prediction simulation.</p>\n"
"<p>Further event counters are enabled: </p>\n"
"<ul><li>Number of executed conditional branches and related predictor misses (\n"
"\"Bc\"/\"Bcm\").</li>\n"
"<li>Executed indirect jumps and related misses of the jump address predictor (\n"
"\"Bi\"/\"Bim\").)</li></ul>") + "</body></html>");
group.registerAspect(&collectSystime);
collectSystime.setSettingsKey(base + "Callgrind.CollectSystime");
collectSystime.setLabelPlacement(BoolAspect::LabelPlacement::AtCheckBoxWithoutDummyLabel);
collectSystime.setLabelText(tr("Collect system call time"));
collectSystime.setToolTip(tr("Collects information for system call times."));
group.registerAspect(&collectBusEvents);
collectBusEvents.setLabelPlacement(BoolAspect::LabelPlacement::AtCheckBoxWithoutDummyLabel);
collectBusEvents.setSettingsKey(base + "Callgrind.CollectBusEvents");
collectBusEvents.setLabelText(tr("Collect global bus events"));
collectBusEvents.setToolTip(tr("Collect the number of global bus events that are executed. "
"The event type \"Ge\" is used for these events."));
group.registerAspect(&minimumInclusiveCostRatio);
minimumInclusiveCostRatio.setSettingsKey(base + "Callgrind.MinimumCostRatio");
minimumInclusiveCostRatio.setDefaultValue(0.01);
minimumInclusiveCostRatio.setSuffix(tr("%"));
minimumInclusiveCostRatio.setLabelText(tr("Result view: Minimum event cost:"));
minimumInclusiveCostRatio.setToolTip(tr("Limits the amount of results the profiler gives you. "
"A lower limit will likely increase performance."));
group.registerAspect(&visualizationMinimumInclusiveCostRatio);
visualizationMinimumInclusiveCostRatio.setSettingsKey(base + "Callgrind.VisualisationMinimumCostRatio");
visualizationMinimumInclusiveCostRatio.setDefaultValue(10.0);
visualizationMinimumInclusiveCostRatio.setLabelText(tr("Visualization: Minimum event cost:"));
visualizationMinimumInclusiveCostRatio.setSuffix(tr("%"));
group.registerAspect(&visibleErrorKinds);
visibleErrorKinds.setSettingsKey(base + "VisibleErrorKinds");
QList<int> defaultErrorKinds;
for (int i = 0; i < Valgrind::XmlProtocol::MemcheckErrorKindCount; ++i)
defaultErrorKinds << i;
visibleErrorKinds.setDefaultValue(defaultErrorKinds);
}
void ValgrindBaseSettings::fromMap(const QVariantMap &map) void ValgrindBaseSettings::fromMap(const QVariantMap &map)
{ {
// General group.fromMap(map);
setIfPresent(map, valgrindExeC, &m_valgrindExecutable); if (ValgrindGlobalSettings::instance() != this) {
setIfPresent(map, valgrindArgumentsC, &m_valgrindArguments); // FIXME: Update project page e.g. on "Restore Global", aspects
setIfPresent(map, selfModifyingCodeDetectionC, // there are 'autoapply', and Aspect::cancel() is normally part of
(int*) &m_selfModifyingCodeDetection); // the 'manual apply' machinery.
group.setAutoApply(false);
// Memcheck group.cancel();
setIfPresent(map, numCallersC, &m_numCallers); group.setAutoApply(true);
setIfPresent(map, memcheckArgumentsC, &m_memcheckArguments);
setIfPresent(map, leakCheckOnFinishC, (int*) &m_leakCheckOnFinish);
setIfPresent(map, showReachableC, &m_showReachable);
setIfPresent(map, trackOriginsC, &m_trackOrigins);
setIfPresent(map, filterExternalIssuesC, &m_filterExternalIssues);
if (map.contains(visibleErrorKindsC)) {
m_visibleErrorKinds.clear();
foreach (const QVariant &val, map.value(visibleErrorKindsC).toList())
m_visibleErrorKinds << val.toInt();
} }
// Callgrind
setIfPresent(map, callgrindArgumentsC, &m_callgrindArguments);
setIfPresent(map, kcachegrindExeC, &m_kcachegrindExecutable);
setIfPresent(map, callgrindEnableCacheSimC, &m_enableCacheSim);
setIfPresent(map, callgrindEnableBranchSimC, &m_enableBranchSim);
setIfPresent(map, callgrindCollectSystimeC, &m_collectSystime);
setIfPresent(map, callgrindCollectBusEventsC, &m_collectBusEvents);
setIfPresent(map, callgrindEnableEventToolTipsC, &m_enableEventToolTips);
setIfPresent(map, callgrindMinimumCostRatioC, &m_minimumInclusiveCostRatio);
setIfPresent(map, callgrindVisualisationMinimumCostRatioC,
&m_visualisationMinimumInclusiveCostRatio);
emit changed();
} }
void ValgrindBaseSettings::toMap(QVariantMap &map) const void ValgrindBaseSettings::toMap(QVariantMap &map) const
{ {
// General group.toMap(map);
map.insert(valgrindExeC, m_valgrindExecutable);
map.insert(valgrindArgumentsC, m_valgrindArguments);
map.insert(selfModifyingCodeDetectionC, m_selfModifyingCodeDetection);
// Memcheck
map.insert(memcheckArgumentsC, m_memcheckArguments);
map.insert(numCallersC, m_numCallers);
map.insert(leakCheckOnFinishC, m_leakCheckOnFinish);
map.insert(showReachableC, m_showReachable);
map.insert(trackOriginsC, m_trackOrigins);
map.insert(filterExternalIssuesC, m_filterExternalIssues);
QVariantList errorKinds;
foreach (int i, m_visibleErrorKinds)
errorKinds << i;
map.insert(visibleErrorKindsC, errorKinds);
// Callgrind
map.insert(callgrindArgumentsC, m_callgrindArguments);
map.insert(kcachegrindExeC, m_kcachegrindExecutable);
map.insert(callgrindEnableCacheSimC, m_enableCacheSim);
map.insert(callgrindEnableBranchSimC, m_enableBranchSim);
map.insert(callgrindCollectSystimeC, m_collectSystime);
map.insert(callgrindCollectBusEventsC, m_collectBusEvents);
map.insert(callgrindEnableEventToolTipsC, m_enableEventToolTips);
map.insert(callgrindMinimumCostRatioC, m_minimumInclusiveCostRatio);
map.insert(callgrindVisualisationMinimumCostRatioC,
m_visualisationMinimumInclusiveCostRatio);
}
void ValgrindBaseSettings::setValgrindExecutable(const QString &valgrindExecutable)
{
m_valgrindExecutable = valgrindExecutable;
}
void ValgrindBaseSettings::setValgrindArguments(const QString &arguments)
{
if (m_valgrindArguments != arguments) {
m_valgrindArguments = arguments;
emit valgrindArgumentsChanged(arguments);
}
}
void ValgrindBaseSettings::setSelfModifyingCodeDetection(int smcDetection)
{
if (m_selfModifyingCodeDetection != smcDetection) {
m_selfModifyingCodeDetection = (SelfModifyingCodeDetection) smcDetection;
emit selfModifyingCodeDetectionChanged(smcDetection);
}
}
void ValgrindBaseSettings::setMemcheckArguments(const QString &arguments)
{
if (m_memcheckArguments != arguments) {
m_memcheckArguments = arguments;
emit memcheckArgumentsChanged(arguments);
}
}
QString ValgrindBaseSettings::valgrindExecutable() const
{
return m_valgrindExecutable;
}
ValgrindBaseSettings::SelfModifyingCodeDetection ValgrindBaseSettings::selfModifyingCodeDetection() const
{
return m_selfModifyingCodeDetection;
}
void ValgrindBaseSettings::setNumCallers(int numCallers)
{
if (m_numCallers != numCallers) {
m_numCallers = numCallers;
emit numCallersChanged(numCallers);
}
}
void ValgrindBaseSettings::setLeakCheckOnFinish(int leakCheckOnFinish)
{
if (m_leakCheckOnFinish != leakCheckOnFinish) {
m_leakCheckOnFinish = (LeakCheckOnFinish) leakCheckOnFinish;
emit leakCheckOnFinishChanged(leakCheckOnFinish);
}
}
void ValgrindBaseSettings::setShowReachable(bool showReachable)
{
if (m_showReachable != showReachable) {
m_showReachable = showReachable;
emit showReachableChanged(showReachable);
}
}
void ValgrindBaseSettings::setTrackOrigins(bool trackOrigins)
{
if (m_trackOrigins != trackOrigins) {
m_trackOrigins = trackOrigins;
emit trackOriginsChanged(trackOrigins);
}
}
void ValgrindBaseSettings::setFilterExternalIssues(bool filterExternalIssues)
{
if (m_filterExternalIssues != filterExternalIssues) {
m_filterExternalIssues = filterExternalIssues;
emit filterExternalIssuesChanged(filterExternalIssues);
}
}
void ValgrindBaseSettings::setVisibleErrorKinds(const QList<int> &visibleErrorKinds)
{
if (m_visibleErrorKinds != visibleErrorKinds) {
m_visibleErrorKinds = visibleErrorKinds;
emit visibleErrorKindsChanged(visibleErrorKinds);
}
}
QString ValgrindBaseSettings::kcachegrindExecutable() const
{
return m_kcachegrindExecutable;
}
void ValgrindBaseSettings::setCallgrindArguments(const QString &arguments)
{
if (m_callgrindArguments != arguments) {
m_callgrindArguments = arguments;
emit callgrindArgumentsChanged(arguments);
}
}
void ValgrindBaseSettings::setKCachegrindExecutable(const QString &exec)
{
m_kcachegrindExecutable = exec;
}
void ValgrindBaseSettings::setEnableCacheSim(bool enable)
{
if (m_enableCacheSim == enable)
return;
m_enableCacheSim = enable;
emit enableCacheSimChanged(enable);
}
void ValgrindBaseSettings::setEnableBranchSim(bool enable)
{
if (m_enableBranchSim == enable)
return;
m_enableBranchSim = enable;
emit enableBranchSimChanged(enable);
}
void ValgrindBaseSettings::setCollectSystime(bool collect)
{
if (m_collectSystime == collect)
return;
m_collectSystime = collect;
emit collectSystimeChanged(collect);
}
void ValgrindBaseSettings::setCollectBusEvents(bool collect)
{
if (m_collectBusEvents == collect)
return;
m_collectBusEvents = collect;
emit collectBusEventsChanged(collect);
}
void ValgrindBaseSettings::setEnableEventToolTips(bool enable)
{
if (m_enableEventToolTips == enable)
return;
m_enableEventToolTips = enable;
emit enableEventToolTipsChanged(enable);
}
void ValgrindBaseSettings::setMinimumInclusiveCostRatio(
double minimumInclusiveCostRatio)
{
if (m_minimumInclusiveCostRatio == minimumInclusiveCostRatio)
return;
m_minimumInclusiveCostRatio = qBound(0.0, minimumInclusiveCostRatio, 100.0);
emit minimumInclusiveCostRatioChanged(minimumInclusiveCostRatio);
}
void ValgrindBaseSettings::setVisualisationMinimumInclusiveCostRatio(
double minimumInclusiveCostRatio)
{
if (m_visualisationMinimumInclusiveCostRatio == minimumInclusiveCostRatio)
return;
m_visualisationMinimumInclusiveCostRatio = qBound(0.0, minimumInclusiveCostRatio, 100.0);
emit visualisationMinimumInclusiveCostRatioChanged(minimumInclusiveCostRatio);
} }
@@ -338,8 +239,39 @@ ValgrindGlobalSettings::ValgrindGlobalSettings()
{ {
theGlobalSettings = this; theGlobalSettings = this;
const QString base = "Analyzer.Valgrind";
group.registerAspect(&suppressionFiles_);
suppressionFiles_.setSettingsKey(base + "SupressionFiles");
group.registerAspect(&lastSuppressionDirectory);
lastSuppressionDirectory.setSettingsKey(base + "LastSuppressionDirectory");
group.registerAspect(&lastSuppressionHistory);
lastSuppressionHistory.setSettingsKey(base + "LastSuppressionHistory");
group.registerAspect(&detectCycles);
detectCycles.setSettingsKey(base + "Callgrind.CycleDetection");
detectCycles.setDefaultValue(true);
detectCycles.setLabelText("O"); // FIXME: Create a real icon
detectCycles.setToolTip(tr("Enable cycle detection to properly handle recursive "
"or circular function calls."));
group.registerAspect(&costFormat);
costFormat.setSettingsKey(base + "Callgrind.CostFormat");
costFormat.setDefaultValue(CostDelegate::FormatRelative);
costFormat.setDisplayStyle(SelectionAspect::DisplayStyle::ComboBox);
group.registerAspect(&shortenTemplates);
shortenTemplates.setSettingsKey(base + "Callgrind.ShortenTemplates");
shortenTemplates.setDefaultValue(true);
shortenTemplates.setLabelText("<>"); // FIXME: Create a real icon
shortenTemplates.setToolTip(tr("Remove template parameter lists when displaying function names."));
setConfigWidgetCreator([this] { return ValgrindOptionsPage::createSettingsWidget(this); }); setConfigWidgetCreator([this] { return ValgrindOptionsPage::createSettingsWidget(this); });
readSettings(); readSettings();
group.forEachAspect([](BaseAspect *aspect) { aspect->setAutoApply(false); });
} }
ValgrindGlobalSettings *ValgrindGlobalSettings::instance() ValgrindGlobalSettings *ValgrindGlobalSettings::instance()
@@ -347,125 +279,35 @@ ValgrindGlobalSettings *ValgrindGlobalSettings::instance()
return theGlobalSettings; return theGlobalSettings;
} }
void ValgrindGlobalSettings::fromMap(const QVariantMap &map)
{
ValgrindBaseSettings::fromMap(map);
// Memcheck
m_suppressionFiles = map.value(suppressionFilesC).toStringList();
m_lastSuppressionDirectory = map.value(lastSuppressionDirectoryC).toString();
m_lastSuppressionHistory = map.value(lastSuppressionHistoryC).toStringList();
// Callgrind
// special code as the default one does not cope with the enum properly
if (map.contains(callgrindCostFormatC))
m_costFormat = static_cast<CostDelegate::CostFormat>(map.value(callgrindCostFormatC).toInt());
setIfPresent(map, callgrindCycleDetectionC, &m_detectCycles);
setIfPresent(map, callgrindShortenTemplates, &m_shortenTemplates);
}
void ValgrindGlobalSettings::toMap(QVariantMap &map) const
{
ValgrindBaseSettings::toMap(map);
// Memcheck
map.insert(suppressionFilesC, m_suppressionFiles);
map.insert(lastSuppressionDirectoryC, m_lastSuppressionDirectory);
map.insert(lastSuppressionHistoryC, m_lastSuppressionHistory);
// Callgrind
map.insert(callgrindCostFormatC, m_costFormat);
map.insert(callgrindCycleDetectionC, m_detectCycles);
map.insert(callgrindShortenTemplates, m_shortenTemplates);
}
// //
// Memcheck // Memcheck
// //
QStringList ValgrindGlobalSettings::suppressionFiles() const QStringList ValgrindGlobalSettings::suppressionFiles() const
{ {
return m_suppressionFiles; return suppressionFiles_.value();
} }
void ValgrindGlobalSettings::addSuppressionFiles(const QStringList &suppressions) void ValgrindGlobalSettings::addSuppressionFiles(const QStringList &suppressions)
{ {
foreach (const QString &s, suppressions) suppressionFiles_.appendValues(suppressions);
if (!m_suppressionFiles.contains(s))
m_suppressionFiles.append(s);
} }
void ValgrindGlobalSettings::removeSuppressionFiles(const QStringList &suppressions) void ValgrindGlobalSettings::removeSuppressionFiles(const QStringList &suppressions)
{ {
foreach (const QString &s, suppressions) suppressionFiles_.removeValues(suppressions);
m_suppressionFiles.removeAll(s);
} }
QString ValgrindGlobalSettings::lastSuppressionDialogDirectory() const QVariantMap ValgrindBaseSettings::defaultSettings() const
{ {
return m_lastSuppressionDirectory; QVariantMap defaults;
} group.forEachAspect([&defaults](BaseAspect *aspect) {
defaults.insert(aspect->settingsKey(), aspect->defaultValue());
void ValgrindGlobalSettings::setLastSuppressionDialogDirectory(const QString &directory) });
{ return defaults;
m_lastSuppressionDirectory = directory;
}
QStringList ValgrindGlobalSettings::lastSuppressionDialogHistory() const
{
return m_lastSuppressionHistory;
}
void ValgrindGlobalSettings::setLastSuppressionDialogHistory(const QStringList &history)
{
m_lastSuppressionHistory = history;
} }
static const char groupC[] = "Analyzer"; static const char groupC[] = "Analyzer";
static QVariantMap defaultSettings()
{
QVariantMap defaults;
// General
defaults.insert(valgrindExeC, "valgrind");
defaults.insert(valgrindArgumentsC, QString());
defaults.insert(selfModifyingCodeDetectionC, ValgrindBaseSettings::DetectSmcStackOnly);
// Memcheck
defaults.insert(memcheckArgumentsC, QString());
defaults.insert(numCallersC, 25);
defaults.insert(leakCheckOnFinishC, ValgrindBaseSettings::LeakCheckOnFinishSummaryOnly);
defaults.insert(showReachableC, false);
defaults.insert(trackOriginsC, true);
defaults.insert(filterExternalIssuesC, true);
QVariantList defaultErrorKinds;
for (int i = 0; i < Valgrind::XmlProtocol::MemcheckErrorKindCount; ++i)
defaultErrorKinds << i;
defaults.insert(visibleErrorKindsC, defaultErrorKinds);
defaults.insert(suppressionFilesC, QStringList());
defaults.insert(lastSuppressionDirectoryC, QString());
defaults.insert(lastSuppressionHistoryC, QStringList());
// Callgrind
defaults.insert(callgrindArgumentsC, QString());
defaults.insert(kcachegrindExeC, "kcachegrind");
defaults.insert(callgrindEnableCacheSimC, false);
defaults.insert(callgrindEnableBranchSimC, false);
defaults.insert(callgrindCollectSystimeC, false);
defaults.insert(callgrindCollectBusEventsC, false);
defaults.insert(callgrindEnableEventToolTipsC, true);
defaults.insert(callgrindMinimumCostRatioC, 0.01);
defaults.insert(callgrindVisualisationMinimumCostRatioC, 10.0);
defaults.insert(callgrindCostFormatC, CostDelegate::FormatRelative);
defaults.insert(callgrindCycleDetectionC, true);
defaults.insert(callgrindShortenTemplates, true);
return defaults;
}
void ValgrindGlobalSettings::readSettings() void ValgrindGlobalSettings::readSettings()
{ {
QVariantMap defaults = defaultSettings(); QVariantMap defaults = defaultSettings();
@@ -494,43 +336,6 @@ void ValgrindGlobalSettings::writeSettings() const
settings->endGroup(); settings->endGroup();
} }
//
// Callgrind
//
CostDelegate::CostFormat ValgrindGlobalSettings::costFormat() const
{
return m_costFormat;
}
void ValgrindGlobalSettings::setCostFormat(CostDelegate::CostFormat format)
{
m_costFormat = format;
writeSettings();
}
bool ValgrindGlobalSettings::detectCycles() const
{
return m_detectCycles;
}
void ValgrindGlobalSettings::setDetectCycles(bool on)
{
m_detectCycles = on;
writeSettings();
}
bool ValgrindGlobalSettings::shortenTemplates() const
{
return m_shortenTemplates;
}
void ValgrindGlobalSettings::setShortenTemplates(bool on)
{
m_shortenTemplates = on;
writeSettings();
}
////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////
// //
// ValgrindProjectSettings // ValgrindProjectSettings
@@ -540,24 +345,12 @@ void ValgrindGlobalSettings::setShortenTemplates(bool on)
ValgrindProjectSettings::ValgrindProjectSettings() ValgrindProjectSettings::ValgrindProjectSettings()
{ {
setConfigWidgetCreator([this] { return ValgrindOptionsPage::createSettingsWidget(this); }); setConfigWidgetCreator([this] { return ValgrindOptionsPage::createSettingsWidget(this); });
}
void ValgrindProjectSettings::fromMap(const QVariantMap &map) group.registerAspect(&disabledGlobalSuppressionFiles);
{ disabledGlobalSuppressionFiles.setSettingsKey("Analyzer.Valgrind.RemovedSuppressionFiles");
ValgrindBaseSettings::fromMap(map);
// Memcheck group.registerAspect(&addedSuppressionFiles);
setIfPresent(map, addedSuppressionFilesC, &m_addedSuppressionFiles); addedSuppressionFiles.setSettingsKey("Analyzer.Valgrind.AddedSuppressionFiles");
setIfPresent(map, removedSuppressionFilesC, &m_disabledGlobalSuppressionFiles);
}
void ValgrindProjectSettings::toMap(QVariantMap &map) const
{
ValgrindBaseSettings::toMap(map);
// Memcheck
map.insert(addedSuppressionFilesC, m_addedSuppressionFiles);
map.insert(removedSuppressionFilesC, m_disabledGlobalSuppressionFiles);
} }
// //
@@ -568,11 +361,11 @@ void ValgrindProjectSettings::addSuppressionFiles(const QStringList &suppression
{ {
const QStringList globalSuppressions = ValgrindGlobalSettings::instance()->suppressionFiles(); const QStringList globalSuppressions = ValgrindGlobalSettings::instance()->suppressionFiles();
for (const QString &s : suppressions) { for (const QString &s : suppressions) {
if (m_addedSuppressionFiles.contains(s)) if (addedSuppressionFiles.value().contains(s))
continue; continue;
m_disabledGlobalSuppressionFiles.removeAll(s); disabledGlobalSuppressionFiles.removeValue(s);
if (!globalSuppressions.contains(s)) if (!globalSuppressions.contains(s))
m_addedSuppressionFiles.append(s); addedSuppressionFiles.appendValue(s);
} }
} }
@@ -580,18 +373,18 @@ void ValgrindProjectSettings::removeSuppressionFiles(const QStringList &suppress
{ {
const QStringList globalSuppressions = ValgrindGlobalSettings::instance()->suppressionFiles(); const QStringList globalSuppressions = ValgrindGlobalSettings::instance()->suppressionFiles();
for (const QString &s : suppressions) { for (const QString &s : suppressions) {
m_addedSuppressionFiles.removeAll(s); addedSuppressionFiles.removeValue(s);
if (globalSuppressions.contains(s)) if (globalSuppressions.contains(s))
m_disabledGlobalSuppressionFiles.append(s); disabledGlobalSuppressionFiles.appendValue(s);
} }
} }
QStringList ValgrindProjectSettings::suppressionFiles() const QStringList ValgrindProjectSettings::suppressionFiles() const
{ {
QStringList ret = ValgrindGlobalSettings::instance()->suppressionFiles(); QStringList ret = ValgrindGlobalSettings::instance()->suppressionFiles();
for (const QString &s : m_disabledGlobalSuppressionFiles) for (const QString &s : disabledGlobalSuppressionFiles.value())
ret.removeAll(s); ret.removeAll(s);
ret.append(m_addedSuppressionFiles); ret.append(addedSuppressionFiles.value());
return ret; return ret;
} }

View File

@@ -27,11 +27,9 @@
#pragma once #pragma once
#include "callgrindcostdelegate.h" #include "callgrindcostdelegate.h"
#include <projectexplorer/runconfiguration.h>
#include <QObject> #include <projectexplorer/runconfiguration.h>
#include <QString> #include <projectexplorer/runconfigurationaspects.h>
#include <QVariant>
namespace Valgrind { namespace Valgrind {
namespace Internal { namespace Internal {
@@ -46,6 +44,8 @@ class ValgrindBaseSettings : public ProjectExplorer::ISettingsAspect
Q_OBJECT Q_OBJECT
public: public:
ValgrindBaseSettings();
enum SelfModifyingCodeDetection { enum SelfModifyingCodeDetection {
DetectSmcNo, DetectSmcNo,
DetectSmcStackOnly, DetectSmcStackOnly,
@@ -59,8 +59,6 @@ public:
LeakCheckOnFinishYes LeakCheckOnFinishYes
}; };
ValgrindBaseSettings();
void toMap(QVariantMap &map) const override; void toMap(QVariantMap &map) const override;
void fromMap(const QVariantMap &map) override; void fromMap(const QVariantMap &map) override;
@@ -71,121 +69,49 @@ signals:
* Base valgrind settings * Base valgrind settings
*/ */
public: public:
QString valgrindExecutable() const; Utils::StringAspect valgrindExecutable;
QString valgrindArguments() const { return m_valgrindArguments; } Utils::StringAspect valgrindArguments;
SelfModifyingCodeDetection selfModifyingCodeDetection() const; Utils::SelectionAspect selfModifyingCodeDetection;
void setValgrindExecutable(const QString &);
void setValgrindArguments(const QString &arguments);
void setSelfModifyingCodeDetection(int);
signals:
void valgrindArgumentsChanged(const QString &arguments);
void selfModifyingCodeDetectionChanged(int);
private:
QString m_valgrindExecutable;
QString m_valgrindArguments;
SelfModifyingCodeDetection m_selfModifyingCodeDetection;
/** /**
* Base memcheck settings * Base memcheck settings
*/ */
public: public:
QString memcheckArguments() const { return m_memcheckArguments; } Utils::StringAspect memcheckArguments;
int numCallers() const { return m_numCallers; } Utils::IntegerAspect numCallers;
LeakCheckOnFinish leakCheckOnFinish() const { return m_leakCheckOnFinish; } Utils::SelectionAspect leakCheckOnFinish;
bool showReachable() const { return m_showReachable; } Utils::BoolAspect showReachable;
bool trackOrigins() const { return m_trackOrigins; } Utils::BoolAspect trackOrigins;
bool filterExternalIssues() const { return m_filterExternalIssues; } Utils::BoolAspect filterExternalIssues;
QList<int> visibleErrorKinds() const { return m_visibleErrorKinds; } Utils::IntegersAspect visibleErrorKinds;
virtual QStringList suppressionFiles() const = 0; virtual QStringList suppressionFiles() const = 0;
virtual void addSuppressionFiles(const QStringList &) = 0; virtual void addSuppressionFiles(const QStringList &) = 0;
virtual void removeSuppressionFiles(const QStringList &) = 0; virtual void removeSuppressionFiles(const QStringList &) = 0;
void setMemcheckArguments(const QString &arguments);
void setNumCallers(int);
void setLeakCheckOnFinish(int);
void setShowReachable(bool);
void setTrackOrigins(bool);
void setFilterExternalIssues(bool);
void setVisibleErrorKinds(const QList<int> &); void setVisibleErrorKinds(const QList<int> &);
signals: signals:
void memcheckArgumentsChanged(const QString &arguments);
void numCallersChanged(int);
void leakCheckOnFinishChanged(int);
void showReachableChanged(bool);
void trackOriginsChanged(bool);
void filterExternalIssuesChanged(bool);
void visibleErrorKindsChanged(const QList<int> &);
void suppressionFilesRemoved(const QStringList &); void suppressionFilesRemoved(const QStringList &);
void suppressionFilesAdded(const QStringList &); void suppressionFilesAdded(const QStringList &);
protected:
QString m_memcheckArguments;
int m_numCallers;
LeakCheckOnFinish m_leakCheckOnFinish;
bool m_showReachable;
bool m_trackOrigins;
bool m_filterExternalIssues;
QList<int> m_visibleErrorKinds;
/** /**
* Base callgrind settings * Base callgrind settings
*/ */
public: public:
QString callgrindArguments() const { return m_callgrindArguments;} Utils::StringAspect callgrindArguments;
QString kcachegrindExecutable() const; Utils::StringAspect kcachegrindExecutable;
bool enableCacheSim() const { return m_enableCacheSim; } Utils::BoolAspect enableCacheSim;
bool enableBranchSim() const { return m_enableBranchSim; } Utils::BoolAspect enableBranchSim;
bool collectSystime() const { return m_collectSystime; } Utils::BoolAspect collectSystime;
bool collectBusEvents() const { return m_collectBusEvents; } Utils::BoolAspect collectBusEvents;
bool enableEventToolTips() const { return m_enableEventToolTips; } Utils::BoolAspect enableEventToolTips;
Utils::DoubleAspect minimumInclusiveCostRatio;
Utils::DoubleAspect visualizationMinimumInclusiveCostRatio;
/// \return Minimum cost ratio, range [0.0..100.0] Utils::AspectContainer group;
double minimumInclusiveCostRatio() const { return m_minimumInclusiveCostRatio; } QVariantMap defaultSettings() const;
/// \return Minimum cost ratio, range [0.0..100.0]
double visualisationMinimumInclusiveCostRatio() const { return m_visualisationMinimumInclusiveCostRatio; }
void setCallgrindArguments(const QString &arguments);
void setKCachegrindExecutable(const QString &exec);
void setEnableCacheSim(bool enable);
void setEnableBranchSim(bool enable);
void setCollectSystime(bool collect);
void setCollectBusEvents(bool collect);
void setEnableEventToolTips(bool enable);
/// \param minimumInclusiveCostRatio Minimum inclusive cost ratio, valid values are [0.0..100.0]
void setMinimumInclusiveCostRatio(double minimumInclusiveCostRatio);
/// \param minimumInclusiveCostRatio Minimum inclusive cost ratio, valid values are [0.0..100.0]
void setVisualisationMinimumInclusiveCostRatio(double minimumInclusiveCostRatio);
signals:
void callgrindArgumentsChanged(const QString &argumnts);
void enableCacheSimChanged(bool);
void enableBranchSimChanged(bool);
void collectSystimeChanged(bool);
void collectBusEventsChanged(bool);
void enableEventToolTipsChanged(bool);
void minimumInclusiveCostRatioChanged(double);
void visualisationMinimumInclusiveCostRatioChanged(double);
private:
QString m_callgrindArguments;
QString m_kcachegrindExecutable;
bool m_enableCacheSim;
bool m_collectSystime;
bool m_collectBusEvents;
bool m_enableBranchSim;
bool m_enableEventToolTips;
double m_minimumInclusiveCostRatio;
double m_visualisationMinimumInclusiveCostRatio;
}; };
@@ -201,50 +127,28 @@ public:
static ValgrindGlobalSettings *instance(); static ValgrindGlobalSettings *instance();
void toMap(QVariantMap &map) const override; /**
void fromMap(const QVariantMap &map) override;
/*
* Global memcheck settings * Global memcheck settings
*/ */
public:
QStringList suppressionFiles() const override; QStringList suppressionFiles() const override;
// in the global settings we change the internal list directly // in the global settings we change the internal list directly
void addSuppressionFiles(const QStringList &) override; void addSuppressionFiles(const QStringList &) override;
void removeSuppressionFiles(const QStringList &) override; void removeSuppressionFiles(const QStringList &) override;
// internal settings which don't require any UI
void setLastSuppressionDialogDirectory(const QString &directory);
QString lastSuppressionDialogDirectory() const;
void setLastSuppressionDialogHistory(const QStringList &history);
QStringList lastSuppressionDialogHistory() const;
void writeSettings() const; void writeSettings() const;
void readSettings(); void readSettings();
private: Utils::StringListAspect suppressionFiles_;
QStringList m_suppressionFiles; Utils::StringAspect lastSuppressionDirectory;
QString m_lastSuppressionDirectory; Utils::StringAspect lastSuppressionHistory;
QStringList m_lastSuppressionHistory;
/** /**
* Global callgrind settings * Global callgrind settings
*/ */
public: Utils::SelectionAspect costFormat;
CostDelegate::CostFormat costFormat() const; Utils::BoolAspect detectCycles;
bool detectCycles() const; Utils::BoolAspect shortenTemplates;
bool shortenTemplates() const;
void setCostFormat(Valgrind::Internal::CostDelegate::CostFormat format);
void setDetectCycles(bool on);
void setShortenTemplates(bool on);
private:
CostDelegate::CostFormat m_costFormat;
bool m_detectCycles;
bool m_shortenTemplates;
}; };
@@ -258,26 +162,17 @@ class ValgrindProjectSettings : public ValgrindBaseSettings
public: public:
ValgrindProjectSettings(); ValgrindProjectSettings();
void toMap(QVariantMap &map) const override;
void fromMap(const QVariantMap &map) override;
/** /**
* Per-project memcheck settings, saves a diff to the global suppression files list * Per-project memcheck settings, saves a diff to the global suppression files list
*/ */
public:
QStringList suppressionFiles() const override; QStringList suppressionFiles() const override;
// in the project-specific settings we store a diff to the global list // in the project-specific settings we store a diff to the global list
void addSuppressionFiles(const QStringList &suppressions) override; void addSuppressionFiles(const QStringList &suppressions) override;
void removeSuppressionFiles(const QStringList &suppressions) override; void removeSuppressionFiles(const QStringList &suppressions) override;
private: private:
QStringList m_disabledGlobalSuppressionFiles; Utils::StringListAspect disabledGlobalSuppressionFiles;
QStringList m_addedSuppressionFiles; Utils::StringListAspect addedSuppressionFiles;
/**
* Per-project callgrind settings, saves a diff to the global suppression files list
*/
}; };
} // namespace Internal } // namespace Internal