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)
{
Q_UNUSED(val);
QTC_CHECK(false);
}
void BaseAspect::registerSubWidget(QWidget *widget)
@@ -1100,7 +1099,6 @@ QVariant StringAspect::volatileValue() const
void StringAspect::setVolatileValue(const QVariant &val)
{
QTC_CHECK(!isAutoApply());
switch (d->m_displayStyle) {
case PathChooserDisplay:
if (d->m_pathChooserDisplay)
@@ -2084,6 +2082,12 @@ void AspectContainer::reset()
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)
{
for (BaseAspect *aspect : qAsConst(d->m_items))

View File

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

View File

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

View File

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

View File

@@ -133,8 +133,6 @@ public:
void selectFunction(const Function *);
void setCostFormat(CostDelegate::CostFormat format);
void enableCycleDetection(bool enabled);
void shortenTemplates(bool enabled);
void setCostEvent(int index);
/// This function will add custom text marks to the editor
@@ -198,8 +196,6 @@ public:
QAction *m_costAbsolute = nullptr;
QAction *m_costRelative = nullptr;
QAction *m_costRelativeToParent = nullptr;
QAction *m_cycleDetection = nullptr;
QAction *m_shortenTemplates = nullptr;
QComboBox *m_eventCombo = nullptr;
QTimer m_updateTimer;
@@ -382,7 +378,7 @@ CallgrindToolPrivate::CallgrindToolPrivate()
action->setIcon(kCachegrindIcon.icon());
action->setToolTip(CallgrindTool::tr("Open results in KCachegrind."));
connect(action, &QAction::triggered, this, [this, settings] {
QProcess::startDetached(settings->kcachegrindExecutable(), { m_lastFileName });
QProcess::startDetached(settings->kcachegrindExecutable.value(), { m_lastFileName });
});
// dump action
@@ -488,40 +484,20 @@ CallgrindToolPrivate::CallgrindToolPrivate()
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
action = m_filterProjectCosts = new QAction(CallgrindTool::tr("Show Project Costs Only"), this);
action->setIcon(Utils::Icons::FILTER.icon());
action->setToolTip(CallgrindTool::tr("Show only profiling info that originated from this project source."));
action->setCheckable(true);
action = m_filterProjectCosts = settings->filterExternalIssues.action();
connect(action, &QAction::toggled, this, &CallgrindToolPrivate::handleFilterProjectCosts);
// Filter
///FIXME: find workaround for https://bugreports.qt.io/browse/QTCREATORBUG-3247
m_searchFilter = new QLineEdit;
m_searchFilter->setPlaceholderText(CallgrindTool::tr("Filter..."));
connect(m_searchFilter, &QLineEdit::textChanged,
&m_updateTimer, QOverload<>::of(&QTimer::start));
setCostFormat(settings->costFormat());
enableCycleDetection(settings->detectCycles());
setCostFormat(CostDelegate::CostFormat(settings->costFormat.value()));
m_perspective.addToolBarAction(m_cycleDetection);
m_perspective.addToolBarAction(m_shortenTemplates);
m_perspective.addToolBarAction(settings->detectCycles.action());
m_perspective.addToolBarAction(settings->shortenTemplates.action());
m_perspective.addToolBarAction(m_filterProjectCosts);
m_perspective.addToolBarWidget(m_searchFilter);
@@ -640,16 +616,6 @@ void CallgrindToolPrivate::setCostEvent(int 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
// depending on initialization sequence (whether callgrind was current).
CostDelegate::CostFormat CallgrindToolPrivate::costFormat() const
@@ -671,7 +637,7 @@ void CallgrindToolPrivate::updateCostFormat()
m_callersView->setCostFormat(format);
}
if (ValgrindGlobalSettings *settings = ValgrindGlobalSettings::instance())
settings->setCostFormat(format);
settings->costFormat.setValue(format);
}
void CallgrindToolPrivate::handleFilterProjectCosts()
@@ -789,9 +755,9 @@ void CallgrindToolPrivate::setupRunner(CallgrindToolRunner *toolRunner)
// apply project settings
ValgrindProjectSettings settings;
settings.fromMap(runControl->settingsData(ANALYZER_VALGRIND_SETTINGS));
m_visualization->setMinimumInclusiveCostRatio(settings.visualisationMinimumInclusiveCostRatio() / 100.0);
m_proxyModel.setMinimumInclusiveCostRatio(settings.minimumInclusiveCostRatio() / 100.0);
m_dataModel.setVerboseToolTipsEnabled(settings.enableEventToolTips());
m_visualization->setMinimumInclusiveCostRatio(settings.visualizationMinimumInclusiveCostRatio.value() / 100.0);
m_proxyModel.setMinimumInclusiveCostRatio(settings.minimumInclusiveCostRatio.value() / 100.0);
m_dataModel.setVerboseToolTipsEnabled(settings.enableEventToolTips.value());
m_toolBusy = true;
updateRunActions();
@@ -949,7 +915,8 @@ void CallgrindToolPrivate::takeParserData(ParseData *data)
doClear(true);
setParseData(data);
const QString kcachegrindExecutable = ValgrindGlobalSettings::instance()->kcachegrindExecutable();
const QString kcachegrindExecutable =
ValgrindGlobalSettings::instance()->kcachegrindExecutable.value();
const bool kcachegrindExists = !Utils::Environment::systemEnvironment().searchInPath(
kcachegrindExecutable).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"};
if (m_settings.trackOrigins())
if (m_settings.trackOrigins.value())
arguments << "--track-origins=yes";
if (m_settings.showReachable())
if (m_settings.showReachable.value())
arguments << "--show-reachable=yes";
QString leakCheckValue;
switch (m_settings.leakCheckOnFinish()) {
switch (m_settings.leakCheckOnFinish.value()) {
case ValgrindBaseSettings::LeakCheckOnFinishNo:
leakCheckValue = "no";
break;
@@ -215,12 +215,12 @@ QStringList MemcheckToolRunner::toolArguments() const
foreach (const QString &file, m_settings.suppressionFiles())
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)
arguments << "--vgdb=yes" << "--vgdb-error=0";
arguments << Utils::QtcProcess::splitArgs(m_settings.memcheckArguments());
arguments << Utils::QtcProcess::splitArgs(m_settings.memcheckArguments.value());
return arguments;
}
@@ -916,22 +916,22 @@ void MemcheckToolPrivate::updateFromSettings()
foreach (const QVariant &v, action->data().toList()) {
bool ok;
int kind = v.toInt(&ok);
if (ok && !m_settings->visibleErrorKinds().contains(kind))
if (ok && !m_settings->visibleErrorKinds.value().contains(kind))
contained = false;
}
action->setChecked(contained);
}
m_filterProjectAction->setChecked(!m_settings->filterExternalIssues());
m_filterProjectAction->setChecked(!m_settings->filterExternalIssues.value());
m_errorView->settingsChanged(m_settings);
connect(m_settings, &ValgrindBaseSettings::visibleErrorKindsChanged,
connect(&m_settings->visibleErrorKinds, &IntegersAspect::valueChanged,
&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.setFilterExternalIssues(m_settings->filterExternalIssues());
m_errorProxyModel.setFilterExternalIssues(m_settings->filterExternalIssues.value());
}
void MemcheckToolPrivate::maybeActiveRunConfigurationChanged()
@@ -1006,7 +1006,7 @@ void MemcheckToolPrivate::setupRunner(MemcheckToolRunner *runTool)
void MemcheckToolPrivate::loadShowXmlLogFile(const QString &filePath, const QString &exitMsg)
{
clearErrorView();
m_settings->setFilterExternalIssues(false);
m_settings->filterExternalIssues.setValue(false);
m_filterProjectAction->setChecked(true);
m_perspective.select();
Core::ModeManager::activateMode(Debugger::Constants::MODE_DEBUG);
@@ -1092,7 +1092,7 @@ void MemcheckToolPrivate::updateErrorFilter()
QTC_ASSERT(m_errorView, return);
QTC_ASSERT(m_settings, return);
m_settings->setFilterExternalIssues(!m_filterProjectAction->isChecked());
m_settings->filterExternalIssues.setValue(!m_filterProjectAction->isChecked());
QList<int> errorKinds;
foreach (QAction *a, m_errorFilterActions) {
@@ -1105,7 +1105,7 @@ void MemcheckToolPrivate::updateErrorFilter()
errorKinds << kind;
}
}
m_settings->setVisibleErrorKinds(errorKinds);
m_settings->visibleErrorKinds.setValue(errorKinds);
}
int MemcheckToolPrivate::updateUiAfterFinishedHelper()

View File

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

View File

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

View File

@@ -28,20 +28,23 @@
#include "valgrindsettings.h"
#include "valgrindplugin.h"
#include "ui_valgrindconfigwidget.h"
#include <debugger/analyzer/analyzericons.h>
#include <utils/algorithm.h>
#include <utils/hostosinfo.h>
#include <utils/layoutbuilder.h>
#include <utils/qtcassert.h>
#include <QDebug>
#include <QStandardItemModel>
#include <QFileDialog>
#include <QListView>
#include <QPushButton>
#include <QStandardItemModel>
#include <functional>
using namespace Utils;
namespace Valgrind {
namespace Internal {
@@ -53,10 +56,10 @@ class ValgrindConfigWidget : public Core::IOptionsPageWidget
public:
explicit ValgrindConfigWidget(ValgrindBaseSettings *settings);
~ValgrindConfigWidget() override;
void apply() final
{
ValgrindGlobalSettings::instance()->group.apply();
ValgrindGlobalSettings::instance()->writeSettings();
}
@@ -73,172 +76,102 @@ private:
void updateUi();
ValgrindBaseSettings *m_settings;
Ui::ValgrindConfigWidget *m_ui;
QStandardItemModel *m_model;
QPushButton *addSuppression;
QPushButton *removeSuppression;
QListView *suppressionList;
QStandardItemModel m_model;
};
ValgrindConfigWidget::ValgrindConfigWidget(ValgrindBaseSettings *settings)
: m_settings(settings),
m_ui(new Ui::ValgrindConfigWidget)
: m_settings(settings)
{
m_ui->setupUi(this);
m_model = new QStandardItemModel(this);
addSuppression = new QPushButton(tr("Add..."));
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();
connect(m_settings, &ValgrindBaseSettings::changed, this, &ValgrindConfigWidget::updateUi);
connect(m_ui->valgrindExeChooser, &Utils::PathChooser::rawPathChanged,
m_settings, &ValgrindBaseSettings::setValgrindExecutable);
connect(addSuppression, &QPushButton::clicked,
this, &ValgrindConfigWidget::slotAddSuppression);
connect(removeSuppression, &QPushButton::clicked,
this, &ValgrindConfigWidget::slotRemoveSuppression);
connect(m_ui->valgrindArgumentsLineEdit, &QLineEdit::textChanged,
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,
connect(&s, &ValgrindBaseSettings::suppressionFilesRemoved,
this, &ValgrindConfigWidget::slotSuppressionsRemoved);
connect(m_settings, &ValgrindBaseSettings::suppressionFilesAdded,
connect(&s, &ValgrindBaseSettings::suppressionFilesAdded,
this, &ValgrindConfigWidget::slotSuppressionsAdded);
connect(m_ui->suppressionList->selectionModel(), &QItemSelectionModel::selectionChanged,
connect(suppressionList->selectionModel(), &QItemSelectionModel::selectionChanged,
this, &ValgrindConfigWidget::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()
{
m_ui->valgrindExeChooser->setPath(m_settings->valgrindExecutable());
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();
m_model.clear();
foreach (const QString &file, m_settings->suppressionFiles())
m_model->appendRow(new QStandardItem(file));
m_model.appendRow(new QStandardItem(file));
}
void ValgrindConfigWidget::slotAddSuppression()
@@ -247,14 +180,14 @@ void ValgrindConfigWidget::slotAddSuppression()
QTC_ASSERT(conf, return);
QStringList files = QFileDialog::getOpenFileNames(this,
tr("Valgrind Suppression Files"),
conf->lastSuppressionDialogDirectory(),
conf->lastSuppressionDirectory.value(),
tr("Valgrind Suppression File (*.supp);;All Files (*)"));
//dialog.setHistory(conf->lastSuppressionDialogHistory());
if (!files.isEmpty()) {
foreach (const QString &file, files)
m_model->appendRow(new QStandardItem(file));
m_model.appendRow(new QStandardItem(file));
m_settings->addSuppressionFiles(files);
conf->setLastSuppressionDialogDirectory(QFileInfo(files.at(0)).absolutePath());
conf->lastSuppressionDirectory.setValue(QFileInfo(files.at(0)).absolutePath());
//conf->setLastSuppressionDialogHistory(dialog.history());
}
}
@@ -262,11 +195,11 @@ void ValgrindConfigWidget::slotAddSuppression()
void ValgrindConfigWidget::slotSuppressionsAdded(const QStringList &files)
{
QStringList filesToAdd = files;
for (int i = 0, c = m_model->rowCount(); i < c; ++i)
filesToAdd.removeAll(m_model->item(i)->text());
for (int i = 0, c = m_model.rowCount(); i < c; ++i)
filesToAdd.removeAll(m_model.item(i)->text());
foreach (const QString &file, filesToAdd)
m_model->appendRow(new QStandardItem(file));
m_model.appendRow(new QStandardItem(file));
}
void ValgrindConfigWidget::slotRemoveSuppression()
@@ -275,7 +208,7 @@ void ValgrindConfigWidget::slotRemoveSuppression()
QList<int> rows;
QStringList removed;
foreach (const QModelIndex &index, m_ui->suppressionList->selectionModel()->selectedIndexes()) {
foreach (const QModelIndex &index, suppressionList->selectionModel()->selectedIndexes()) {
rows << index.row();
removed << index.data().toString();
}
@@ -283,16 +216,16 @@ void ValgrindConfigWidget::slotRemoveSuppression()
Utils::sort(rows, std::greater<int>());
foreach (int row, rows)
m_model->removeRow(row);
m_model.removeRow(row);
m_settings->removeSuppressionFiles(removed);
}
void ValgrindConfigWidget::slotSuppressionsRemoved(const QStringList &files)
{
for (int i = 0; i < m_model->rowCount(); ++i) {
if (files.contains(m_model->item(i)->text())) {
m_model->removeRow(i);
for (int i = 0; i < m_model.rowCount(); ++i) {
if (files.contains(m_model.item(i)->text())) {
m_model.removeRow(i);
--i;
}
}
@@ -300,24 +233,24 @@ void ValgrindConfigWidget::slotSuppressionsRemoved(const QStringList &files)
void ValgrindConfigWidget::setSuppressions(const QStringList &files)
{
m_model->clear();
m_model.clear();
foreach (const QString &file, files)
m_model->appendRow(new QStandardItem(file));
m_model.appendRow(new QStandardItem(file));
}
QStringList ValgrindConfigWidget::suppressions() const
{
QStringList ret;
for (int i = 0; i < m_model->rowCount(); ++i)
ret << m_model->item(i)->text();
for (int i = 0; i < m_model.rowCount(); ++i)
ret << m_model.item(i)->text();
return ret;
}
void ValgrindConfigWidget::slotSuppressionSelectionChanged()
{
m_ui->removeSuppression->setEnabled(m_ui->suppressionList->selectionModel()->hasSelection());
removeSuppression->setEnabled(suppressionList->selectionModel()->hasSelection());
}
// 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);
#endif
CommandLine valgrind{m_settings.valgrindExecutable()};
valgrind.addArgs(m_settings.valgrindArguments(), CommandLine::Raw);
CommandLine valgrind{m_settings.valgrindExecutable.value()};
valgrind.addArgs(m_settings.valgrindArguments.value(), CommandLine::Raw);
valgrind.addArgs(genericToolArguments());
valgrind.addArgs(toolArguments());
@@ -124,7 +124,7 @@ QStringList ValgrindToolRunner::genericToolArguments() const
{
QString smcCheckValue;
switch (m_settings.selfModifyingCodeDetection()) {
switch (m_settings.selfModifyingCodeDetection.value()) {
case ValgrindBaseSettings::DetectSmcNo:
smcCheckValue = "none";
break;
@@ -175,7 +175,7 @@ void ValgrindToolRunner::receiveProcessOutput(const QString &output, OutputForma
void ValgrindToolRunner::receiveProcessError(const QString &message, QProcess::ProcessError error)
{
if (error == QProcess::FailedToStart) {
const QString valgrind = m_settings.valgrindExecutable();
const QString valgrind = m_settings.valgrindExecutable.value();
if (!valgrind.isEmpty())
appendMessage(tr("Error: \"%1\" could not be started: %2").arg(valgrind, message), ErrorMessageFormat);
else

View File

@@ -29,43 +29,16 @@
#include "valgrindconfigwidget.h"
#include <coreplugin/icore.h>
#include <utils/qtcassert.h>
#include <utils/utilsicons.h>
#include <valgrind/xmlprotocol/error.h>
#include <QSettings>
#include <QDebug>
const char numCallersC[] = "Analyzer.Valgrind.NumCallers";
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";
using namespace Utils;
namespace Valgrind {
namespace Internal {
@@ -76,253 +49,181 @@ namespace Internal {
//
//////////////////////////////////////////////////////////////////
/**
* 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)
ValgrindBaseSettings::ValgrindBaseSettings()
{
if (map.contains(key))
*val = map.value(key).template value<T>();
}
// Note that this is used twice, once for project settings in the .user files
// and once for global settings in QtCreator.ini. This uses intentionally
// the same key to facilitate copying using fromMap/toMap.
QString base = "Analyzer.Valgrind.";
ValgrindBaseSettings::ValgrindBaseSettings() = default;
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();
}
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)
{
// General
setIfPresent(map, valgrindExeC, &m_valgrindExecutable);
setIfPresent(map, valgrindArgumentsC, &m_valgrindArguments);
setIfPresent(map, selfModifyingCodeDetectionC,
(int*) &m_selfModifyingCodeDetection);
// Memcheck
setIfPresent(map, numCallersC, &m_numCallers);
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();
group.fromMap(map);
if (ValgrindGlobalSettings::instance() != this) {
// FIXME: Update project page e.g. on "Restore Global", aspects
// there are 'autoapply', and Aspect::cancel() is normally part of
// the 'manual apply' machinery.
group.setAutoApply(false);
group.cancel();
group.setAutoApply(true);
}
// 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
{
// General
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);
group.toMap(map);
}
@@ -338,8 +239,39 @@ ValgrindGlobalSettings::ValgrindGlobalSettings()
{
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); });
readSettings();
group.forEachAspect([](BaseAspect *aspect) { aspect->setAutoApply(false); });
}
ValgrindGlobalSettings *ValgrindGlobalSettings::instance()
@@ -347,125 +279,35 @@ ValgrindGlobalSettings *ValgrindGlobalSettings::instance()
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
//
QStringList ValgrindGlobalSettings::suppressionFiles() const
{
return m_suppressionFiles;
return suppressionFiles_.value();
}
void ValgrindGlobalSettings::addSuppressionFiles(const QStringList &suppressions)
{
foreach (const QString &s, suppressions)
if (!m_suppressionFiles.contains(s))
m_suppressionFiles.append(s);
suppressionFiles_.appendValues(suppressions);
}
void ValgrindGlobalSettings::removeSuppressionFiles(const QStringList &suppressions)
{
foreach (const QString &s, suppressions)
m_suppressionFiles.removeAll(s);
suppressionFiles_.removeValues(suppressions);
}
QString ValgrindGlobalSettings::lastSuppressionDialogDirectory() const
QVariantMap ValgrindBaseSettings::defaultSettings() const
{
return m_lastSuppressionDirectory;
}
void ValgrindGlobalSettings::setLastSuppressionDialogDirectory(const QString &directory)
{
m_lastSuppressionDirectory = directory;
}
QStringList ValgrindGlobalSettings::lastSuppressionDialogHistory() const
{
return m_lastSuppressionHistory;
}
void ValgrindGlobalSettings::setLastSuppressionDialogHistory(const QStringList &history)
{
m_lastSuppressionHistory = history;
QVariantMap defaults;
group.forEachAspect([&defaults](BaseAspect *aspect) {
defaults.insert(aspect->settingsKey(), aspect->defaultValue());
});
return defaults;
}
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()
{
QVariantMap defaults = defaultSettings();
@@ -494,43 +336,6 @@ void ValgrindGlobalSettings::writeSettings() const
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
@@ -540,24 +345,12 @@ void ValgrindGlobalSettings::setShortenTemplates(bool on)
ValgrindProjectSettings::ValgrindProjectSettings()
{
setConfigWidgetCreator([this] { return ValgrindOptionsPage::createSettingsWidget(this); });
}
void ValgrindProjectSettings::fromMap(const QVariantMap &map)
{
ValgrindBaseSettings::fromMap(map);
group.registerAspect(&disabledGlobalSuppressionFiles);
disabledGlobalSuppressionFiles.setSettingsKey("Analyzer.Valgrind.RemovedSuppressionFiles");
// Memcheck
setIfPresent(map, addedSuppressionFilesC, &m_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);
group.registerAspect(&addedSuppressionFiles);
addedSuppressionFiles.setSettingsKey("Analyzer.Valgrind.AddedSuppressionFiles");
}
//
@@ -568,11 +361,11 @@ void ValgrindProjectSettings::addSuppressionFiles(const QStringList &suppression
{
const QStringList globalSuppressions = ValgrindGlobalSettings::instance()->suppressionFiles();
for (const QString &s : suppressions) {
if (m_addedSuppressionFiles.contains(s))
if (addedSuppressionFiles.value().contains(s))
continue;
m_disabledGlobalSuppressionFiles.removeAll(s);
disabledGlobalSuppressionFiles.removeValue(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();
for (const QString &s : suppressions) {
m_addedSuppressionFiles.removeAll(s);
addedSuppressionFiles.removeValue(s);
if (globalSuppressions.contains(s))
m_disabledGlobalSuppressionFiles.append(s);
disabledGlobalSuppressionFiles.appendValue(s);
}
}
QStringList ValgrindProjectSettings::suppressionFiles() const
{
QStringList ret = ValgrindGlobalSettings::instance()->suppressionFiles();
for (const QString &s : m_disabledGlobalSuppressionFiles)
for (const QString &s : disabledGlobalSuppressionFiles.value())
ret.removeAll(s);
ret.append(m_addedSuppressionFiles);
ret.append(addedSuppressionFiles.value());
return ret;
}

View File

@@ -27,11 +27,9 @@
#pragma once
#include "callgrindcostdelegate.h"
#include <projectexplorer/runconfiguration.h>
#include <QObject>
#include <QString>
#include <QVariant>
#include <projectexplorer/runconfiguration.h>
#include <projectexplorer/runconfigurationaspects.h>
namespace Valgrind {
namespace Internal {
@@ -46,6 +44,8 @@ class ValgrindBaseSettings : public ProjectExplorer::ISettingsAspect
Q_OBJECT
public:
ValgrindBaseSettings();
enum SelfModifyingCodeDetection {
DetectSmcNo,
DetectSmcStackOnly,
@@ -59,8 +59,6 @@ public:
LeakCheckOnFinishYes
};
ValgrindBaseSettings();
void toMap(QVariantMap &map) const override;
void fromMap(const QVariantMap &map) override;
@@ -71,121 +69,49 @@ signals:
* Base valgrind settings
*/
public:
QString valgrindExecutable() const;
QString valgrindArguments() const { return m_valgrindArguments; }
SelfModifyingCodeDetection selfModifyingCodeDetection() const;
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;
Utils::StringAspect valgrindExecutable;
Utils::StringAspect valgrindArguments;
Utils::SelectionAspect selfModifyingCodeDetection;
/**
* Base memcheck settings
*/
public:
QString memcheckArguments() const { return m_memcheckArguments; }
int numCallers() const { return m_numCallers; }
LeakCheckOnFinish leakCheckOnFinish() const { return m_leakCheckOnFinish; }
bool showReachable() const { return m_showReachable; }
bool trackOrigins() const { return m_trackOrigins; }
bool filterExternalIssues() const { return m_filterExternalIssues; }
QList<int> visibleErrorKinds() const { return m_visibleErrorKinds; }
Utils::StringAspect memcheckArguments;
Utils::IntegerAspect numCallers;
Utils::SelectionAspect leakCheckOnFinish;
Utils::BoolAspect showReachable;
Utils::BoolAspect trackOrigins;
Utils::BoolAspect filterExternalIssues;
Utils::IntegersAspect visibleErrorKinds;
virtual QStringList suppressionFiles() const = 0;
virtual void addSuppressionFiles(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> &);
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 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
*/
public:
QString callgrindArguments() const { return m_callgrindArguments;}
QString kcachegrindExecutable() const;
Utils::StringAspect callgrindArguments;
Utils::StringAspect kcachegrindExecutable;
bool enableCacheSim() const { return m_enableCacheSim; }
bool enableBranchSim() const { return m_enableBranchSim; }
bool collectSystime() const { return m_collectSystime; }
bool collectBusEvents() const { return m_collectBusEvents; }
bool enableEventToolTips() const { return m_enableEventToolTips; }
Utils::BoolAspect enableCacheSim;
Utils::BoolAspect enableBranchSim;
Utils::BoolAspect collectSystime;
Utils::BoolAspect collectBusEvents;
Utils::BoolAspect enableEventToolTips;
Utils::DoubleAspect minimumInclusiveCostRatio;
Utils::DoubleAspect visualizationMinimumInclusiveCostRatio;
/// \return Minimum cost ratio, range [0.0..100.0]
double minimumInclusiveCostRatio() const { return m_minimumInclusiveCostRatio; }
/// \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;
Utils::AspectContainer group;
QVariantMap defaultSettings() const;
};
@@ -201,50 +127,28 @@ public:
static ValgrindGlobalSettings *instance();
void toMap(QVariantMap &map) const override;
void fromMap(const QVariantMap &map) override;
/*
/**
* Global memcheck settings
*/
public:
QStringList suppressionFiles() const override;
// in the global settings we change the internal list directly
void addSuppressionFiles(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 readSettings();
private:
QStringList m_suppressionFiles;
QString m_lastSuppressionDirectory;
QStringList m_lastSuppressionHistory;
Utils::StringListAspect suppressionFiles_;
Utils::StringAspect lastSuppressionDirectory;
Utils::StringAspect lastSuppressionHistory;
/**
* Global callgrind settings
*/
public:
CostDelegate::CostFormat costFormat() const;
bool detectCycles() const;
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;
Utils::SelectionAspect costFormat;
Utils::BoolAspect detectCycles;
Utils::BoolAspect shortenTemplates;
};
@@ -258,26 +162,17 @@ class ValgrindProjectSettings : public ValgrindBaseSettings
public:
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
*/
public:
QStringList suppressionFiles() const override;
// in the project-specific settings we store a diff to the global list
void addSuppressionFiles(const QStringList &suppressions) override;
void removeSuppressionFiles(const QStringList &suppressions) override;
private:
QStringList m_disabledGlobalSuppressionFiles;
QStringList m_addedSuppressionFiles;
/**
* Per-project callgrind settings, saves a diff to the global suppression files list
*/
Utils::StringListAspect disabledGlobalSuppressionFiles;
Utils::StringListAspect addedSuppressionFiles;
};
} // namespace Internal