forked from qt-creator/qt-creator
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 <riitta-leena.miettinen@digia.com> Reviewed-by: hjk <hjk121@nokiamail.com>
This commit is contained in:
@@ -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">
|
||||
<item row="1" column="0">
|
||||
<widget class="QLabel" name="smcDetectionLabel">
|
||||
<property name="text">
|
||||
<string>Backtrace frame count:</string>
|
||||
</property>
|
||||
<property name="buddy">
|
||||
<cstring>numCallers</cstring>
|
||||
<string>Detect self-modifying code:</string>
|
||||
</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 row="1" column="1">
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_2">
|
||||
<item>
|
||||
<widget class="QListView" name="suppressionList">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Expanding" vsizetype="Expanding">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>1</verstretch>
|
||||
</sizepolicy>
|
||||
<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>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_2" stretch="0,0,1">
|
||||
<property name="sizeConstraint">
|
||||
<enum>QLayout::SetMinimumSize</enum>
|
||||
<spacer name="horizontalSpacer">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</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>
|
||||
<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;
|
||||
|
||||
|
||||
/**
|
||||
|
||||
Reference in New Issue
Block a user