OSDN Git Service

Update license.
[qt-creator-jp/qt-creator-jp.git] / src / plugins / debugger / gdb / localplaingdbadapter.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 ** Contact: Nokia Corporation (info@qt.nokia.com)
8 **
9 **
10 ** GNU Lesser General Public License Usage
11 **
12 ** This file may be used under the terms of the GNU Lesser General Public
13 ** License version 2.1 as published by the Free Software Foundation and
14 ** appearing in the file LICENSE.LGPL included in the packaging of this file.
15 ** Please review the following information to ensure the GNU Lesser General
16 ** Public License version 2.1 requirements will be met:
17 ** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
18 **
19 ** In addition, as a special exception, Nokia gives you certain additional
20 ** rights. These rights are described in the Nokia Qt LGPL Exception
21 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
22 **
23 ** Other Usage
24 **
25 ** Alternatively, this file may be used in accordance with the terms and
26 ** conditions contained in a signed written agreement between you and Nokia.
27 **
28 ** If you have questions regarding the use of this file, please contact
29 ** Nokia at qt-info@nokia.com.
30 **
31 **************************************************************************/
32
33 #include "localplaingdbadapter.h"
34
35 #include "gdbengine.h"
36 #include "debuggerstartparameters.h"
37 #include "procinterrupt.h"
38 #include "debuggercore.h"
39 #include "debuggerstringutils.h"
40
41 #include <utils/qtcassert.h>
42
43 #include <QtCore/QFileInfo>
44 #include <QtCore/QProcess>
45 #include <QtGui/QMessageBox>
46
47 namespace Debugger {
48 namespace Internal {
49
50 ///////////////////////////////////////////////////////////////////////
51 //
52 // PlainGdbAdapter
53 //
54 ///////////////////////////////////////////////////////////////////////
55
56 LocalPlainGdbAdapter::LocalPlainGdbAdapter(GdbEngine *engine, QObject *parent)
57     : AbstractPlainGdbAdapter(engine, parent)
58 {
59     // Output
60     connect(&m_outputCollector, SIGNAL(byteDelivery(QByteArray)),
61         engine, SLOT(readDebugeeOutput(QByteArray)));
62 }
63
64 AbstractGdbAdapter::DumperHandling LocalPlainGdbAdapter::dumperHandling() const
65 {
66     // LD_PRELOAD fails for System-Qt on Mac.
67 #if defined(Q_OS_WIN) || defined(Q_OS_MAC)
68     return DumperLoadedByGdb;
69 #else
70     return DumperLoadedByGdbPreload;
71 #endif
72 }
73
74 void LocalPlainGdbAdapter::startAdapter()
75 {
76     QTC_ASSERT(state() == EngineSetupRequested, qDebug() << state());
77     showMessage(_("TRYING TO START ADAPTER"));
78
79     if (!prepareCommand())
80         return;
81
82     QStringList gdbArgs;
83
84     if (!m_outputCollector.listen()) {
85         m_engine->handleAdapterStartFailed(tr("Cannot set up communication with child process: %1")
86                 .arg(m_outputCollector.errorString()), QString());
87         return;
88     }
89     gdbArgs.append(_("--tty=") + m_outputCollector.serverName());
90
91     if (!startParameters().workingDirectory.isEmpty())
92         m_gdbProc.setWorkingDirectory(startParameters().workingDirectory);
93     if (startParameters().environment.size())
94         m_gdbProc.setEnvironment(startParameters().environment.toStringList());
95
96     if (!m_engine->startGdb(gdbArgs)) {
97         m_outputCollector.shutdown();
98         return;
99     }
100
101     checkForReleaseBuild();
102     m_engine->handleAdapterStarted();
103 }
104
105 void LocalPlainGdbAdapter::setupInferior()
106 {
107     AbstractPlainGdbAdapter::setupInferior();
108 }
109
110 void LocalPlainGdbAdapter::runEngine()
111 {
112     AbstractPlainGdbAdapter::runEngine();
113 }
114
115 void LocalPlainGdbAdapter::shutdownInferior()
116 {
117     m_engine->defaultInferiorShutdown("kill");
118 }
119
120 void LocalPlainGdbAdapter::shutdownAdapter()
121 {
122     showMessage(_("PLAIN ADAPTER SHUTDOWN %1").arg(state()));
123     m_outputCollector.shutdown();
124     m_engine->notifyAdapterShutdownOk();
125 }
126
127 void LocalPlainGdbAdapter::checkForReleaseBuild()
128 {
129     // Quick check for a "release" build
130     QProcess proc;
131     QStringList args;
132     args.append(_("-h"));
133     args.append(_("-j"));
134     args.append(_(".debug_info"));
135     args.append(startParameters().executable);
136     proc.start(_("objdump"), args);
137     proc.closeWriteChannel();
138     if (!proc.waitForStarted()) {
139         showMessage(_("OBJDUMP PROCESS COULD NOT BE STARTED. "
140             "RELEASE BUILD CHECK WILL FAIL"));
141         return;
142     }
143     proc.waitForFinished();
144     QByteArray ba = proc.readAllStandardOutput();
145     // This should yield something like
146     // "debuggertest:     file format elf32-i386\n\n"
147     // "Sections:\nIdx Name          Size      VMA       LMA       File off  Algn\n"
148     // "30 .debug_info   00087d36  00000000  00000000  0006bbd5  2**0\n"
149     // " CONTENTS, READONLY, DEBUGGING"
150     if (ba.contains("Sections:") && !ba.contains(".debug_info")) {
151         showMessageBox(QMessageBox::Information, "Warning",
152            tr("This does not seem to be a \"Debug\" build.\n"
153               "Setting breakpoints by file name and line number may fail."));
154     }
155 }
156
157 void LocalPlainGdbAdapter::interruptInferior()
158 {
159     const qint64 attachedPID = m_engine->inferiorPid();
160     if (attachedPID <= 0) {
161         showMessage(_("TRYING TO INTERRUPT INFERIOR BEFORE PID WAS OBTAINED"));
162         return;
163     }
164
165     if (interruptProcess(attachedPID)) {
166         showMessage(_("INTERRUPTED %1").arg(attachedPID));
167     } else {
168         showMessage(_("CANNOT INTERRUPT %1").arg(attachedPID));
169         m_engine->notifyInferiorStopFailed();
170     }
171 }
172
173 QByteArray LocalPlainGdbAdapter::execFilePath() const
174 {
175     return QFileInfo(startParameters().executable)
176             .absoluteFilePath().toLocal8Bit();
177 }
178
179 bool LocalPlainGdbAdapter::infoTargetNecessary() const
180 {
181 #ifdef Q_OS_LINUX
182     return true;
183 #else
184     return false;
185 #endif
186 }
187
188 QByteArray LocalPlainGdbAdapter::toLocalEncoding(const QString &s) const
189 {
190     return s.toLocal8Bit();
191 }
192
193 QString LocalPlainGdbAdapter::fromLocalEncoding(const QByteArray &b) const
194 {
195     return QString::fromLocal8Bit(b);
196 }
197
198 } // namespace Internal
199 } // namespace Debugger