bug 200591, "File Options > Don't Debug Eval/Timeouts isn't working", r=brendan
prevent any stack with a disabled frame from being debugged during single-stepping, or break-on-throw. Also adds versioning support to the jsdIDebuggerService interface. git-svn-id: svn://10.0.0.236/trunk@141407 18797224-902f-48f8-a5cc-f745e15eee43
This commit is contained in:
@@ -160,12 +160,47 @@ interface jsdIDebuggerService : nsISupports
|
||||
* When this flag is set the internal call hook will collect profile data.
|
||||
*/
|
||||
const unsigned long COLLECT_PROFILE_DATA = 0x08;
|
||||
/**
|
||||
* When this flag is set, stack frames that are disabled for debugging
|
||||
* will not appear in the call stack chain.
|
||||
*/
|
||||
const unsigned long HIDE_DISABLED_FRAMES = 0x10;
|
||||
/**
|
||||
* When this flag is set, the debugger will only check the
|
||||
* JSD_SCRIPT_DEBUG_BIT on the top (most recent) stack frame. This
|
||||
* makes it possible to stop in an enabled frame which was called from
|
||||
* a stack that contains a disabled frame.
|
||||
*
|
||||
* When this flag is *not* set, any stack that contains a disabled frame
|
||||
* will not be debugged (the execution hook will not be invoked.)
|
||||
*
|
||||
* This only applies when the reason for calling the hook would have
|
||||
* been TYPE_INTERRUPTED or TYPE_THROW. TYPE_BREAKPOINT,
|
||||
* TYPE_DEBUG_REQUESTED, and TYPE_DEBUGGER_KEYWORD always stop, regardless
|
||||
* of this setting, as long as the top frame is not disabled.
|
||||
*
|
||||
* If HIDE_DISABLED_FRAMES is set, this is effectively set as well.
|
||||
*/
|
||||
const unsigned long MASK_TOP_FRAME_ONLY = 0x20;
|
||||
|
||||
/**
|
||||
* Debugger service flags.
|
||||
*/
|
||||
attribute unsigned long flags;
|
||||
|
||||
/**
|
||||
* Major version number of implementation.
|
||||
*/
|
||||
readonly attribute unsigned long implementationMajor;
|
||||
/**
|
||||
* Minor version number of implementation.
|
||||
*/
|
||||
readonly attribute unsigned long implementationMinor;
|
||||
/**
|
||||
* Free form string identifier for implementation.
|
||||
*/
|
||||
readonly attribute string implementationString;
|
||||
|
||||
/**
|
||||
* |true| if the debugger should register an app-start observer in order
|
||||
* to begin collecting debug information when mozilla is launched.
|
||||
|
||||
@@ -237,6 +237,8 @@ struct JSDExecHook
|
||||
void* callerdata;
|
||||
};
|
||||
|
||||
#define TS_HAS_DISABLED_FRAME 0x01
|
||||
|
||||
struct JSDThreadState
|
||||
{
|
||||
JSCList links; /* we are part of a JSCList */
|
||||
@@ -244,6 +246,7 @@ struct JSDThreadState
|
||||
void* thread;
|
||||
JSCList stack;
|
||||
uintN stackDepth;
|
||||
uintN flags;
|
||||
};
|
||||
|
||||
struct JSDStackFrameInfo
|
||||
|
||||
@@ -164,8 +164,19 @@ jsd_CallExecutionHook(JSDContext* jsdc,
|
||||
|
||||
if(hook && NULL != (jsdthreadstate = jsd_NewThreadState(jsdc,cx)))
|
||||
{
|
||||
hookanswer = hook(jsdc, jsdthreadstate, type, hookData, rval);
|
||||
jsd_DestroyThreadState(jsdc, jsdthreadstate);
|
||||
if ((type != JSD_HOOK_THROW && type != JSD_HOOK_INTERRUPTED) ||
|
||||
jsdc->flags & JSD_MASK_TOP_FRAME_ONLY ||
|
||||
!(jsdthreadstate->flags & TS_HAS_DISABLED_FRAME))
|
||||
{
|
||||
/*
|
||||
* if it's not a throw and it's not an interrupt,
|
||||
* or we're only masking the top frame,
|
||||
* or there are no disabled frames in this stack,
|
||||
* then call out.
|
||||
*/
|
||||
hookanswer = hook(jsdc, jsdthreadstate, type, hookData, rval);
|
||||
jsd_DestroyThreadState(jsdc, jsdthreadstate);
|
||||
}
|
||||
}
|
||||
|
||||
switch(hookanswer)
|
||||
|
||||
@@ -70,8 +70,14 @@ _addNewFrame(JSDContext* jsdc,
|
||||
JSD_LOCK_SCRIPTS(jsdc);
|
||||
jsdscript = jsd_FindJSDScript(jsdc, script);
|
||||
JSD_UNLOCK_SCRIPTS(jsdc);
|
||||
if (!jsdscript || !JSD_IS_DEBUG_ENABLED(jsdc, jsdscript))
|
||||
if (!jsdscript || (jsdc->flags & JSD_HIDE_DISABLED_FRAMES &&
|
||||
!JSD_IS_DEBUG_ENABLED(jsdc, jsdscript)))
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (!JSD_IS_DEBUG_ENABLED(jsdc, jsdscript))
|
||||
jsdthreadstate->flags |= TS_HAS_DISABLED_FRAME;
|
||||
}
|
||||
|
||||
jsdframe = (JSDStackFrameInfo*) calloc(1, sizeof(JSDStackFrameInfo));
|
||||
@@ -128,26 +134,31 @@ jsd_NewThreadState(JSDContext* jsdc, JSContext *cx )
|
||||
((jsdc->flags & JSD_INCLUDE_NATIVE_FRAMES) ||
|
||||
!JS_IsNativeFrame(cx, fp)))
|
||||
{
|
||||
|
||||
if (!_addNewFrame( jsdc, jsdthreadstate, script, pc, fp ) &&
|
||||
jsdthreadstate->stackDepth == 0)
|
||||
JSDStackFrameInfo *frame;
|
||||
|
||||
frame = _addNewFrame( jsdc, jsdthreadstate, script, pc, fp );
|
||||
|
||||
if (jsdthreadstate->stackDepth == 0 && !frame) ||
|
||||
(jsdthreadstate->stackDepth == 1 && frame &&
|
||||
!JSD_IS_DEBUG_ENABLED(jsdc, frame->jsdscript)))
|
||||
{
|
||||
/*
|
||||
* if we failed to create the first frame, fail the entire
|
||||
* thread state.
|
||||
* if we failed to create the first frame, or the top frame
|
||||
* is not enabled for debugging, fail the entire thread state.
|
||||
*/
|
||||
break;
|
||||
JS_INIT_CLIST(&jsdthreadstate->links);
|
||||
jsd_DestroyThreadState(jsdc, jsdthreadstate);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* if there is no stack, then this threadstate can not be constructed */
|
||||
if( 0 == jsdthreadstate->stackDepth )
|
||||
|
||||
if (jsdthreadstate->stackDepth == 0)
|
||||
{
|
||||
free(jsdthreadstate);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
JSD_LOCK_THREADSTATES(jsdc);
|
||||
JS_APPEND_LINK(&jsdthreadstate->links, &jsdc->threadsStates);
|
||||
JSD_UNLOCK_THREADSTATES(jsdc);
|
||||
|
||||
@@ -95,6 +95,9 @@
|
||||
{0xad, 0x26, 0x11, 0x3f, 0x2c, 0x02, 0xd0, 0xfe} \
|
||||
}
|
||||
|
||||
#define JSDS_MAJOR_VERSION 1
|
||||
#define JSDS_MINOR_VERSION 1
|
||||
|
||||
#define NS_CATMAN_CTRID "@mozilla.org/categorymanager;1"
|
||||
#define NS_JSRT_CTRID "@mozilla.org/js/xpc/RuntimeService;1"
|
||||
|
||||
@@ -107,8 +110,9 @@ jsds_GCCallbackProc (JSContext *cx, JSGCStatus status);
|
||||
|
||||
/*******************************************************************************
|
||||
* global vars
|
||||
*******************************************************************************/
|
||||
******************************************************************************/
|
||||
|
||||
const char implementationString[] = "Mozilla JavaScript Debugger Service";
|
||||
static NS_DEFINE_CID(kAppShellCID, NS_APPSHELL_CID);
|
||||
static NS_DEFINE_CID(kEventQueueServiceCID, NS_EVENTQUEUESERVICE_CID);
|
||||
|
||||
@@ -2370,6 +2374,29 @@ jsdService::SetFlags (PRUint32 flags)
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
jsdService::GetImplementationString(char **_rval)
|
||||
{
|
||||
*_rval = PL_strdup(implementationString);
|
||||
if (!*_rval)
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
jsdService::GetImplementationMajor(PRUint32 *_rval)
|
||||
{
|
||||
*_rval = JSDS_MAJOR_VERSION;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
jsdService::GetImplementationMinor(PRUint32 *_rval)
|
||||
{
|
||||
*_rval = JSDS_MINOR_VERSION;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
jsdService::GetIsOn (PRBool *_rval)
|
||||
{
|
||||
|
||||
@@ -208,6 +208,28 @@ JSD_ClearAllProfileData(JSDContext* jsdc);
|
||||
* When this flag is set the internal call hook will collect profile data.
|
||||
*/
|
||||
#define JSD_COLLECT_PROFILE_DATA 0x08
|
||||
/*
|
||||
* When this flag is set, stack frames that are disabled for debugging
|
||||
* will not appear in the call stack chain.
|
||||
*/
|
||||
#define JSD_HIDE_DISABLED_FRAMES 0x10
|
||||
/*
|
||||
* When this flag is set, the debugger will only check the
|
||||
* JSD_SCRIPT_DEBUG_BIT on the top (most recent) stack frame. This
|
||||
* makes it possible to stop in an enabled frame which was called from
|
||||
* a stack that contains a disabled frame.
|
||||
*
|
||||
* When this flag is *not* set, any stack that contains a disabled frame
|
||||
* will not be debugged (the execution hook will not be invoked.)
|
||||
*
|
||||
* This only applies when the reason for calling the hook would have
|
||||
* been JSD_HOOK_INTERRUPTED or JSD_HOOK_THROW. JSD_HOOK_BREAKPOINT,
|
||||
* JSD_HOOK_DEBUG_REQUESTED, and JSD_HOOK_DEBUGGER_KEYWORD always stop,
|
||||
* regardless of this setting, as long as the top frame is not disabled.
|
||||
*
|
||||
* If JSD_HIDE_DISABLED_FRAMES is set, this is effectively set as well.
|
||||
*/
|
||||
#define JSD_MASK_TOP_FRAME_ONLY 0x20
|
||||
|
||||
extern JSD_PUBLIC_API(void)
|
||||
JSD_SetContextFlags (JSDContext* jsdc, uint32 flags);
|
||||
|
||||
Reference in New Issue
Block a user