Bug 699528. Make pausing/unpausing JSD try to turn off/on debug mode as needed. r=sfink

The new boolean argument to SetDebugModeWhenPossible is needed because if we allow sync-disable of debug mode we seem to crash when loading pages with Firebug active.
This commit is contained in:
Boris Zbarsky 2011-11-09 16:11:39 -05:00
parent 7098cf79c4
commit 947e01ba92
5 changed files with 58 additions and 30 deletions

View File

@ -274,7 +274,10 @@ interface jsdIDebuggerService : nsISupports
*/
unsigned long pause();
/**
* Undo a pause.
* Undo a pause. Once this is called, the debugger won't start
* getting execution callbacks until the stack is fully unwound so
* that no JS scripts are live. There is no way to query whether
* there are such scripts left to unwind at a given point in time.
*
* @return depth The number of remaining pending pause calls.
*/

View File

@ -471,7 +471,7 @@ jsds_NotifyPendingDeadScripts (JSContext *cx)
if (jsds) {
NS_ADDREF(jsds);
jsds->GetScriptHook (getter_AddRefs(hook));
jsds->Pause(nsnull);
jsds->DoPause(nsnull, true);
}
DeadScript *deadScripts = gDeadScripts;
@ -506,7 +506,7 @@ jsds_NotifyPendingDeadScripts (JSContext *cx)
}
if (jsds) {
jsds->UnPause(nsnull);
jsds->DoUnPause(nsnull, true);
NS_RELEASE(jsds);
}
}
@ -583,9 +583,9 @@ jsds_ErrorHookProc (JSDContext *jsdc, JSContext *cx, const char *message,
errnum = 0;
}
gJsds->Pause(nsnull);
gJsds->DoPause(nsnull, true);
hook->OnError (nsDependentCString(message), fileName, line, pos, flags, errnum, val, &rval);
gJsds->UnPause(nsnull);
gJsds->DoUnPause(nsnull, true);
running = false;
if (!rval)
@ -626,9 +626,9 @@ jsds_CallHookProc (JSDContext* jsdc, JSDThreadState* jsdthreadstate,
nsCOMPtr<jsdIStackFrame> frame =
getter_AddRefs(jsdStackFrame::FromPtr(jsdc, jsdthreadstate,
native_frame));
gJsds->Pause(nsnull);
gJsds->DoPause(nsnull, true);
hook->OnCall(frame, type);
gJsds->UnPause(nsnull);
gJsds->DoUnPause(nsnull, true);
jsdStackFrame::InvalidateAll();
return JS_TRUE;
@ -688,13 +688,13 @@ jsds_ExecutionHookProc (JSDContext* jsdc, JSDThreadState* jsdthreadstate,
nsCOMPtr<jsdIStackFrame> frame =
getter_AddRefs(jsdStackFrame::FromPtr(jsdc, jsdthreadstate,
native_frame));
gJsds->Pause(nsnull);
gJsds->DoPause(nsnull, true);
jsdIValue *inout_rv = js_rv;
NS_IF_ADDREF(inout_rv);
hook->OnExecute (frame, type, &inout_rv, &hook_rv);
js_rv = inout_rv;
NS_IF_RELEASE(inout_rv);
gJsds->UnPause(nsnull);
gJsds->DoUnPause(nsnull, true);
jsdStackFrame::InvalidateAll();
if (hook_rv == JSD_HOOK_RETURN_RET_WITH_VAL ||
@ -734,9 +734,9 @@ jsds_ScriptHookProc (JSDContext* jsdc, JSDScript* jsdscript, JSBool creating,
#ifdef CAUTIOUS_SCRIPTHOOK
JS_UNKEEP_ATOMS(rt);
#endif
gJsds->Pause(nsnull);
gJsds->DoPause(nsnull, true);
hook->OnScriptCreated (script);
gJsds->UnPause(nsnull);
gJsds->DoUnPause(nsnull, true);
#ifdef CAUTIOUS_SCRIPTHOOK
JS_KEEP_ATOMS(rt);
#endif
@ -763,9 +763,9 @@ jsds_ScriptHookProc (JSDContext* jsdc, JSDScript* jsdscript, JSBool creating,
JS_UNKEEP_ATOMS(rt);
#endif
gJsds->Pause(nsnull);
gJsds->DoPause(nsnull, true);
hook->OnScriptDestroyed (jsdis);
gJsds->UnPause(nsnull);
gJsds->DoUnPause(nsnull, true);
#ifdef CAUTIOUS_SCRIPTHOOK
JS_KEEP_ATOMS(rt);
#endif
@ -2546,21 +2546,12 @@ jsdService::AsyncOn (jsdIActivationCallback *activationCallback)
{
nsresult rv;
/* get JS things from the CallContext */
nsCOMPtr<nsIXPConnect> xpc = do_GetService(nsIXPConnect::GetCID(), &rv);
if (NS_FAILED(rv)) return rv;
nsAXPCNativeCallContext *cc = nsnull;
rv = xpc->GetCurrentNativeCallContext(&cc);
if (NS_FAILED(rv)) return rv;
JSContext *cx;
rv = cc->GetJSContext (&cx);
if (NS_FAILED(rv)) return rv;
mActivationCallback = activationCallback;
return xpc->SetDebugModeWhenPossible(true);
return xpc->SetDebugModeWhenPossible(true, true);
}
NS_IMETHODIMP
@ -2706,7 +2697,7 @@ jsdService::Off (void)
if (NS_FAILED(rv))
return rv;
xpc->SetDebugModeWhenPossible(false);
xpc->SetDebugModeWhenPossible(false, true);
return NS_OK;
}
@ -2721,6 +2712,12 @@ jsdService::GetPauseDepth(PRUint32 *_rval)
NS_IMETHODIMP
jsdService::Pause(PRUint32 *_rval)
{
return DoPause(_rval, false);
}
nsresult
jsdService::DoPause(PRUint32 *_rval, bool internalCall)
{
if (!mCx)
return NS_ERROR_NOT_INITIALIZED;
@ -2734,6 +2731,15 @@ jsdService::Pause(PRUint32 *_rval)
JSD_ClearTopLevelHook (mCx);
JSD_ClearFunctionHook (mCx);
JSD_DebuggerPause (mCx);
nsresult rv;
nsCOMPtr<nsIXPConnect> xpc = do_GetService(nsIXPConnect::GetCID(), &rv);
if (NS_FAILED(rv)) return rv;
if (!internalCall) {
rv = xpc->SetDebugModeWhenPossible(false, false);
NS_ENSURE_SUCCESS(rv, rv);
}
}
if (_rval)
@ -2744,6 +2750,12 @@ jsdService::Pause(PRUint32 *_rval)
NS_IMETHODIMP
jsdService::UnPause(PRUint32 *_rval)
{
return DoUnPause(_rval, false);
}
nsresult
jsdService::DoUnPause(PRUint32 *_rval, bool internalCall)
{
if (!mCx)
return NS_ERROR_NOT_INITIALIZED;
@ -2774,6 +2786,15 @@ jsdService::UnPause(PRUint32 *_rval)
JSD_SetFunctionHook (mCx, jsds_CallHookProc, NULL);
else
JSD_ClearFunctionHook (mCx);
nsresult rv;
nsCOMPtr<nsIXPConnect> xpc = do_GetService(nsIXPConnect::GetCID(), &rv);
if (NS_FAILED(rv)) return rv;
if (!internalCall) {
rv = xpc->SetDebugModeWhenPossible(true, false);
NS_ENSURE_SUCCESS(rv, rv);
}
}
if (_rval)
@ -3110,9 +3131,9 @@ jsdService::EnterNestedEventLoop (jsdINestCallback *callback, PRUint32 *_rval)
if (NS_SUCCEEDED(stack->Push(nsnull))) {
if (callback) {
Pause(nsnull);
DoPause(nsnull, true);
rv = callback->OnNest();
UnPause(nsnull);
DoUnPause(nsnull, true);
}
while (NS_SUCCEEDED(rv) && mNestedLoopLevel >= nestLevel) {

View File

@ -291,6 +291,9 @@ class jsdService : public jsdIDebuggerService
bool CheckInterruptHook() { return !!mInterruptHook; }
nsresult DoPause(PRUint32 *_rval, bool internalCall);
nsresult DoUnPause(PRUint32 *_rval, bool internalCall);
private:
bool mOn;
PRUint32 mPauseLevel;

View File

@ -392,7 +392,7 @@ interface nsIXPCFunctionThisTranslator : nsISupports
{ 0xbd, 0xd6, 0x0, 0x0, 0x64, 0x65, 0x73, 0x74 } }
%}
[uuid(a995b541-d514-43f1-ac0e-f49746c0b063)]
[uuid(29b63029-0868-4344-b0ca-d93256ee7c78)]
interface nsIXPConnect : nsISupports
{
%{ C++
@ -795,5 +795,6 @@ interface nsIXPConnect : nsISupports
* This method will turn debug mode on or off when the context
* stack reaches zero length.
*/
[noscript] void setDebugModeWhenPossible(in boolean mode);
[noscript] void setDebugModeWhenPossible(in boolean mode,
in boolean allowSyncDisable);
};

View File

@ -2862,10 +2862,10 @@ nsXPConnect::Base64Decode(JSContext *cx, jsval val, jsval *out)
}
NS_IMETHODIMP
nsXPConnect::SetDebugModeWhenPossible(bool mode)
nsXPConnect::SetDebugModeWhenPossible(bool mode, bool allowSyncDisable)
{
gDesiredDebugMode = mode;
if (!mode)
if (!mode && allowSyncDisable)
CheckForDebugMode(mRuntime->GetJSRuntime());
return NS_OK;
}