~bzoltan/kubuntu-packaging/decouple_cmake_plugin

« back to all changes in this revision

Viewing changes to src/plugins/valgrind/callgrindtool.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:
41
41
#include <valgrind/callgrind/callgrindfunction.h>
42
42
#include <valgrind/callgrind/callgrindfunctioncall.h>
43
43
#include <valgrind/callgrind/callgrindparsedata.h>
 
44
#include <valgrind/callgrind/callgrindparser.h>
44
45
#include <valgrind/callgrind/callgrindproxymodel.h>
45
46
#include <valgrind/callgrind/callgrindstackbrowser.h>
46
47
#include <valgrind/valgrindplugin.h>
47
48
#include <valgrind/valgrindsettings.h>
48
49
 
49
50
#include <analyzerbase/analyzermanager.h>
50
 
#include <analyzerbase/analyzersettings.h>
51
51
#include <analyzerbase/analyzerutils.h>
52
52
#include <analyzerbase/analyzerconstants.h>
53
53
 
54
 
#include <coreplugin/actionmanager/actioncontainer.h>
55
 
#include <coreplugin/actionmanager/actionmanager.h>
56
 
#include <coreplugin/actionmanager/command.h>
57
54
#include <coreplugin/coreconstants.h>
58
 
#include <coreplugin/icontext.h>
59
55
#include <coreplugin/icore.h>
60
56
 
61
57
#include <cplusplus/LookupContext.h>
62
58
#include <cplusplus/Overview.h>
63
 
#include <cppeditor/cppeditorconstants.h>
64
59
#include <extensionsystem/iplugin.h>
65
60
#include <texteditor/itexteditor.h>
66
61
 
80
75
#include <QCheckBox>
81
76
#include <QComboBox>
82
77
#include <QDockWidget>
 
78
#include <QFileDialog>
83
79
#include <QGraphicsItem>
84
80
#include <QHBoxLayout>
85
81
#include <QLineEdit>
86
82
#include <QMenu>
 
83
#include <QMessageBox>
87
84
#include <QSortFilterProxyModel>
88
85
#include <QToolBar>
89
86
#include <QToolButton>
95
92
using namespace Analyzer;
96
93
using namespace Core;
97
94
using namespace Valgrind::Callgrind;
 
95
using namespace ProjectExplorer;
98
96
 
99
97
namespace Valgrind {
100
98
namespace Internal {
117
115
    void doClear(bool clearParseData);
118
116
    void updateEventCombo();
119
117
 
120
 
    IAnalyzerEngine *createEngine(const AnalyzerStartParameters &sp,
 
118
    AnalyzerRunControl *createRunControl(const AnalyzerStartParameters &sp,
121
119
        ProjectExplorer::RunConfiguration *runConfiguration = 0);
122
120
 
123
121
signals:
129
127
public slots:
130
128
    void slotClear();
131
129
    void slotRequestDump();
 
130
    void loadExternalXmlLogFile();
132
131
 
133
132
    void selectFunction(const Valgrind::Callgrind::Function *);
134
133
    void setCostFormat(Valgrind::Internal::CostDelegate::CostFormat format);
162
161
    void visualisationFunctionSelected(const Valgrind::Callgrind::Function *function);
163
162
    void showParserResults(const Valgrind::Callgrind::ParseData *data);
164
163
 
165
 
    void takeParserData(CallgrindEngine *engine);
166
 
    void engineStarting(const Analyzer::IAnalyzerEngine *);
 
164
    void takeParserData(CallgrindRunControl *rc);
 
165
    void takeParserData(ParseData *data);
 
166
    void engineStarting(const Analyzer::AnalyzerRunControl *);
167
167
    void engineFinished();
168
168
 
169
169
    void editorOpened(Core::IEditor *);
203
203
 
204
204
    QVector<CallgrindTextMark *> m_textMarks;
205
205
 
 
206
    QAction *m_loadExternalLogFile;
206
207
    QAction *m_dumpAction;
207
208
    QAction *m_resetAction;
208
209
    QAction *m_pauseAction;
209
 
    QAction *m_showCostsOfFunctionAction;
210
210
 
211
211
    QString m_toggleCollectFunction;
212
 
    ValgrindGlobalSettings *m_settings; // Not owned
213
212
};
214
213
 
215
214
 
236
235
    , m_dumpAction(0)
237
236
    , m_resetAction(0)
238
237
    , m_pauseAction(0)
239
 
    , m_showCostsOfFunctionAction(0)
240
 
    , m_settings(0)
241
238
{
242
239
    m_updateTimer->setInterval(200);
243
240
    m_updateTimer->setSingleShot(true);
248
245
    m_proxyModel->setFilterKeyColumn(DataModel::NameColumn);
249
246
    m_proxyModel->setFilterCaseSensitivity(Qt::CaseInsensitive);
250
247
 
251
 
    m_settings = AnalyzerGlobalSettings::instance()->subConfig<ValgrindGlobalSettings>();
252
 
 
253
248
    connect(m_stackBrowser, SIGNAL(currentChanged()), SLOT(stackBrowserChanged()));
254
249
    connect(m_updateTimer, SIGNAL(timeout()), SLOT(updateFilterString()));
255
250
}
322
317
    if (QFile::exists(func->file())) {
323
318
        ///TODO: custom position support?
324
319
        int line = func->lineNumber();
325
 
        Core::EditorManager::openEditorAt(func->file(), qMax(line, 0));
 
320
        EditorManager::openEditorAt(func->file(), qMax(line, 0));
326
321
    }
327
322
}
328
323
 
396
391
        m_calleesView->setCostFormat(format);
397
392
        m_callersView->setCostFormat(format);
398
393
    }
399
 
    if (m_settings)
400
 
        m_settings->setCostFormat(format);
 
394
    if (ValgrindGlobalSettings *settings = ValgrindPlugin::globalSettings())
 
395
        settings->setCostFormat(format);
401
396
}
402
397
 
403
398
void CallgrindToolPrivate::handleFilterProjectCosts()
408
403
    if (m_filterProjectCosts->isChecked()) {
409
404
        const QString projectDir = pro->projectDirectory();
410
405
        m_proxyModel->setFilterBaseDir(projectDir);
411
 
    }
412
 
    else {
 
406
    } else {
413
407
        m_proxyModel->setFilterBaseDir(QString());
414
408
    }
415
409
}
505
499
    d = new CallgrindToolPrivate(this);
506
500
    setObjectName(QLatin1String("CallgrindTool"));
507
501
 
508
 
    connect(Core::ICore::editorManager(), SIGNAL(editorOpened(Core::IEditor*)),
 
502
    connect(EditorManager::instance(), SIGNAL(editorOpened(Core::IEditor*)),
509
503
        d, SLOT(editorOpened(Core::IEditor*)));
510
504
}
511
505
 
514
508
    delete d;
515
509
}
516
510
 
517
 
Core::Id CallgrindTool::id() const
518
 
{
519
 
    return Core::Id("Callgrind");
520
 
}
521
 
 
522
 
ProjectExplorer::RunMode CallgrindTool::runMode() const
523
 
{
524
 
    return ProjectExplorer::CallgrindRunMode;
525
 
}
526
 
 
527
 
QString CallgrindTool::displayName() const
528
 
{
529
 
    return tr("Valgrind Function Profiler");
530
 
}
531
 
 
532
 
QString CallgrindTool::description() const
533
 
{
534
 
    return tr("Valgrind Profile uses the \"callgrind\" tool to "
535
 
              "record function calls when a program runs.");
 
511
RunMode CallgrindTool::runMode() const
 
512
{
 
513
    return CallgrindRunMode;
536
514
}
537
515
 
538
516
IAnalyzerTool::ToolMode CallgrindTool::toolMode() const
540
518
    return ReleaseMode;
541
519
}
542
520
 
543
 
void CallgrindTool::extensionsInitialized()
544
 
{
545
 
    Core::Context analyzerContext = Core::Context(Analyzer::Constants::C_ANALYZEMODE);
546
 
 
547
 
    // check if there is a CppEditor context menu, if true, add our own context menu actions
548
 
    if (Core::ActionContainer *editorContextMenu =
549
 
            Core::ActionManager::actionContainer(CppEditor::Constants::M_CONTEXT)) {
550
 
        QAction *action = 0;
551
 
        Core::Command *cmd = 0;
552
 
 
553
 
        editorContextMenu->addSeparator(analyzerContext);
554
 
 
555
 
        action = new QAction(tr("Profile Costs of this Function and its Callees"), this);
556
 
        action->setIcon(QIcon(QLatin1String(Analyzer::Constants::ANALYZER_CONTROL_START_ICON)));
557
 
        connect(action, SIGNAL(triggered()), d, SLOT(handleShowCostsOfFunction()));
558
 
        cmd = Core::ActionManager::registerAction(action, "Analyzer.Callgrind.ShowCostsOfFunction",
559
 
            analyzerContext);
560
 
        editorContextMenu->addAction(cmd);
561
 
        cmd->setAttribute(Core::Command::CA_Hide);
562
 
        cmd->setAttribute(Core::Command::CA_NonConfigurable);
563
 
        d->m_showCostsOfFunctionAction = action;
564
 
    }
565
 
}
566
 
 
567
 
IAnalyzerEngine *CallgrindTool::createEngine(const AnalyzerStartParameters &sp,
568
 
    ProjectExplorer::RunConfiguration *runConfiguration)
569
 
{
570
 
    return d->createEngine(sp, runConfiguration);
571
 
}
572
 
 
573
 
IAnalyzerEngine *CallgrindToolPrivate::createEngine(const AnalyzerStartParameters &sp,
574
 
    ProjectExplorer::RunConfiguration *runConfiguration)
575
 
{
576
 
    CallgrindEngine *engine = new CallgrindEngine(q, sp, runConfiguration);
577
 
 
578
 
    connect(engine, SIGNAL(parserDataReady(CallgrindEngine*)),
579
 
            SLOT(takeParserData(CallgrindEngine*)));
580
 
    connect(engine, SIGNAL(starting(const Analyzer::IAnalyzerEngine*)),
581
 
            SLOT(engineStarting(const Analyzer::IAnalyzerEngine*)));
582
 
    connect(engine, SIGNAL(finished()),
 
521
AnalyzerRunControl *CallgrindTool::createRunControl(const AnalyzerStartParameters &sp,
 
522
    RunConfiguration *runConfiguration)
 
523
{
 
524
    return d->createRunControl(sp, runConfiguration);
 
525
}
 
526
 
 
527
AnalyzerRunControl *CallgrindToolPrivate::createRunControl(const AnalyzerStartParameters &sp,
 
528
    RunConfiguration *runConfiguration)
 
529
{
 
530
    CallgrindRunControl *rc = new CallgrindRunControl(sp, runConfiguration);
 
531
 
 
532
    connect(rc, SIGNAL(parserDataReady(CallgrindRunControl*)),
 
533
            SLOT(takeParserData(CallgrindRunControl*)));
 
534
    connect(rc, SIGNAL(starting(const Analyzer::AnalyzerRunControl*)),
 
535
            SLOT(engineStarting(const Analyzer::AnalyzerRunControl*)));
 
536
    connect(rc, SIGNAL(finished()),
583
537
            SLOT(engineFinished()));
584
538
 
585
 
    connect(this, SIGNAL(dumpRequested()), engine, SLOT(dump()));
586
 
    connect(this, SIGNAL(resetRequested()), engine, SLOT(reset()));
587
 
    connect(this, SIGNAL(pauseToggled(bool)), engine, SLOT(setPaused(bool)));
 
539
    connect(this, SIGNAL(dumpRequested()), rc, SLOT(dump()));
 
540
    connect(this, SIGNAL(resetRequested()), rc, SLOT(reset()));
 
541
    connect(this, SIGNAL(pauseToggled(bool)), rc, SLOT(setPaused(bool)));
588
542
 
589
 
    // initialize engine
590
 
    engine->setPaused(m_pauseAction->isChecked());
 
543
    // initialize run control
 
544
    rc->setPaused(m_pauseAction->isChecked());
591
545
 
592
546
    // we may want to toggle collect for one function only in this run
593
 
    engine->setToggleCollectFunction(m_toggleCollectFunction);
 
547
    rc->setToggleCollectFunction(m_toggleCollectFunction);
594
548
    m_toggleCollectFunction.clear();
595
549
 
596
 
    AnalyzerManager::showStatusMessage(AnalyzerManager::msgToolStarted(q->displayName()));
597
 
 
598
 
    QTC_ASSERT(m_visualisation, return engine);
 
550
    QTC_ASSERT(m_visualisation, return rc);
599
551
 
600
552
    // apply project settings
601
553
    if (runConfiguration) {
602
 
        if (const AnalyzerRunConfigurationAspect *analyzerSettings = runConfiguration->extraAspect<AnalyzerRunConfigurationAspect>()) {
603
 
            if (const ValgrindProjectSettings *settings = analyzerSettings->subConfig<ValgrindProjectSettings>()) {
 
554
        if (IRunConfigurationAspect *analyzerAspect = runConfiguration->extraAspect(ANALYZER_VALGRIND_SETTINGS)) {
 
555
            if (const ValgrindBaseSettings *settings = qobject_cast<ValgrindBaseSettings *>(analyzerAspect->currentSettings())) {
604
556
                m_visualisation->setMinimumInclusiveCostRatio(settings->visualisationMinimumInclusiveCostRatio() / 100.0);
605
557
                m_proxyModel->setMinimumInclusiveCostRatio(settings->minimumInclusiveCostRatio() / 100.0);
606
558
                m_dataModel->setVerboseToolTipsEnabled(settings->enableEventToolTips());
607
559
            }
608
560
        }
609
561
    }
610
 
    return engine;
 
562
    return rc;
611
563
}
612
564
 
613
565
void CallgrindTool::startTool(StartMode mode)
614
566
{
615
 
    ValgrindPlugin::startValgrindTool(this, mode);
 
567
    ValgrindTool::startTool(mode);
616
568
    d->setBusyCursor(true);
617
569
}
618
570
 
 
571
void CallgrindTool::loadExternalXmlLogFile()
 
572
{
 
573
    d->loadExternalXmlLogFile();
 
574
}
 
575
 
 
576
void CallgrindTool::handleShowCostsOfFunction()
 
577
{
 
578
   d->handleShowCostsOfFunction();
 
579
}
 
580
 
619
581
QWidget *CallgrindTool::createWidgets()
620
582
{
621
583
    return d->createWidgets();
703
665
    layout->setSpacing(0);
704
666
    widget->setLayout(layout);
705
667
 
 
668
    // load external XML log file
 
669
    action = new QAction(this);
 
670
    action->setIcon(QIcon(QLatin1String(Core::Constants::ICON_OPENFILE)));
 
671
    action->setToolTip(tr("Load External XML Log File"));
 
672
    connect(action, SIGNAL(triggered(bool)), this, SLOT(loadExternalXmlLogFile()));
 
673
    layout->addWidget(createToolButton(action));
 
674
    m_loadExternalLogFile = action;
 
675
 
706
676
    // dump action
707
677
    action = new QAction(this);
708
678
    action->setDisabled(true);
800
770
    layout->addWidget(button);
801
771
    }
802
772
 
 
773
 
 
774
    ValgrindGlobalSettings *settings = ValgrindPlugin::globalSettings();
 
775
 
803
776
    // cycle detection
804
777
    //action = new QAction(QLatin1String("Cycle Detection"), this); ///FIXME: icon
805
778
    action = new QAction(QLatin1String("O"), this); ///FIXME: icon
806
779
    action->setToolTip(tr("Enable cycle detection to properly handle recursive or circular function calls."));
807
780
    action->setCheckable(true);
808
781
    connect(action, SIGNAL(toggled(bool)), m_dataModel, SLOT(enableCycleDetection(bool)));
809
 
    connect(action, SIGNAL(toggled(bool)), m_settings, SLOT(setDetectCycles(bool)));
 
782
    connect(action, SIGNAL(toggled(bool)), settings, SLOT(setDetectCycles(bool)));
810
783
    layout->addWidget(createToolButton(action));
811
784
    m_cycleDetection = action;
812
785
 
815
788
    action->setToolTip(tr("This removes template parameter lists when displaying function names."));
816
789
    action->setCheckable(true);
817
790
    connect(action, SIGNAL(toggled(bool)), m_dataModel, SLOT(setShortenTemplates(bool)));
818
 
    connect(action, SIGNAL(toggled(bool)), m_settings, SLOT(setShortenTemplates(bool)));
 
791
    connect(action, SIGNAL(toggled(bool)), settings, SLOT(setShortenTemplates(bool)));
819
792
    layout->addWidget(createToolButton(action));
820
793
    m_shortenTemplates = action;
821
794
 
836
809
    layout->addWidget(filter);
837
810
    m_searchFilter = filter;
838
811
 
839
 
    setCostFormat(m_settings->costFormat());
840
 
    enableCycleDetection(m_settings->detectCycles());
 
812
    setCostFormat(settings->costFormat());
 
813
    enableCycleDetection(settings->detectCycles());
841
814
 
842
815
    layout->addWidget(new Utils::StyledSeparator);
843
816
    layout->addStretch();
851
824
    m_textMarks.clear();
852
825
}
853
826
 
854
 
void CallgrindToolPrivate::engineStarting(const Analyzer::IAnalyzerEngine *)
 
827
void CallgrindToolPrivate::engineStarting(const Analyzer::AnalyzerRunControl *)
855
828
{
856
829
    // enable/disable actions
857
830
    m_resetAction->setEnabled(true);
858
831
    m_dumpAction->setEnabled(true);
 
832
    m_loadExternalLogFile->setEnabled(false);
859
833
    clearTextMarks();
860
834
    slotClear();
861
835
}
865
839
    // enable/disable actions
866
840
    m_resetAction->setEnabled(false);
867
841
    m_dumpAction->setEnabled(false);
 
842
    m_loadExternalLogFile->setEnabled(true);
868
843
 
869
844
    const ParseData *data = m_dataModel->parseData();
870
845
    if (data)
892
867
    AnalyzerManager::showStatusMessage(msg);
893
868
}
894
869
 
895
 
void CallgrindToolPrivate::editorOpened(Core::IEditor *editor)
 
870
void CallgrindToolPrivate::editorOpened(IEditor *editor)
896
871
{
897
872
    TextEditor::ITextEditor *textEditor = qobject_cast<TextEditor::ITextEditor *>(editor);
898
873
    if (!textEditor)
908
883
    // find callgrind text mark that corresponds to this editor's file and line number
909
884
    const Function *func = 0;
910
885
    foreach (CallgrindTextMark *textMark, m_textMarks) {
911
 
        if (textMark->fileName() == editor->document()->fileName() && textMark->lineNumber() == line) {
 
886
        if (textMark->fileName() == editor->document()->filePath() && textMark->lineNumber() == line) {
912
887
            func = textMark->function();
913
888
            break;
914
889
        }
948
923
 
949
924
    m_toggleCollectFunction = qualifiedFunctionName + QLatin1String("()");
950
925
 
951
 
    AnalyzerManager::selectTool(q, StartMode(StartLocal));
952
 
    AnalyzerManager::startTool(q, StartMode(StartLocal));
 
926
    AnalyzerManager::selectTool(q, StartLocal);
 
927
    AnalyzerManager::startTool();
953
928
}
954
929
 
955
930
void CallgrindToolPrivate::slotRequestDump()
959
934
    dumpRequested();
960
935
}
961
936
 
962
 
void CallgrindToolPrivate::takeParserData(CallgrindEngine *engine)
963
 
{
964
 
    ParseData *data = engine->takeParserData();
 
937
void CallgrindToolPrivate::loadExternalXmlLogFile()
 
938
{
 
939
    const QString filePath = QFileDialog::getOpenFileName(
 
940
                Core::ICore::mainWindow(),
 
941
                tr("Open Callgrind XML Log File"),
 
942
                QString(),
 
943
                tr("XML Files (*.xml);;All Files (*)"));
 
944
    if (filePath.isEmpty())
 
945
        return;
 
946
 
 
947
    QFile logFile(filePath);
 
948
    if (!logFile.open(QIODevice::ReadOnly | QIODevice::Text)) {
 
949
        QMessageBox::critical(AnalyzerManager::mainWindow(), tr("Internal Error"),
 
950
            tr("Failed to open file for reading: %1").arg(filePath));
 
951
        return;
 
952
    }
 
953
 
 
954
    AnalyzerManager::showStatusMessage(tr("Parsing Profile Data..."));
 
955
    QCoreApplication::processEvents();
 
956
 
 
957
    Parser parser;
 
958
    parser.parse(&logFile);
 
959
    takeParserData(parser.takeData());
 
960
}
 
961
 
 
962
void CallgrindToolPrivate::takeParserData(CallgrindRunControl *rc)
 
963
{
 
964
    takeParserData(rc->takeParserData());
 
965
}
 
966
 
 
967
void CallgrindToolPrivate::takeParserData(ParseData *data)
 
968
{
965
969
    showParserResults(data);
966
970
 
967
971
    if (!data)