Commit 548319c5 authored by Nikolai Kosjar's avatar Nikolai Kosjar Committed by hjk

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: default avatarLeena Miettinen <riitta-leena.miettinen@digia.com>
Reviewed-by: default avatarhjk <hjk121@nokiamail.com>
parent 00de61a7
......@@ -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());
......
......@@ -6,8 +6,8 @@
<rect>
<x>0</x>
<y>0</y>
<width>597</width>
<height>312</height>
<width>628</width>
<height>368</height>
</rect>
</property>
<layout class="QGridLayout" name="gridLayout">
......@@ -22,15 +22,15 @@
<property name="title">
<string>Generic Settings</string>
</property>
<layout class="QHBoxLayout" name="horizontalLayout_2">
<item>
<layout class="QGridLayout" name="gridLayout_2">
<item row="0" column="0">
<widget class="QLabel" name="valgrindExeLabel">
<property name="text">
<string>Valgrind executable:</string>
</property>
</widget>
</item>
<item>
<item row="0" column="1">
<widget class="Utils::PathChooser" name="valgrindExeChooser" native="true">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
......@@ -40,118 +40,57 @@
</property>
</widget>
</item>
</layout>
</widget>
</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>Memory Analysis Options</string>
</property>
<layout class="QFormLayout" name="formLayout_4">
<property name="fieldGrowthPolicy">
<enum>QFormLayout::ExpandingFieldsGrow</enum>
</property>
<item row="2" 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="3" column="0">
<widget class="QLabel" name="label">
<item row="1" column="0">
<widget class="QLabel" name="smcDetectionLabel">
<property name="text">
<string>Suppression files:</string>
</property>
<property name="buddy">
<cstring>suppressionList</cstring>
<string>Detect self-modifying code:</string>
</property>
</widget>
</item>
<item row="4" 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 row="1" column="1">
<layout class="QHBoxLayout" name="horizontalLayout_2">
<item>
<layout class="QVBoxLayout" name="verticalLayout_2" stretch="0,0,1">
<property name="sizeConstraint">
<enum>QLayout::SetMinimumSize</enum>
<widget class="QComboBox" name="smcDetectionComboBox">
<property name="currentIndex">
<number>1</number>
</property>
<item>
<widget class="QPushButton" name="addSuppression">
<property name="text">
<string>Add...</string>
</property>
</widget>
<property name="text">
<string>No</string>
</property>
</item>
<item>
<widget class="QPushButton" name="removeSuppression">
<property name="text">
<string>Remove</string>
</property>
<property name="flat">
<bool>false</bool>
</property>
</widget>
<property name="text">
<string>Only on Stack</string>
</property>
</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>
<property name="text">
<string>Everywhere</string>
</property>
</item>
</layout>
<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="2" column="1">
<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 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>
</layout>
</widget>
</item>
......@@ -309,6 +248,118 @@ With cache simulation, further event counters are enabled:
</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>Memory Analysis Options</string>
</property>
<layout class="QFormLayout" name="formLayout_4">
<property name="fieldGrowthPolicy">
<enum>QFormLayout::ExpandingFieldsGrow</enum>
</property>
<item row="2" 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="3" 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="4" 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="2" column="1">
<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 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>
</layout>
</widget>
</item>
</layout>
</widget>
<customwidgets>
......
......@@ -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();
......
......@@ -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;
};
......
......@@ -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);
......
......@@ -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;
/**
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment