diff --git a/src/plugins/valgrind/valgrindconfigwidget.cpp b/src/plugins/valgrind/valgrindconfigwidget.cpp
index 1817ab1ca9d99c6203b9ddf222daaebf8d3cf9b7..bd35b5a044505eb2d5593794aa9afaf3e67cddd8 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 0b8bd1a07c8e3256fc0e3f4bf5fd7fe1ae0778ff..454f28fc3d0cb7e6c90c28cc4139bd939a8eadac 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 5717f0e3940c16cb21f7efe366d58791df2b5da4..b36d5230c05761bffd33941f44f636b479c75f16 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 03c284630a928d98f8a2aaf001f4032594d2c60b..335b5879477d8feaf74fa1d84e7df9813c0bf20b 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 0756c561e648bf1a1afcd766488c34f53f256919..e771e11dc79f50f73ed806b873faeeba24b0a093 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 e090e6e62105425eac218244c7f82b366c679c06..9dd3b738b481cd24cc786abca106386ff8ab5386 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;
/**