coregdbadapter.cpp 5.51 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33
/**************************************************************************
**
** This file is part of Qt Creator
**
** Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
**
** Contact: Nokia Corporation (qt-info@nokia.com)
**
** Commercial Usage
**
** Licensees holding valid Qt Commercial licenses may use this file in
** accordance with the Qt Commercial License Agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and Nokia.
**
** GNU Lesser General Public License Usage
**
** Alternatively, this file may be used under the terms of the GNU Lesser
** General Public License version 2.1 as published by the Free Software
** Foundation and appearing in the file LICENSE.LGPL included in the
** packaging of this file.  Please review the following information to
** ensure the GNU Lesser General Public License version 2.1 requirements
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** If you are unsure which license is appropriate for your use, please
** contact the sales department at http://qt.nokia.com/contact.
**
**************************************************************************/

#include "coregdbadapter.h"

#include "debuggeractions.h"
#include "gdbengine.h"
34
#include "debuggerstringutils.h"
35 36 37 38

#include <utils/qtcassert.h>

#include <QtCore/QFileInfo>
Oswald Buddenhagen's avatar
Oswald Buddenhagen committed
39
#include <QtGui/QMessageBox>
40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60

namespace Debugger {
namespace Internal {

#define CB(callback) \
    static_cast<GdbEngine::AdapterCallback>(&CoreGdbAdapter::callback), \
    STRINGIFY(callback)

///////////////////////////////////////////////////////////////////////
//
// CoreGdbAdapter
//
///////////////////////////////////////////////////////////////////////

CoreGdbAdapter::CoreGdbAdapter(GdbEngine *engine, QObject *parent)
    : AbstractGdbAdapter(engine, parent)
{
}

void CoreGdbAdapter::startAdapter()
{
hjk's avatar
hjk committed
61
    QTC_ASSERT(state() == EngineStarting, qDebug() << state());
62 63 64
    setState(AdapterStarting);
    debugMessage(_("TRYING TO START ADAPTER"));

Oswald Buddenhagen's avatar
Oswald Buddenhagen committed
65 66
    if (!m_engine->startGdb())
        return;
67 68 69 70 71 72

    emit adapterStarted();
}

void CoreGdbAdapter::startInferior()
{
hjk's avatar
hjk committed
73
    QTC_ASSERT(state() == InferiorStarting, qDebug() << state());
hjk's avatar
hjk committed
74 75
    m_executable = startParameters().executable;
    if (m_executable.isEmpty()) {
Oswald Buddenhagen's avatar
Oswald Buddenhagen committed
76
#ifdef EXE_FROM_CORE
hjk's avatar
hjk committed
77 78 79
        // Extra round trip to get executable name from core file.
        // This is sometimes not the full name, so it can't be used
        // as the generic solution.
80

Oswald Buddenhagen's avatar
Oswald Buddenhagen committed
81 82 83 84 85 86 87
        m_round = 1;
        loadCoreFile();
#else
        showMessageBox(QMessageBox::Warning, tr("Error Loading Symbols"),
                       tr("No executable to load symbols from specified."));
#endif
        return;
hjk's avatar
hjk committed
88
    }
Oswald Buddenhagen's avatar
Oswald Buddenhagen committed
89 90 91 92
#ifdef EXE_FROM_CORE
    m_round = 2;
#endif
    loadExeAndSyms();
hjk's avatar
hjk committed
93 94
}

Oswald Buddenhagen's avatar
Oswald Buddenhagen committed
95
void CoreGdbAdapter::loadExeAndSyms()
hjk's avatar
hjk committed
96
{
Oswald Buddenhagen's avatar
Oswald Buddenhagen committed
97 98 99 100
    // Do that first, otherwise no symbols are loaded.
    QFileInfo fi(m_executable);
    m_engine->postCommand(_("-file-exec-and-symbols \"%1\"")
        .arg(fi.absoluteFilePath()), CB(handleFileExecAndSymbols));
101 102
}

103 104 105 106 107
void CoreGdbAdapter::handleFileExecAndSymbols(const GdbResponse &response)
{
    QTC_ASSERT(state() == InferiorStarting, qDebug() << state());
    if (response.resultClass == GdbResultDone) {
        showStatusMessage(tr("Symbols found."));
108
    } else {
Oswald Buddenhagen's avatar
Oswald Buddenhagen committed
109 110 111
        QString msg = tr("Loading symbols from \"%1\" failed:\n").arg(m_executable)
            + __(response.data.findChild("msg").data());
        showMessageBox(QMessageBox::Warning, tr("Error Loading Symbols"), msg);
112
    }
Oswald Buddenhagen's avatar
Oswald Buddenhagen committed
113
    loadCoreFile();
114 115
}

Oswald Buddenhagen's avatar
Oswald Buddenhagen committed
116 117 118 119 120 121 122 123 124
void CoreGdbAdapter::loadCoreFile()
{
    // Quoting core name below fails in gdb 6.8-debian.
    QFileInfo fi(startParameters().coreFile);
    QString coreName = fi.absoluteFilePath();
    m_engine->postCommand(_("target core ") + coreName, CB(handleTargetCore));
}

void CoreGdbAdapter::handleTargetCore(const GdbResponse &response)
hjk's avatar
hjk committed
125 126 127
{
    QTC_ASSERT(state() == InferiorStarting, qDebug() << state());
    if (response.resultClass == GdbResultDone) {
Oswald Buddenhagen's avatar
Oswald Buddenhagen committed
128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152
#ifdef EXE_FROM_CORE
        if (m_round == 1) {
            m_round = 2;
            GdbMi console = response.data.findChild("consolestreamoutput");
            int pos1 = console.data().indexOf('`');
            int pos2 = console.data().indexOf('\'');
            if (pos1 != -1 && pos2 != -1) {
                m_executable = console.data().mid(pos1 + 1, pos2 - pos1 - 1);
                // Strip off command line arguments. FIXME: make robust.
                int idx = m_executable.indexOf(_c(' '));
                if (idx >= 0)
                    m_executable.truncate(idx);
                if (!m_executable.isEmpty()) {
                    // Finish extra round ...
                    showStatusMessage(tr("Attached to core temporarily."));
                    m_engine->postCommand(_("detach"));
                    // ... and retry.
                    loadExeAndSyms();
                    return;
                }
            }
            showMessageBox(QMessageBox::Warning, tr("Error Loading Symbols"),
                           tr("Unable to determine executable from core file."));
        }
#endif
hjk's avatar
hjk committed
153 154 155
        showStatusMessage(tr("Attached to core."));
        setState(InferiorUnrunnable);
        m_engine->updateAll();
156
    } else {
Oswald Buddenhagen's avatar
Oswald Buddenhagen committed
157 158 159
        QString msg = tr("Attach to core \"%1\" failed:\n").arg(startParameters().coreFile)
            + __(response.data.findChild("msg").data());
        emit inferiorStartFailed(msg);
hjk's avatar
hjk committed
160 161
    }
}
Oswald Buddenhagen's avatar
Oswald Buddenhagen committed
162

163 164 165 166 167 168 169 170
void CoreGdbAdapter::interruptInferior()
{
    // A core should never 'run'
    QTC_ASSERT(false, /**/);
}

} // namespace Internal
} // namespace Debugger