~bzoltan/kubuntu-packaging/decouple_cmake_plugin

« back to all changes in this revision

Viewing changes to src/plugins/valgrind/memchecktool.cpp

  • Committer: Timo Jyrinki
  • Date: 2013-11-15 12:25:23 UTC
  • mfrom: (1.1.28)
  • Revision ID: timo.jyrinki@canonical.com-20131115122523-i2kyamsu4gs2mu1m
New upstream release.

Show diffs side-by-side

added added

removed removed

Lines of Context:
37
37
#include <analyzerbase/analyzermanager.h>
38
38
#include <analyzerbase/analyzerconstants.h>
39
39
 
 
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>
68
69
 
69
70
#include <QString>
70
71
#include <QLatin1String>
 
72
#include <QFileDialog>
71
73
#include <QFileInfo>
72
74
#include <QFile>
73
75
#include <QDir>
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();
148
149
            }
149
150
        }
150
151
 
220
221
void MemcheckTool::settingsDestroyed(QObject *settings)
221
222
{
222
223
    QTC_ASSERT(m_settings == settings, return);
223
 
    m_settings = AnalyzerGlobalSettings::instance();
 
224
    m_settings = ValgrindPlugin::globalSettings();
 
225
}
 
226
 
 
227
void MemcheckTool::updateFromSettings()
 
228
{
 
229
    foreach (QAction *action, m_errorFilterActions) {
 
230
        bool contained = true;
 
231
        foreach (const QVariant &v, action->data().toList()) {
 
232
            bool ok;
 
233
            int kind = v.toInt(&ok);
 
234
            if (ok && !m_settings->visibleErrorKinds().contains(kind))
 
235
                contained = false;
 
236
        }
 
237
        action->setChecked(contained);
 
238
    }
 
239
 
 
240
    m_filterProjectAction->setChecked(!m_settings->filterExternalIssues());
 
241
    m_errorView->settingsChanged(m_settings);
 
242
 
 
243
    connect(m_settings, SIGNAL(visibleErrorKindsChanged(QList<int>)),
 
244
            m_errorProxyModel, SLOT(setAcceptedKinds(QList<int>)));
 
245
    m_errorProxyModel->setAcceptedKinds(m_settings->visibleErrorKinds());
 
246
 
 
247
    connect(m_settings, SIGNAL(filterExternalIssuesChanged(bool)),
 
248
            m_errorProxyModel, SLOT(setFilterExternalIssues(bool)));
 
249
    m_errorProxyModel->setFilterExternalIssues(m_settings->filterExternalIssues());
224
250
}
225
251
 
226
252
void MemcheckTool::maybeActiveRunConfigurationChanged()
227
253
{
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());
234
260
 
235
261
    if (!settings) // fallback to global settings
236
 
        settings = AnalyzerGlobalSettings::instance();
 
262
        settings = ValgrindPlugin::globalSettings();
237
263
 
238
264
    if (m_settings == settings)
239
265
        return;
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);
250
 
 
251
276
    connect(m_settings, SIGNAL(destroyed(QObject*)), SLOT(settingsDestroyed(QObject*)));
252
277
 
253
 
    ValgrindBaseSettings *memcheckSettings = m_settings->subConfig<ValgrindBaseSettings>();
254
 
    QTC_ASSERT(memcheckSettings, return);
255
 
 
256
 
    foreach (QAction *action, m_errorFilterActions) {
257
 
        bool contained = true;
258
 
        foreach (const QVariant &v, action->data().toList()) {
259
 
            bool ok;
260
 
            int kind = v.toInt(&ok);
261
 
            if (ok && !memcheckSettings->visibleErrorKinds().contains(kind))
262
 
                contained = false;
263
 
        }
264
 
        action->setChecked(contained);
265
 
    }
266
 
 
267
 
    m_filterProjectAction->setChecked(!memcheckSettings->filterExternalIssues());
268
 
    m_errorView->settingsChanged(m_settings);
269
 
 
270
 
    connect(memcheckSettings, SIGNAL(visibleErrorKindsChanged(QList<int>)),
271
 
            m_errorProxyModel, SLOT(setAcceptedKinds(QList<int>)));
272
 
    m_errorProxyModel->setAcceptedKinds(memcheckSettings->visibleErrorKinds());
273
 
 
274
 
    connect(memcheckSettings, SIGNAL(filterExternalIssuesChanged(bool)),
275
 
            m_errorProxyModel, SLOT(setFilterExternalIssues(bool)));
276
 
    m_errorProxyModel->setFilterExternalIssues(memcheckSettings->filterExternalIssues());
277
 
}
278
 
 
279
 
Core::Id MemcheckTool::id() const
280
 
{
281
 
    return Core::Id("Memcheck");
 
278
    updateFromSettings();
282
279
}
283
280
 
284
281
RunMode MemcheckTool::runMode() const
286
283
    return MemcheckRunMode;
287
284
}
288
285
 
289
 
QString MemcheckTool::displayName() const
290
 
{
291
 
    return tr("Valgrind Memory Analyzer");
292
 
}
293
 
 
294
 
QString MemcheckTool::description() const
295
 
{
296
 
    return tr("Valgrind Analyze Memory uses the \"memcheck\" tool to find "
297
 
              "memory leaks");
298
 
}
299
 
 
300
 
AbstractAnalyzerSubConfig *MemcheckTool::createGlobalSettings()
301
 
{
302
 
    return new ValgrindGlobalSettings();
303
 
}
304
 
 
305
 
AbstractAnalyzerSubConfig *MemcheckTool::createProjectSettings()
306
 
{
307
 
    return new ValgrindProjectSettings();
308
 
}
309
 
 
310
286
IAnalyzerTool::ToolMode MemcheckTool::toolMode() const
311
287
{
312
288
    return DebugMode;
401
377
    layout->setMargin(0);
402
378
    layout->setSpacing(0);
403
379
 
 
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;
 
389
 
404
390
    // Go to previous leak.
405
391
    action = new QAction(this);
406
392
    action->setDisabled(true);
445
431
    return widget;
446
432
}
447
433
 
448
 
IAnalyzerEngine *MemcheckTool::createEngine(const AnalyzerStartParameters &sp,
 
434
AnalyzerRunControl *MemcheckTool::createRunControl(const AnalyzerStartParameters &sp,
449
435
                                            RunConfiguration *runConfiguration)
450
436
{
451
437
    m_frameFinder->setFiles(runConfiguration ? runConfiguration->target()
452
438
        ->project()->files(Project::AllFiles) : QStringList());
453
439
 
454
 
    MemcheckEngine *engine = new MemcheckEngine(this, sp, runConfiguration);
 
440
    MemcheckRunControl *engine = new MemcheckRunControl(sp, runConfiguration);
455
441
 
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()));
464
449
    return engine;
465
450
}
466
451
 
467
 
void MemcheckTool::startTool(StartMode mode)
468
 
{
469
 
    ValgrindPlugin::startValgrindTool(this, mode);
470
 
}
471
 
 
472
 
void MemcheckTool::engineStarting(const IAnalyzerEngine *engine)
 
452
void MemcheckTool::engineStarting(const AnalyzerRunControl *engine)
473
453
{
474
454
    setBusyCursor(true);
475
455
    clearErrorView();
 
456
    m_loadExternalLogFile->setDisabled(true);
476
457
 
477
458
    QString dir;
478
459
    if (RunConfiguration *rc = engine->runConfiguration())
479
460
        dir = rc->target()->project()->projectDirectory() + QDir::separator();
480
461
 
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();
484
465
 
504
485
    Core::EditorManager::openEditorAt(file, 0);
505
486
}
506
487
 
 
488
void MemcheckTool::loadExternalXmlLogFile()
 
489
{
 
490
    const QString filePath = QFileDialog::getOpenFileName(
 
491
                Core::ICore::mainWindow(),
 
492
                tr("Open Memcheck XML Log File"),
 
493
                QString(),
 
494
                tr("XML Files (*.xml);;All Files (*)"));
 
495
    if (filePath.isEmpty())
 
496
        return;
 
497
 
 
498
    QFile *logFile = new QFile(filePath);
 
499
    if (!logFile->open(QIODevice::ReadOnly | QIODevice::Text)) {
 
500
        delete logFile;
 
501
        QMessageBox::critical(m_errorView, tr("Internal Error"),
 
502
            tr("Failed to open file for reading: %1").arg(filePath));
 
503
        return;
 
504
    }
 
505
 
 
506
    setBusyCursor(true);
 
507
    clearErrorView();
 
508
    m_loadExternalLogFile->setDisabled(true);
 
509
 
 
510
    if (!m_settings || m_settings != ValgrindPlugin::globalSettings()) {
 
511
        m_settings = ValgrindPlugin::globalSettings();
 
512
        m_errorView->settingsChanged(m_settings);
 
513
        updateFromSettings();
 
514
    }
 
515
 
 
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()));
 
523
 
 
524
    parser->parse(logFile); // ThreadedParser owns the file
 
525
}
 
526
 
507
527
void MemcheckTool::parserError(const Valgrind::XmlProtocol::Error &error)
508
528
{
509
529
    m_errorModel->addError(error);
512
532
void MemcheckTool::internalParserError(const QString &errorString)
513
533
{
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));
516
536
}
517
537
 
518
538
void MemcheckTool::clearErrorView()
530
550
    QTC_ASSERT(m_errorView, return);
531
551
    QTC_ASSERT(m_settings, return);
532
552
 
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());
536
554
 
537
555
    QList<int> errorKinds;
538
556
    foreach (QAction *a, m_errorFilterActions) {
545
563
                errorKinds << kind;
546
564
        }
547
565
    }
548
 
    memcheckSettings->setVisibleErrorKinds(errorKinds);
 
566
    m_settings->setVisibleErrorKinds(errorKinds);
549
567
}
550
568
 
551
 
void MemcheckTool::finished()
 
569
int MemcheckTool::updateUiAfterFinishedHelper()
552
570
{
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);
 
576
    return issuesFound;
 
577
}
 
578
 
 
579
void MemcheckTool::engineFinished()
 
580
{
 
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."));
 
585
}
 
586
 
 
587
void MemcheckTool::loadingExternalXmlLogFileFinished()
 
588
{
 
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."));
559
593
}
560
594
 
561
595
void MemcheckTool::setBusyCursor(bool busy)