diff options
author | ggayed | 2012-01-18 17:37:06 +0000 |
---|---|---|
committer | ggayed | 2012-01-18 17:37:06 +0000 |
commit | 67d2be48b0df8a525c30f445eafe147060d17751 (patch) | |
tree | 0878271a739cdc079da06b7f06b8045733892add /development | |
parent | 517f8811d29ae91f9abef08ef0078f565c94df6e (diff) | |
download | webtools.jsdt.debug-67d2be48b0df8a525c30f445eafe147060d17751.tar.gz webtools.jsdt.debug-67d2be48b0df8a525c30f445eafe147060d17751.tar.xz webtools.jsdt.debug-67d2be48b0df8a525c30f445eafe147060d17751.zip |
send onError instead of onBreak for errors, clear CrossfireServer fully when connection dropped, update Crossfire version string
Diffstat (limited to 'development')
5 files changed, 220 insertions, 167 deletions
diff --git a/development/org.eclipse.wst.jsdt.debug.ie/IECrossfireInstaller/Release/IECrossfireInstaller.msi b/development/org.eclipse.wst.jsdt.debug.ie/IECrossfireInstaller/Release/IECrossfireInstaller.msi Binary files differindex 493a766..78f3e02 100644 --- a/development/org.eclipse.wst.jsdt.debug.ie/IECrossfireInstaller/Release/IECrossfireInstaller.msi +++ b/development/org.eclipse.wst.jsdt.debug.ie/IECrossfireInstaller/Release/IECrossfireInstaller.msi diff --git a/development/org.eclipse.wst.jsdt.debug.ie/IECrossfireServer/CrossfireContext.cpp b/development/org.eclipse.wst.jsdt.debug.ie/IECrossfireServer/CrossfireContext.cpp index b5c7303..cfbb674 100644 --- a/development/org.eclipse.wst.jsdt.debug.ie/IECrossfireServer/CrossfireContext.cpp +++ b/development/org.eclipse.wst.jsdt.debug.ie/IECrossfireServer/CrossfireContext.cpp @@ -80,6 +80,15 @@ const wchar_t* CrossfireContext::KEY_CAUSE = L"cause"; const wchar_t* CrossfireContext::KEY_MESSAGE = L"message"; const wchar_t* CrossfireContext::KEY_TITLE = L"title"; +/* event: onError */ +const wchar_t* CrossfireContext::EVENT_ONERROR = L"onError"; +const wchar_t* CrossfireContext::KEY_CATEGORY = L"category"; +const wchar_t* CrossfireContext::KEY_COLUMNNUMBER = L"columnNumber"; +const wchar_t* CrossfireContext::KEY_ERROR = L"error"; +const wchar_t* CrossfireContext::KEY_FILENAME = L"fileName"; +const wchar_t* CrossfireContext::KEY_LINENUMBER = L"lineNumber"; +const wchar_t* CrossfireContext::VALUE_JS = L"js"; + /* event: onResume */ const wchar_t* CrossfireContext::EVENT_ONRESUME = L"onResume"; @@ -672,165 +681,6 @@ void CrossfireContext::evalComplete(IDebugProperty* value, void* data) { /* CrossfireContext */ -void CrossfireContext::breakpointHit(IRemoteDebugApplicationThread *pDebugAppThread, BREAKREASON br, IActiveScriptErrorDebug *pScriptErrorDebug) { - m_running = false; - - /* - * IE has just entered a suspended state. If any of the steps preceeding the - * sending of the onBreak event fail then a resume (step out) must be done so - * that the server is not left in a suspended state without the client's knowledge. - */ - CComPtr<IEnumDebugStackFrames> stackFrames = NULL; - HRESULT hr = pDebugAppThread->EnumStackFrames(&stackFrames); - if (FAILED(hr)) { - Logger::error("CrossfireContext.breakpointHit(): EnumStackFrames() failed", hr); - resumeFromBreak(BREAKRESUMEACTION_STEP_OUT); - return; - } - - DebugStackFrameDescriptor stackFrameDescriptor; - ULONG numFetched = 0; - hr = stackFrames->Next(1, &stackFrameDescriptor, &numFetched); - if (FAILED(hr) || numFetched != 1) { - Logger::error("CrossfireContext.breakpointHit(): EnumStackFrames->Next() failed", hr); - resumeFromBreak(BREAKRESUMEACTION_STEP_OUT); - return; - } - - IDebugStackFrame* frame = stackFrameDescriptor.pdsf; - CComPtr<IDebugCodeContext> codeContext = NULL; - hr = frame->GetCodeContext(&codeContext); - if (FAILED(hr)) { - Logger::error("CrossfireContext.breakpointHit(): GetCodeContext() failed", hr); - resumeFromBreak(BREAKRESUMEACTION_STEP_OUT); - return; - } - - CComPtr<IDebugDocumentContext> documentContext = NULL; - hr = codeContext->GetDocumentContext(&documentContext); - if (FAILED(hr)) { - Logger::error("CrossfireContext.breakpointHit(): GetDocumentContext() failed", hr); - resumeFromBreak(BREAKRESUMEACTION_STEP_OUT); - return; - } - - CComPtr<IDebugDocument> document = NULL; - hr = documentContext->GetDocument(&document); - if (FAILED(hr)) { - Logger::error("CrossfireContext.breakpointHit(): GetDocument() failed", hr); - resumeFromBreak(BREAKRESUMEACTION_STEP_OUT); - return; - } - - CComPtr<IDebugDocumentText> documentText = NULL; - hr = document->QueryInterface(IID_IDebugDocumentText, (void**)&documentText); - if (FAILED(hr)) { - Logger::error("CrossfireContext.breakpointHit(): QueryInterface() failed", hr); - resumeFromBreak(BREAKRESUMEACTION_STEP_OUT); - return; - } - - ULONG position, numChars; - hr = documentText->GetPositionOfContext(documentContext, &position, &numChars); - if (FAILED(hr)) { - Logger::error("CrossfireContext.breakpointHit(): GetPositionOfContext() failed", hr); - resumeFromBreak(BREAKRESUMEACTION_STEP_OUT); - return; - } - - ULONG lineNumber, column; - hr = documentText->GetLineOfPosition(position, &lineNumber, &column); - if (FAILED(hr)) { - Logger::error("CrossfireContext.breakpointHit(): GetLineOfContext() failed", hr); - resumeFromBreak(BREAKRESUMEACTION_STEP_OUT); - return; - } - lineNumber++; - - CComBSTR bstrUrl; - hr = document->GetName(DOCUMENTNAMETYPE_TITLE, &bstrUrl); - if (FAILED(hr)) { - Logger::error("CrossfireContext.breakpointHit(): GetName() failed", hr); - resumeFromBreak(BREAKRESUMEACTION_STEP_OUT); - return; - } - URL url(bstrUrl); - - /* - * If the cause of the break is a breakpoint then locate the breakpoint and - * determine whether the onBreak event should be sent (eg.- does the breakpoint - * have a hit count to respect, a condition to evaluate, etc.). - */ - if (br == BREAKREASON_BREAKPOINT) { - CrossfireBreakpoint* breakpoint = NULL; - std::map<unsigned int, CrossfireBreakpoint*>::iterator iterator = m_breakpoints->begin(); - while (iterator != m_breakpoints->end()) { - CrossfireBreakpoint* current = iterator->second; - if (current->getType() == CrossfireLineBreakpoint::BPTYPE_LINE) { - CrossfireLineBreakpoint* lineBp = (CrossfireLineBreakpoint*)current; - if (lineBp->getLine() == lineNumber && ((URL*)lineBp->getUrl())->isEqual(&url)) { - lineBp->breakpointHit(); - if (!lineBp->matchesHitCount() && resumeFromBreak(BREAKRESUMEACTION_CONTINUE)) { - return; - } - const std::wstring* conditionString = lineBp->getCondition(); - if (conditionString) { - wchar_t* condition = (wchar_t*)conditionString->c_str(); - if (evaluateAsync(frame, condition, DEBUG_TEXT_RETURNVALUE | DEBUG_TEXT_NOSIDEEFFECTS, this, lineBp)) { - return; - } - } - break; - } - } - iterator++; - } - } - - CrossfireEvent onBreakEvent; - onBreakEvent.setName(EVENT_ONBREAK); - Value body; - Value location; - location.addObjectValue(KEY_LINE, &Value((double)lineNumber)); - location.addObjectValue(KEY_URL, &Value(url.getString())); - body.addObjectValue(KEY_LOCATION, &location); - Value cause; - switch (br) { - case BREAKREASON_ERROR: { - cause.addObjectValue(KEY_TITLE, &Value(L"error")); - EXCEPINFO excepInfo; - HRESULT hr = pScriptErrorDebug->GetExceptionInfo(&excepInfo); - if (FAILED(hr)) { - Logger::error("IEDebugger::onHandleBreakPoint(): GetExceptionInfo() failed", hr); - } else { - if (excepInfo.bstrDescription) { - cause.addObjectValue(KEY_MESSAGE, &Value(excepInfo.bstrDescription)); - } - } - break; - } - case BREAKREASON_DEBUGGER_HALT: { - cause.addObjectValue(KEY_TITLE, &Value(L"suspend")); - break; - } - case BREAKREASON_STEP: { - cause.addObjectValue(KEY_TITLE, &Value(L"step")); - break; - } - case BREAKREASON_BREAKPOINT: { - cause.addObjectValue(KEY_TITLE, &Value(L"breakpoint")); - break; - } - default: { - cause.addObjectValue(KEY_TITLE, &Value(L"suspend")); - break; - } - } - body.addObjectValue(KEY_CAUSE, &cause); - onBreakEvent.setBody(&body); - sendEvent(&onBreakEvent); -} - bool CrossfireContext::createValueForFrame(IDebugStackFrame* stackFrame, unsigned int frameIndex, bool includeScopes, Value** _value) { *_value = NULL; @@ -1267,6 +1117,181 @@ bool CrossfireContext::evaluateAsync(IDebugStackFrame* stackFrame, wchar_t* expr return true; } +void CrossfireContext::executionBreak(IRemoteDebugApplicationThread *pDebugAppThread, BREAKREASON br, IActiveScriptErrorDebug *pScriptErrorDebug) { + m_running = false; + + /* + * IE has just entered a suspended state. If any of the steps preceeding the + * sending of the break event fail then a resume (step out) must be done so + * that the server is not left in a suspended state without the client's knowledge. + */ + CComPtr<IEnumDebugStackFrames> stackFrames = NULL; + HRESULT hr = pDebugAppThread->EnumStackFrames(&stackFrames); + if (FAILED(hr)) { + Logger::error("CrossfireContext.executionBreak(): EnumStackFrames() failed", hr); + resumeFromBreak(BREAKRESUMEACTION_STEP_OUT); + return; + } + + DebugStackFrameDescriptor stackFrameDescriptor; + ULONG numFetched = 0; + hr = stackFrames->Next(1, &stackFrameDescriptor, &numFetched); + if (FAILED(hr) || numFetched != 1) { + Logger::error("CrossfireContext.executionBreak(): EnumStackFrames->Next() failed", hr); + resumeFromBreak(BREAKRESUMEACTION_STEP_OUT); + return; + } + + IDebugStackFrame* frame = stackFrameDescriptor.pdsf; + CComPtr<IDebugCodeContext> codeContext = NULL; + hr = frame->GetCodeContext(&codeContext); + if (FAILED(hr)) { + Logger::error("CrossfireContext.executionBreak(): GetCodeContext() failed", hr); + resumeFromBreak(BREAKRESUMEACTION_STEP_OUT); + return; + } + + CComPtr<IDebugDocumentContext> documentContext = NULL; + hr = codeContext->GetDocumentContext(&documentContext); + if (FAILED(hr)) { + Logger::error("CrossfireContext.executionBreak(): GetDocumentContext() failed", hr); + resumeFromBreak(BREAKRESUMEACTION_STEP_OUT); + return; + } + + CComPtr<IDebugDocument> document = NULL; + hr = documentContext->GetDocument(&document); + if (FAILED(hr)) { + Logger::error("CrossfireContext.executionBreak(): GetDocument() failed", hr); + resumeFromBreak(BREAKRESUMEACTION_STEP_OUT); + return; + } + + CComPtr<IDebugDocumentText> documentText = NULL; + hr = document->QueryInterface(IID_IDebugDocumentText, (void**)&documentText); + if (FAILED(hr)) { + Logger::error("CrossfireContext.executionBreak(): QueryInterface() failed", hr); + resumeFromBreak(BREAKRESUMEACTION_STEP_OUT); + return; + } + + ULONG position, numChars; + hr = documentText->GetPositionOfContext(documentContext, &position, &numChars); + if (FAILED(hr)) { + Logger::error("CrossfireContext.executionBreak(): GetPositionOfContext() failed", hr); + resumeFromBreak(BREAKRESUMEACTION_STEP_OUT); + return; + } + + ULONG lineNumber, column; + hr = documentText->GetLineOfPosition(position, &lineNumber, &column); + if (FAILED(hr)) { + Logger::error("CrossfireContext.executionBreak(): GetLineOfContext() failed", hr); + resumeFromBreak(BREAKRESUMEACTION_STEP_OUT); + return; + } + lineNumber++; + + CComBSTR bstrUrl; + hr = document->GetName(DOCUMENTNAMETYPE_TITLE, &bstrUrl); + if (FAILED(hr)) { + Logger::error("CrossfireContext.executionBreak(): GetName() failed", hr); + resumeFromBreak(BREAKRESUMEACTION_STEP_OUT); + return; + } + URL url(bstrUrl); + + /* + * If the cause of the break is a breakpoint then locate the breakpoint and + * determine whether the onBreak event should be sent (eg.- does the breakpoint + * have a hit count to respect, a condition to evaluate, etc.). + */ + if (br == BREAKREASON_BREAKPOINT) { + CrossfireBreakpoint* breakpoint = NULL; + std::map<unsigned int, CrossfireBreakpoint*>::iterator iterator = m_breakpoints->begin(); + while (iterator != m_breakpoints->end()) { + CrossfireBreakpoint* current = iterator->second; + if (current->getType() == CrossfireLineBreakpoint::BPTYPE_LINE) { + CrossfireLineBreakpoint* lineBp = (CrossfireLineBreakpoint*)current; + if (lineBp->getLine() == lineNumber && ((URL*)lineBp->getUrl())->isEqual(&url)) { + lineBp->breakpointHit(); + if (!lineBp->matchesHitCount() && resumeFromBreak(BREAKRESUMEACTION_CONTINUE)) { + return; + } + const std::wstring* conditionString = lineBp->getCondition(); + if (conditionString) { + wchar_t* condition = (wchar_t*)conditionString->c_str(); + if (evaluateAsync(frame, condition, DEBUG_TEXT_RETURNVALUE | DEBUG_TEXT_NOSIDEEFFECTS, this, lineBp)) { + return; + } + } + break; + } + } + iterator++; + } + } + + CrossfireEvent breakEvent; + if (br == BREAKREASON_ERROR) { + /* broken out separately because this event object differs from the others */ + breakEvent.setName(EVENT_ONERROR); + Value body; + Value error; + EXCEPINFO excepInfo; + HRESULT hr = pScriptErrorDebug->GetExceptionInfo(&excepInfo); + if (FAILED(hr)) { + Logger::error("IEDebugger::executionBreak(): GetExceptionInfo() failed", hr); + } else { + if (excepInfo.bstrDescription) { + error.addObjectValue(KEY_MESSAGE, &Value(excepInfo.bstrDescription)); + } + } + error.addObjectValue(KEY_LINENUMBER, &Value((double)lineNumber)); + error.addObjectValue(KEY_COLUMNNUMBER, &Value((double)column)); + error.addObjectValue(KEY_FILENAME, &Value(url.getString())); + error.addObjectValue(KEY_CATEGORY, &Value(VALUE_JS)); + body.addObjectValue(KEY_ERROR, &error); + breakEvent.setBody(&body); + + /* + * The Crossfire spec does not specify that the server should be left in a + * suspended state when a JS error occurs, so it must be resumed here, + * otherwise it will appear hung to the client. + */ + resumeFromBreak(BREAKRESUMEACTION_CONTINUE); + } else { + breakEvent.setName(EVENT_ONBREAK); + Value body; + Value location; + location.addObjectValue(KEY_LINE, &Value((double)lineNumber)); + location.addObjectValue(KEY_URL, &Value(url.getString())); + body.addObjectValue(KEY_LOCATION, &location); + Value cause; + switch (br) { + case BREAKREASON_DEBUGGER_HALT: { + cause.addObjectValue(KEY_TITLE, &Value(L"suspend")); + break; + } + case BREAKREASON_STEP: { + cause.addObjectValue(KEY_TITLE, &Value(L"step")); + break; + } + case BREAKREASON_BREAKPOINT: { + cause.addObjectValue(KEY_TITLE, &Value(L"breakpoint")); + break; + } + default: { + cause.addObjectValue(KEY_TITLE, &Value(L"suspend")); + break; + } + } + body.addObjectValue(KEY_CAUSE, &cause); + breakEvent.setBody(&body); + } + sendEvent(&breakEvent); +} + bool CrossfireContext::getDebugApplication(IRemoteDebugApplication** _value) { *_value = NULL; @@ -1609,7 +1634,7 @@ bool CrossfireContext::resumeFromBreak(BREAKRESUMEACTION action) { Logger::error("CrossfireContext.resumeFromBreak(): GetApplication() failed", hr); return false; } - hr = application->ResumeFromBreakPoint(thread, action, ERRORRESUMEACTION_SkipErrorStatement); + hr = application->ResumeFromBreakPoint(thread, action, ERRORRESUMEACTION_AbortCallAndReturnErrorToCaller); if (FAILED(hr)) { Logger::error("CrossfireContext.resumeFromBreak(): ResumeFromBreakPoint() failed", hr); return false; diff --git a/development/org.eclipse.wst.jsdt.debug.ie/IECrossfireServer/CrossfireContext.h b/development/org.eclipse.wst.jsdt.debug.ie/IECrossfireServer/CrossfireContext.h index cce2a36..204693e 100644 --- a/development/org.eclipse.wst.jsdt.debug.ie/IECrossfireServer/CrossfireContext.h +++ b/development/org.eclipse.wst.jsdt.debug.ie/IECrossfireServer/CrossfireContext.h @@ -35,7 +35,7 @@ class CrossfireContext : IBreakpointTarget, IJSEvalHandler { public: CrossfireContext(DWORD processId, DWORD threadId, wchar_t* url, CrossfireServer* server); virtual ~CrossfireContext(); - void breakpointHit(IRemoteDebugApplicationThread *pDebugAppThread, BREAKREASON br, IActiveScriptErrorDebug *pScriptErrorDebug); + void executionBreak(IRemoteDebugApplicationThread *pDebugAppThread, BREAKREASON br, IActiveScriptErrorDebug *pScriptErrorDebug); bool getDebugApplication(IRemoteDebugApplication** _value); IDebugApplicationNode* getLastInitializedScriptNode(); wchar_t* getName(); @@ -160,6 +160,15 @@ private: static const wchar_t* KEY_MESSAGE; static const wchar_t* KEY_TITLE; + /* event: onError */ + static const wchar_t* EVENT_ONERROR; + static const wchar_t* KEY_CATEGORY; + static const wchar_t* KEY_COLUMNNUMBER; + static const wchar_t* KEY_ERROR; + static const wchar_t* KEY_FILENAME; + static const wchar_t* KEY_LINENUMBER; + static const wchar_t* VALUE_JS; + /* event: onResume */ static const wchar_t* EVENT_ONRESUME; diff --git a/development/org.eclipse.wst.jsdt.debug.ie/IECrossfireServer/CrossfireServer.cpp b/development/org.eclipse.wst.jsdt.debug.ie/IECrossfireServer/CrossfireServer.cpp index 9fa3e89..e68cc38 100644 --- a/development/org.eclipse.wst.jsdt.debug.ie/IECrossfireServer/CrossfireServer.cpp +++ b/development/org.eclipse.wst.jsdt.debug.ie/IECrossfireServer/CrossfireServer.cpp @@ -48,7 +48,7 @@ const wchar_t* CrossfireServer::KEY_CURRENT = L"current"; /* command: version */ const wchar_t* CrossfireServer::COMMAND_VERSION = L"version"; const wchar_t* CrossfireServer::KEY_VERSION = L"version"; -const wchar_t* CrossfireServer::VERSION_STRING = L"0.3"; +const wchar_t* CrossfireServer::VERSION_STRING = L"0.3a10"; /* event: closed */ const wchar_t* CrossfireServer::EVENT_CLOSED = L"closed"; @@ -669,21 +669,40 @@ void CrossfireServer::received(wchar_t* msg) { } void CrossfireServer::reset() { + delete m_bpManager; + m_bpManager = new CrossfireBPManager(); + + std::map<DWORD, IBrowserContext*>::iterator iterator = m_browsers->begin(); + while (iterator != m_browsers->end()) { + iterator->second->Release(); + iterator++; + } + m_browsers->clear(); + m_connection->close(); delete m_connection; m_connection = NULL; - std::map<DWORD,CrossfireContext*>::iterator iterator = m_contexts->begin(); - while (iterator != m_contexts->end()) { - delete iterator->second; - iterator++; + std::map<DWORD, CrossfireContext*>::iterator iterator2 = m_contexts->begin(); + while (iterator2 != m_contexts->end()) { + delete iterator2->second; + iterator2++; } m_contexts->clear(); + + std::vector<CrossfireEvent*>::iterator iterator3 = m_pendingEvents->begin(); + while (iterator3 != m_pendingEvents->end()) { + delete *iterator3; + iterator3++; + } + m_pendingEvents->clear(); + m_currentContextPID = 0; m_handshakeReceived = false; m_inProgressPacket->clear(); m_lastRequestSeq = -1; m_port = -1; + m_processingRequest = false; } void CrossfireServer::sendEvent(CrossfireEvent* eventObj) { diff --git a/development/org.eclipse.wst.jsdt.debug.ie/IECrossfireServer/IEDebugger.cpp b/development/org.eclipse.wst.jsdt.debug.ie/IECrossfireServer/IEDebugger.cpp index b75491c..de1f917 100644 --- a/development/org.eclipse.wst.jsdt.debug.ie/IECrossfireServer/IEDebugger.cpp +++ b/development/org.eclipse.wst.jsdt.debug.ie/IECrossfireServer/IEDebugger.cpp @@ -45,7 +45,7 @@ STDMETHODIMP IEDebugger::onDebugOutput(LPCOLESTR pstr) { STDMETHODIMP IEDebugger::onHandleBreakPoint(IRemoteDebugApplicationThread *pDebugAppThread, BREAKREASON br, IActiveScriptErrorDebug *pScriptErrorDebug) { if (m_context) { - m_context->breakpointHit(pDebugAppThread, br, pScriptErrorDebug); + m_context->executionBreak(pDebugAppThread, br, pScriptErrorDebug); } else { // TODO should probably resume in this case? } |