Partial solution to debugging eval() code

classic Classic list List threaded Threaded
7 messages Options
Reply | Threaded
Open this post in threaded view
|

Partial solution to debugging eval() code

John J Barton
I have worked out a partial solution to the issues discussed in Bug
#307984, that eval() code line numbers appear to overlap regular code.
For errors in compile, I recompute the line number and extract the
source into a data: url.  For run time, I breakpoint the eval-creation
script in an onScriptCreated hook and re-eval it with a file name using
jsdIStackFrame.eval().  Some more details:

http://www.almaden.ibm.com/cs/people/bartonjj/fireclipse/test/DynLoadTest/WebContent/DynamicJavascriptErrors.htm

I implemented this in Firebug and I'll make that code available soon.

Unfortunately the key use case for this code is dojo, and for that the
implementation is not quite enough.  As far as I can tell, dojo calls
eval() from eval() code. Errors in the second eval() will, in my scheme,
be within the jsdIStackFrame.eval() call.  Code below this call seems to
be "undebuggable", that I cannot breakpoint it etc.

The question is why?  I cannot see from the spidermonkey or jsd code why
this eval will not act like normal eval.  I do see a number of flags
that indicate that it is *intended* to be different (eg
JSFRAME_DEBUGGER), but I can't find where these flags are tested.  I am
hoping that there may be some way to defeat this and allow such code to
be debugged.

As it stands the partial implementation should help some folks and
especially it will help determine if data: url is a good naming scheme.
(Its pretty horrible for debugger debugging BTW ;-).

John.
_______________________________________________
dev-apps-js-debugger mailing list
[hidden email]
https://lists.mozilla.org/listinfo/dev-apps-js-debugger
Reply | Threaded
Open this post in threaded view
|

Re: Partial solution to debugging eval() code

James Ross
John J. Barton wrote:

> Unfortunately the key use case for this code is dojo, and for that the
> implementation is not quite enough.  As far as I can tell, dojo calls
> eval() from eval() code. Errors in the second eval() will, in my scheme,
> be within the jsdIStackFrame.eval() call.  Code below this call seems to
> be "undebuggable", that I cannot breakpoint it etc.
>
> The question is why?  I cannot see from the spidermonkey or jsd code why
> this eval will not act like normal eval.  I do see a number of flags
> that indicate that it is *intended* to be different (eg
> JSFRAME_DEBUGGER), but I can't find where these flags are tested.  I am
> hoping that there may be some way to defeat this and allow such code to
> be debugged.

I've not checked in this specific case, but in a number of cases the JSD
code will ignore calls to break into the debugger for most cases if it
is already nested into the debugger. In other words, if you get a
breakpoint trigger and then call some code that would ordinarily trigger
the same/another breakpoint, it is ignored, so the debugger never nests.

If you want to try being clever, would it not be possible to - from the
stack frame - work out the eval line number by subtracting the offset of
the call above it? I still think SpiderMonkey needs to fix this by
numbering the eval lines from 1 and not line-of-call. :)

--
James Ross <[hidden email]>
ChatZilla Developer
_______________________________________________
dev-apps-js-debugger mailing list
[hidden email]
https://lists.mozilla.org/listinfo/dev-apps-js-debugger
Reply | Threaded
Open this post in threaded view
|

Re: Partial solution to debugging eval() code

John J Barton
James Ross wrote:
> If you want to try being clever, would it not be possible to - from the
> stack frame - work out the eval line number by subtracting the offset of
> the call above it? I still think SpiderMonkey needs to fix this by
> numbering the eval lines from 1 and not line-of-call. :)
>

The eval line number relative to the eval source isn't useful unless we
have the eval source.  Numbering the eval lines from 1 would just shift
the problem from one random-looking location to another ;-).

But the real problem with these solutions is that the stack containing
the offsets is only available when eval() is called, while the code that
one wants to debug is called at any time later.  So we have foo() from
and eval that looks like it came from file bootstrap.js:240.   But we
don't have the source containing foo() declaration and we don't know
how many nested eval()s came between bootstrap.js:240 and the eval()
that spawned foo().

Or so I think now.  Maybe I'll look to see if this fact or fiction.

I sure wish I could build the moz code so I could debug into jsd and
see what really goes on.

John.
_______________________________________________
dev-apps-js-debugger mailing list
[hidden email]
https://lists.mozilla.org/listinfo/dev-apps-js-debugger
Reply | Threaded
Open this post in threaded view
|

Re: Partial solution to debugging eval() code

John J Barton
Ok, what I said was fiction. I do have the source of eval-s,
from my scheme. What I need is to relate functions to their
correct source. I was using the frame.eval() to both jobs,
but I can just use it to get the source and different scheme
to relate the functions:

All jsd "scripts" are one of four types: (or so I think)
   top-level
   eval-level
   functions defined in top-level   << no problem
   functions defined in eval-level  << problem
All scripts come thru the onScriptCreated hook.  It looks like
the js engine emits all of the functions in each XX-level script
then emits the XX-level script. So if I stack up the scripts
until I see either top-level (discard stack) or eval-level
(mark all as fileName = data:url from eval). Then I can do your
line number subtraction to define baseLineNumber relative to
the eval source.

I'll try this one.
John.



John J. Barton wrote:

> James Ross wrote:
>> If you want to try being clever, would it not be possible to - from
>> the stack frame - work out the eval line number by subtracting the
>> offset of the call above it? I still think SpiderMonkey needs to fix
>> this by numbering the eval lines from 1 and not line-of-call. :)
>>
>
> The eval line number relative to the eval source isn't useful unless we
> have the eval source.  Numbering the eval lines from 1 would just shift
> the problem from one random-looking location to another ;-).
>
> But the real problem with these solutions is that the stack containing
> the offsets is only available when eval() is called, while the code that
> one wants to debug is called at any time later.  So we have foo() from
> and eval that looks like it came from file bootstrap.js:240.   But we
> don't have the source containing foo() declaration and we don't know
> how many nested eval()s came between bootstrap.js:240 and the eval()
> that spawned foo().
>
> Or so I think now.  Maybe I'll look to see if this fact or fiction.
>
> I sure wish I could build the moz code so I could debug into jsd and
> see what really goes on.
>
> John.
_______________________________________________
dev-apps-js-debugger mailing list
[hidden email]
https://lists.mozilla.org/listinfo/dev-apps-js-debugger
Reply | Threaded
Open this post in threaded view
|

Re: Partial solution to debugging eval() code

John J Barton
John J. Barton wrote:

> Ok, what I said was fiction. I do have the source of eval-s,
> from my scheme. What I need is to relate functions to their
> correct source. I was using the frame.eval() to both jobs,
> but I can just use it to get the source and different scheme
> to relate the functions:
>
> All jsd "scripts" are one of four types: (or so I think)
>   top-level
>   eval-level
>   functions defined in top-level   << no problem
>   functions defined in eval-level  << problem

Actually a fifth one has appeared:  event scripts like onclick
for lines like
        <a onclick="doHi();">I'll say if you do.</a>
These come in as scripts on line 1 of the HTML file, apparently
generated by the browser.  Don't cause problem with the
eval() detector, so its more a question of supporting them in
the debugger.
_______________________________________________
dev-apps-js-debugger mailing list
[hidden email]
https://lists.mozilla.org/listinfo/dev-apps-js-debugger
Reply | Threaded
Open this post in threaded view
|

Re: Partial solution to debugging eval() code

timeless-3
John J. Barton wrote:
> All jsd "scripts" are one of four types: (or so I think)
>   top-level
>   eval-level
>   functions defined in top-level   << no problem
>   functions defined in eval-level  << problem
...
> Actually a fifth one has appeared:  event scripts like onclick
> for lines like
>         <a onclick="doHi();">I'll say if you do.</a>
> These come in as scripts on line 1 of the HTML file, apparently
> generated by the browser.  Don't cause problem with the
> eval() detector, so its more a question of supporting them in
> the debugger.

I'm asleep, but I believe the following is correct:

the sixth is:

<a
id=foo><script>document.getElementById("foo").setAttribute("onclick","foo()")</
a>

note that onclick and friends are compiled each time they're triggered
(for more fun, check out xbl!).

_______________________________________________
dev-apps-js-debugger mailing list
[hidden email]
https://lists.mozilla.org/listinfo/dev-apps-js-debugger
Reply | Threaded
Open this post in threaded view
|

Re: Partial solution to debugging eval() code

John J Barton
timeless wrote:

> John J. Barton wrote:
>> All jsd "scripts" are one of four types: (or so I think)
>>   top-level
>>   eval-level
>>   functions defined in top-level   << no problem
>>   functions defined in eval-level  << problem
> ...
>> Actually a fifth one has appeared:  event scripts like onclick
>> for lines like
>>         <a onclick="doHi();">I'll say if you do.</a>
>> These come in as scripts on line 1 of the HTML file, apparently
>> generated by the browser.  Don't cause problem with the
>> eval() detector, so its more a question of supporting them in
>> the debugger.
>
> I'm asleep, but I believe the following is correct:
>
> the sixth is:
>
> <a
> id=foo><script>document.getElementById("foo").setAttribute("onclick","foo()")</
> a>
>
> note that onclick and friends are compiled each time they're triggered
> (for more fun, check out xbl!).
>
Thanks, looks like this case and the onclick attribute end up looking
the same by the time they get to onScriptCreated.  Your case followed mine:

onScriptCreated:
1-2@http://localhost:63636/.fireclipse.eclipse.workspace/DynLoadTest/WebContent/TimelessLinkedScript.html
onScriptCreated: onclick
     function onclick(event) {
         foo();
     }
onScriptCreated:
1-2@http://localhost:63636/.fireclipse.eclipse.workspace/DynLoadTest/WebContent/JavaScriptInTags.html
onScriptCreated: onclick
     function onclick(event) {
         doHi();
     }

I guess my heuristic is
   "! (from .js file) && (after top_level for that file)"
I think venkman calls "after top_level" "sealed".  Maybe
the last test is enough.

(Firebug doesn't deal with XUL so far, so I'll pass on xbl ;-).

John.
_______________________________________________
dev-apps-js-debugger mailing list
[hidden email]
https://lists.mozilla.org/listinfo/dev-apps-js-debugger