diff options
author | Lars Knoll <[email protected]> | 2014-03-04 10:35:11 +0100 |
---|---|---|
committer | The Qt Project <[email protected]> | 2014-03-07 16:55:12 +0100 |
commit | 39b54d7293741c712116010b33f0d9823ab2ab1c (patch) | |
tree | 0af462863604bc130b1232a53477185b9d59c158 | |
parent | 245f5ce7bb194438fc643e5c928382f47556e2f2 (diff) |
Fixes to breakpoint handling
Make sure stepping works correctly, and we always
break at a valid breakpoint.
Change-Id: I6a3032b3ae204484b8a92b2031904a7f681c7f80
Reviewed-by: Simon Hausmann <[email protected]>
-rw-r--r-- | src/qml/compiler/qv4isel_moth.cpp | 21 | ||||
-rw-r--r-- | src/qml/compiler/qv4isel_moth_p.h | 2 | ||||
-rw-r--r-- | src/qml/jsruntime/qv4debugging.cpp | 49 | ||||
-rw-r--r-- | src/qml/jsruntime/qv4debugging_p.h | 7 |
4 files changed, 42 insertions, 37 deletions
diff --git a/src/qml/compiler/qv4isel_moth.cpp b/src/qml/compiler/qv4isel_moth.cpp index 3993bc9acc..921af76151 100644 --- a/src/qml/compiler/qv4isel_moth.cpp +++ b/src/qml/compiler/qv4isel_moth.cpp @@ -385,8 +385,9 @@ void InstructionSelection::run(int functionIndex) push.value = quint32(locals); addInstruction(push); - uint currentLine = -1; + currentLine = -1; for (int i = 0, ei = _function->basicBlocks.size(); i != ei; ++i) { + blockNeedsDebugInstruction = irModule->debugMode; _block = _function->basicBlocks[i]; _nextBlock = (i < ei - 1) ? _function->basicBlocks[i + 1] : 0; _addrs.insert(_block, _codeNext - _codeStart); @@ -408,6 +409,7 @@ void InstructionSelection::run(int functionIndex) if (s->location.isValid()) { if (s->location.startLine != currentLine) { + blockNeedsDebugInstruction = false; currentLine = s->location.startLine; if (irModule->debugMode) { Instruction::Debug debug; @@ -423,11 +425,6 @@ void InstructionSelection::run(int functionIndex) s->accept(this); } - if (irModule->debugMode) { - Instruction::Debug debug; - debug.lineNumber = currentLine; - addInstruction(debug); - } } // TODO: patch stack size (the push instruction) @@ -1039,6 +1036,12 @@ void InstructionSelection::visitJump(IR::Jump *s) if (_removableJumps.contains(s)) return; + if (blockNeedsDebugInstruction) { + Instruction::Debug debug; + debug.lineNumber = currentLine; + addInstruction(debug); + } + Instruction::Jump jump; jump.offset = 0; ptrdiff_t loc = addInstruction(jump) + (((const char *)&jump.offset) - ((const char *)&jump)); @@ -1048,6 +1051,12 @@ void InstructionSelection::visitJump(IR::Jump *s) void InstructionSelection::visitCJump(IR::CJump *s) { + if (blockNeedsDebugInstruction) { + Instruction::Debug debug; + debug.lineNumber = currentLine; + addInstruction(debug); + } + Param condition; if (IR::Temp *t = s->cond->asTemp()) { condition = getResultParam(t); diff --git a/src/qml/compiler/qv4isel_moth_p.h b/src/qml/compiler/qv4isel_moth_p.h index 000ff634e7..4c01434156 100644 --- a/src/qml/compiler/qv4isel_moth_p.h +++ b/src/qml/compiler/qv4isel_moth_p.h @@ -169,6 +169,8 @@ private: QQmlEnginePrivate *qmlEngine; + bool blockNeedsDebugInstruction; + uint currentLine; IR::BasicBlock *_block; IR::BasicBlock *_nextBlock; diff --git a/src/qml/jsruntime/qv4debugging.cpp b/src/qml/jsruntime/qv4debugging.cpp index 92273417a9..04489903c3 100644 --- a/src/qml/jsruntime/qv4debugging.cpp +++ b/src/qml/jsruntime/qv4debugging.cpp @@ -113,12 +113,12 @@ public: Debugger::Debugger(QV4::ExecutionEngine *engine) : m_engine(engine) + , m_currentContext(0) , m_agent(0) , m_state(Running) , m_stepping(NotStepping) , m_pauseRequested(false) , m_haveBreakPoints(false) - , m_stopForStepping(false) , m_breakOnThrow(false) , m_returnedValue(Primitive::undefinedValue()) , m_gatherSources(0) @@ -180,6 +180,7 @@ void Debugger::resume(Speed speed) if (!m_returnedValue.isUndefined()) m_returnedValue = Encode::undefined(); + m_currentContext = m_engine->currentContext(); m_stepping = speed; m_runningCondition.wakeAll(); } @@ -187,14 +188,14 @@ void Debugger::resume(Speed speed) void Debugger::addBreakPoint(const QString &fileName, int lineNumber, const QString &condition) { QMutexLocker locker(&m_lock); - m_breakPoints.insert(DebuggerBreakPoint(fileName, lineNumber), condition); + m_breakPoints.insert(DebuggerBreakPoint(fileName.mid(fileName.lastIndexOf('/') + 1), lineNumber), condition); m_haveBreakPoints = true; } void Debugger::removeBreakPoint(const QString &fileName, int lineNumber) { QMutexLocker locker(&m_lock); - m_breakPoints.remove(DebuggerBreakPoint(fileName, lineNumber)); + m_breakPoints.remove(DebuggerBreakPoint(fileName.mid(fileName.lastIndexOf('/') + 1), lineNumber)); m_haveBreakPoints = !m_breakPoints.isEmpty(); } @@ -207,10 +208,8 @@ void Debugger::setBreakOnThrow(bool onoff) Debugger::ExecutionState Debugger::currentExecutionState() const { - // ### Locking ExecutionState state; - state.function = getFunction(); - state.fileName = state.function->sourceFile(); + state.fileName = getFunction()->sourceFile(); state.lineNumber = engine()->currentContext()->lineNumber; return state; @@ -451,10 +450,7 @@ void Debugger::maybeBreakAtInstruction() return; QMutexLocker locker(&m_lock); - if (m_breakPoints.isEmpty()) - return; - - ExecutionState state = currentExecutionState(); + int lineNumber = engine()->currentContext()->lineNumber; if (m_gatherSources) { m_gatherSources->run(); @@ -464,20 +460,22 @@ void Debugger::maybeBreakAtInstruction() switch (m_stepping) { case StepOver: + if (m_currentContext != m_engine->currentContext()) + break; + // fall through case StepIn: pauseAndWait(Step); - break; + return; case StepOut: case NotStepping: - if (m_stopForStepping) { // Serve debugging requests from the agent - m_stopForStepping = false; - pauseAndWait(Step); - } else if (m_pauseRequested) { // Serve debugging requests from the agent - m_pauseRequested = false; - pauseAndWait(PauseRequest); - } else if (reallyHitTheBreakPoint(state.fileName, state.lineNumber)) { - pauseAndWait(BreakPoint); - } + break; + } + + if (m_pauseRequested) { // Serve debugging requests from the agent + m_pauseRequested = false; + pauseAndWait(PauseRequest); + } else if (m_haveBreakPoints && reallyHitTheBreakPoint(getFunction()->sourceFile(), lineNumber)) { + pauseAndWait(BreakPoint); } } @@ -486,8 +484,7 @@ void Debugger::enteringFunction() QMutexLocker locker(&m_lock); if (m_stepping == StepIn) { - m_stepping = NotStepping; - m_stopForStepping = true; + m_currentContext = m_engine->currentContext(); } } @@ -497,9 +494,9 @@ void Debugger::leavingFunction(const ReturnedValue &retVal) QMutexLocker locker(&m_lock); - if (m_stepping == StepOut || m_stepping == StepOver) { - m_stepping = NotStepping; - m_stopForStepping = true; + if (m_stepping != NotStepping && m_currentContext == m_engine->currentContext()) { + m_currentContext = m_engine->currentContext()->parent; + m_stepping = StepOver; m_returnedValue = retVal; } } @@ -552,7 +549,7 @@ void Debugger::pauseAndWait(PauseReason reason) bool Debugger::reallyHitTheBreakPoint(const QString &filename, int linenr) { - BreakPoints::iterator it = m_breakPoints.find(DebuggerBreakPoint(filename, linenr)); + BreakPoints::iterator it = m_breakPoints.find(DebuggerBreakPoint(filename.mid(filename.lastIndexOf('/') + 1), linenr)); if (it == m_breakPoints.end()) return false; QString condition = it.value(); diff --git a/src/qml/jsruntime/qv4debugging_p.h b/src/qml/jsruntime/qv4debugging_p.h index 9c97dd5f9e..47a7d77b28 100644 --- a/src/qml/jsruntime/qv4debugging_p.h +++ b/src/qml/jsruntime/qv4debugging_p.h @@ -161,14 +161,12 @@ public: void setBreakOnThrow(bool onoff); + // used for testing struct ExecutionState { - ExecutionState() : lineNumber(-1), function(0) {} QString fileName; int lineNumber; - Function *function; }; - ExecutionState currentExecutionState() const; bool pauseAtNextOpportunity() const { @@ -203,8 +201,8 @@ private: void runInEngine_havingLock(Debugger::Job *job); private: - QV4::ExecutionEngine *m_engine; + QV4::ExecutionContext *m_currentContext; DebuggerAgent *m_agent; QMutex m_lock; QWaitCondition m_runningCondition; @@ -212,7 +210,6 @@ private: Speed m_stepping; bool m_pauseRequested; bool m_haveBreakPoints; - bool m_stopForStepping; bool m_breakOnThrow; BreakPoints m_breakPoints; |