Re: AW: jsd-Interface usage

Unknown <[email protected]>
Newsgroups gmane.comp.mozilla.devel.jsdebugger
Organization Another Netscape Collabra Server User
Message-ID <[email protected]>
(cc'ing npm.jsdebugger for posterity)

PCMAP_PRETTYPRINT means that the line number passed to
isLineExecutable() or setBreakpoint() is relative to the pretty
printed version of the function's source.  PCMAP_SOURCETEXT means the
the line number is relative to the source file where the script was
defined.  Pretty Printing, in this case, is exactly what you get from
the toSource() function.  All pretty printed scripts start at line 1.

"foo.js"
01 /*
02  * three lines of comments
03  */
04 function foo(x)
06 {
05   if (!x)
06     foo(true);
07 }

The function foo() starts at line 5 (the place where the "{" appears),
but the first place to set a breakpoint isn't until line 6 (the place
where the first statement/expression appears) using the
PCMAP_SOURCETEXT mapping.  Pretty printed, the foo() function looks
like this...

01 function foo(x) {
02   if (!x) {
03     foo(true);
04   }
05 }

Here, the function starts on line 1, and the first executable line is
on line 2.  By line 6, the function is over.

jsdScript.baseLineNumber is always relative to the source file.  So,
for any function except those at the very top of the file, it looks
like you're setting breakpoints well past the end of the function.
Try using PCMAP_SOURCETEXT instead.

I'm not sure why you're getting NS_ERROR_FAILURE for the
isLineExecutable call.  According to
http://lxr.mozilla.org/mozilla/source/js/jsd/jsd_xpc.cpp#1017, that
should only happen when something has gone wrong in a bad way.  If you
have a C++ debugger (and a debug build of mozilla), I'd be curious to
see where it's actually bailing out.  Using PCMAP_SOURCETEXT, though,
should keep you away from this codepath anyway.

As for your assumptions:

-  Yes, it's possible to watch all scripts that are executed, but
setting a breakpoint at every line of every function is a bad way to
do it.  It's going to slow things down too much.  The interpretHook is
a better choice.  The interpretHook is called just before the next
pseudocode is executed by the interpreter, so you don't need to set
any breakpoints at all.  You don't want this to happen for everything
mozilla does though (the entire front end if javascript, after all),
so I'd recommend you set the debugger service up so the scripts are
NOT debuggable by default.

   jsds.flags |= jsdIDebuggerService.DEBUG_WHEN_SET;

This tells the debugger service that scripts should only be debuggable
when their FLAG_DEBUG is set.  The default configuration is that
FLAG_DEBUG means the script is NOT debuggable.  Once you set this
flag, you'll have to set

   jsdScript.flags |= jsdIScript.FLAG_DEBUG;

on every script object that you want to trace through.

If you get this working, you'll notice that your interpret hook is
called multiple times for the same line, in most instances.  That's
because each line of JS can potentially turn into multiple
pseudo-instructions, and the interpret hook is called once for each of
them.  You'll have to debounce this yourself.  Venkman does it by
remembering the last place (url/source line) where the interpretHook
was called.  If the interpret hook is called again for the same
location, it is ignored.

- No, I don't think it's possible to set breakpoints in event handlers
defined inline in the .html file, unless things have changed in
mozilla.  That sounds like something you can worry about at a later
stage, though.

- Yes, it is possible to set a breakpoint in the onScriptCreated hook.
Venkman does it for when it needs to turn a future breakpoint into a
hard breakpoint.

I should point out that "jsdScript" objects may not be what you think.
A jsdScript object is created for every function (and every nested
function) that appears in a file.  The sample foo.js above will result
in two jsdScript objects.  The first is for the top-level script
(where the comments and the function definition live.)  The top level
script has only one executable line, line 5 in the sourcetext.  If you
set a breakpoint here, the debugger will stop when foo() is
*compiled*, not when it is executed.  To stop in foo(), you need to
set your breakpoints in the jsdScript object that represents the foo()
function.  A similar situation happens for nested functions.

In Venkman, every row in the Loaded Scripts view represents a unique
jsdScript object.

I hope this helps a bit.

Rob.
- Hide quoted text -

On Tue, 14 Sep 2004 10:27:09 +0200, Philipp Vogt <[email protected]> wrote:
 > Hello!
 >
 > Thank you for your reply. I would be very glad, if you could spend 
some more
 > time in answering this email. Or perhaps you know someone else who 
might be
 > able to help me with my problem?
 >
 > Robert Ginda <mailto:[email protected]> schrieb am Montag, 13. 
September 2004
 > 23:26:
 >
 > > You mentioned that one the the calls was throwing an exception, but
 > > you never said what the exception was.  That might be a clue.
 >
 > + QueryInterface (function) [native code]
 > + message (string) 'Component returned failure code: 0x80004005
 > (NS_ERROR_FAILURE) [jsdIScript.isLineExecutable]'
 > + result (number) 2147500037
 > + name (string) 'NS_ERROR_FAILURE'
 > + filename (string) 'chrome://xssplugin/content/xssplugin.js'
 > + lineNumber (number) 47
 >
 > isLineExcutable only returns NS_ERROR_FAILURE if the prettyprintlinemap
 > couldn't be created.
 >
 > http://lxr.mozilla.org/mozilla/source/js/jsd/jsd_xpc.cpp#1383
 >
 > [isValid snipped]
 >
 > I'll look into that
 >
 > > See
 > > http://lxr.mozilla.org/mozilla/source/js/jsd/idl/jsdIDebuggerS
 > > ervice.idl for more details.
 >
 >   I looked into that but I didn't find an explaination for my problem.
 >
 >   So perhaps you might be able to help me with some assumptions:
 >
 > - Is it possible to watch all scripts that are executed? Is it 
possible to
 > set a breakpoint to: <a onmouseover="alert('xxx');">? The other parts of
 > javascript in a webpage are generating a callback to 
onScriptCreated() - as
 > far as I can see.
 >
 > - Is it possible to set breakpoints (with setBreakpoint()) to scripts 
in the
 > onScriptCreated()-callbackfunction (as I try) or has it to be done in a
 > later stage (perhaps not all of the objects to set a breakpoint are 
already
 > created)?
 >
 > Here are my condensed steps:
 >
 > var xssdbg = new Object();
 >
 > // get the service, turn it on
 > xssdbg.jsds =
 > 
Components.classes["@mozilla.org/js/jsd/debuggerservice;1"].getService().Que
 > ryInterface(Components.interfaces.jsdIDebuggerService);
 > xssdbg.jsds.on();
 >
 > // now some interal definitions. All of my functions are of type
 > jsdIExecutionHook, which are never called :-(
 > xssdbg.breakpointHook = { onExecute: jsdBreakpointHook };
 > xssdbg.debuggerHook = { onExecute: jsdDebuggerHook };
 > xssdbg.debugHook = { onExecute: jsdDebugHook };
 >
 > // set the callbackfunctions
 > xssdbg.jsds.breakpointHook = xssdbg.breakpointHook;
 > xssdbg.jsds.debuggerHook  = xssdbg.debuggerHook;
 > xssdbg.jsds.debugHook  = xssdbg.debugHook;
 > var enumer = { enumerateScript: xssdbg.scriptHook.onScriptCreated };
 > xssdbg.jsds.scriptHook = xssdbg.scriptHook; // <- the only one that gets
 > called.
 > xssdbg.jsds.enumerateScripts(enumer);
 >
 > // now to my onScriptCreated (from venkman) - which is defined before the
 > lines above
 > xssdbg.scriptHook = new Object();
 >
 > xssdbg.scriptHook.onScriptCreated =
 > function sh_created (jsdScript)
 > {
 >   // set script to debugable - perhaps some more flags are necessary to
 > enable debugging?
 >   jsdScript.flags |= FLAG_DEBUG;
 >
 >   // calculate end
 >   var lines = String(jsdScript.functionSource).split("\n");
 >   var end = jsdScript.baseLineNumber + jsdScript.lineExtent;
 >
 >   // set a breakpoint to each line, if it is executable
 >   for (var i = jsdScript.baseLineNumber; i <= end; ++i) {
 >
 >     // here i get the above mentioned exception "NS_ERROR_FAILURE". For
 > nearly every line.
 >     if (jsdScript.isLineExecutable(i, PCMAP_PRETTYPRINT)) {
 >
 >       // is the calculation of the pc correct? perhaps I set the 
breakpoint
 > to a wrong line?
 >       var mypc = jsdScript.lineToPc(i, PCMAP_PRETTYPRINT);
 >
 >       // set the breakpoint
 >       jsdScript.setBreakpoint(mypc);
 >     }
 >   }
 > }
 >
 > > Rob.
 >
 > regards
 >
 >   Philipp
 >
 > --
 > Philipp Vogt
 > Student
 > Informatik TU-Wien
 > EMail : [email protected]
 >         [email protected]
 >         [email protected]
 > Tel   : +43 1 946 95 24, Mobil: +43 (0) 699 1 946 95 24
 > ICQ   : 29928354
 > pgp fingerprint: F8B3 EFF8 C6D2 31E1 E855  3959 942D 24EA D66B B8A4
 > pgp-schluessel:  http://members.chello.at/philipp.vogt/vogge.asc
 >
 >
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.