Bug 341764 - Should be able to debug from the slow script dialog if a debugger is present

r=bsmedberg for makefile changes and r=sicking for dom changes
sr=shaver


git-svn-id: svn://10.0.0.236/trunk@200621 18797224-902f-48f8-a5cc-f745e15eee43
This commit is contained in:
gijskruitbosch%gmail.com 2006-06-22 21:30:49 +00:00
parent ecab05101a
commit 4f58af4765
4 changed files with 89 additions and 18 deletions

View File

@ -170,6 +170,10 @@ ifdef MOZ_XUL
tier_9_dirs += rdf
endif
ifdef MOZ_JSDEBUGGER
tier_9_dirs += js/jsd
endif
tier_9_dirs += \
uriloader \
modules/libpref \
@ -267,10 +271,6 @@ ifdef MOZ_XPINSTALL
tier_50_dirs += xpinstall
endif
ifdef MOZ_JSDEBUGGER
tier_50_dirs += js/jsd
endif
ifdef MOZ_PSM
tier_50_dirs += security/manager
else

View File

@ -1,6 +1,8 @@
KillScriptTitle=Warning: Unresponsive script
KillScriptMessage=A script on this page may be busy, or it may have stopped responding. You can stop the script now, or you can continue to see if the script will complete.
KillScriptWithDebugMessage=A script on this page may be busy, or it may have stopped responding. You can stop the script now, open the script in the debugger, or let the script continue.
StopScriptButton=Stop script
DebugScriptButton=Debug script
WaitForScriptButton=Continue
NeverShowDialogAgain=Never show this dialog again
JSURLLoadBlockedWarning=Attempt to load a javascript: URL from one host\nin a window displaying content from another host\nwas blocked by the security manager.

View File

@ -87,6 +87,10 @@ ifdef NS_TRACE_MALLOC
REQUIRES += tracemalloc
endif
ifdef MOZ_JSDEBUGGER
REQUIRES += jsdebug
endif
CPPSRCS = \
nsBarProps.cpp \
nsDOMException.cpp \
@ -122,4 +126,8 @@ LOCAL_INCLUDES = \
DEFINES += -D_IMPL_NS_LAYOUT
ifdef MOZ_JSDEBUGGER
DEFINES += -DMOZ_JSDEBUGGER
endif
include $(topsrcdir)/config/rules.mk

View File

@ -107,6 +107,10 @@
#include "jsgc.h" // for WAY_TOO_MUCH_GC, if defined for GC debugging
#endif
#ifdef MOZ_JSDEBUGGER
#include "jsdIDebuggerService.h"
#endif
#include "nsIStringBundle.h"
#ifdef MOZ_LOGGING
@ -635,6 +639,35 @@ nsJSContext::DOMBranchCallback(JSContext *cx, JSScript *script)
ireq->GetInterface(NS_GET_IID(nsIPrompt), getter_AddRefs(prompt));
NS_ENSURE_TRUE(prompt, JS_TRUE);
nsresult rv;
// Check if we should offer the option to debug
PRBool debugPossible = (cx->runtime && cx->runtime->debuggerHandler);
#ifdef MOZ_JSDEBUGGER
// Get the debugger service if necessary.
if (debugPossible) {
PRBool jsds_IsOn = PR_FALSE;
const char jsdServiceCtrID[] = "@mozilla.org/js/jsd/debugger-service;1";
nsCOMPtr<jsdIExecutionHook> jsdHook;
nsCOMPtr<jsdIDebuggerService> jsds = do_GetService(jsdServiceCtrID, &rv);
// Check if there's a user for the debugger service that's 'on' for us
if (NS_SUCCEEDED(rv)) {
jsds->GetDebuggerHook(getter_AddRefs(jsdHook));
jsds->GetIsOn(&jsds_IsOn);
if (jsds_IsOn) { // If this is not true, the next call would start jsd...
rv = jsds->OnForRuntime(cx->runtime);
jsds_IsOn = NS_SUCCEEDED(rv);
}
}
// If there is a debug handler registered for this runtime AND
// ((jsd is on AND has a hook) OR (jsd isn't on (something else debugs)))
// then something useful will be done with our request to debug.
debugPossible = ((jsds_IsOn && (jsdHook != nsnull)) || !jsds_IsOn);
}
#endif
// Get localizable strings
nsCOMPtr<nsIStringBundleService>
stringService(do_GetService(NS_STRINGBUNDLE_CONTRACTID));
@ -646,13 +679,9 @@ nsJSContext::DOMBranchCallback(JSContext *cx, JSScript *script)
if (!bundle)
return JS_TRUE;
nsXPIDLString title, msg, stopButton, waitButton, neverShowDlg;
nsXPIDLString title, msg, stopButton, waitButton, debugButton, neverShowDlg;
nsresult rv;
rv = bundle->GetStringFromName(NS_LITERAL_STRING("KillScriptMessage").get(),
getter_Copies(msg));
rv |= bundle->GetStringFromName(NS_LITERAL_STRING("KillScriptTitle").get(),
rv = bundle->GetStringFromName(NS_LITERAL_STRING("KillScriptTitle").get(),
getter_Copies(title));
rv |= bundle->GetStringFromName(NS_LITERAL_STRING("StopScriptButton").get(),
getter_Copies(stopButton));
@ -661,24 +690,37 @@ nsJSContext::DOMBranchCallback(JSContext *cx, JSScript *script)
rv |= bundle->GetStringFromName(NS_LITERAL_STRING("NeverShowDialogAgain").get(),
getter_Copies(neverShowDlg));
if (debugPossible) {
rv |= bundle->GetStringFromName(NS_LITERAL_STRING("DebugScriptButton").get(),
getter_Copies(debugButton));
rv |= bundle->GetStringFromName(NS_LITERAL_STRING("KillScriptWithDebugMessage").get(),
getter_Copies(msg));
}
else {
rv |= bundle->GetStringFromName(NS_LITERAL_STRING("KillScriptMessage").get(),
getter_Copies(msg));
}
//GetStringFromName can return NS_OK and still give NULL string
if (NS_FAILED(rv) || !title || !msg || !stopButton || !waitButton ||
!neverShowDlg) {
(!debugButton && debugPossible) || !neverShowDlg) {
NS_ERROR("Failed to get localized strings.");
return JS_TRUE;
}
PRInt32 buttonPressed = 1; //In case user exits dialog by clicking X
PRBool neverShowDlgChk = PR_FALSE;
PRUint32 buttonFlags = (nsIPrompt::BUTTON_TITLE_IS_STRING *
(nsIPrompt::BUTTON_POS_0 + nsIPrompt::BUTTON_POS_1));
// Add a third button if necessary:
if (debugPossible)
buttonFlags += nsIPrompt::BUTTON_TITLE_IS_STRING * nsIPrompt::BUTTON_POS_2;
// Open the dialog.
rv = prompt->ConfirmEx(title, msg,
(nsIPrompt::BUTTON_TITLE_IS_STRING *
nsIPrompt::BUTTON_POS_0) +
(nsIPrompt::BUTTON_TITLE_IS_STRING *
nsIPrompt::BUTTON_POS_1),
stopButton, waitButton,
nsnull, neverShowDlg, &neverShowDlgChk,
rv = prompt->ConfirmEx(title, msg, buttonFlags, stopButton, waitButton,
debugButton, neverShowDlg, &neverShowDlgChk,
&buttonPressed);
if (NS_FAILED(rv) || (buttonPressed == 1)) {
@ -695,6 +737,25 @@ nsJSContext::DOMBranchCallback(JSContext *cx, JSScript *script)
ctx->mBranchCallbackTime = PR_Now();
return JS_TRUE;
}
else if ((buttonPressed == 2) && debugPossible) {
// Debug the script
jsval rval;
switch(cx->runtime->debuggerHandler(cx, script, cx->fp->pc, &rval,
cx->runtime->debuggerHandlerData)) {
case JSTRAP_RETURN:
cx->fp->rval = rval;
return JS_TRUE;
case JSTRAP_ERROR:
cx->throwing = JS_FALSE;
return JS_FALSE;
case JSTRAP_THROW:
JS_SetPendingException(cx, rval);
return JS_FALSE;
case JSTRAP_CONTINUE:
default:
return JS_TRUE;
}
}
return JS_FALSE;
}