From c5cc771656b068cec6ed253dbe010bf363d3fcc8 Mon Sep 17 00:00:00 2001 From: hjk Date: Wed, 17 Feb 2021 11:00:36 +0100 Subject: [PATCH] Valgrind: Allow specifying extra arguments to valgrind etc Fixes: QTCREATORBUG-18693 Change-Id: Ibb968dcd82b118340a45329b4a14b28d85700661 Reviewed-by: Christian Stenger --- .../src/analyze/creator-valgrind.qdoc | 7 +- src/plugins/valgrind/callgrindengine.cpp | 3 + src/plugins/valgrind/memchecktool.cpp | 2 + src/plugins/valgrind/valgrindconfigwidget.cpp | 19 + src/plugins/valgrind/valgrindconfigwidget.ui | 486 ++++++++++-------- src/plugins/valgrind/valgrindengine.cpp | 1 + src/plugins/valgrind/valgrindsettings.cpp | 36 ++ src/plugins/valgrind/valgrindsettings.h | 12 + 8 files changed, 335 insertions(+), 231 deletions(-) diff --git a/doc/qtcreator/src/analyze/creator-valgrind.qdoc b/doc/qtcreator/src/analyze/creator-valgrind.qdoc index 210ea15f123..da0952f3175 100644 --- a/doc/qtcreator/src/analyze/creator-valgrind.qdoc +++ b/doc/qtcreator/src/analyze/creator-valgrind.qdoc @@ -131,7 +131,8 @@ You can write your own suppression files if parts of your project contain errors you cannot fix and you do not want to be reminded of them. Click - \uicontrol Add in the \uicontrol {Memory Analysis} dialog to add the suppression files. + \uicontrol Add in the \uicontrol {MemCheck Memory Analysis} dialog to add + the suppression files. For more information about writing suppression files, see \l{http://valgrind.org/docs/manual/manual-core.html#manual-core.suppress} {Suppressing Errors} in the Valgrind documentation. @@ -220,8 +221,8 @@ of the project. To specify settings for Valgrind, select \uicontrol Tools > - \uicontrol Options > \uicontrol Analyzer. The \uicontrol {Profiling Options} - group contains Callgrind options. + \uicontrol Options > \uicontrol Analyzer. The \uicontrol + {Callgrind Profiling Options} group contains Callgrind options. \image qtcreator-valgrind-callgrind-options.png "Valgrind options" diff --git a/src/plugins/valgrind/callgrindengine.cpp b/src/plugins/valgrind/callgrindengine.cpp index 22512b7438f..2bf80550fbf 100644 --- a/src/plugins/valgrind/callgrindengine.cpp +++ b/src/plugins/valgrind/callgrindengine.cpp @@ -35,6 +35,7 @@ #include #include +#include using namespace ProjectExplorer; using namespace Valgrind::Callgrind; @@ -96,6 +97,8 @@ QStringList CallgrindToolRunner::toolArguments() const if (!m_argumentForToggleCollect.isEmpty()) arguments << m_argumentForToggleCollect; + arguments << Utils::QtcProcess::splitArgs(m_settings.callgrindArguments()); + return arguments; } diff --git a/src/plugins/valgrind/memchecktool.cpp b/src/plugins/valgrind/memchecktool.cpp index 7e4e7b82fc9..418728e642a 100644 --- a/src/plugins/valgrind/memchecktool.cpp +++ b/src/plugins/valgrind/memchecktool.cpp @@ -220,6 +220,8 @@ QStringList MemcheckToolRunner::toolArguments() const if (m_withGdb) arguments << "--vgdb=yes" << "--vgdb-error=0"; + arguments << Utils::QtcProcess::splitArgs(m_settings.memcheckArguments()); + return arguments; } diff --git a/src/plugins/valgrind/valgrindconfigwidget.cpp b/src/plugins/valgrind/valgrindconfigwidget.cpp index 513f2925789..b3f9831a90b 100644 --- a/src/plugins/valgrind/valgrindconfigwidget.cpp +++ b/src/plugins/valgrind/valgrindconfigwidget.cpp @@ -93,6 +93,12 @@ ValgrindConfigWidget::ValgrindConfigWidget(ValgrindBaseSettings *settings) connect(m_ui->valgrindExeChooser, &Utils::PathChooser::rawPathChanged, m_settings, &ValgrindBaseSettings::setValgrindExecutable); + + 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::of(&QComboBox::currentIndexChanged), m_settings, &ValgrindBaseSettings::setSelfModifyingCodeDetection); @@ -108,6 +114,11 @@ ValgrindConfigWidget::ValgrindConfigWidget(ValgrindBaseSettings *settings) // 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, @@ -151,6 +162,11 @@ ValgrindConfigWidget::ValgrindConfigWidget(ValgrindBaseSettings *settings) 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); @@ -204,6 +220,9 @@ ValgrindConfigWidget::~ValgrindConfigWidget() 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()); diff --git a/src/plugins/valgrind/valgrindconfigwidget.ui b/src/plugins/valgrind/valgrindconfigwidget.ui index f0fae915ef9..474cde18612 100644 --- a/src/plugins/valgrind/valgrindconfigwidget.ui +++ b/src/plugins/valgrind/valgrindconfigwidget.ui @@ -6,8 +6,8 @@ 0 0 - 708 - 397 + 727 + 658 @@ -20,34 +20,10 @@ - Generic Settings + Valgrind Generic Settings - - - - Valgrind executable: - - - - - - - - 1 - 0 - - - - - - - - Detect self-modifying code: - - - - + @@ -91,10 +67,249 @@ + + + + Valgrind executable: + + + + + + + + 1 + 0 + + + + + + + + Detect self-modifying code: + + + + + + + Valgrind arguments: + + + + + + - + + + + Qt::Vertical + + + QSizePolicy::Expanding + + + + 1 + 500 + + + + + + + + + 0 + 0 + + + + MemCheck Memory Analysis Options + + + + + + Track origins of uninitialized memory + + + true + + + + + + + Show reachable and indirectly lost blocks + + + + + + + Check for leaks on finish: + + + + + + + + + 0 + + + + No + + + + + Summary Only + + + + + Full + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + Backtrace frame count: + + + numCallers + + + + + + + + + 5 + + + 50 + + + 12 + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + Suppression files: + + + suppressionList + + + + + + + + + + 0 + 1 + + + + + + + + QLayout::SetMinimumSize + + + + + Add... + + + + + + + Remove + + + false + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + + + + + + + Extra MemCheck arguments: + + + + + + + + + + @@ -103,10 +318,10 @@ - Profiling Options + CallGrind Profiling Options - + Limits the amount of results the profiler gives you. A lower limit will likely increase performance. @@ -119,7 +334,7 @@ - + % @@ -135,7 +350,7 @@ - + Show additional information for events in tooltips @@ -203,14 +418,14 @@ With cache simulation, further event counters are enabled: - + Visualization: Minimum event cost: - + @@ -226,14 +441,14 @@ With cache simulation, further event counters are enabled: - - + + KCachegrind executable: - + @@ -243,200 +458,15 @@ With cache simulation, further event counters are enabled: - - - - - - - Qt::Vertical - - - QSizePolicy::Expanding - - - - 1 - 500 - - - - - - - - - 0 - 0 - - - - Memory Analysis Options - - - - + + - Track origins of uninitialized memory - - - true + Extra CallGrind arguments: - - - - Show reachable and indirectly lost blocks - - - - - - - Check for leaks on finish: - - - - - - - - - 0 - - - - No - - - - - Summary Only - - - - - Full - - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - - - Backtrace frame count: - - - numCallers - - - - - - - - - 5 - - - 50 - - - 12 - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - - - Suppression files: - - - suppressionList - - - - - - - - - - 0 - 1 - - - - - - - - QLayout::SetMinimumSize - - - - - Add... - - - - - - - Remove - - - false - - - - - - - Qt::Vertical - - - - 20 - 40 - - - - - - - + + diff --git a/src/plugins/valgrind/valgrindengine.cpp b/src/plugins/valgrind/valgrindengine.cpp index 41086584acf..5b6e378a0f5 100644 --- a/src/plugins/valgrind/valgrindengine.cpp +++ b/src/plugins/valgrind/valgrindengine.cpp @@ -78,6 +78,7 @@ void ValgrindToolRunner::start() #endif CommandLine valgrind{m_settings.valgrindExecutable()}; + valgrind.addArgs(m_settings.valgrindArguments(), CommandLine::Raw); valgrind.addArgs(genericToolArguments()); valgrind.addArgs(toolArguments()); diff --git a/src/plugins/valgrind/valgrindsettings.cpp b/src/plugins/valgrind/valgrindsettings.cpp index 5c3db87c8f4..72fd3418ea7 100644 --- a/src/plugins/valgrind/valgrindsettings.cpp +++ b/src/plugins/valgrind/valgrindsettings.cpp @@ -45,6 +45,7 @@ const char removedSuppressionFilesC[] = "Analyzer.Valgrind.RemovedSuppressionFil 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"; @@ -61,8 +62,10 @@ const char callgrindVisualisationMinimumCostRatioC[] = "Analyzer.Valgrind.Callgr 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 Internal { @@ -88,11 +91,13 @@ 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); @@ -104,6 +109,7 @@ void ValgrindBaseSettings::fromMap(const QVariantMap &map) } // Callgrind + setIfPresent(map, callgrindArgumentsC, &m_callgrindArguments); setIfPresent(map, kcachegrindExeC, &m_kcachegrindExecutable); setIfPresent(map, callgrindEnableCacheSimC, &m_enableCacheSim); setIfPresent(map, callgrindEnableBranchSimC, &m_enableBranchSim); @@ -121,9 +127,11 @@ 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); @@ -135,6 +143,7 @@ void ValgrindBaseSettings::toMap(QVariantMap &map) const 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); @@ -151,6 +160,14 @@ void ValgrindBaseSettings::setValgrindExecutable(const QString &valgrindExecutab 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) { @@ -159,6 +176,14 @@ void ValgrindBaseSettings::setSelfModifyingCodeDetection(int smcDetection) } } +void ValgrindBaseSettings::setMemcheckArguments(const QString &arguments) +{ + if (m_memcheckArguments != arguments) { + m_memcheckArguments = arguments; + emit memcheckArgumentsChanged(arguments); + } +} + QString ValgrindBaseSettings::valgrindExecutable() const { return m_valgrindExecutable; @@ -222,6 +247,14 @@ 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; @@ -396,9 +429,11 @@ void ValgrindGlobalSettings::readSettings() // General defaults.insert(valgrindExeC, "valgrind"); + defaults.insert(valgrindArgumentsC, QString()); defaults.insert(selfModifyingCodeDetectionC, DetectSmcStackOnly); // Memcheck + defaults.insert(memcheckArgumentsC, QString()); defaults.insert(numCallersC, 25); defaults.insert(leakCheckOnFinishC, LeakCheckOnFinishSummaryOnly); defaults.insert(showReachableC, false); @@ -414,6 +449,7 @@ void ValgrindGlobalSettings::readSettings() defaults.insert(lastSuppressionHistoryC, QStringList()); // Callgrind + defaults.insert(callgrindArgumentsC, QString()); defaults.insert(kcachegrindExeC, "kcachegrind"); defaults.insert(callgrindEnableCacheSimC, false); defaults.insert(callgrindEnableBranchSimC, false); diff --git a/src/plugins/valgrind/valgrindsettings.h b/src/plugins/valgrind/valgrindsettings.h index eb7311cb125..1f119b76698 100644 --- a/src/plugins/valgrind/valgrindsettings.h +++ b/src/plugins/valgrind/valgrindsettings.h @@ -72,16 +72,20 @@ signals: */ 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; @@ -89,6 +93,7 @@ private: * 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; } @@ -100,6 +105,7 @@ public: 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); @@ -108,6 +114,7 @@ public: void setVisibleErrorKinds(const QList &); signals: + void memcheckArgumentsChanged(const QString &arguments); void numCallersChanged(int); void leakCheckOnFinishChanged(int); void showReachableChanged(bool); @@ -118,6 +125,7 @@ signals: void suppressionFilesAdded(const QStringList &); protected: + QString m_memcheckArguments; int m_numCallers; LeakCheckOnFinish m_leakCheckOnFinish; bool m_showReachable; @@ -129,6 +137,7 @@ protected: * Base callgrind settings */ public: + QString callgrindArguments() const { return m_callgrindArguments;} QString kcachegrindExecutable() const; bool enableCacheSim() const { return m_enableCacheSim; } @@ -143,6 +152,7 @@ public: /// \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); @@ -157,6 +167,7 @@ public: void setVisualisationMinimumInclusiveCostRatio(double minimumInclusiveCostRatio); signals: + void callgrindArgumentsChanged(const QString &argumnts); void enableCacheSimChanged(bool); void enableBranchSimChanged(bool); void collectSystimeChanged(bool); @@ -166,6 +177,7 @@ signals: void visualisationMinimumInclusiveCostRatioChanged(double); private: + QString m_callgrindArguments; QString m_kcachegrindExecutable; bool m_enableCacheSim; bool m_collectSystime;