Ignore:
Timestamp:
May 5, 2011, 5:36:53 AM (14 years ago)
Author:
Dmitry A. Kuminov
Message:

trunk: Merged in qt 4.7.2 sources from branches/vendor/nokia/qt.

Location:
trunk
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • trunk

  • trunk/tools/runonphone/symbianutils/launcher.cpp

    r769 r846  
    11/****************************************************************************
    22**
    3 ** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
     3** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
    44** All rights reserved.
    55** Contact: Nokia Corporation (qt-info@nokia.com)
     
    4545#include "trkdevice.h"
    4646#include "bluetoothlistener.h"
     47#include "symbiandevicemanager.h"
    4748
    4849#include <QtCore/QTimer>
     
    5455#include <QtCore/QScopedPointer>
    5556
     57#include <cstdio>
     58
    5659namespace trk {
     60
     61struct CrashReportState {
     62    CrashReportState();
     63    void clear();
     64
     65    typedef uint Thread;
     66    typedef QList<Thread> Threads;
     67    Threads threads;
     68
     69    QList<uint> registers;
     70    QByteArray stack;
     71    uint sp;
     72    uint fetchingStackPID;
     73    uint fetchingStackTID;
     74};
     75
     76CrashReportState::CrashReportState()
     77{
     78    clear();
     79}
     80
     81void CrashReportState::clear()
     82{
     83    threads.clear();
     84    stack.clear();
     85    sp = fetchingStackPID = fetchingStackTID = 0;
     86}
    5787
    5888struct LauncherPrivate {
     
    6292        uint copyFileHandle;
    6393        QScopedPointer<QByteArray> data;
    64         int position;
     94        qint64 position;
     95        QScopedPointer<QFile> localFile;
    6596    };
    6697
     
    76107
    77108    CopyState m_copyState;
     109    CopyState m_downloadState;
    78110    QString m_fileName;
    79111    QStringList m_commandLineArgs;
     
    82114    Launcher::Actions m_startupActions;
    83115    bool m_closeDevice;
     116    CrashReportState m_crashReportState;
    84117};
    85118
     
    101134{
    102135    d->m_startupActions = startupActions;
    103     connect(d->m_device.data(), SIGNAL(messageReceived(trk::TrkResult)), this, SLOT(handleResult(trk::TrkResult)));   
    104     connect(this, SIGNAL(finished()), d->m_device.data(), SLOT(close()));
     136    connect(d->m_device.data(), SIGNAL(messageReceived(trk::TrkResult)), this, SLOT(handleResult(trk::TrkResult)));
    105137}
    106138
    107139Launcher::~Launcher()
    108140{
     141    // Destroyed before protocol was through: Close
     142    if (d->m_closeDevice && d->m_device->isOpen())
     143        d->m_device->close();
     144    emit destroyed(d->m_device->port());
    109145    logMessage("Shutting down.\n");
    110146    delete d;
     
    155191}
    156192
     193void Launcher::setDownloadFileName(const QString &srcName, const QString &dstName)
     194{
     195    d->m_downloadState.sourceFileName = srcName;
     196    d->m_downloadState.destinationFileName = dstName;
     197}
     198
    157199void Launcher::setInstallFileName(const QString &name)
    158200{
     
    189231{
    190232    errorMessage->clear();
     233    d->m_crashReportState.clear();
    191234    if (d->m_verbose) {
    192         const QString msg = QString::fromLatin1("Port=%1 Executable=%2 Arguments=%3 Package=%4 Remote Package=%5 Install file=%6")
    193                             .arg(trkServerName(), d->m_fileName,
    194                                  d->m_commandLineArgs.join(QString(QLatin1Char(' '))),
    195                                  d->m_copyState.sourceFileName, d->m_copyState.destinationFileName, d->m_installFileName);
     235        QString msg;
     236        QTextStream str(&msg);
     237        str.setIntegerBase(16);
     238        str << "Actions=0x" << d->m_startupActions;
     239        str.setIntegerBase(10);
     240        str << " Port=" << trkServerName();
     241        if (!d->m_fileName.isEmpty())
     242            str << " Executable=" << d->m_fileName;
     243        if (!d->m_commandLineArgs.isEmpty())
     244            str << " Arguments= " << d->m_commandLineArgs.join(QString(QLatin1Char(' ')));
     245        if (!d->m_copyState.sourceFileName.isEmpty())
     246            str << " Package/Source=" << d->m_copyState.sourceFileName;
     247        if (!d->m_copyState.destinationFileName.isEmpty())
     248            str << " Remote Package/Destination=" << d->m_copyState.destinationFileName;
     249        if (!d->m_downloadState.sourceFileName.isEmpty())
     250            str << " Source=" << d->m_downloadState.sourceFileName;
     251        if (!d->m_downloadState.destinationFileName.isEmpty())
     252            str << " Destination=" << d->m_downloadState.destinationFileName;
     253        if (!d->m_installFileName.isEmpty())
     254            str << " Install file=" << d->m_installFileName;
    196255        logMessage(msg);
    197256    }
     
    215274    if (!d->m_device->isOpen() && !d->m_device->open(errorMessage))
    216275        return false;
    217     if (d->m_closeDevice) {
    218         connect(this, SIGNAL(finished()), d->m_device.data(), SLOT(close()));
    219     } else {
    220         disconnect(this, SIGNAL(finished()), d->m_device.data(), 0);
    221     }
    222276    setState(Connecting);
    223277    // Set up the temporary 'waiting' state if we do not get immediate connection
     
    253307    else if (d->m_startupActions & ActionRun)
    254308        startInferiorIfNeeded();
     309    else if (d->m_startupActions & ActionDownload)
     310        copyFileFromRemote();
    255311}
    256312
     
    265321    if (d->m_verbose)
    266322        qDebug() << "LAUNCHER: " << qPrintable(msg);
     323}
     324
     325void Launcher::handleFinished()
     326{
     327    if (d->m_closeDevice)
     328        d->m_device->close();
     329    emit finished();
    267330}
    268331
     
    288351    case WaitingForTrk:
    289352        setState(Disconnected);
    290         emit finished();
     353        handleFinished();
    291354        break;
    292355    }
     
    332395    QByteArray str = result.toString().toUtf8();
    333396    if (result.isDebugOutput) { // handle application output
    334         logMessage("APPLICATION OUTPUT: " + result.data);
    335         emit applicationOutputReceived(result.data);
     397        QString msg;
     398        if (result.multiplex == MuxTextTrace) {
     399            if (result.data.length() > 8) {
     400            quint64 timestamp = extractInt64(result.data) & 0x0FFFFFFFFFFFFFFFULL;
     401            quint64 secs = timestamp / 1000000000;
     402            quint64 ns = timestamp % 1000000000;
     403            msg = QString("[%1.%2] %3").arg(secs).arg(ns).arg(QString(result.data.mid(8)));
     404            logMessage("TEXT TRACE: " + msg);
     405            }
     406        } else {
     407            logMessage("APPLICATION OUTPUT: " + stringFromArray(result.data));
     408            msg = result.data;
     409        }
     410        msg.replace("\r\n", "\n");
     411        if(!msg.endsWith('\n')) msg.append('\n');
     412        emit applicationOutputReceived(msg);
    336413        return;
    337414    }
     
    369446        // target->host OS notification
    370447        case TrkNotifyCreated: { // Notify Created
    371             /*
    372             const char *data = result.data.data();
    373             byte error = result.data.at(0);
    374             byte type = result.data.at(1); // type: 1 byte; for dll item, this value is 2.
    375             uint pid = extractInt(data + 2); //  ProcessID: 4 bytes;
    376             uint tid = extractInt(data + 6); //threadID: 4 bytes
    377             uint codeseg = extractInt(data + 10); //code address: 4 bytes; code base address for the library
    378             uint dataseg = extractInt(data + 14); //data address: 4 bytes; data base address for the library
    379             uint len = extractShort(data + 18); //length: 2 bytes; length of the library name string to follow
    380             QByteArray name = result.data.mid(20, len); // name: library name
    381 
    382             logMessage(prefix + "NOTE: LIBRARY LOAD: " + str);
    383             logMessage(prefix + "TOKEN: " + result.token);
    384             logMessage(prefix + "ERROR: " + int(error));
    385             logMessage(prefix + "TYPE:  " + int(type));
    386             logMessage(prefix + "PID:   " + pid);
    387             logMessage(prefix + "TID:   " + tid);
    388             logMessage(prefix + "CODE:  " + codeseg);
    389             logMessage(prefix + "DATA:  " + dataseg);
    390             logMessage(prefix + "LEN:   " + len);
    391             logMessage(prefix + "NAME:  " + name);
    392             */
    393448
    394449            if (result.data.size() < 10)
    395450                break;
     451            const char *data = result.data.constData();
     452            const byte error = result.data.at(0);
     453            Q_UNUSED(error)
     454            const byte type = result.data.at(1); // type: 1 byte; for dll item, this value is 2.
     455            const uint tid = extractInt(data + 6); //threadID: 4 bytes
     456            Q_UNUSED(tid)
     457            if (type == kDSOSDLLItem && result.data.size() >=20) {
     458                const Library lib = Library(result);
     459                d->m_session.libraries.push_back(lib);
     460                emit libraryLoaded(lib);
     461            }
    396462            QByteArray ba;
    397463            ba.append(result.data.mid(2, 8));
    398464            d->m_device->sendTrkMessage(TrkContinue, TrkCallback(), ba, "CONTINUE");
    399             //d->m_device->sendTrkAck(result.token)
    400465            break;
    401466        }
    402467        case TrkNotifyDeleted: { // NotifyDeleted
    403468            const ushort itemType = (unsigned char)result.data.at(1);
    404             const ushort len = result.data.size() > 12 ? extractShort(result.data.data() + 10) : ushort(0);
     469            const uint pid = result.data.size() >= 6 ? extractShort(result.data.constData() + 2) : 0;
     470            const uint tid = result.data.size() >= 10 ? extractShort(result.data.constData() + 6) : 0;
     471            Q_UNUSED(tid)
     472            const ushort len = result.data.size() > 12 ? extractShort(result.data.constData() + 10) : ushort(0);
    405473            const QString name = len ? QString::fromAscii(result.data.mid(12, len)) : QString();
    406474            logMessage(QString::fromLatin1("%1 %2 UNLOAD: %3").
     
    408476                       arg(name));
    409477            d->m_device->sendTrkAck(result.token);
    410             if (itemType == 0 // process
     478            if (itemType == kDSOSProcessItem // process
    411479                && result.data.size() >= 10
    412480                && d->m_session.pid == extractInt(result.data.data() + 6)) {
    413                 disconnectTrk();
     481                    if (d->m_startupActions & ActionDownload)
     482                        copyFileFromRemote();
     483                    else
     484                        disconnectTrk();
     485            }
     486            else if (itemType == kDSOSDLLItem && len) {
     487                // Remove libraries of process.
     488                for (QList<Library>::iterator it = d->m_session.libraries.begin(); it != d->m_session.libraries.end(); ) {
     489                    if ((*it).pid == pid && (*it).name == name) {
     490                        emit libraryUnloaded(*it);
     491                        it = d->m_session.libraries.erase(it);
     492                    } else {
     493                        ++it;
     494                    }
     495                }
    414496            }
    415497            break;
     
    447529        if (d->m_startupActions == ActionPingOnly) {
    448530            setState(Disconnected);
    449             emit finished();
     531            handleFinished();
    450532        }
    451533        return;
     
    456538    d->m_session.trkAppVersion.protocolMinor = result.data.at(4);
    457539    setState(DeviceDescriptionReceived);
     540    const QString msg = deviceDescription();
     541    emit deviceDescriptionReceived(trkServerName(), msg);
    458542    // Ping mode: Log & Terminate
    459543    if (d->m_startupActions == ActionPingOnly) {
    460         qWarning("%s", qPrintable(deviceDescription()));
     544        qWarning("%s", qPrintable(msg));
    461545        setState(Disconnected);
    462         emit finished();
    463     }
     546        handleFinished();
     547    }
     548}
     549
     550static inline QString msgCannotOpenRemoteFile(const QString &fileName, const QString &message)
     551{
     552    return Launcher::tr("Cannot open remote file '%1': %2").arg(fileName, message);
     553}
     554
     555static inline QString msgCannotOpenLocalFile(const QString &fileName, const QString &message)
     556{
     557    return Launcher::tr("Cannot open '%1': %2").arg(fileName, message);
    464558}
    465559
     
    467561{
    468562    if (result.errorCode() || result.data.size() < 6) {
    469         emit canNotCreateFile(d->m_copyState.destinationFileName, result.errorString());
     563        const QString msg = msgCannotOpenRemoteFile(d->m_copyState.destinationFileName, result.errorString());
     564        logMessage(msg);
     565        emit canNotCreateFile(d->m_copyState.destinationFileName, msg);
    470566        disconnectTrk();
    471567        return;
     
    473569    const char *data = result.data.data();
    474570    d->m_copyState.copyFileHandle = extractInt(data + 2);
    475     QFile file(d->m_copyState.sourceFileName);
    476     file.open(QIODevice::ReadOnly);
     571    const QString localFileName = d->m_copyState.sourceFileName;
     572    QFile file(localFileName);
     573    d->m_copyState.position = 0;
     574    if (!file.open(QIODevice::ReadOnly)) {
     575        const QString msg = msgCannotOpenLocalFile(localFileName, file.errorString());
     576        logMessage(msg);
     577        emit canNotOpenLocalFile(localFileName, msg);
     578        closeRemoteFile(true);
     579        disconnectTrk();
     580        return;
     581    }
    477582    d->m_copyState.data.reset(new QByteArray(file.readAll()));
    478     d->m_copyState.position = 0;
    479583    file.close();
    480584    continueCopying();
     585}
     586
     587void Launcher::handleFileOpened(const TrkResult &result)
     588{
     589    if (result.errorCode() || result.data.size() < 6) {
     590        const QString msg = msgCannotOpenRemoteFile(d->m_downloadState.sourceFileName, result.errorString());
     591        logMessage(msg);
     592        emit canNotOpenFile(d->m_downloadState.sourceFileName, msg);
     593        disconnectTrk();
     594        return;
     595    }
     596    d->m_downloadState.position = 0;
     597    const QString localFileName = d->m_downloadState.destinationFileName;
     598    bool opened = false;
     599    if (localFileName == QLatin1String("-")) {
     600        d->m_downloadState.localFile.reset(new QFile);
     601        opened = d->m_downloadState.localFile->open(stdout, QFile::WriteOnly);
     602    } else {
     603        d->m_downloadState.localFile.reset(new QFile(localFileName));
     604        opened = d->m_downloadState.localFile->open(QFile::WriteOnly | QFile::Truncate);
     605    }
     606    if (!opened) {
     607        const QString msg = msgCannotOpenLocalFile(localFileName, d->m_downloadState.localFile->errorString());
     608        logMessage(msg);
     609        emit canNotOpenLocalFile(localFileName, msg);
     610        closeRemoteFile(true);
     611        disconnectTrk();
     612    }
     613    continueReading();
     614}
     615
     616void Launcher::continueReading()
     617{
     618    QByteArray ba;
     619    appendInt(&ba, d->m_downloadState.copyFileHandle, TargetByteOrder);
     620    appendShort(&ba, 2048, TargetByteOrder);
     621    d->m_device->sendTrkMessage(TrkReadFile, TrkCallback(this, &Launcher::handleRead), ba);
     622}
     623
     624void Launcher::handleRead(const TrkResult &result)
     625{
     626    if (result.errorCode() || result.data.size() < 4) {
     627        d->m_downloadState.localFile->close();
     628        closeRemoteFile(true);
     629        disconnectTrk();
     630    } else {
     631        int length = extractShort(result.data.data() + 2);
     632        //TRK doesn't tell us the file length, so we need to keep reading until it returns 0 length
     633        if (length > 0) {
     634            d->m_downloadState.localFile->write(result.data.data() + 4, length);
     635            continueReading();
     636        } else {
     637            closeRemoteFile(true);
     638            disconnectTrk();
     639        }
     640    }
    481641}
    482642
     
    494654void Launcher::continueCopying(uint lastCopiedBlockSize)
    495655{
    496     int size = d->m_copyState.data->length();
     656    qint64 size = d->m_copyState.data->length();
    497657    d->m_copyState.position += lastCopiedBlockSize;
    498658    if (size == 0)
    499659        emit copyProgress(100);
    500660    else {
    501         int percent = qMin((d->m_copyState.position*100)/size, 100);
    502         emit copyProgress(percent);
     661        const qint64 hundred = 100;
     662        const qint64 percent = qMin( (d->m_copyState.position * hundred) / size, hundred);
     663        emit copyProgress(static_cast<int>(percent));
    503664    }
    504665    if (d->m_copyState.position < size) {
     
    533694    else if (d->m_startupActions & ActionRun)
    534695        startInferiorIfNeeded();
     696    else if (d->m_startupActions & ActionDownload)
     697        copyFileFromRemote();
    535698    else
    536699        disconnectTrk();
     
    577740    }
    578741    emit applicationRunning(d->m_session.pid);
     742    //create a "library" entry for the executable which launched the process
     743    Library lib;
     744    lib.pid = d->m_session.pid;
     745    lib.codeseg = d->m_session.codeseg;
     746    lib.dataseg = d->m_session.dataseg;
     747    lib.name = d->m_fileName.toUtf8();
     748    d->m_session.libraries << lib;
     749    emit libraryLoaded(lib);
     750
    579751    QByteArray ba;
    580752    appendInt(&ba, d->m_session.pid);
     
    587759    logMessage("   FINISHED: " + stringFromArray(result.data));
    588760    setState(Disconnected);
    589     emit finished();
     761    handleFinished();
    590762}
    591763
     
    596768    const char *data = result.data.data() + 1;
    597769
    598     QString str = QLatin1String("SUPPORTED: ");
    599     for (int i = 0; i < 32; ++i) {
    600         //str.append("  [" + formatByte(data[i]) + "]: ");
    601         for (int j = 0; j < 8; ++j) {
    602             if (data[i] & (1 << j)) {
    603                 str.append(QString::number(i * 8 + j, 16));
    604                 str.append(QLatin1Char(' '));
     770    if (d->m_verbose > 1) {
     771        QString str = QLatin1String("SUPPORTED: ");
     772        for (int i = 0; i < 32; ++i) {
     773            for (int j = 0; j < 8; ++j) {
     774                if (data[i] & (1 << j)) {
     775                    str.append(QString::number(i * 8 + j, 16));
     776                    str.append(QLatin1Char(' '));
     777                }
    605778            }
    606779        }
    607     }
    608     logMessage(str);
     780        logMessage(str);
     781    }
    609782}
    610783
     
    670843    emit copyingStarted();
    671844    QByteArray ba;
    672     ba.append(char(10));
     845    ba.append(char(10)); //kDSFileOpenWrite | kDSFileOpenBinary
    673846    appendString(&ba, d->m_copyState.destinationFileName.toLocal8Bit(), TargetByteOrder, false);
    674847    d->m_device->sendTrkMessage(TrkOpenFile, TrkCallback(this, &Launcher::handleFileCreation), ba);
     848}
     849
     850void Launcher::copyFileFromRemote()
     851{
     852    emit copyingStarted();
     853    QByteArray ba;
     854    ba.append(char(9)); //kDSFileOpenRead | kDSFileOpenBinary
     855    appendString(&ba, d->m_downloadState.sourceFileName.toLocal8Bit(), TargetByteOrder, false);
     856    d->m_device->sendTrkMessage(TrkOpenFile, TrkCallback(this, &Launcher::handleFileOpened), ba);
    675857}
    676858
     
    695877    if (d->m_startupActions & ActionRun) {
    696878        startInferiorIfNeeded();
     879    } else if (d->m_startupActions & ActionDownload) {
     880        copyFileFromRemote();
    697881    } else {
    698882        disconnectTrk();
     
    705889    // It's not started yet
    706890    QByteArray ba;
    707     appendShort(&ba, 0, TargetByteOrder); // create new process
     891    appendShort(&ba, 0, TargetByteOrder); // create new process (kDSOSProcessItem)
    708892    ba.append(char(0)); // options - currently unused
    709     if(arguments.isEmpty()) {
    710         appendString(&ba, executable.toLocal8Bit(), TargetByteOrder);
    711         return ba;
    712     }
    713     // Append full command line as one string (leading length information).
    714     QByteArray commandLineBa;
    715     commandLineBa.append(executable.toLocal8Bit());
    716     commandLineBa.append('\0');
    717     commandLineBa.append(arguments.join(QString(QLatin1Char(' '))).toLocal8Bit());
    718     appendString(&ba, commandLineBa, TargetByteOrder);
     893    // One string consisting of binary terminated by '\0' and arguments terminated by '\0'
     894    QByteArray commandLineBa = executable.toLocal8Bit();
     895    commandLineBa.append(char(0));
     896    if (!arguments.isEmpty())
     897        commandLineBa.append(arguments.join(QString(QLatin1Char(' '))).toLocal8Bit());
     898    appendString(&ba, commandLineBa, TargetByteOrder, true);
     899    return ba;
     900}
     901
     902QByteArray Launcher::readMemoryMessage(uint pid, uint tid, uint from, uint len)
     903{
     904    QByteArray ba;
     905    ba.reserve(11);
     906    ba.append(char(0x8)); // Options, FIXME: why?
     907    appendShort(&ba, len);
     908    appendInt(&ba, from);
     909    appendInt(&ba, pid);
     910    appendInt(&ba, tid);
     911    return ba;
     912}
     913
     914QByteArray Launcher::readRegistersMessage(uint pid, uint tid)
     915{
     916    QByteArray ba;
     917    ba.reserve(15);
     918    ba.append(char(0)); // Register set, only 0 supported
     919    appendShort(&ba, 0); //R0
     920    appendShort(&ba, 16); // last register CPSR
     921    appendInt(&ba, pid);
     922    appendInt(&ba, tid);
    719923    return ba;
    720924}
     
    738942    d->m_device->sendTrkMessage(TrkContinue, TrkCallback(), ba, "CONTINUE");
    739943}
     944
     945// Acquire a device from SymbianDeviceManager, return 0 if not available.
     946Launcher *Launcher::acquireFromDeviceManager(const QString &serverName,
     947                                             QObject *parent,
     948                                             QString *errorMessage)
     949{
     950    SymbianUtils::SymbianDeviceManager *sdm = SymbianUtils::SymbianDeviceManager::instance();
     951    const QSharedPointer<trk::TrkDevice> device = sdm->acquireDevice(serverName);
     952    if (device.isNull()) {
     953        *errorMessage = tr("Unable to acquire a device for port '%1'. It appears to be in use.").arg(serverName);
     954        return 0;
     955    }
     956    // Wire release signal.
     957    Launcher *rc = new Launcher(trk::Launcher::ActionPingOnly, device, parent);
     958    connect(rc, SIGNAL(deviceDescriptionReceived(QString,QString)),
     959            sdm, SLOT(setAdditionalInformation(QString,QString)));
     960    connect(rc, SIGNAL(destroyed(QString)), sdm, SLOT(releaseDevice(QString)));
     961    return rc;
     962}
     963
     964// Preliminary release of device, disconnecting the signal.
     965void Launcher::releaseToDeviceManager(Launcher *launcher)
     966{
     967    SymbianUtils::SymbianDeviceManager *sdm = SymbianUtils::SymbianDeviceManager::instance();
     968    // Disentangle launcher and its device, remove connection from destroyed
     969    launcher->setCloseDevice(false);
     970    TrkDevice *device = launcher->trkDevice().data();
     971    launcher->disconnect(device);
     972    device->disconnect(launcher);
     973    launcher->disconnect(sdm);
     974    sdm->releaseDevice(launcher->trkServerName());
     975}
     976
     977void Launcher::getRegistersAndCallStack(uint pid, uint tid)
     978{
     979    d->m_device->sendTrkMessage(TrkReadRegisters,
     980                                TrkCallback(this, &Launcher::handleReadRegisters),
     981                                Launcher::readRegistersMessage(pid, tid));
     982    d->m_crashReportState.fetchingStackPID = pid;
     983    d->m_crashReportState.fetchingStackTID = tid;
     984}
     985
     986void Launcher::handleReadRegisters(const TrkResult &result)
     987{
     988    if(result.errorCode() || result.data.size() < (17*4)) {
     989        terminate();
     990        return;
     991    }
     992    const char* data = result.data.constData() + 1;
     993    d->m_crashReportState.registers.clear();
     994    d->m_crashReportState.stack.clear();
     995    for (int i=0;i<17;i++) {
     996        uint r = extractInt(data);
     997        data += 4;
     998        d->m_crashReportState.registers.append(r);
     999    }
     1000    d->m_crashReportState.sp = d->m_crashReportState.registers.at(13);
     1001
     1002    const ushort len = 1024 - (d->m_crashReportState.sp % 1024); //read to 1k boundary first
     1003    const QByteArray ba = Launcher::readMemoryMessage(d->m_crashReportState.fetchingStackPID,
     1004                                                      d->m_crashReportState.fetchingStackTID,
     1005                                                      d->m_crashReportState.sp,
     1006                                                      len);
     1007    d->m_device->sendTrkMessage(TrkReadMemory, TrkCallback(this, &Launcher::handleReadStack), ba);
     1008    d->m_crashReportState.sp += len;
     1009}
     1010
     1011void Launcher::handleReadStack(const TrkResult &result)
     1012{
     1013    if (result.errorCode()) {
     1014        //error implies memory fault when reaching end of stack
     1015        emit registersAndCallStackReadComplete(d->m_crashReportState.registers, d->m_crashReportState.stack);
     1016        return;
     1017    }
     1018
     1019    const uint len = extractShort(result.data.constData() + 1);
     1020    d->m_crashReportState.stack.append(result.data.mid(3, len));
     1021
     1022    if (d->m_crashReportState.sp - d->m_crashReportState.registers.at(13) > 0x10000) {
     1023        //read enough stack, stop here
     1024        emit registersAndCallStackReadComplete(d->m_crashReportState.registers, d->m_crashReportState.stack);
     1025        return;
     1026    }
     1027    //read 1k more
     1028    const QByteArray ba = Launcher::readMemoryMessage(d->m_crashReportState.fetchingStackPID,
     1029                                                      d->m_crashReportState.fetchingStackTID,
     1030                                                      d->m_crashReportState.sp,
     1031                                                      1024);
     1032    d->m_device->sendTrkMessage(TrkReadMemory, TrkCallback(this, &Launcher::handleReadStack), ba);
     1033    d->m_crashReportState.sp += 1024;
     1034}
     1035
    7401036} // namespace trk
Note: See TracChangeset for help on using the changeset viewer.