From 548319c5235aba389f12baa8791cb0378d5ae5fd Mon Sep 17 00:00:00 2001 From: Nikolai Kosjar Date: Fri, 6 Sep 2013 16:33:48 +0200 Subject: [PATCH] Valgrind: Add gui option "Detect self-modifying code" Setting this option to e.g. "Everywhere Except in File-backend Mappings" allows to 'valgrind' Qt Creator itself. Without that option the valgrind process will die if certain code paths are executed. Change-Id: I8888456d324a25ce092f0b0128407adf2159f496 Reviewed-by: Leena Miettinen Reviewed-by: hjk --- src/plugins/valgrind/valgrindconfigwidget.cpp | 3 + src/plugins/valgrind/valgrindconfigwidget.ui | 255 +++++++++++------- src/plugins/valgrind/valgrindengine.cpp | 24 +- src/plugins/valgrind/valgrindengine.h | 3 + src/plugins/valgrind/valgrindsettings.cpp | 18 ++ src/plugins/valgrind/valgrindsettings.h | 11 + 6 files changed, 211 insertions(+), 103 deletions(-) diff --git a/src/plugins/valgrind/valgrindconfigwidget.cpp b/src/plugins/valgrind/valgrindconfigwidget.cpp index 1817ab1ca9..bd35b5a044 100644 --- a/src/plugins/valgrind/valgrindconfigwidget.cpp +++ b/src/plugins/valgrind/valgrindconfigwidget.cpp @@ -64,6 +64,8 @@ ValgrindConfigWidget::ValgrindConfigWidget(ValgrindBaseSettings *settings, m_settings, SLOT(setValgrindExecutable(QString))); connect(m_settings, SIGNAL(valgrindExecutableChanged(QString)), m_ui->valgrindExeChooser, SLOT(setPath(QString))); + connect(m_ui->smcDetectionComboBox, SIGNAL(currentIndexChanged(int)), + m_settings, SLOT(setSelfModifyingCodeDetection(int))); if (Utils::HostOsInfo::isWindowsHost()) { // FIXME: On Window we know that we don't have a local valgrind @@ -158,6 +160,7 @@ ValgrindConfigWidget::~ValgrindConfigWidget() void ValgrindConfigWidget::updateUi() { m_ui->valgrindExeChooser->setPath(m_settings->valgrindExecutable()); + m_ui->smcDetectionComboBox->setCurrentIndex(m_settings->selfModifyingCodeDetection()); m_ui->enableCacheSim->setChecked(m_settings->enableCacheSim()); m_ui->enableBranchSim->setChecked(m_settings->enableBranchSim()); m_ui->collectSystime->setChecked(m_settings->collectSystime()); diff --git a/src/plugins/valgrind/valgrindconfigwidget.ui b/src/plugins/valgrind/valgrindconfigwidget.ui index 0b8bd1a07c..454f28fc3d 100644 --- a/src/plugins/valgrind/valgrindconfigwidget.ui +++ b/src/plugins/valgrind/valgrindconfigwidget.ui @@ -6,8 +6,8 @@ 0 0 - 597 - 312 + 628 + 368 @@ -22,15 +22,15 @@ Generic Settings - - + + Valgrind executable: - + @@ -40,118 +40,57 @@ - - - - - - - - 0 - 0 - - - - Memory Analysis Options - - - - QFormLayout::ExpandingFieldsGrow - - - - - Backtrace frame count: - - - numCallers - - - - - + + - Suppression files: - - - suppressionList + Detect self-modifying code: - - - - - - - 0 - 1 - - - - + + - - - QLayout::SetMinimumSize + + + 1 - - - Add... - - + + No + - - - Remove - - - false - - + + Only on Stack + - - - Qt::Vertical - - - - 20 - 40 - - - + + Everywhere + - + + + Everywhere Except in File-backend Mappings + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + - - - - 5 - - - 50 - - - 12 - - - - - - - Track origins of uninitialized memory - - - true - - - @@ -309,6 +248,118 @@ With cache simulation, further event counters are enabled: + + + + + 0 + 0 + + + + Memory Analysis Options + + + + QFormLayout::ExpandingFieldsGrow + + + + + Backtrace frame count: + + + numCallers + + + + + + + Suppression files: + + + suppressionList + + + + + + + + + + 0 + 1 + + + + + + + + QLayout::SetMinimumSize + + + + + Add... + + + + + + + Remove + + + false + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + + + + + + + 5 + + + 50 + + + 12 + + + + + + + Track origins of uninitialized memory + + + true + + + + + + diff --git a/src/plugins/valgrind/valgrindengine.cpp b/src/plugins/valgrind/valgrindengine.cpp index 5717f0e394..b36d5230c0 100644 --- a/src/plugins/valgrind/valgrindengine.cpp +++ b/src/plugins/valgrind/valgrindengine.cpp @@ -106,7 +106,7 @@ bool ValgrindRunControl::startEngine() if (!sp.analyzerCmdPrefix.isEmpty()) valgrindExe = sp.analyzerCmdPrefix + QLatin1Char(' ') + valgrindExe; run->setValgrindExecutable(valgrindExe); - run->setValgrindArguments(toolArguments()); + run->setValgrindArguments(genericToolArguments() + toolArguments()); run->setDebuggeeExecutable(sp.debuggee); run->setDebuggeeArguments(sp.debuggeeArgs); run->setEnvironment(sp.environment); @@ -137,6 +137,28 @@ QString ValgrindRunControl::executable() const return startParameters().debuggee; } +QStringList ValgrindRunControl::genericToolArguments() const +{ + QTC_ASSERT(m_settings, return QStringList()); + QString smcCheckValue; + switch (m_settings->selfModifyingCodeDetection()) { + case ValgrindBaseSettings::DetectSmcNo: + smcCheckValue = QLatin1String("none"); + break; + case ValgrindBaseSettings::DetectSmcEverywhere: + smcCheckValue = QLatin1String("all"); + break; + case ValgrindBaseSettings::DetectSmcEverywhereButFile: + smcCheckValue = QLatin1String("all-non-file"); + break; + case ValgrindBaseSettings::DetectSmcStackOnly: + default: + smcCheckValue = QLatin1String("stack"); + break; + } + return QStringList() << QLatin1String("--smc-check=") + smcCheckValue; +} + void ValgrindRunControl::handleProgressCanceled() { AnalyzerManager::stopTool(); diff --git a/src/plugins/valgrind/valgrindengine.h b/src/plugins/valgrind/valgrindengine.h index 03c284630a..335b587947 100644 --- a/src/plugins/valgrind/valgrindengine.h +++ b/src/plugins/valgrind/valgrindengine.h @@ -73,6 +73,9 @@ private slots: void receiveProcessOutput(const QByteArray &output, Utils::OutputFormat format); void receiveProcessError(const QString &message, QProcess::ProcessError error); +private: + QStringList genericToolArguments() const; + private: bool m_isStopping; }; diff --git a/src/plugins/valgrind/valgrindsettings.cpp b/src/plugins/valgrind/valgrindsettings.cpp index 0756c561e6..e771e11dc7 100644 --- a/src/plugins/valgrind/valgrindsettings.cpp +++ b/src/plugins/valgrind/valgrindsettings.cpp @@ -44,6 +44,7 @@ using namespace Analyzer; const char numCallersC[] = "Analyzer.Valgrind.NumCallers"; 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"; @@ -89,6 +90,8 @@ void ValgrindBaseSettings::fromMap(const QVariantMap &map) { // General setIfPresent(map, QLatin1String(valgrindExeC), &m_valgrindExecutable); + setIfPresent(map, QLatin1String(selfModifyingCodeDetectionC), + (int*) &m_selfModifyingCodeDetection); // Memcheck setIfPresent(map, QLatin1String(numCallersC), &m_numCallers); @@ -117,6 +120,7 @@ void ValgrindBaseSettings::toMap(QVariantMap &map) const { // General map.insert(QLatin1String(valgrindExeC), m_valgrindExecutable); + map.insert(QLatin1String(selfModifyingCodeDetectionC), m_selfModifyingCodeDetection); // Memcheck map.insert(QLatin1String(numCallersC), m_numCallers); @@ -146,11 +150,24 @@ void ValgrindBaseSettings::setValgrindExecutable(const QString &valgrindExecutab } } +void ValgrindBaseSettings::setSelfModifyingCodeDetection(int smcDetection) +{ + if (m_selfModifyingCodeDetection != smcDetection) { + m_selfModifyingCodeDetection = (SelfModifyingCodeDetection) smcDetection; + emit selfModifyingCodeDetectionChanged(smcDetection); + } +} + QString ValgrindBaseSettings::valgrindExecutable() const { return m_valgrindExecutable; } +ValgrindBaseSettings::SelfModifyingCodeDetection ValgrindBaseSettings::selfModifyingCodeDetection() const +{ + return m_selfModifyingCodeDetection; +} + void ValgrindBaseSettings::setNumCallers(int numCallers) { if (m_numCallers != numCallers) { @@ -347,6 +364,7 @@ void ValgrindGlobalSettings::readSettings() // General defaults.insert(QLatin1String(valgrindExeC), QLatin1String("valgrind")); + defaults.insert(QLatin1String(selfModifyingCodeDetectionC), DetectSmcStackOnly); // Memcheck defaults.insert(QLatin1String(numCallersC), 25); diff --git a/src/plugins/valgrind/valgrindsettings.h b/src/plugins/valgrind/valgrindsettings.h index e090e6e621..9dd3b738b4 100644 --- a/src/plugins/valgrind/valgrindsettings.h +++ b/src/plugins/valgrind/valgrindsettings.h @@ -51,6 +51,13 @@ class ValgrindBaseSettings : public ProjectExplorer::ISettingsAspect Q_OBJECT public: + enum SelfModifyingCodeDetection { + DetectSmcNo, + DetectSmcStackOnly, + DetectSmcEverywhere, + DetectSmcEverywhereButFile + }; + ValgrindBaseSettings() {} void toMap(QVariantMap &map) const; @@ -64,15 +71,19 @@ signals: */ public: QString valgrindExecutable() const; + SelfModifyingCodeDetection selfModifyingCodeDetection() const; public slots: void setValgrindExecutable(const QString &); + void setSelfModifyingCodeDetection(int); signals: void valgrindExecutableChanged(const QString &); + void selfModifyingCodeDetectionChanged(int); private: QString m_valgrindExecutable; + SelfModifyingCodeDetection m_selfModifyingCodeDetection; /** -- GitLab