void ScriptDebuggerPrivate::exceptionThrow(qint64 /*scriptId*/, const QScriptValue &exception, bool hasHandler) { if (!hasHandler) { errorMessage(QString::fromLatin1("uncaught exception: %0").arg(exception.toString())); QScriptContext *ctx = engine()->currentContext(); int lineNumber = QScriptContextInfo(ctx).lineNumber(); ScriptInfo *info = scriptInfo(ctx); QString lineText = info ? info->lineText(lineNumber) : QString("(no source text available)"); message(QString::fromLatin1("%0\t%1").arg(lineNumber).arg(lineText)); interactive(); } }
void ScriptDebuggerPrivate::positionChange(qint64 scriptId, int lineNumber, int /*columnNumber*/) { ScriptInfo *info = 0; bool enterInteractiveMode = false; if (m_bpManager->hasBreakpoints()) { // check if we hit a breakpoint info = m_scripts.value(scriptId); QScriptContext *ctx = engine()->currentContext(); QScriptContextInfo ctxInfo(ctx); QScriptValue callee = ctx->callee(); // try fileName:lineNumber int bpid = m_bpManager->findBreakpoint(info->fileName(), lineNumber); if ((bpid != -1) && m_bpManager->isBreakpointEnabled(bpid)) { message(QString::fromLatin1("Breakpoint %0 at %1:%2") .arg(bpid + 1).arg(info->fileName()).arg(lineNumber)); if (m_bpManager->isBreakpointSingleShot(bpid)) m_bpManager->removeBreakpoint(bpid); } if (bpid == -1) { // try function bpid = m_bpManager->findBreakpoint(callee); if ((bpid != -1) && m_bpManager->isBreakpointEnabled(bpid)) { message(QString::fromLatin1("Breakpoint %0, %1()") .arg(bpid + 1).arg(ctxInfo.functionName())); if (m_bpManager->isBreakpointSingleShot(bpid)) m_bpManager->removeBreakpoint(bpid); } } if ((bpid == -1) && !ctxInfo.functionName().isEmpty()) { // try functionName:fileName bpid = m_bpManager->findBreakpoint(ctxInfo.functionName(), ctxInfo.fileName()); if ((bpid != -1) && m_bpManager->isBreakpointEnabled(bpid)) { message(QString::fromLatin1("Breakpoint %0, %1():%2").arg(bpid + 1) .arg(ctxInfo.functionName()).arg(ctxInfo.fileName())); if (m_bpManager->isBreakpointSingleShot(bpid)) m_bpManager->removeBreakpoint(bpid); } } enterInteractiveMode = (bpid != -1); } switch (mode()) { case Run: break; case StepInto: enterInteractiveMode = true; break; case StepOver: enterInteractiveMode = enterInteractiveMode || (m_stepDepth <= 0); break; } if (enterInteractiveMode) { if (!info) info = m_scripts.value(scriptId); Q_ASSERT(info); message(QString::fromLatin1("%0\t%1").arg(lineNumber).arg(info->lineText(lineNumber))); interactive(); } }
bool ScriptDebuggerPrivate::executeCommand(const QString &command, const QStringList &args) { if (command == QLatin1String("c") || command == QLatin1String("continue")) { setMode(Run); return true; } else if (command == QLatin1String("s") || command == QLatin1String("step")) { setMode(StepInto); return true; } else if (command == QLatin1String("n") || command == QLatin1String("next")) { setMode(StepOver); m_stepDepth = 0; return true; } else if (command == QLatin1String("f") || command == QLatin1String("frame")) { bool ok = false; int index = args.value(0).toInt(&ok); if (ok) { if (index < 0 || index >= frameCount()) { errorMessage("No such frame."); } else { setCurrentFrameIndex(index); QScriptContext *ctx = currentFrameContext(); message(QString::fromLatin1("#%0 %1").arg(index).arg(ctx->toString())); } } } else if (command == QLatin1String("bt") || command == QLatin1String("backtrace")) { QScriptContext *ctx = engine()->currentContext(); int index = -1; while (ctx) { ++index; QString line = ctx->toString(); message(QString::fromLatin1("#%0 %1").arg(index).arg(line)); ctx = ctx->parentContext(); } } else if (command == QLatin1String("up")) { int index = currentFrameIndex() + 1; if (index == frameCount()) { errorMessage(QString::fromLatin1("Initial frame selected; you cannot go up.")); } else { setCurrentFrameIndex(index); QScriptContext *ctx = currentFrameContext(); message(QString::fromLatin1("#%0 %1").arg(index).arg(ctx->toString())); } } else if (command == QLatin1String("down")) { int index = currentFrameIndex() - 1; if (index < 0) { errorMessage(QString::fromLatin1("Bottom (innermost) frame selected; you cannot go down.")); } else { setCurrentFrameIndex(index); QScriptContext *ctx = currentFrameContext(); message(QString::fromLatin1("#%0 %1").arg(index).arg(ctx->toString())); } } else if (command == QLatin1String("b") || command == QLatin1String("break")) { QString str = args.value(0); int colonIndex = str.indexOf(QLatin1Char(':')); if (colonIndex != -1) { // filename:line form QString fileName = str.left(colonIndex); int lineNumber = str.mid(colonIndex+1).toInt(); int id = m_bpManager->setBreakpoint(fileName, lineNumber); message(QString::fromLatin1("Breakpoint %0 at %1, line %2.").arg(id+1).arg(fileName).arg(lineNumber)); } else { // function QScriptValue fun = engine()->globalObject().property(str); if (fun.isFunction()) { int id = m_bpManager->setBreakpoint(fun); message(QString::fromLatin1("Breakpoint %0 at %1().").arg(id+1).arg(str)); } } } else if (command == QLatin1String("d") || command == QLatin1String("delete")) { int id = args.value(0).toInt() - 1; m_bpManager->removeBreakpoint(id); } else if (command == QLatin1String("disable")) { int id = args.value(0).toInt() - 1; m_bpManager->setBreakpointEnabled(id, false); } else if (command == QLatin1String("enable")) { int id = args.value(0).toInt() - 1; m_bpManager->setBreakpointEnabled(id, true); } else if (command == QLatin1String("list")) { QScriptContext *ctx = currentFrameContext(); ScriptInfo *progInfo = scriptInfo(ctx); if (!progInfo) { errorMessage("No source text available for this frame."); } else { QScriptContextInfo ctxInfo(ctx); bool ok; int line = args.value(0).toInt(&ok); if (ok) { line = qMax(1, line - 5); } else { line = listLineNumber(); if (line == -1) line = qMax(progInfo->lineNumber(), ctxInfo.lineNumber() - 5); } for (int i = line; i < line + 10; ++i) { message(QString::fromLatin1("%0\t%1").arg(i).arg(progInfo->lineText(i))); } setListLineNumber(line + 10); } } else if (command == QLatin1String("info")) { if (args.size() < 1) { } else { QString what = args.value(0); if (what == QLatin1String("locals")) { QScriptValueIterator it(currentFrameContext()->activationObject()); while (it.hasNext()) { it.next(); QString line; line.append(it.name()); line.append(QLatin1String(" = ")); line.append(safeValueToString(it.value())); message(line); } } } } else if (command == QLatin1String("help")) { message("continue - continue execution\n" "step - step into statement\n" "next - step over statement\n" "list - show where you are\n" "\n" "break - set breakpoint\n" "delete - remove breakpoint\n" "disable - disable breakpoint\n" "enable - enable breakpoint\n" "\n" "backtrace - show backtrace\n" "up - one frame up\n" "down - one frame down\n" "frame - set frame\n" "\n" "info locals - show local variables"); } else { errorMessage(QString::fromLatin1("Undefined command \"%0\". Try \"help\".") .arg(command)); } return false; }