OSDN Git Service

1eca9ec58feaf22f660b8bdf37406fa2d94daeb0
[qt-creator-jp/qt-creator-jp.git] / src / plugins / valgrindtoolbase / valgrindengine.cpp
1 /**************************************************************************
2 **
3 ** This file is part of Qt Creator
4 **
5 ** Copyright (c) 2011 Nokia Corporation and/or its subsidiary(-ies).
6 **
7 ** Author: Nicolas Arnaud-Cormos, KDAB (nicolas.arnaud-cormos@kdab.com)
8 **
9 ** Contact: Nokia Corporation (qt-info@nokia.com)
10 **
11 ** No Commercial Usage
12 **
13 ** This file contains pre-release code and may not be distributed.
14 ** You may use this file in accordance with the terms and conditions
15 ** contained in the Technology Preview License Agreement accompanying
16 ** this package.
17 **
18 ** GNU Lesser General Public License Usage
19 **
20 ** Alternatively, this file may be used under the terms of the GNU Lesser
21 ** General Public License version 2.1 as published by the Free Software
22 ** Foundation and appearing in the file LICENSE.LGPL included in the
23 ** packaging of this file.  Please review the following information to
24 ** ensure the GNU Lesser General Public License version 2.1 requirements
25 ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
26 **
27 ** In addition, as a special exception, Nokia gives you certain additional
28 ** rights.  These rights are described in the Nokia Qt LGPL Exception
29 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
30 **
31 ** If you have questions regarding the use of this file, please contact
32 ** Nokia at qt-info@nokia.com.
33 **
34 **************************************************************************/
35
36 #include "valgrindengine.h"
37 #include "valgrindsettings.h"
38
39 #include <coreplugin/icore.h>
40 #include <coreplugin/ioutputpane.h>
41 #include <coreplugin/progressmanager/progressmanager.h>
42 #include <coreplugin/progressmanager/futureprogress.h>
43 #include <extensionsystem/pluginmanager.h>
44 #include <projectexplorer/applicationrunconfiguration.h>
45
46 #define VALGRIND_DEBUG_OUTPUT 0
47
48 using namespace Analyzer;
49 using namespace Analyzer::Internal;
50 using namespace Utils;
51
52 ValgrindEngine::ValgrindEngine(ProjectExplorer::RunConfiguration *runConfiguration)
53     : IAnalyzerEngine(runConfiguration),
54       m_settings(0),
55       m_progress(new QFutureInterface<void>()) ,
56       m_isStopping(false)
57 {
58     ProjectExplorer::LocalApplicationRunConfiguration *localAppConfig =
59             qobject_cast<ProjectExplorer::LocalApplicationRunConfiguration *>(runConfiguration);
60
61     m_settings = runConfiguration->extraAspect<AnalyzerProjectSettings>();
62     if (!localAppConfig || !m_settings)
63         return;
64
65     m_workingDirectory = localAppConfig->workingDirectory();
66     m_executable = localAppConfig->executable();
67     m_commandLineArguments = localAppConfig->commandLineArguments();
68     m_environment = localAppConfig->environment();
69 }
70
71 ValgrindEngine::~ValgrindEngine()
72 {
73     delete m_progress;
74 }
75
76 void ValgrindEngine::start()
77 {
78     emit starting(this);
79
80     Core::FutureProgress* fp = Core::ICore::instance()->progressManager()->addTask(m_progress->future(),
81                                                         progressTitle(), "valgrind");
82     fp->setKeepOnFinish(Core::FutureProgress::DontKeepOnFinish);
83     m_progress->reportStarted();
84
85 #if VALGRIND_DEBUG_OUTPUT
86     emit standardOutputReceived(tr("Valgrind options: %1").arg(toolArguments().join(" ")));
87     emit standardOutputReceived(tr("Working directory: %1").arg(m_workingDirectory));
88     emit standardOutputReceived(tr("Command-line arguments: %1").arg(m_commandLineArguments));
89 #endif
90
91     runner()->setWorkingDirectory(m_workingDirectory);
92     runner()->setValgrindExecutable(m_settings->subConfig<ValgrindSettings>()->valgrindExecutable());
93     runner()->setValgrindArguments(toolArguments());
94     runner()->setDebuggeeExecutable(m_executable);
95     // note that m_commandLineArguments may contain several arguments in one string
96     runner()->setDebuggeeArguments(m_commandLineArguments);
97     runner()->setEnvironment(m_environment);
98
99     connect(runner(), SIGNAL(standardOutputReceived(QByteArray)),
100             SLOT(receiveStandardOutput(QByteArray)));
101     connect(runner(), SIGNAL(standardErrorReceived(QByteArray)),
102             SLOT(receiveStandardError(QByteArray)));
103     connect(runner(), SIGNAL(processErrorReceived(QString, QProcess::ProcessError)),
104             SLOT(receiveProcessError(QString, QProcess::ProcessError)));
105     connect(runner(), SIGNAL(finished()),
106             SLOT(runnerFinished()));
107
108     runner()->start();
109 }
110
111 void ValgrindEngine::stop()
112 {
113     m_isStopping = true;
114     runner()->stop();
115 }
116
117 QString ValgrindEngine::executable() const
118 {
119     return m_executable;
120 }
121
122 void ValgrindEngine::runnerFinished()
123 {
124     emit standardOutputReceived(tr("** Analysing finished **"));
125     emit finished();
126
127     m_progress->reportFinished();
128
129     disconnect(runner(), SIGNAL(standardOutputReceived(QByteArray)),
130                this, SLOT(receiveStandardOutput(QByteArray)));
131     disconnect(runner(), SIGNAL(standardErrorReceived(QByteArray)),
132                this, SLOT(receiveStandardError(QByteArray)));
133     disconnect(runner(), SIGNAL(processErrorReceived(QString, QProcess::ProcessError)),
134                this, SLOT(receiveProcessError(QString, QProcess::ProcessError)));
135     disconnect(runner(), SIGNAL(finished()),
136                this, SLOT(runnerFinished()));
137 }
138
139 void ValgrindEngine::receiveStandardOutput(const QByteArray &b)
140 {
141     emit standardOutputReceived(QString::fromLocal8Bit(b));
142 }
143
144 void ValgrindEngine::receiveStandardError(const QByteArray &b)
145 {
146     emit standardErrorReceived(QString::fromLocal8Bit(b));
147 }
148
149 void ValgrindEngine::receiveProcessError(const QString &error, QProcess::ProcessError e)
150 {
151     if (e == QProcess::FailedToStart) {
152         const QString &valgrind = m_settings->subConfig<ValgrindSettings>()->valgrindExecutable();
153         if (!valgrind.isEmpty()) {
154             emit standardErrorReceived(tr("** Error: \"%1\" could not be started: %2 **").arg(valgrind).arg(error));
155         } else {
156             emit standardErrorReceived(tr("** Error: no valgrind executable set **"));
157         }
158     } else if (m_isStopping && e == QProcess::Crashed) { // process gets killed on stop
159         emit standardErrorReceived(tr("** Process Terminated **"));
160     } else {
161         emit standardErrorReceived(QString("** %1 **").arg(error));
162     }
163
164     if (m_isStopping)
165         return;
166
167     ///FIXME: get a better API for this into Qt Creator
168     ExtensionSystem::PluginManager *pm = ExtensionSystem::PluginManager::instance();
169     QList< Core::IOutputPane *> panes = pm->getObjects<Core::IOutputPane>();
170     foreach(Core::IOutputPane *pane, panes) {
171         if (pane->displayName() == tr("Application Output")) {
172             pane->popup(false);
173             break;
174         }
175     }
176 }