Changeset 846 for trunk/tools/runonphone/symbianutils/launcher.cpp
- Timestamp:
- May 5, 2011, 5:36:53 AM (14 years ago)
- Location:
- trunk
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk
- Property svn:mergeinfo changed
/branches/vendor/nokia/qt/4.7.2 (added) merged: 845 /branches/vendor/nokia/qt/current merged: 844 /branches/vendor/nokia/qt/4.6.3 removed
- Property svn:mergeinfo changed
-
trunk/tools/runonphone/symbianutils/launcher.cpp
r769 r846 1 1 /**************************************************************************** 2 2 ** 3 ** Copyright (C) 201 0Nokia Corporation and/or its subsidiary(-ies).3 ** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). 4 4 ** All rights reserved. 5 5 ** Contact: Nokia Corporation (qt-info@nokia.com) … … 45 45 #include "trkdevice.h" 46 46 #include "bluetoothlistener.h" 47 #include "symbiandevicemanager.h" 47 48 48 49 #include <QtCore/QTimer> … … 54 55 #include <QtCore/QScopedPointer> 55 56 57 #include <cstdio> 58 56 59 namespace trk { 60 61 struct 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 76 CrashReportState::CrashReportState() 77 { 78 clear(); 79 } 80 81 void CrashReportState::clear() 82 { 83 threads.clear(); 84 stack.clear(); 85 sp = fetchingStackPID = fetchingStackTID = 0; 86 } 57 87 58 88 struct LauncherPrivate { … … 62 92 uint copyFileHandle; 63 93 QScopedPointer<QByteArray> data; 64 int position; 94 qint64 position; 95 QScopedPointer<QFile> localFile; 65 96 }; 66 97 … … 76 107 77 108 CopyState m_copyState; 109 CopyState m_downloadState; 78 110 QString m_fileName; 79 111 QStringList m_commandLineArgs; … … 82 114 Launcher::Actions m_startupActions; 83 115 bool m_closeDevice; 116 CrashReportState m_crashReportState; 84 117 }; 85 118 … … 101 134 { 102 135 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))); 105 137 } 106 138 107 139 Launcher::~Launcher() 108 140 { 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()); 109 145 logMessage("Shutting down.\n"); 110 146 delete d; … … 155 191 } 156 192 193 void Launcher::setDownloadFileName(const QString &srcName, const QString &dstName) 194 { 195 d->m_downloadState.sourceFileName = srcName; 196 d->m_downloadState.destinationFileName = dstName; 197 } 198 157 199 void Launcher::setInstallFileName(const QString &name) 158 200 { … … 189 231 { 190 232 errorMessage->clear(); 233 d->m_crashReportState.clear(); 191 234 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; 196 255 logMessage(msg); 197 256 } … … 215 274 if (!d->m_device->isOpen() && !d->m_device->open(errorMessage)) 216 275 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 }222 276 setState(Connecting); 223 277 // Set up the temporary 'waiting' state if we do not get immediate connection … … 253 307 else if (d->m_startupActions & ActionRun) 254 308 startInferiorIfNeeded(); 309 else if (d->m_startupActions & ActionDownload) 310 copyFileFromRemote(); 255 311 } 256 312 … … 265 321 if (d->m_verbose) 266 322 qDebug() << "LAUNCHER: " << qPrintable(msg); 323 } 324 325 void Launcher::handleFinished() 326 { 327 if (d->m_closeDevice) 328 d->m_device->close(); 329 emit finished(); 267 330 } 268 331 … … 288 351 case WaitingForTrk: 289 352 setState(Disconnected); 290 emit finished();353 handleFinished(); 291 354 break; 292 355 } … … 332 395 QByteArray str = result.toString().toUtf8(); 333 396 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); 336 413 return; 337 414 } … … 369 446 // target->host OS notification 370 447 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 bytes377 uint codeseg = extractInt(data + 10); //code address: 4 bytes; code base address for the library378 uint dataseg = extractInt(data + 14); //data address: 4 bytes; data base address for the library379 uint len = extractShort(data + 18); //length: 2 bytes; length of the library name string to follow380 QByteArray name = result.data.mid(20, len); // name: library name381 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 */393 448 394 449 if (result.data.size() < 10) 395 450 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 } 396 462 QByteArray ba; 397 463 ba.append(result.data.mid(2, 8)); 398 464 d->m_device->sendTrkMessage(TrkContinue, TrkCallback(), ba, "CONTINUE"); 399 //d->m_device->sendTrkAck(result.token)400 465 break; 401 466 } 402 467 case TrkNotifyDeleted: { // NotifyDeleted 403 468 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); 405 473 const QString name = len ? QString::fromAscii(result.data.mid(12, len)) : QString(); 406 474 logMessage(QString::fromLatin1("%1 %2 UNLOAD: %3"). … … 408 476 arg(name)); 409 477 d->m_device->sendTrkAck(result.token); 410 if (itemType == 0// process478 if (itemType == kDSOSProcessItem // process 411 479 && result.data.size() >= 10 412 480 && 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 } 414 496 } 415 497 break; … … 447 529 if (d->m_startupActions == ActionPingOnly) { 448 530 setState(Disconnected); 449 emit finished();531 handleFinished(); 450 532 } 451 533 return; … … 456 538 d->m_session.trkAppVersion.protocolMinor = result.data.at(4); 457 539 setState(DeviceDescriptionReceived); 540 const QString msg = deviceDescription(); 541 emit deviceDescriptionReceived(trkServerName(), msg); 458 542 // Ping mode: Log & Terminate 459 543 if (d->m_startupActions == ActionPingOnly) { 460 qWarning("%s", qPrintable( deviceDescription()));544 qWarning("%s", qPrintable(msg)); 461 545 setState(Disconnected); 462 emit finished(); 463 } 546 handleFinished(); 547 } 548 } 549 550 static 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 555 static inline QString msgCannotOpenLocalFile(const QString &fileName, const QString &message) 556 { 557 return Launcher::tr("Cannot open '%1': %2").arg(fileName, message); 464 558 } 465 559 … … 467 561 { 468 562 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); 470 566 disconnectTrk(); 471 567 return; … … 473 569 const char *data = result.data.data(); 474 570 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 } 477 582 d->m_copyState.data.reset(new QByteArray(file.readAll())); 478 d->m_copyState.position = 0;479 583 file.close(); 480 584 continueCopying(); 585 } 586 587 void 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 616 void 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 624 void 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 } 481 641 } 482 642 … … 494 654 void Launcher::continueCopying(uint lastCopiedBlockSize) 495 655 { 496 intsize = d->m_copyState.data->length();656 qint64 size = d->m_copyState.data->length(); 497 657 d->m_copyState.position += lastCopiedBlockSize; 498 658 if (size == 0) 499 659 emit copyProgress(100); 500 660 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)); 503 664 } 504 665 if (d->m_copyState.position < size) { … … 533 694 else if (d->m_startupActions & ActionRun) 534 695 startInferiorIfNeeded(); 696 else if (d->m_startupActions & ActionDownload) 697 copyFileFromRemote(); 535 698 else 536 699 disconnectTrk(); … … 577 740 } 578 741 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 579 751 QByteArray ba; 580 752 appendInt(&ba, d->m_session.pid); … … 587 759 logMessage(" FINISHED: " + stringFromArray(result.data)); 588 760 setState(Disconnected); 589 emit finished();761 handleFinished(); 590 762 } 591 763 … … 596 768 const char *data = result.data.data() + 1; 597 769 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 } 605 778 } 606 779 } 607 }608 logMessage(str);780 logMessage(str); 781 } 609 782 } 610 783 … … 670 843 emit copyingStarted(); 671 844 QByteArray ba; 672 ba.append(char(10)); 845 ba.append(char(10)); //kDSFileOpenWrite | kDSFileOpenBinary 673 846 appendString(&ba, d->m_copyState.destinationFileName.toLocal8Bit(), TargetByteOrder, false); 674 847 d->m_device->sendTrkMessage(TrkOpenFile, TrkCallback(this, &Launcher::handleFileCreation), ba); 848 } 849 850 void 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); 675 857 } 676 858 … … 695 877 if (d->m_startupActions & ActionRun) { 696 878 startInferiorIfNeeded(); 879 } else if (d->m_startupActions & ActionDownload) { 880 copyFileFromRemote(); 697 881 } else { 698 882 disconnectTrk(); … … 705 889 // It's not started yet 706 890 QByteArray ba; 707 appendShort(&ba, 0, TargetByteOrder); // create new process 891 appendShort(&ba, 0, TargetByteOrder); // create new process (kDSOSProcessItem) 708 892 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 902 QByteArray 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 914 QByteArray 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); 719 923 return ba; 720 924 } … … 738 942 d->m_device->sendTrkMessage(TrkContinue, TrkCallback(), ba, "CONTINUE"); 739 943 } 944 945 // Acquire a device from SymbianDeviceManager, return 0 if not available. 946 Launcher *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. 965 void 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 977 void 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 986 void 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 1011 void 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 740 1036 } // namespace trk
Note:
See TracChangeset
for help on using the changeset viewer.