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:
rginda%netscape.com
2003-04-18 20:12:11 +00:00
parent dc1de8c614
commit 8a5d068645
6 changed files with 123 additions and 14 deletions

View File

@@ -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.

View File

@@ -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

View File

@@ -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)

View File

@@ -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);

View File

@@ -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)
{

View File

@@ -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);