Skip to main content
summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorggayed2012-01-18 17:37:06 +0000
committerggayed2012-01-18 17:37:06 +0000
commit67d2be48b0df8a525c30f445eafe147060d17751 (patch)
tree0878271a739cdc079da06b7f06b8045733892add /development
parent517f8811d29ae91f9abef08ef0078f565c94df6e (diff)
downloadwebtools.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')
-rw-r--r--development/org.eclipse.wst.jsdt.debug.ie/IECrossfireInstaller/Release/IECrossfireInstaller.msibin2466816 -> 2470400 bytes
-rw-r--r--development/org.eclipse.wst.jsdt.debug.ie/IECrossfireServer/CrossfireContext.cpp345
-rw-r--r--development/org.eclipse.wst.jsdt.debug.ie/IECrossfireServer/CrossfireContext.h11
-rw-r--r--development/org.eclipse.wst.jsdt.debug.ie/IECrossfireServer/CrossfireServer.cpp29
-rw-r--r--development/org.eclipse.wst.jsdt.debug.ie/IECrossfireServer/IEDebugger.cpp2
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
index 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
Binary files differ
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?
}

Back to the top