Changeset 846 for trunk/tools/runonphone/trksignalhandler.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/trksignalhandler.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) … … 43 43 #include <QCoreApplication> 44 44 #include <QObject> 45 #include <QFile> 46 #include <QDir> 45 47 #include "trksignalhandler.h" 48 #include "trkutils.h" 49 50 class CrashState 51 { 52 public: 53 uint pid; 54 uint tid; 55 QString crashReason; 56 uint crashPC; 57 }; 46 58 47 59 class TrkSignalHandlerPrivate … … 55 67 QTextStream err; 56 68 int loglevel; 69 int lastpercent; 70 QList<trk::Library> libraries; 71 QFile crashlogtextfile; 72 QFile crashstackfile; 73 QList<CrashState> queuedCrashes; 74 QList<int> dyingThreads; 75 QString crashlogPath; 76 bool crashlog; 77 bool terminateNeeded; 57 78 }; 58 79 … … 108 129 void TrkSignalHandler::applicationRunning(uint pid) 109 130 { 131 Q_UNUSED(pid) 110 132 if (d->loglevel > 0) 111 133 d->out << "Running..." << endl; … … 132 154 { 133 155 if (d->loglevel > 0) { 134 d->out << percent << "% "; 156 if (d->lastpercent == 0) 157 d->out << "[ ]\r[" << flush; 158 while (percent > d->lastpercent) { 159 d->out << QLatin1Char('#'); 160 d->lastpercent+=2; //because typical console is 80 chars wide 161 } 135 162 d->out.flush(); 136 163 if (percent==100) … … 150 177 } 151 178 179 void TrkSignalHandler::setCrashLogging(bool enabled) 180 { 181 d->crashlog = enabled; 182 } 183 184 void TrkSignalHandler::setCrashLogPath(QString path) 185 { 186 d->crashlogPath = path; 187 } 188 189 bool lessThanCodeBase(const trk::Library& cs1, const trk::Library& cs2) 190 { 191 return cs1.codeseg < cs2.codeseg; 192 } 193 152 194 void TrkSignalHandler::stopped(uint pc, uint pid, uint tid, const QString& reason) 153 195 { 154 196 d->err << "STOPPED: pc=" << hex << pc << " pid=" << pid 155 197 << " tid=" << tid << dec << " - " << reason << endl; 156 // if it was a breakpoint, then we could continue with "emit resume(pid, tid);" 157 // since we have set no breakpoints, it will be a just in time debug of a panic / exception 158 emit terminate(); 198 199 if (d->crashlog) { 200 CrashState cs; 201 cs.pid = pid; 202 cs.tid = tid; 203 cs.crashPC = pc; 204 cs.crashReason = reason; 205 206 if (d->dyingThreads.contains(tid)) { 207 if(d->queuedCrashes.isEmpty()) 208 emit terminate(); 209 else 210 d->terminateNeeded = true; 211 } else { 212 d->queuedCrashes.append(cs); 213 d->dyingThreads.append(tid); 214 215 if (d->queuedCrashes.count() == 1) { 216 d->err << "Fetching registers and stack..." << endl; 217 emit getRegistersAndCallStack(pid, tid); 218 } 219 } 220 } 221 else 222 emit terminate(); 223 } 224 225 void TrkSignalHandler::registersAndCallStackReadComplete(const QList<uint>& registers, const QByteArray& stack) 226 { 227 CrashState cs = d->queuedCrashes.first(); 228 QDir dir(d->crashlogPath); 229 d->crashlogtextfile.setFileName(dir.filePath(QString("d_exc_%1.txt").arg(cs.tid))); 230 d->crashstackfile.setFileName(dir.filePath(QString("d_exc_%1.stk").arg(cs.tid))); 231 d->crashlogtextfile.open(QIODevice::WriteOnly); 232 QTextStream crashlog(&d->crashlogtextfile); 233 234 crashlog << "-----------------------------------------------------------------------------" << endl; 235 crashlog << "EKA2 USER CRASH LOG" << endl; 236 crashlog << "Thread Name: " << QString("ProcessID-%1::ThreadID-%2").arg(cs.pid).arg(cs.tid) << endl; 237 crashlog << "Thread ID: " << cs.tid << endl; 238 //this is wrong, but TRK doesn't make stack limit available so we lie 239 crashlog << QString("User Stack %1-%2").arg(registers.at(13), 8, 16, QChar('0')).arg(registers.at(13) + stack.size(), 8, 16, QChar('0')) << endl; 240 //this is also wrong, but TRK doesn't give all information for exceptions 241 crashlog << QString("Panic: PC=%1 ").arg(cs.crashPC, 8, 16, QChar('0')) << cs.crashReason << endl; 242 crashlog << endl; 243 crashlog << "USER REGISTERS:" << endl; 244 crashlog << QString("CPSR=%1").arg(registers.at(16), 8, 16, QChar('0')) << endl; 245 for (int i=0;i<16;i+=4) { 246 crashlog << QString("r%1=%2 %3 %4 %5") 247 .arg(i, 2, 10, QChar('0')) 248 .arg(registers.at(i), 8, 16, QChar('0')) 249 .arg(registers.at(i+1), 8, 16, QChar('0')) 250 .arg(registers.at(i+2), 8, 16, QChar('0')) 251 .arg(registers.at(i+3), 8, 16, QChar('0')) << endl; 252 } 253 crashlog << endl; 254 255 //emit info for post mortem debug 256 qSort(d->libraries.begin(), d->libraries.end(), lessThanCodeBase); 257 d->err << "Code Segments:" << endl; 258 crashlog << "CODE SEGMENTS:" << endl; 259 for(int i=0; i<d->libraries.count(); i++) { 260 const trk::Library& seg = d->libraries.at(i); 261 if(seg.pid != cs.pid) 262 continue; 263 if (d->loglevel > 1) { 264 d->err << QString("Code: %1 Data: %2 Name: ") 265 .arg(seg.codeseg, 8, 16, QChar('0')) 266 .arg(seg.dataseg, 8, 16, QChar('0')) 267 << seg.name << endl; 268 } 269 270 //produce fake code segment end addresses since we don't get the real ones from TRK 271 uint end; 272 if (i+1 < d->libraries.count()) 273 end = d->libraries.at(i+1).codeseg - 1; 274 else 275 end = 0xFFFFFFFF; 276 277 crashlog << QString("%1-%2 ") 278 .arg(seg.codeseg, 8, 16, QChar('0')) 279 .arg(end, 8, 16, QChar('0')) 280 << seg.name << endl; 281 } 282 283 d->crashlogtextfile.close(); 284 285 if (d->loglevel > 1) { 286 d->err << "Registers:" << endl; 287 for (int i=0;i<16;i++) { 288 d->err << QString("R%1: %2 ").arg(i, 2, 10, QChar('0')).arg(registers.at(i), 8, 16, QChar('0')); 289 if (i % 4 == 3) 290 d->err << endl; 291 } 292 d->err << QString("CPSR: %1").arg(registers.at(16), 8, 16, QChar('0')) << endl; 293 294 d->err << "Stack:" << endl; 295 uint sp = registers.at(13); 296 for(int i=0; i<stack.size(); i+=16, sp+=16) { 297 d->err << QString("%1: ").arg(sp, 8, 16, QChar('0')); 298 d->err << trk::stringFromArray(stack.mid(i,16)); 299 d->err << endl; 300 } 301 } 302 d->crashstackfile.open(QIODevice::WriteOnly); 303 d->crashstackfile.write(stack); 304 d->crashstackfile.close(); 305 306 if (d->loglevel > 0) 307 d->err << "Crash logs saved to " << d->crashlogtextfile.fileName() << " & " << d->crashstackfile.fileName() << endl; 308 309 // resume the thread to allow Symbian OS to handle the panic normally. 310 // terminate when a non main thread is suspended reboots the phone (TRK bug) 311 emit resume(cs.pid, cs.tid); 312 313 //fetch next crashed thread 314 d->queuedCrashes.removeFirst(); 315 if (d->queuedCrashes.count()) { 316 cs = d->queuedCrashes.first(); 317 d->err << "Fetching registers and stack..." << endl; 318 emit getRegistersAndCallStack(cs.pid, cs.tid); 319 } 320 else if (d->terminateNeeded) 321 emit terminate(); 322 323 } 324 325 void TrkSignalHandler::libraryLoaded(const trk::Library &lib) 326 { 327 d->libraries << lib; 328 } 329 330 void TrkSignalHandler::libraryUnloaded(const trk::Library &lib) 331 { 332 for (QList<trk::Library>::iterator i = d->libraries.begin(); i != d->libraries.end(); i++) { 333 if((*i).name == lib.name && (*i).pid == lib.pid) 334 i = d->libraries.erase(i); 335 } 159 336 } 160 337 … … 168 345 : out(stdout), 169 346 err(stderr), 170 loglevel(0) 347 loglevel(0), 348 lastpercent(0), 349 terminateNeeded(false) 171 350 { 172 351
Note:
See TracChangeset
for help on using the changeset viewer.