37
37
#include <analyzerbase/analyzermanager.h>
38
38
#include <analyzerbase/analyzerconstants.h>
40
#include <valgrind/valgrindsettings.h>
40
41
#include <valgrind/xmlprotocol/errorlistmodel.h>
41
42
#include <valgrind/xmlprotocol/stackmodel.h>
42
43
#include <valgrind/xmlprotocol/error.h>
138
140
if (m_filterExternalIssues && !error.stacks().isEmpty()) {
139
141
// ALGORITHM: look at last five stack frames, if none of these is inside any open projects,
140
142
// assume this error was created by an external library
141
SessionManager *session = ProjectExplorerPlugin::instance()->session();
142
143
QSet<QString> validFolders;
143
foreach (Project *project, session->projects()) {
144
foreach (Project *project, SessionManager::projects()) {
144
145
validFolders << project->projectDirectory();
145
146
foreach (Target *target, project->targets()) {
146
147
foreach (BuildConfiguration *config, target->buildConfigurations())
147
validFolders << config->buildDirectory();
148
validFolders << config->buildDirectory().toString();
220
221
void MemcheckTool::settingsDestroyed(QObject *settings)
222
223
QTC_ASSERT(m_settings == settings, return);
223
m_settings = AnalyzerGlobalSettings::instance();
224
m_settings = ValgrindPlugin::globalSettings();
227
void MemcheckTool::updateFromSettings()
229
foreach (QAction *action, m_errorFilterActions) {
230
bool contained = true;
231
foreach (const QVariant &v, action->data().toList()) {
233
int kind = v.toInt(&ok);
234
if (ok && !m_settings->visibleErrorKinds().contains(kind))
237
action->setChecked(contained);
240
m_filterProjectAction->setChecked(!m_settings->filterExternalIssues());
241
m_errorView->settingsChanged(m_settings);
243
connect(m_settings, SIGNAL(visibleErrorKindsChanged(QList<int>)),
244
m_errorProxyModel, SLOT(setAcceptedKinds(QList<int>)));
245
m_errorProxyModel->setAcceptedKinds(m_settings->visibleErrorKinds());
247
connect(m_settings, SIGNAL(filterExternalIssuesChanged(bool)),
248
m_errorProxyModel, SLOT(setFilterExternalIssues(bool)));
249
m_errorProxyModel->setFilterExternalIssues(m_settings->filterExternalIssues());
226
252
void MemcheckTool::maybeActiveRunConfigurationChanged()
228
AnalyzerSettings *settings = 0;
229
ProjectExplorerPlugin *pe = ProjectExplorerPlugin::instance();
230
if (Project *project = pe->startupProject())
254
ValgrindBaseSettings *settings = 0;
255
if (Project *project = SessionManager::startupProject())
231
256
if (Target *target = project->activeTarget())
232
257
if (RunConfiguration *rc = target->activeRunConfiguration())
233
settings = rc->extraAspect<AnalyzerRunConfigurationAspect>();
258
if (IRunConfigurationAspect *aspect = rc->extraAspect(ANALYZER_VALGRIND_SETTINGS))
259
settings = qobject_cast<ValgrindBaseSettings *>(aspect->currentSettings());
235
261
if (!settings) // fallback to global settings
236
settings = AnalyzerGlobalSettings::instance();
262
settings = ValgrindPlugin::globalSettings();
238
264
if (m_settings == settings)
247
273
// now make the new settings current, update and connect input widgets
248
274
m_settings = settings;
249
275
QTC_ASSERT(m_settings, return);
251
276
connect(m_settings, SIGNAL(destroyed(QObject*)), SLOT(settingsDestroyed(QObject*)));
253
ValgrindBaseSettings *memcheckSettings = m_settings->subConfig<ValgrindBaseSettings>();
254
QTC_ASSERT(memcheckSettings, return);
256
foreach (QAction *action, m_errorFilterActions) {
257
bool contained = true;
258
foreach (const QVariant &v, action->data().toList()) {
260
int kind = v.toInt(&ok);
261
if (ok && !memcheckSettings->visibleErrorKinds().contains(kind))
264
action->setChecked(contained);
267
m_filterProjectAction->setChecked(!memcheckSettings->filterExternalIssues());
268
m_errorView->settingsChanged(m_settings);
270
connect(memcheckSettings, SIGNAL(visibleErrorKindsChanged(QList<int>)),
271
m_errorProxyModel, SLOT(setAcceptedKinds(QList<int>)));
272
m_errorProxyModel->setAcceptedKinds(memcheckSettings->visibleErrorKinds());
274
connect(memcheckSettings, SIGNAL(filterExternalIssuesChanged(bool)),
275
m_errorProxyModel, SLOT(setFilterExternalIssues(bool)));
276
m_errorProxyModel->setFilterExternalIssues(memcheckSettings->filterExternalIssues());
279
Core::Id MemcheckTool::id() const
281
return Core::Id("Memcheck");
278
updateFromSettings();
284
281
RunMode MemcheckTool::runMode() const
286
283
return MemcheckRunMode;
289
QString MemcheckTool::displayName() const
291
return tr("Valgrind Memory Analyzer");
294
QString MemcheckTool::description() const
296
return tr("Valgrind Analyze Memory uses the \"memcheck\" tool to find "
300
AbstractAnalyzerSubConfig *MemcheckTool::createGlobalSettings()
302
return new ValgrindGlobalSettings();
305
AbstractAnalyzerSubConfig *MemcheckTool::createProjectSettings()
307
return new ValgrindProjectSettings();
310
286
IAnalyzerTool::ToolMode MemcheckTool::toolMode() const
312
288
return DebugMode;
401
377
layout->setMargin(0);
402
378
layout->setSpacing(0);
380
// Load external XML log file
381
action = new QAction(this);
382
action->setIcon(QIcon(QLatin1String(Core::Constants::ICON_OPENFILE)));
383
action->setToolTip(tr("Load External XML Log File"));
384
connect(action, SIGNAL(triggered(bool)), this, SLOT(loadExternalXmlLogFile()));
385
button = new QToolButton;
386
button->setDefaultAction(action);
387
layout->addWidget(button);
388
m_loadExternalLogFile = action;
404
390
// Go to previous leak.
405
391
action = new QAction(this);
406
392
action->setDisabled(true);
448
IAnalyzerEngine *MemcheckTool::createEngine(const AnalyzerStartParameters &sp,
434
AnalyzerRunControl *MemcheckTool::createRunControl(const AnalyzerStartParameters &sp,
449
435
RunConfiguration *runConfiguration)
451
437
m_frameFinder->setFiles(runConfiguration ? runConfiguration->target()
452
438
->project()->files(Project::AllFiles) : QStringList());
454
MemcheckEngine *engine = new MemcheckEngine(this, sp, runConfiguration);
440
MemcheckRunControl *engine = new MemcheckRunControl(sp, runConfiguration);
456
connect(engine, SIGNAL(starting(const Analyzer::IAnalyzerEngine*)),
457
this, SLOT(engineStarting(const Analyzer::IAnalyzerEngine*)));
442
connect(engine, SIGNAL(starting(const Analyzer::AnalyzerRunControl*)),
443
this, SLOT(engineStarting(const Analyzer::AnalyzerRunControl*)));
458
444
connect(engine, SIGNAL(parserError(Valgrind::XmlProtocol::Error)),
459
445
this, SLOT(parserError(Valgrind::XmlProtocol::Error)));
460
446
connect(engine, SIGNAL(internalParserError(QString)),
461
447
this, SLOT(internalParserError(QString)));
462
connect(engine, SIGNAL(finished()), this, SLOT(finished()));
463
AnalyzerManager::showStatusMessage(AnalyzerManager::msgToolStarted(displayName()));
448
connect(engine, SIGNAL(finished()), this, SLOT(engineFinished()));
467
void MemcheckTool::startTool(StartMode mode)
469
ValgrindPlugin::startValgrindTool(this, mode);
472
void MemcheckTool::engineStarting(const IAnalyzerEngine *engine)
452
void MemcheckTool::engineStarting(const AnalyzerRunControl *engine)
474
454
setBusyCursor(true);
475
455
clearErrorView();
456
m_loadExternalLogFile->setDisabled(true);
478
459
if (RunConfiguration *rc = engine->runConfiguration())
479
460
dir = rc->target()->project()->projectDirectory() + QDir::separator();
481
const MemcheckEngine *mEngine = dynamic_cast<const MemcheckEngine *>(engine);
462
const MemcheckRunControl *mEngine = dynamic_cast<const MemcheckRunControl *>(engine);
482
463
QTC_ASSERT(mEngine, return);
483
464
const QString name = QFileInfo(mEngine->executable()).fileName();
504
485
Core::EditorManager::openEditorAt(file, 0);
488
void MemcheckTool::loadExternalXmlLogFile()
490
const QString filePath = QFileDialog::getOpenFileName(
491
Core::ICore::mainWindow(),
492
tr("Open Memcheck XML Log File"),
494
tr("XML Files (*.xml);;All Files (*)"));
495
if (filePath.isEmpty())
498
QFile *logFile = new QFile(filePath);
499
if (!logFile->open(QIODevice::ReadOnly | QIODevice::Text)) {
501
QMessageBox::critical(m_errorView, tr("Internal Error"),
502
tr("Failed to open file for reading: %1").arg(filePath));
508
m_loadExternalLogFile->setDisabled(true);
510
if (!m_settings || m_settings != ValgrindPlugin::globalSettings()) {
511
m_settings = ValgrindPlugin::globalSettings();
512
m_errorView->settingsChanged(m_settings);
513
updateFromSettings();
516
ThreadedParser *parser = new ThreadedParser;
517
connect(parser, SIGNAL(error(Valgrind::XmlProtocol::Error)),
518
this, SLOT(parserError(Valgrind::XmlProtocol::Error)));
519
connect(parser, SIGNAL(internalError(QString)),
520
this, SLOT(internalParserError(QString)));
521
connect(parser, SIGNAL(finished()), this, SLOT(loadingExternalXmlLogFileFinished()));
522
connect(parser, SIGNAL(finished()), parser, SLOT(deleteLater()));
524
parser->parse(logFile); // ThreadedParser owns the file
507
527
void MemcheckTool::parserError(const Valgrind::XmlProtocol::Error &error)
509
529
m_errorModel->addError(error);
512
532
void MemcheckTool::internalParserError(const QString &errorString)
514
534
QMessageBox::critical(m_errorView, tr("Internal Error"),
515
tr("Error occurred parsing valgrind output: %1").arg(errorString));
535
tr("Error occurred parsing Valgrind output: %1").arg(errorString));
518
538
void MemcheckTool::clearErrorView()
530
550
QTC_ASSERT(m_errorView, return);
531
551
QTC_ASSERT(m_settings, return);
533
ValgrindBaseSettings *memcheckSettings = m_settings->subConfig<ValgrindBaseSettings>();
534
QTC_ASSERT(memcheckSettings, return);
535
memcheckSettings->setFilterExternalIssues(!m_filterProjectAction->isChecked());
553
m_settings->setFilterExternalIssues(!m_filterProjectAction->isChecked());
537
555
QList<int> errorKinds;
538
556
foreach (QAction *a, m_errorFilterActions) {
545
563
errorKinds << kind;
548
memcheckSettings->setVisibleErrorKinds(errorKinds);
566
m_settings->setVisibleErrorKinds(errorKinds);
551
void MemcheckTool::finished()
569
int MemcheckTool::updateUiAfterFinishedHelper()
553
const int n = m_errorModel->rowCount();
554
m_goBack->setEnabled(n > 1);
555
m_goNext->setEnabled(n > 1);
556
const QString msg = AnalyzerManager::msgToolFinished(displayName(), n);
557
AnalyzerManager::showStatusMessage(msg);
571
const int issuesFound = m_errorModel->rowCount();
572
m_goBack->setEnabled(issuesFound > 1);
573
m_goNext->setEnabled(issuesFound > 1);
574
m_loadExternalLogFile->setEnabled(true);
558
575
setBusyCursor(false);
579
void MemcheckTool::engineFinished()
581
const int issuesFound = updateUiAfterFinishedHelper();
582
AnalyzerManager::showStatusMessage(issuesFound > 0
583
? AnalyzerManager::tr("Memory Analyzer Tool finished, %n issues were found.", 0, issuesFound)
584
: AnalyzerManager::tr("Memory Analyzer Tool finished, no issues were found."));
587
void MemcheckTool::loadingExternalXmlLogFileFinished()
589
const int issuesFound = updateUiAfterFinishedHelper();
590
AnalyzerManager::showStatusMessage(issuesFound > 0
591
? AnalyzerManager::tr("Log file processed, %n issues were found.", 0, issuesFound)
592
: AnalyzerManager::tr("Log file processed, no issues were found."));
561
595
void MemcheckTool::setBusyCursor(bool busy)