Debugging Greasemonkey scripts with FB

844 views
Skip to first unread message

Olivier

unread,
Jul 28, 2009, 5:20:03 AM7/28/09
to Firebug
Hi,

As i understand it, Greasemonkey scripts do not appear in FB's scripts
tab, nor can they be debugged using FB.
I've started looking into FB code and read the FB extension
documentation, but i'm new to FB and don't really know where to start
poking to get to this goal: debugging GM scripts with FB.
I guess that's the kind of situation where feedback from this list
would be very helpful... :-)

I guess a good start would be to add GM scripts to FB's context list
of scripts.
Does it sound like it would be enough to enjoy all of FB debugging
features with these scripts?
Where in the code should i start poking to get there the proper way?

Thanks in advance,

Olivier

johnjbarton

unread,
Jul 28, 2009, 11:48:16 AM7/28/09
to Firebug
How are Greasemonkey scripts added to the web page?

jjb

Olivier Cornu

unread,
Jul 28, 2009, 2:56:15 PM7/28/09
to fir...@googlegroups.com
On Tue, Jul 28, 2009 at 17:48, johnjbarton<johnj...@johnjbarton.com> wrote:
>
> How are Greasemonkey scripts added to the web page?

Well, i guess that in order to be accurate one must answer they are
not "added" to the web page. They are executed in a sandbox built
around a XPCNWrapper of the page's window:

var safeWin = new XPCNativeWrapper(window);
var sandbox = new Components.utils.Sandbox(safeWin);
sandbox.__proto__ = safeWin;
Components.utils.evalInSandbox(scriptSourceCode, sandbox);

As of now, there is nowhere FB could grab a reference to such a
sandbox or the running script source code. However, i'm thinking about
providing them (script source+sandbox) to FB somehow from the GM code.
As i see it so far, i'd like to be able to browse the running GM
scripts source code from FB scripts tab, as well as poke around in
these scripts sandboxes in the FB console tab after a cd(sandbox). In
a perfect world, i'd love to achieve that via a simple FB extension
included in the GM add-on, but it probably is over-optimistic... :-)

--
Olivier

johnjbarton

unread,
Jul 28, 2009, 3:53:19 PM7/28/09
to Firebug
Run Firebug with tracing and set up for your page. Then use Tracing
option FBS_CREATION and FBS_SRCUNITS. Run the Greasemonkey code and
look for the jsdIScript creation messages. (You will want to turn off
these tracing options, they have high overhead).

Once you figure out what jsd things of the GM scripts, you need to
convince Firebug to add them to the context for the web page. After
that I guess Firebug will work for you.

jjb

On Jul 28, 11:56 am, Olivier Cornu <o.co...@gmail.com> wrote:

Olivier Cornu

unread,
Jul 29, 2009, 8:55:49 AM7/29/09
to fir...@googlegroups.com
Thanks for your help, John, it's really appreciated. :-)


On Tue, Jul 28, 2009 at 21:53, johnjbarton<johnj...@johnjbarton.com> wrote:
>
> Run Firebug with tracing and set up for your page. Then use Tracing
> option FBS_CREATION and FBS_SRCUNITS. Run the Greasemonkey code and
> look for the jsdIScript creation messages. (You will want to turn off
> these tracing options, they have high overhead).

So, i did run FB-1.4X.1 with FBS_CREATION and FBS_SRCUNITS.
I guess the following output is what i'm looking for: traces for the
GM script (#178), from creation to destruction:


85. [extensions.firebug] onScriptCreated:
178@(302-314)file:/home/olivier/dev/webmonkey/src/components/webmonkey.js
file:///home/olivier/.mozilla/firefox/gmdev/extensions/fir...@software.joehewitt.com/components/firebug-service.js
(1512)
file:///home/olivier/.mozilla/firefox/gmdev/extensions/fir...@software.joehewitt.com/components/firebug-service.js
(2555)
()
### webmonkey.js:302 is indeed where
Components.utils.evalInSandbox(scriptSource, sandbox) is located.

86. [extensions.firebug] onScriptCreated: ''
file:///home/olivier/.mozilla/firefox/gmdev/extensions/fir...@software.joehewitt.com/components/firebug-service.js
(1514)
file:///home/olivier/.mozilla/firefox/gmdev/extensions/fir...@software.joehewitt.com/components/firebug-service.js
(2555)
()
### Here, Object->data shows the GM script source code.

87. [extensions.firebug] createdScriptHasCaller 4 FF3.1:false
file:///home/olivier/.mozilla/firefox/gmdev/extensions/fir...@software.joehewitt.com/components/firebug-service.js
(1600)
file:///home/olivier/.mozilla/firefox/gmdev/extensions/fir...@software.joehewitt.com/components/firebug-service.js
(1524)
file:///home/olivier/.mozilla/firefox/gmdev/extensions/fir...@software.joehewitt.com/components/firebug-service.js
(2555)
()

88. [extensions.firebug] createdScriptHasCaller null
file:///home/olivier/.mozilla/firefox/gmdev/extensions/fir...@software.joehewitt.com/components/firebug-service.js
(1525)
file:///home/olivier/.mozilla/firefox/gmdev/extensions/fir...@software.joehewitt.com/components/firebug-service.js
(2555)
()
### Looking at the code, i suppose from these last 2 that the
script is considered as having "no caller" (FYI,
createdScriptHasCaller() returns on line 1617).

89. [extensions.firebug] onScriptCreated: set BP at PC 0 in top level
tag=178:file:/home/olivier/dev/webmonkey/src/components/webmonkey.js
jsd depth:1
file:///home/olivier/.mozilla/firefox/gmdev/extensions/fir...@software.joehewitt.com/components/firebug-service.js
(1538)
file:///home/olivier/.mozilla/firefox/gmdev/extensions/fir...@software.joehewitt.com/components/firebug-service.js
(2555)
()

90. [extensions.firebug] onBreakpoint frame.script.tag=178
file:///home/olivier/.mozilla/firefox/gmdev/extensions/fir...@software.joehewitt.com/components/firebug-service.js
(1169)
file:///home/olivier/.mozilla/firefox/gmdev/extensions/fir...@software.joehewitt.com/components/firebug-service.js
(2555)
file:///home/olivier/dev/webmonkey/src/components/webmonkey.js (302)

91. [extensions.firebug] FBS.onTopLevelScriptCreated no debuggr for 178
file:///home/olivier/.mozilla/firefox/gmdev/extensions/fir...@software.joehewitt.com/components/firebug-service.js
(1446)
file:///home/olivier/.mozilla/firefox/gmdev/extensions/fir...@software.joehewitt.com/components/firebug-service.js
(1181)
file:///home/olivier/.mozilla/firefox/gmdev/extensions/fir...@software.joehewitt.com/components/firebug-service.js
(2555)
file:///home/olivier/dev/webmonkey/src/components/webmonkey.js (302)
### It seems fbs.findDebugger(frame):1435 fails to find the
associated context (see below).

92. [extensions.firebug] fbs.onTopLevelScriptCreated script.tag:178
href: no sourceFile
file:///home/olivier/.mozilla/firefox/gmdev/extensions/fir...@software.joehewitt.com/components/firebug-service.js
(1456)
file:///home/olivier/.mozilla/firefox/gmdev/extensions/fir...@software.joehewitt.com/components/firebug-service.js
(1181)
file:///home/olivier/.mozilla/firefox/gmdev/extensions/fir...@software.joehewitt.com/components/firebug-service.js
(2555)
file:///home/olivier/dev/webmonkey/src/components/webmonkey.js (302)

93. [extensions.firebug] Top Scripts Uncleared:
file:///home/olivier/.mozilla/firefox/gmdev/extensions/fir...@software.joehewitt.com/components/firebug-service.js
(1190)
file:///home/olivier/.mozilla/firefox/gmdev/extensions/fir...@software.joehewitt.com/components/firebug-service.js
(2555)
file:///home/olivier/dev/webmonkey/src/components/webmonkey.js (302)

94. [extensions.firebug] fbs.onScriptDestroyed 178
file:///home/olivier/.mozilla/firefox/gmdev/extensions/fir...@software.joehewitt.com/components/firebug-service.js
(1634)
file:///home/olivier/.mozilla/firefox/gmdev/extensions/fir...@software.joehewitt.com/components/firebug-service.js
(2555)


From here, i turned on FBS_FINDDEBUGGER to get more feedback on
why/how findDebugger() failed. It yielded:

[extensions.firebug] fbs.getFrameScopeWindowAncestor found scope chain
bottom, not Window: Sandbox
[extensions.firebug] fbs.findDebugger no frame Window, looking down the stack
[extensions.firebug] fbs.findDebugger fell thru bottom of stack


As it seems a Sandbox is not a "supported" scope, i tried this
quick-&-dirty-hack(TM) in getFrameScopeWindowAncestor():

--- firebug-service.js~ 2009-07-29 13:25:51.913450368 +0200
+++ firebug-service.js 2009-07-29 13:26:42.293449931 +0200
@@ -2573,7 +2573,7 @@
while(scope.jsParent)
scope = scope.jsParent;

- if (scope.jsClassName == "Window" || scope.jsClassName ==
"ChromeWindow")
+ if (scope.jsClassName == "Window" || scope.jsClassName ==
"ChromeWindow" || scope.jsClassName == "Sandbox")
return scope.getWrappedValue();

if (FBTrace.DBG_FBS_FINDDEBUGGER)


Apart of the fact that this throws "too much recursion" errors at
firebug-service:2559 (hook()), webmonkey.js (the add-on XPCOM, not the
script unfortunately) appears in FB scripts tab. Nevertheless, it's a
tiny progress. :-p


> Once you figure out what jsd things of the GM scripts, you need to
> convince Firebug to add them to the context for  the web page. After
> that I guess Firebug will work for you.

I'm not there yet! I guess i'll have to keep on working in this
direction... Any hint will be much appreciated. :-)

I guess one of my problems at this stage will be that
getFrameScopeWindowAncestor() is expected to return an object that is
_both_ a Window and a JS scope: in the context of a GM script, these
are two different things (the scope is the Sandbox).
Patched as shown above, the console tab does not work (it doesn't
answer commands). If i return the associated window instead of the
sandbox, the console works... in the scope of the window, i.e. scripts
vars are unreachable (and, as a side note, entered console commands
show up in the scripts tab as evals -- is that normal?).


--
Olivier

Olivier Cornu

unread,
Jul 29, 2009, 10:05:19 AM7/29/09
to fir...@googlegroups.com
On Wed, Jul 29, 2009 at 14:55, Olivier Cornu<o.c...@gmail.com> wrote:
> As it seems a Sandbox is not a "supported" scope, i tried this
> quick-&-dirty-hack(TM) in getFrameScopeWindowAncestor():
>
> --- firebug-service.js~ 2009-07-29 13:25:51.913450368 +0200
> +++ firebug-service.js  2009-07-29 13:26:42.293449931 +0200
> @@ -2573,7 +2573,7 @@
>         while(scope.jsParent)
>             scope = scope.jsParent;
>
> -        if (scope.jsClassName == "Window" || scope.jsClassName ==
> "ChromeWindow")
> +        if (scope.jsClassName == "Window" || scope.jsClassName ==
> "ChromeWindow" || scope.jsClassName == "Sandbox")
>             return  scope.getWrappedValue();
>
>         if (FBTrace.DBG_FBS_FINDDEBUGGER)
>
>
> Apart of the fact that this throws "too much recursion" errors at
> firebug-service:2559 (hook())

More precisely, the error is logged by notifyObservers() at
firebug-trace-service.js:181.
It's consistently thrown, unless there is an opened FB Tracing window.


--
Olivier

johnjbarton

unread,
Jul 29, 2009, 11:11:11 AM7/29/09
to Firebug


On Jul 29, 5:55 am, Olivier Cornu <o.co...@gmail.com> wrote:
...
> As it seems a Sandbox is not a "supported" scope, i tried this

Yes, you are on the the right track....

> quick-&-dirty-hack(TM) in getFrameScopeWindowAncestor():
>
> --- firebug-service.js~ 2009-07-29 13:25:51.913450368 +0200
> +++ firebug-service.js  2009-07-29 13:26:42.293449931 +0200
> @@ -2573,7 +2573,7 @@
>          while(scope.jsParent)
>              scope = scope.jsParent;
>
> -        if (scope.jsClassName == "Window" || scope.jsClassName ==
> "ChromeWindow")
> +        if (scope.jsClassName == "Window" || scope.jsClassName ==
> "ChromeWindow" || scope.jsClassName == "Sandbox")
>              return  scope.getWrappedValue();

While Chromebug can with with non-window scopes, Firebug cannot.

>
>          if (FBTrace.DBG_FBS_FINDDEBUGGER)
>
> Apart of the fact that this throws "too much recursion" errors at
> firebug-service:2559 (hook()), webmonkey.js (the add-on XPCOM, not the
> script unfortunately) appears in FB scripts tab. Nevertheless, it's a
> tiny progress. :-p

I don't understand "the addon XPCOM".

>
> > Once you figure out what jsd things of the GM scripts, you need to
> > convince Firebug to add them to the context for  the web page. After
> > that I guess Firebug will work for you.
>
> I'm not there yet! I guess i'll have to keep on working in this
> direction... Any hint will be much appreciated. :-)
>
> I guess one of my problems at this stage will be that
> getFrameScopeWindowAncestor() is expected to return an object that is
> _both_ a Window and a JS scope: in the context of a GM script, these
> are two different things (the scope is the Sandbox).

Well getFrameScopeWindowAncestor() must return a nsIDOMWindow for
Firebug. In particular it needs to return the window that the GM
script was applied to. But I think you want to know that the compile
was in a Sandbox.

I think that at this stage in the processing the only thing we are
trying to do is create a "SourceFile", that is Firebug's metadata for
a compilation unit, and put that SourceFile in the correct context.
The scope analysis is only a means to that end. Firefox mixes up all
of the scripts from web pages and xul: we are just trying to sort out
where this particular script belongs. For that we need the window
then we can use getContextByWindow() to get the context we want to
attach to.

But we also need to know that the compile was in a Sandbox so we can
create a SandboxSourceFile (which by the way is not defined yet ;-).
This would be returned from onTopLevelScriptCreated. You don't need
the sandbox itself, just a way to know that you need to get the source
from GM (well I assume you have a way to get the source...).

With a SandboxSourceFile and the correct context, I guess the rest
will come together.

You won't see any of the GM script's top level objects this way, I
suppose they are in the sandbox object. But you can't reach them from
the web page anyway. You will see stuff when you hit a breakpoint in a
GM script.

(Chromebug creates new contexts for every sandbox, but I don't think
that is very helpful, you want the GM script to appear with the rest
of the page stuff.)


Does this give you enough hints?

jjb

johnjbarton

unread,
Jul 29, 2009, 11:12:16 AM7/29/09
to Firebug


On Jul 29, 7:05 am, Olivier Cornu <o.co...@gmail.com> wrote:
...
> > Apart of the fact that this throws "too much recursion" errors at
> > firebug-service:2559 (hook())
>
> More precisely, the error is logged by notifyObservers() at
> firebug-trace-service.js:181.
> It's consistently thrown, unless there is an opened FB Tracing window.

Your line numbers seem different from mine. Are you using the updated
SVN branches/firebug1.5?

jjb

Olivier Cornu

unread,
Jul 30, 2009, 5:35:10 AM7/30/09
to fir...@googlegroups.com
On Wed, Jul 29, 2009 at 17:11, johnjbarton<johnj...@johnjbarton.com> wrote:
> On Jul 29, 5:55 am, Olivier Cornu <o.co...@gmail.com> wrote:
>> quick-&-dirty-hack(TM) in getFrameScopeWindowAncestor():
>>
>> --- firebug-service.js~ 2009-07-29 13:25:51.913450368 +0200
>> +++ firebug-service.js  2009-07-29 13:26:42.293449931 +0200
>> @@ -2573,7 +2573,7 @@
>>          while(scope.jsParent)
>>              scope = scope.jsParent;
>>
>> -        if (scope.jsClassName == "Window" || scope.jsClassName ==
>> "ChromeWindow")
>> +        if (scope.jsClassName == "Window" || scope.jsClassName ==
>> "ChromeWindow" || scope.jsClassName == "Sandbox")
>>              return  scope.getWrappedValue();
>
> While Chromebug can with with non-window scopes, Firebug cannot.

Do you think i should browse Chromebug code for inspiration, then?


>> Apart of the fact that this throws "too much recursion" errors at
>> firebug-service:2559 (hook()), webmonkey.js (the add-on XPCOM, not the
>> script unfortunately) appears in FB scripts tab. Nevertheless, it's a
>> tiny progress. :-p
>
> I don't understand "the addon XPCOM".

I meant it's a GM XPCOM service source file (like Firebug's firebug-service.js).


>> I guess one of my problems at this stage will be that
>> getFrameScopeWindowAncestor() is expected to return an object that is
>> _both_ a Window and a JS scope: in the context of a GM script, these
>> are two different things (the scope is the Sandbox).
>
> Well getFrameScopeWindowAncestor() must return a nsIDOMWindow for
> Firebug. In particular it needs to return the window that the GM
> script was applied to. But I think you want to know that the compile
> was in a Sandbox.
>
> I think that at this stage in the processing the only thing we are
> trying to do is create a "SourceFile", that is Firebug's metadata for
> a compilation unit, and put that SourceFile in the correct context.
> The scope analysis is only a means to that end. Firefox mixes up all
> of the scripts from web pages and xul: we are just trying to sort out
> where this particular script belongs.  For that we need the window
> then we can use getContextByWindow() to get the context we want to
> attach to.

Alright. In the specific case of a GM script Sandbox, it's quite
straightforward to extract a reference back to the target nsiDOMWindow
(it holds several of them). In other words, it should be easy to find
the right context (/me is checking that box).

> But we also need to know that the compile was in a Sandbox so we can
> create a SandboxSourceFile (which by the way is not defined yet ;-).
> This would be returned from onTopLevelScriptCreated. You don't need
> the sandbox itself, just a way to know that you need to get the source
> from GM (well I assume you have a way to get the source...).

As noted in my previous mail, the source code run in the Sandbox
appears at some point in the Firebug trace (step #86):
script.functionSource logged by onScriptCreated() on line 1514.
It is not the script source in its exact original form though (it
lacks some metadata/comments, etc), so it might still be a good idea
to make this original source available from GM somehow.

> With a SandboxSourceFile and the correct context, I guess the rest
> will come together.

I guess that, if we rely on GM to provide the Sandbox source, that
would be a GMSandboxSourceFile (as opposed to a general Sandbox
mechanism)?

> You won't see any of the GM script's top level objects this way, I
> suppose they are in the sandbox object. But you can't reach them from
> the web page anyway. You will see stuff when you hit a breakpoint in a
> GM script.

That'd be excellent already. :-)
Then i'd just like to add a way for users to poke around in a script
Sandbox/scope from the Firebug console tab, which implies a mean for
users to select said scope -- cd(scope)?

> Does this give you enough hints?

That's a lot -- more than i was expecting! It's great, thanks again
for that. :-)

I guess i've got the big picture now, i just to work a bit more on the
specifics...
Anyway, i've got enough to move forward significantly. Back to work!


--
Olivier

Olivier Cornu

unread,
Jul 30, 2009, 5:37:09 AM7/30/09
to fir...@googlegroups.com

FB-1.4X.1 so far.
I'll switch to the current SVN branch from now on...

--
Olivier

johnjbarton

unread,
Jul 30, 2009, 11:25:06 AM7/30/09
to Firebug


On Jul 30, 2:35 am, Olivier Cornu <o.co...@gmail.com> wrote:
...
> > But we also need to know that the compile was in a Sandbox so we can
> > create a SandboxSourceFile (which by the way is not defined yet ;-).
> > This would be returned from onTopLevelScriptCreated. You don't need
> > the sandbox itself, just a way to know that you need to get the source
> > from GM (well I assume you have a way to get the source...).
>
> As noted in my previous mail, the source code run in the Sandbox
> appears at some point in the Firebug trace (step #86):
> script.functionSource logged by onScriptCreated() on line 1514.
> It is not the script source in its exact original form though (it
> lacks some metadata/comments, etc), so it might still be a good idea
> to make this original source available from GM somehow.


jsdIScript.functionSource is the so-called pretty-print, but it is
correctly called the decompiled function. The line number will not
match the source in your editor.

>
> > With a SandboxSourceFile and the correct context, I guess the rest
> > will come together.
>
> I guess that, if we rely on GM to provide the Sandbox source, that
> would be a GMSandboxSourceFile (as opposed to a general Sandbox
> mechanism)?

Sure. I suppose the correct distinction would be by how the SourceFile
object differs from other SourceFile objects, but GMSandbox is fine.

>
> > You won't see any of the GM script's top level objects this way, I
> > suppose they are in the sandbox object. But you can't reach them from
> > the web page anyway. You will see stuff when you hit a breakpoint in a
> > GM script.
>
> That'd be excellent already. :-)
> Then i'd just like to add a way for users to poke around in a script
> Sandbox/scope from the Firebug console tab, which implies a mean for
> users to select said scope -- cd(scope)?

Strictly speaking you can't poke around in the scope of a function X
unless X is being compiled or run. I suppose you would allow users to
examine the properties of the Sandbox object. It would be more for
curiosity than practical us I think. The whole point (and failing) of
the sandbox is it be invisible.
jjb

Olivier Cornu

unread,
Jul 30, 2009, 4:30:59 PM7/30/09
to fir...@googlegroups.com
On Thu, Jul 30, 2009 at 17:25, johnjbarton<johnj...@johnjbarton.com> wrote:
> On Jul 30, 2:35 am, Olivier Cornu <o.co...@gmail.com> wrote:
>> As noted in my previous mail, the source code run in the Sandbox
>> appears at some point in the Firebug trace (step #86):
>> script.functionSource logged by onScriptCreated() on line 1514.
>> It is not the script source in its exact original form though (it
>> lacks some metadata/comments, etc), so it might still be a good idea
>> to make this original source available from GM somehow.
>
>
> jsdIScript.functionSource is the so-called pretty-print, but it is
> correctly called the decompiled  function. The line number will not
> match the source in your editor.

That's right: it's true there's a real value in showing the script
exactly as it is on-disk.
This raises another question: a running script can actually be a
bundle of JS files glued together thanks to a PHP-like @include
directive. In other words, we're potentially dealing with a bunch of
SourceFiles to be "spawned" out of a single jsdIScript.
As, i guess, there usually is a one-to-one relationship between
SourceFile and jsdIScript in Firebug, do you think this can be an
issue?


>> I guess that, if we rely on GM to provide the Sandbox source, that
>> would be a GMSandboxSourceFile (as opposed to a general Sandbox
>> mechanism)?
>
> Sure. I suppose the correct distinction would be by how the SourceFile
> object differs from other SourceFile objects, but GMSandbox is fine.

SandboxSourceFile is good, especially if Firebug defines some kind of
interface allowing tiers components to provide sources for their
Sandboxed scripts (and GM complies to that). ;-)


>> Then i'd just like to add a way for users to poke around in a script
>> Sandbox/scope from the Firebug console tab, which implies a mean for
>> users to select said scope -- cd(scope)?
>
> Strictly speaking you can't poke around in the scope of a function X
> unless X is being compiled or run. I suppose you would allow users to
> examine the properties of the Sandbox object.

Yes: as script global vars are Sandbox properties, i thought it could
be helpful to explore their values...


--
Olivier

johnjbarton

unread,
Jul 30, 2009, 4:59:52 PM7/30/09
to Firebug


On Jul 30, 1:30 pm, Olivier Cornu <o.co...@gmail.com> wrote:
> On Thu, Jul 30, 2009 at 17:25, johnjbarton<johnjbar...@johnjbarton.com> wrote:
> > On Jul 30, 2:35 am, Olivier Cornu <o.co...@gmail.com> wrote:
> >> As noted in my previous mail, the source code run in the Sandbox
> >> appears at some point in the Firebug trace (step #86):
> >> script.functionSource logged by onScriptCreated() on line 1514.
> >> It is not the script source in its exact original form though (it
> >> lacks some metadata/comments, etc), so it might still be a good idea
> >> to make this original source available from GM somehow.
>
> > jsdIScript.functionSource is the so-called pretty-print, but it is
> > correctly called the decompiled  function. The line number will not
> > match the source in your editor.
>
> That's right: it's true there's a real value in showing the script
> exactly as it is on-disk.
> This raises another question: a running script can actually be a
> bundle of JS files glued together thanks to a PHP-like @include
> directive. In other words, we're potentially dealing with a bunch of
> SourceFiles to be "spawned" out of a single jsdIScript.
> As, i guess, there usually is a one-to-one relationship between
> SourceFile and jsdIScript in Firebug, do you think this can be an
> issue?

No, because what ever happens on the server is someone else's problem.
We get what the browser sees, that is the problem we need to work on.

The jsdIScript object corresponds to a function in Javascript.
SourceFile is a Firebug invention that tries to group all of the
jsdIScript objects that logically belong together. Firefox has no such
grouping, it just a big pile.

>
> >> I guess that, if we rely on GM to provide the Sandbox source, that
> >> would be a GMSandboxSourceFile (as opposed to a general Sandbox
> >> mechanism)?
>
> > Sure. I suppose the correct distinction would be by how the SourceFile
> > object differs from other SourceFile objects, but GMSandbox is fine.
>
> SandboxSourceFile is good, especially if Firebug defines some kind of
> interface allowing tiers components to provide sources for their
> Sandboxed scripts (and GM complies to that). ;-)

You lost me here. Firefox compile, we watch.

>
> >> Then i'd just like to add a way for users to poke around in a script
> >> Sandbox/scope from the Firebug console tab, which implies a mean for
> >> users to select said scope -- cd(scope)?
>
> > Strictly speaking you can't poke around in the scope of a function X
> > unless X is being compiled or run. I suppose you would allow users to
> > examine the properties of the Sandbox object.
>
> Yes: as script global vars are Sandbox properties, i thought it could
> be helpful to explore their values...

You could try to see if Chromebug will show you the sandbox values.
Firebug is not really set up to deal with them. I suppose we could go
in that direction, but honestly I don't expect to do that.


>
> --
> Olivier

Olivier Cornu

unread,
Aug 1, 2009, 7:13:20 AM8/1/09
to fir...@googlegroups.com
On Thu, Jul 30, 2009 at 22:59, johnjbarton<johnj...@johnjbarton.com> wrote:
>
> The jsdIScript object corresponds to a function in Javascript.
> SourceFile is a Firebug invention that tries to group all of the
> jsdIScript objects that logically belong together. Firefox has no such
> grouping, it just a big pile.

Well, my question was more: how is the jsdIScript/SourceFile relation
constrained in the Firebug framework? But i should probably get more
familiar with Firebug SourceFiles before going there...
Just to make it clearer though, i meant: as i understand it, it
usually is about linking "spawned" jsdIScripts to a SourceFile, while
in the GM-script discovery step it is about creating several
SourceFiles objects in the context of one on(JsdI)Script handler.


>> SandboxSourceFile is good, especially if Firebug defines some kind of
>> interface allowing tiers components to provide sources for their
>> Sandboxed scripts (and GM complies to that). ;-)
>
> You lost me here. Firefox compile, we watch.

We watch but i understand we don't usually watch sandboxes which, i
suppose, are particular.
I'm assuming Firebug usually builds SourceFiles out of JS script DOM
elements. In the case of a Sandbox (i.e. without corresponding DOM
element), there seem to be no way for Firebug to build a proper
SourceFile alone, when one is needed as is the case with GM scripts.
It can only do so if it's provided with proper data by the Sandbox
owner -- GM here.
If that's the case, why not take it as an opportunity for Firebug to
support Sandbox debugging? The idea being to provide an interface
tiers chrome code can use to register Sandboxes they want to debug.
I understand Firebug is focused on web page debugging (as opposed to
chrome debugging), yet it makes sense to include chrome code
dynamically altering said page, doesn't it?


> You could try to see if Chromebug will show you the sandbox values.
> Firebug is not really set up to deal with them. I suppose we could go
> in that direction, but honestly I don't expect to do that.

I've been unlucky with Chromebug: i tried to install it once but it
was making FF crash (FF could not even start, iirc).
But i did some (limited) testing of script Sandbox values poking
around: it worked as mentioned.


--
Olivier

johnjbarton

unread,
Aug 1, 2009, 12:34:16 PM8/1/09
to Firebug


On Aug 1, 4:13 am, Olivier Cornu <o.co...@gmail.com> wrote:
> On Thu, Jul 30, 2009 at 22:59, johnjbarton<johnjbar...@johnjbarton.com> wrote:
>
> > The jsdIScript object corresponds to a function in Javascript.
> > SourceFile is a Firebug invention that tries to group all of the
> > jsdIScript objects that logically belong together. Firefox has no such
> > grouping, it just a big pile.
>
> Well, my question was more: how is the jsdIScript/SourceFile relation
> constrained in the Firebug framework? But i should probably get more
> familiar with Firebug SourceFiles before going there...

The SourceFile objects are created just after the JS source is
compiled. From Firebug's perspective it works like this:

Suddenly a function arrives having just been compiled. We know a
URL associated with the source of the function but not the source or
window. Firebug tests the call stack to see if this function is an
outer function. Typically no, so we add it to a temp list.
More functions arrive then one passes the outer function test. We
set a break point in PC=0 and return.
A breakpoint hits. If it is on PC=0 we take the outer function
script and all of the inner functions on the temp list and create a
SourceFile. In the process we do analysis of the call stack to
determine if the source is in a .js file or from eval() or event
handler. That allows us to put the source into the SourceFile. Then we
remove the breakpoint and allow the outer function to complete.

SourceFiles are then used to map jsdIScripts to source that is shown
to the user. (SourceFiles are defined in lib.js)

Since GM is also an extension it could easily help by providing a
method that returns the source so Firebug can copy it into its cache
and point from the SourceFile into the cache.

> Just to make it clearer though, i meant: as i understand it, it
> usually is about linking "spawned" jsdIScripts to a SourceFile, while
> in the GM-script discovery step it is about creating several
> SourceFiles objects in the context of one on(JsdI)Script handler.

The GM script is compiled in a sandbox, so the entire compile will be
one SourceFile.

>
> >> SandboxSourceFile is good, especially if Firebug defines some kind of
> >> interface allowing tiers components to provide sources for their
> >> Sandboxed scripts (and GM complies to that). ;-)
>
> > You lost me here. Firefox compile, we watch.
>
> We watch but i understand we don't usually watch sandboxes which, i
> suppose, are particular.

Ok, I see what you meant. Firebug watches the compile as I described
above.

> I'm assuming Firebug usually builds SourceFiles out of JS script DOM
> elements. In the case of a Sandbox (i.e. without corresponding DOM
> element), there seem to be no way for Firebug to build a proper
> SourceFile alone, when one is needed as is the case with GM scripts.

As above, the SourceFile does not use the window except to figure out
which context to add the SourceFile into. We get all of our info from
the compiler.

> It can only do so if it's provided with proper data by the Sandbox
> owner -- GM here.
> If that's the case, why not take it as an opportunity for Firebug to
> support Sandbox debugging? The idea being to provide an interface
> tiers chrome code can use to register Sandboxes they want to debug.
> I understand Firebug is focused on web page debugging (as opposed to
> chrome debugging), yet it makes sense to include chrome code
> dynamically altering said page, doesn't it?

I think the Sandbox itself is not very interesting, by design. The
whole point of the sandbox is to avoid having the left over bits of
the outer function hang out in the web page. What value do we get
from being able to look at those left over bits? Not too much I
guess. Sure it would be nice to have, but since Firebug is not set up
to show it the implementation could be harder.

>
> > You could try to see if Chromebug will show you the sandbox values.
> > Firebug is not really set up to deal with them. I suppose we could go
> > in that direction, but honestly I don't expect to do that.
>
> I've been unlucky with Chromebug: i tried to install it once but it
> was making FF crash (FF could not even start, iirc).
> But i did some (limited) testing of script Sandbox values poking
> around: it worked as mentioned.

And did you find the content of the sandbox to be critical for
debugging the GM script or only helpful in understanding sandboxes?

I think you can get 80% of the value of Firebug for GM without viewing
the sandbox; viewing the sandbox will be 80% of a complete job. I'd
push on the first 20%.

jjb

> --
> Olivier

Olivier Cornu

unread,
Aug 4, 2009, 6:24:02 AM8/4/09
to fir...@googlegroups.com
On Sat, Aug 1, 2009 at 18:34, johnjbarton<johnj...@johnjbarton.com> wrote:
> The SourceFile objects are created just after the JS source is
> compiled. From Firebug's perspective it works like this:
>
>   Suddenly a function arrives having just been compiled. We know a
> URL associated with the source of the function but not the source or
> window. Firebug tests the call stack to see if this function is an
> outer function. Typically no, so we add it to a temp list.
>   More functions arrive then one passes the outer function test. We
> set a break point in PC=0 and return.
>   A breakpoint hits. If it is on PC=0 we take the outer function
> script and all of the inner functions on the temp list and create a
> SourceFile. In the process we do analysis of the call stack to
> determine if the source is in a .js file or from eval() or event
> handler. That allows us to put the source into the SourceFile. Then we
> remove the breakpoint and allow the outer function to complete.

Thank you, the whole process is much clearer after this. :-)

> SourceFiles are then used to map jsdIScripts to source that is shown
> to the user.  (SourceFiles are defined in lib.js)

Alright. I'm still unsure as to how i am going to deal with the fact
that a single GM script may be composed of several JS source files
(glued and run in the same sandbox), which i'd like to show separately
in Firebug's script tab. But this can be dealt with later...

> Since GM is also an extension it could easily help by providing a
> method that returns the source so Firebug can copy it into its cache
> and point from the SourceFile into the cache.

Yes. And the file name seems to be needed as well, at least for the
GUI: so far it shows webmonkey.js, which is the JS code creating the
sandbox, not the script code running inside it.
I guess this GM method should return the needed script's details,
whatever they end up being. As far as i can see, the only reference to
the running script we share between GM and FB is the Sandbox object
it's running in -- that should be the method parameter.

Overall, here is how i'm proceeding: i patch
firebug-service.js:getFrameScopeWindowAncestor() to allow finding the
right debugger for a GM script sandbox. It then flows as usual up to
debugger.js:onTopLevelScriptCreated(), patched in order to delegate
the work to onSandboxScriptCreated() in case of a Sandbox scope.
Finally, this last method returns a lib.js:SandboxSourceFile object.
Does it look ok so far?


>> Just to make it clearer though, i meant: as i understand it, it
>> usually is about linking "spawned" jsdIScripts to a SourceFile, while
>> in the GM-script discovery step it is about creating several
>> SourceFiles objects in the context of one on(JsdI)Script handler.
>
> The GM script is compiled in a sandbox, so the entire compile will be
> one SourceFile.

It's fine as long as we show all the JS source files composing a GM
script as one big source file. I guess that, if we wanted to show them
separately, Firebug.Debugger#onSandboxScriptCreated() should return an
array of SourceFiles...


>> But i did some (limited) testing of script Sandbox values poking
>> around: it worked as mentioned.
>
> And did you find the content of the sandbox to be critical for
> debugging the GM script or only helpful in understanding sandboxes?

Well, i just tested that it worked, i haven't used it for real
debugging. I kinda thought: "well, i could have a JS console to poke
in that thing just the way FB allows poking in a window... hey, let's
use FB's console for that!". :-)
As i see it, what makes poking in Windows or Sandboxes (equally)
interesting is that you actually are poking in a "top-level" JS scope.
But i might be wrong...

> I think you can get 80% of the value of Firebug for GM without viewing
> the sandbox; viewing the sandbox will be 80% of a complete job. I'd
> push on the first 20%.

No problem: let's focus on the debugger then. :-)


--
Olivier

johnjbarton

unread,
Aug 4, 2009, 10:49:30 AM8/4/09
to Firebug


On Aug 4, 3:24 am, Olivier Cornu <o.co...@gmail.com> wrote:
> On Sat, Aug 1, 2009 at 18:34, johnjbarton<johnjbar...@johnjbarton.com> wrote:
...
> > SourceFiles are then used to map jsdIScripts to source that is shown
> > to the user.  (SourceFiles are defined in lib.js)
>
> Alright. I'm still unsure as to how i am going to deal with the fact
> that a single GM script may be composed of several JS source files
> (glued and run in the same sandbox), which i'd like to show separately
> in Firebug's script tab. But this can be dealt with later...

Oh, I did not know this part.

>
> > Since GM is also an extension it could easily help by providing a
> > method that returns the source so Firebug can copy it into its cache
> > and point from the SourceFile into the cache.

Ok you need to take the list of innerScripts from the GM compile and
create a new

>
> Yes. And the file name seems to be needed as well, at least for the
> GUI: so far it shows webmonkey.js, which is the JS code creating the
> sandbox, not the script code running inside it.

Yes, that is all the compiler knows, because that is what GM told it.

> I guess this GM method should return the needed script's details,
> whatever they end up being. As far as i can see, the only reference to
> the running script we share between GM and FB is the Sandbox object
> it's running in -- that should be the method parameter.

You will need the line numbers for points of concatenation, eg. a.js
1-150, b.js 151-213, c.js 213-end.


>
> Overall, here is how i'm proceeding: i patch
> firebug-service.js:getFrameScopeWindowAncestor() to allow finding the
> right debugger for a GM script sandbox. It then flows as usual up to
> debugger.js:onTopLevelScriptCreated(), patched in order to delegate
> the work to onSandboxScriptCreated() in case of a Sandbox scope.
> Finally, this last method returns a lib.js:SandboxSourceFile object.
> Does it look ok so far?

You might return a sourcefile representing the webmonkey.js with a
single script, the outer script representing the body of the function
that run the sandbox global method (called outerScript in Firebug).

>
> >> Just to make it clearer though, i meant: as i understand it, it
> >> usually is about linking "spawned" jsdIScripts to a SourceFile, while
> >> in the GM-script discovery step it is about creating several
> >> SourceFiles objects in the context of one on(JsdI)Script handler.
>
> > The GM script is compiled in a sandbox, so the entire compile will be
> > one SourceFile.

Now that I realize you want to decompose, this it not true.

>
> It's fine as long as we show all the JS source files composing a GM
> script as one big source file. I guess that, if we wanted to show them
> separately, Firebug.Debugger#onSandboxScriptCreated() should return an
> array of SourceFiles...

Or just jam the other ones on the context and return one representing
the outerScript.

To create the others you need to walk the list of innerScripts and
compare the source ranges (baseLineNumber, lineExtent) to the
webmonkey.js and your list of actual sources with their line ranges.
Divvy them up.
jjb

Olivier Cornu

unread,
Aug 9, 2009, 7:15:00 AM8/9/09
to fir...@googlegroups.com
On Tue, Aug 4, 2009 at 16:49, johnjbarton<johnj...@johnjbarton.com> wrote:
> On Aug 4, 3:24 am, Olivier Cornu <o.co...@gmail.com> wrote:
>> On Sat, Aug 1, 2009 at 18:34, johnjbarton<johnjbar...@johnjbarton.com> wrote:
> ...
>> > SourceFiles are then used to map jsdIScripts to source that is shown
>> > to the user.  (SourceFiles are defined in lib.js)
>>
>> Alright. I'm still unsure as to how i am going to deal with the fact
>> that a single GM script may be composed of several JS source files
>> (glued and run in the same sandbox), which i'd like to show separately
>> in Firebug's script tab. But this can be dealt with later...
>
> Oh, I did not know this part.

It's somewhat reassuring to realize there's been some misunderstanding
around this at some point... :-p


>> Yes. And the file name seems to be needed as well, at least for the
>> GUI: so far it shows webmonkey.js, which is the JS code creating the
>> sandbox, not the script code running inside it.
>
> Yes, that is all the compiler knows, because that is what GM told it.

I take it this is happening behind the scene: i'm not aware of any GM
code specifically providing this kind of information to the compiler.


>> I guess this GM method should return the needed script's details,
>> whatever they end up being. As far as i can see, the only reference to
>> the running script we share between GM and FB is the Sandbox object
>> it's running in -- that should be the method parameter.
>
>  You will need the line numbers for points of concatenation, eg. a.js
> 1-150, b.js 151-213, c.js 213-end.

Yes. From what i see, i guess line numbers should be taken care of in
SandboxSourceFile...

> You might return a sourcefile representing the webmonkey.js with a
> single script, the outer script representing the body of the function
> that run the sandbox global method (called outerScript in Firebug).
>

> (...) just jam the other ones on the context and return one representing


> the outerScript.
> To create the others you need to walk the list of innerScripts and
> compare the source ranges (baseLineNumber, lineExtent) to the
> webmonkey.js and your list of actual sources with their line ranges.
> Divvy them up.

Alright. Haven't dealt with line numbers specifics yet but i suppose
it'll make sense when i do.


--
Olivier

trinitrotoluen

unread,
Aug 9, 2009, 7:48:31 AM8/9/09
to fir...@googlegroups.com, firebug+u...@googlegroups.com
Please unsubscribe me.

johnjbarton

unread,
Aug 9, 2009, 10:42:29 AM8/9/09
to Firebug


On Aug 9, 4:15 am, Olivier Cornu <o.co...@gmail.com> wrote:
> On Tue, Aug 4, 2009 at 16:49, johnjbarton<johnjbar...@johnjbarton.com> wrote:
...
> >> Yes. And the file name seems to be needed as well, at least for the
> >> GUI: so far it shows webmonkey.js, which is the JS code creating the
> >> sandbox, not the script code running inside it.
>
> > Yes, that is all the compiler knows, because that is what GM told it.
>
> I take it this is happening behind the scene: i'm not aware of any GM
> code specifically providing this kind of information to the compiler.

There is no way to give this info to the compiler. That's why we have
to do it in Firebug.

>
> >> I guess this GM method should return the needed script's details,
> >> whatever they end up being. As far as i can see, the only reference to
> >> the running script we share between GM and FB is the Sandbox object
> >> it's running in -- that should be the method parameter.
>
> >  You will need the line numbers for points of concatenation, eg. a.js
> > 1-150, b.js 151-213, c.js 213-end.
>
> Yes. From what i see, i guess line numbers should be taken care of in
> SandboxSourceFile...

Yes, it has to translate the line number the user wants to see back
and forth to the ones the compiler assigns.

>
> > You might return a sourcefile representing the webmonkey.js with a
> > single script, the outer script representing the body of the function
> > that run the sandbox global method (called outerScript in Firebug).
>
> > (...) just jam the other ones on the context and return one representing
> > the outerScript.
> > To create the others you need to walk the list of innerScripts and
> > compare the source ranges (baseLineNumber, lineExtent) to the
> > webmonkey.js and your list of actual sources with their line ranges.
> > Divvy them up.
>
> Alright. Haven't dealt with line numbers specifics yet but i suppose
> it'll make sense when i do.

jjb

Med Hadrouj

unread,
Aug 9, 2009, 5:52:48 PM8/9/09
to Firebug
Hi guys,
I just wanted to thank you for the effort you're putting to make this
feature come to life, this would be a great tool for all GM
developpers.
I would be very grateful and interested to test an early releases of
the future extension.

It would be great if someone could write an article that will show the
steps to flollow to "hack" FB to be able to debug GM.
Thanks a lot !

Olivier Cornu

unread,
Aug 11, 2009, 6:16:50 AM8/11/09
to fir...@googlegroups.com
On Sun, Aug 9, 2009 at 23:52, Med Hadrouj<had...@gmail.com> wrote:
> Hi guys,
> I just wanted to thank you for the effort you're putting to make this
> feature come to life, this would be a great tool for all GM
> developpers.
> I would be very grateful and interested to test an early releases of
> the future extension.

Thanks, that's always good to hear... :-)
If you keep following this thread you'll be notified when there's code
up for testing.

> It would be great if someone could write an article that will show the
> steps to flollow to "hack" FB to be able to debug GM.
> Thanks a lot !

I'm not sure how these features may be integrated in FB actually.
Eventually, it'd be nice to get them without hacking FB...

--
Olivier

johnjbarton

unread,
Aug 11, 2009, 11:38:53 AM8/11/09
to Firebug
We would be happy to help you create a GM extension for Firebug.
jjb

On Aug 11, 3:16 am, Olivier Cornu <o.co...@gmail.com> wrote:

Olivier Cornu

unread,
Aug 18, 2009, 1:56:34 PM8/18/09
to fir...@googlegroups.com
On Tue, Aug 11, 2009 at 17:38, johnjbarton<johnj...@johnjbarton.com> wrote:
>
> We would be happy to help you create a GM extension for Firebug.

Considering the amount of FB code patching that seems necessary so far
(firebug-service, debugger, lib...), will this be doable using a FB
extension only?
That would be excellent...


On Tue, Aug 4, 2009 at 16:49, johnjbarton<johnjbar...@johnjbarton.com> wrote:
>> > You will need the line numbers for points of concatenation, eg. a.js
>> > 1-150, b.js 151-213, c.js 213-end.
>>
>> Yes. From what i see, i guess line numbers should be taken care of in
>> SandboxSourceFile...
>
> Yes, it has to translate the line number the user wants to see back
> and forth to the ones the compiler assigns.

Alright. Frankly, i'm still quite puzzled at how the line mangling
between jsdIScript and SourceFile work...
That is, even when sticking to the simple case: one GM script file run
in its Sandbox (i'm temporarily putting aside the complex case: many
files concatenated and run into a single GM script sandbox).
I've been able to make GM scripts proper name and source code appear
in FB's "Scripts" tab. It is possible to set a breakpoint and the
debugger will properly stop on it on page reload. Restarting execution
also works (i haven't really tested stepping). But there are a few
problems (for example, the breakpoint's red dot in the script margin
does not change state when the debugger stops on it).
The only line mangling i've done though is:
SandboxSourceFile.prototype.getBaseLineOffset
this.SandboxSourceFile.prototype.getBaseLineOffset = function()
{
return 304; // TODO depends on number of script tags
https://bugzilla.mozilla.org/show_bug.cgi?id=396568
}

So far i've been able to set a breakpoint in


I'm trying to solve the simple case first, that is:
I suppose the line-nb related methods inherited from SourceFile are
enough in this case.


As a reminder, this is what i do:


>> i patch
>> firebug-service.js:getFrameScopeWindowAncestor() to allow finding the
>> right debugger for a GM script sandbox. It then flows as usual up to
>> debugger.js:onTopLevelScriptCreated(), patched in order to delegate
>> the work to onSandboxScriptCreated() in case of a Sandbox scope.
>> Finally, this last method returns a lib.js:SandboxSourceFile object.

onSandboxScriptCreated() calls a GM method to get details on the
script running in this sandbox. It can thus create a SandboxSourceFile
object with the proper file URL.
As a consequence, the GM script name and source now appear correctly
in FB's Scripts tab; i can set breakpoints in the GM script... :-)

...However breakpoints do not work: on page reload, script execution
is not halted, breakpoints seem disabled (light-red UI dot, unchecked
UI box).
I haven't found out why yet.


--
Olivier

Olivier Cornu

unread,
Aug 18, 2009, 2:02:48 PM8/18/09
to fir...@googlegroups.com
Please discard the previous mail (it's been sent by accident) and
consider the following instead:


On Tue, Aug 18, 2009 at 19:56, Olivier Cornu<o.c...@gmail.com> wrote:
> On Tue, Aug 11, 2009 at 17:38, johnjbarton<johnj...@johnjbarton.com> wrote:
>>
>> We would be happy to help you create a GM extension for Firebug.
>
> Considering the amount of FB code patching that seems necessary so far
> (firebug-service, debugger, lib...), will this be doable using a FB
> extension only?
> That would be excellent...

That's still a question i wanted to ask. :p


> On Tue, Aug 4, 2009 at 16:49, johnjbarton<johnjbar...@johnjbarton.com> wrote:
>>> >  You will need the line numbers for points of concatenation, eg. a.js
>>> > 1-150, b.js 151-213, c.js 213-end.
>>>
>>> Yes. From what i see, i guess line numbers should be taken care of in
>>> SandboxSourceFile...
>>
>> Yes, it has to translate the line number the user wants to see back
>> and forth to the ones the compiler assigns.
>
> Alright. Frankly, i'm still quite puzzled at how the line mangling
> between jsdIScript and SourceFile work...
> That is, even when sticking to the simple case: one GM script file run
> in its Sandbox (i'm temporarily putting aside the complex case: many
> files concatenated and run into a single GM script sandbox).
> I've been able to make GM scripts proper name and source code appear
> in FB's "Scripts" tab. It is possible to set a breakpoint and the
> debugger will properly stop on it on page reload. Restarting execution
> also works (i haven't really tested stepping). But there are a few
> problems (for example, the breakpoint's red dot in the script margin
> does not change state when the debugger stops on it).

The only line mangling i've done though is:

SandboxSourceFile.prototype.getBaseLineOffset = function()
{
   return 304; // webmonkey.js:evalInSandbox() line
}

...which is a dirty hack. :)


> As a reminder, this is what i do:
>>> i patch
>>> firebug-service.js:getFrameScopeWindowAncestor() to allow finding the
>>> right debugger for a GM script sandbox. It then flows as usual up to
>>> debugger.js:onTopLevelScriptCreated(), patched in order to delegate
>>> the work to onSandboxScriptCreated() in case of a Sandbox scope.
>>> Finally, this last method returns a lib.js:SandboxSourceFile object.
>
> onSandboxScriptCreated() calls a GM method to get details on the
> script running in this sandbox. It can thus create a SandboxSourceFile
> object with the proper file URL.


Sorry again for the inconvenience.

--
Olivier

johnjbarton

unread,
Aug 18, 2009, 11:05:14 PM8/18/09
to Firebug


On Aug 18, 11:02 am, Olivier Cornu <o.co...@gmail.com> wrote:
> Please discard the previous mail (it's been sent by accident) and
> consider the following instead:

Sorry you lost me.

I don't mind if we have to split the work between GM extension and
Firebug additions. I don't want GM-specific code in Firebug but I also
don't want extensions to have to try to hack into firebug-
service.js.

For the rest perhaps you can try again?

jjb

Olivier Cornu

unread,
Aug 19, 2009, 9:12:02 AM8/19/09
to fir...@googlegroups.com
On Wed, Aug 19, 2009 at 05:05, johnjbarton<johnj...@johnjbarton.com> wrote:
>
> Sorry you lost me.
>
> I don't mind if we have to split the work between GM extension and
> Firebug additions. I don't want GM-specific code in Firebug but I also
> don't want extensions to have to try to hack into firebug-
> service.js.

Alright. Perhaps it's too soon to talk about how to split the code
between FB and a FB extension for GM...
Yet i'm pleased to learn that your are willing to adapt FB to this
purpose, if needed -- and i'm quite sure GM script developers feel the
same. :-)


> For the rest perhaps you can try again?

Sure! Sorry about that, let me try again...

So far i've been working on the _simple_ case: the GM script is
considered to always be a single file. In other words, i temporarily
left aside the _complex_ case we already talked about, where a GM
script is a concatenation of several files (see: Greasemonkey @require
header tag [1]).

I've made some progress: GM scripts correctly appear (name and source
code) in Firebug's debugger tab. I can set breakpoints and correctly
use the debugger stepping functionalities.
I still have a few issues, though, that i'd like to fix before working
on the _complex_ case. For example, the "this" object in the right
side of the debugger seems to be wrong/empty (see attached
screenshot); is that a problem of context? Or scope?


As a reminder, i'm patching Firebug pretty much as we have have
discussed (see attached patch against Firebug 1.5 branch, rev 4035):
* getFrameScopeWindowAncestor() is patched to find the nsIDOMWindow
associated with a (GM) Sandbox scope. This happens both in
firebug-service.js and debugger.js because
getFrameScopeWindowAncestor() is defined -- and used -- in both of
them.
* onTopLevelScriptCreated() is patched to delegate SourceFile
creation to a new onSandboxScriptCreated() method when the top scope
is a Sandbox (debugger.js).
* this new onSandboxScriptCreated() calls a GM method returning the
GM-script file URL running in that Sandbox, and returns a new
SandboxSourceFile object for this script.
* SandboxSourceFile is a cut-&-paste of TopLevelSourceFile (with a
new "sandbox" compilation_unit_type) except that line-related methods
are tweaked for dealing with Sandboxes (lib.js).

--
Olivier


[1] http://wiki.greasespot.net/Metadata_block#.40require

Capture.png
gm_debugging.patch

johnjbarton

unread,
Aug 19, 2009, 10:58:34 AM8/19/09
to Firebug


On Aug 19, 6:12 am, Olivier Cornu <o.co...@gmail.com> wrote:
> On Wed, Aug 19, 2009 at 05:05, johnjbarton<johnjbar...@johnjbarton.com> wrote:
...
> I still have a few issues, though, that i'd like to fix before working
> on the _complex_ case. For example, the "this" object in the right
> side of the debugger seems to be wrong/empty (see attached
> screenshot); is that a problem of context? Or scope?
>

In the image I see Firebug stopped on a break point in window.sub()
and the 'this' value is the window. So it looks correct to me.
jjb
...

Olivier Cornu

unread,
Aug 19, 2009, 11:04:55 AM8/19/09
to fir...@googlegroups.com

But it's empty (notice "this" has been developed).
There usually is more stuff in there, for example when i debug a JS
script embedded in this same page.
Also, i suppose "this" should be the Sandbox in order to see things as
the debugged script does.

--
Olivier

johnjbarton

unread,
Aug 19, 2009, 11:16:04 AM8/19/09
to Firebug


On Aug 19, 8:04 am, Olivier Cornu <o.co...@gmail.com> wrote:
I guess these two go together: the display is incorrect because the
underlying data is not correct.

I don't know whether or not the sandbox should be "this", since the
whole sandbox model makes not sense to me. I never could figure out
what it did which is why we took it out of Firebug.

jjb

Olivier Cornu

unread,
Aug 19, 2009, 1:05:32 PM8/19/09
to fir...@googlegroups.com
On Wed, Aug 19, 2009 at 17:16, johnjbarton<johnj...@johnjbarton.com> wrote:
> On Aug 19, 8:04 am, Olivier Cornu <o.co...@gmail.com> wrote:
>> On Wed, Aug 19, 2009 at 16:58, johnjbarton<johnjbar...@johnjbarton.com> wrote:
>> > On Aug 19, 6:12 am, Olivier Cornu <o.co...@gmail.com> wrote:
>> >> I still have a few issues, though, that i'd like to fix before working
>> >> on the _complex_ case. For example, the "this" object in the right
>> >> side of the debugger seems to be wrong/empty (see attached
>> >> screenshot); is that a problem of context? Or scope?
>>
>> > In the image I see Firebug stopped on a break point in window.sub()
>> > and the 'this' value is the window. So it looks correct to me.
>>
>> But it's empty (notice "this" has been developed).
>> There usually is more stuff in there, for example when i debug a JS
>> script embedded in this same page.
>> Also, i suppose "this" should be the Sandbox in order to see things as
>> the debugged script does.
>
> I guess these two go together: the display is incorrect because the
> underlying data is not correct.

Probably.
I have troubles finding where in the code is "this" set. Would you be
so kind as to give me a clue?

> I don't know whether or not the sandbox should be "this", since the
> whole sandbox model makes not sense to me. I never could figure out
> what it did which is why we took it out of Firebug.

I'm no sandbox expert, but i understand it allows evaling code with
limited privileges.
A GM script sandbox uses the underlying window, wrapped into a XPCNW,
as its prototype. It seems there's more value in showing this rather
than the target window.


--
Olivier

Olivier Cornu

unread,
Aug 19, 2009, 1:23:14 PM8/19/09
to fir...@googlegroups.com
On Wed, Aug 19, 2009 at 19:05, Olivier Cornu<o.c...@gmail.com> wrote:
>>> > In the image I see Firebug stopped on a break point in window.sub()
>>> > and the 'this' value is the window. So it looks correct to me.
>>>
>>> But it's empty (notice "this" has been developed).
>>> There usually is more stuff in there, for example when i debug a JS
>>> script embedded in this same page.
>>> Also, i suppose "this" should be the Sandbox in order to see things as
>>> the debugged script does.
>>
>> I guess these two go together: the display is incorrect because the
>> underlying data is not correct.
>
> Probably.
> I have troubles finding where in the code is "this" set. Would you be
> so kind as to give me a clue?

Nevermind. Think i found it.

--
Olivier

Olivier Cornu

unread,
Aug 19, 2009, 4:16:03 PM8/19/09
to fir...@googlegroups.com
>>> Also, i suppose "this" should be the Sandbox in order to see things as
>>> the debugged script does.
>>
>> I don't know whether or not the sandbox should be "this", since the
>> whole sandbox model makes not sense to me. I never could figure out
>> what it did which is why we took it out of Firebug.

As i've found out, "this" refers to the script scope. It usually is a
Window but in case of a sandboxed script it's a Sandbox. It's fine
like that.
For the sake of completion: the empty "this" issue was because the
Sandbox object has no hasOwnProperty(), __lookupGetter___() and
__lookupSetter__() methods -- dom.js needs them to correctly print the
object hierarchy. If i put dummy implementations of these methods
everything works fine. :-)


Also, very interestingly: "As of Firefox 3.5/Gecko 1.9.1, it's
possible to optionally specify the JS version, filename, and line
number of the code being evaluated" [1].
This means it seems possible for the Firebug-1.5 to support sandboxed
scripts debugging (when they provide such information) without too
many changes: they pretty much look like other top-level scripts. The
only thing needed is a way for getFrameScopeWindowAncestor() to
discover which window the script should be attached to (if any).
The most generic test i've found (also working with GM) is the
following: if the sandbox prototype is a Window (or a XPCNW of a
Window) return it, otherwise the sandboxed script is ignored. It
probably makes sense to debug sandboxed scripts which are as tied to a
Window as that, although it's not a perfect test to filter relevant
sandboxed scripts...

--
Olivier


[1] https://developer.mozilla.org/en/Components.utils.evalInSandbox

johnjbarton

unread,
Aug 20, 2009, 12:32:32 AM8/20/09
to Firebug


On Aug 19, 1:16 pm, Olivier Cornu <o.co...@gmail.com> wrote:
> >>> Also, i suppose "this" should be the Sandbox in order to see things as
> >>> the debugged script does.
>
> >> I don't know whether or not the sandbox should be "this", since the
> >> whole sandbox model makes not sense to me. I never could figure out
> >> what it did which is why we took it out of Firebug.
>
> As i've found out, "this" refers to the script scope. It usually is a
> Window but in case of a sandboxed script it's a Sandbox. It's fine
> like that.
> For the sake of completion: the empty "this" issue was because the
> Sandbox object has no hasOwnProperty(), __lookupGetter___() and
> __lookupSetter__() methods -- dom.js needs them to correctly print the
> object hierarchy. If i put dummy implementations of these methods
> everything works fine.  :-)

Ok, more evidence that the Sandbox is half-baked ;-)

>
> Also, very interestingly: "As of Firefox 3.5/Gecko 1.9.1, it's
> possible to optionally specify the JS version, filename, and line
> number of the code being evaluated" [1].
> This means it seems possible for the Firebug-1.5 to support sandboxed
> scripts debugging (when they provide such information) without too
> many changes: they pretty much look like other top-level scripts. The
> only thing needed is a way for getFrameScopeWindowAncestor() to
> discover which window the script should be attached to (if any).
> The most generic test i've found (also working with GM) is the
> following: if the sandbox prototype is a Window (or a XPCNW of a
> Window) return it, otherwise the sandboxed script is ignored. It
> probably makes sense to debug sandboxed scripts which are as tied to a
> Window as that, although it's not a perfect test to filter relevant
> sandboxed scripts...

But that assumes a specific model for how the sandbox is used. On the
other hand, as far as I know GM is the only user of the sandbox, so
why not.


jjb

Olivier Cornu

unread,
Aug 20, 2009, 7:59:36 AM8/20/09
to fir...@googlegroups.com
On Thu, Aug 20, 2009 at 06:32, johnjbarton<johnj...@johnjbarton.com> wrote:
> On Aug 19, 1:16 pm, Olivier Cornu <o.co...@gmail.com> wrote:
>>
>> For the sake of completion: the empty "this" issue was because the
>> Sandbox object has no hasOwnProperty(), __lookupGetter___() and
>> __lookupSetter__() methods -- dom.js needs them to correctly print the
>> object hierarchy. If i put dummy implementations of these methods
>> everything works fine.  :-)
>
> Ok, more evidence that the Sandbox is half-baked ;-)

I kind of remember i read somewhere there was a point it, though...
Whatever: it works. :-)


>> Also, very interestingly: "As of Firefox 3.5/Gecko 1.9.1, it's
>> possible to optionally specify the JS version, filename, and line
>> number of the code being evaluated" [1].
>> This means it seems possible for the Firebug-1.5 to support sandboxed
>> scripts debugging (when they provide such information) without too
>> many changes: they pretty much look like other top-level scripts. The
>> only thing needed is a way for getFrameScopeWindowAncestor() to
>> discover which window the script should be attached to (if any).

I can confirm patching getFrameScopeWindowAncestor() is enough to
correctly debug GM scripts: no need to mess further with Firebug core
code (no need for a onSandboxScriptCreated() handler nor a new
SandboxSourceFile object). Sandboxed scripts are successfully treated
like other top-level scripts.

>> The most generic test i've found (also working with GM) is the


>> following: if the sandbox prototype is a Window (or a XPCNW of a
>> Window) return it, otherwise the sandboxed script is ignored. It
>> probably makes sense to debug sandboxed scripts which are as tied to a
>> Window as that, although it's not a perfect test to filter relevant
>> sandboxed scripts...
>
> But that assumes a specific model for how the sandbox is used. On the
> other hand, as far as I know GM is the only user of the sandbox, so
> why not.

Yes, it's not generic enough to cover every Window-mangling sandboxed
script possible. In fact, it's probably impossible to detect all
Window-mangling sandboxed scripts without "prior knowledge": somehow,
FB and tiers chrome code will have to share common assumptions about
where in the sandbox is the Window reference. In which case i suppose
we have to rely on "obvious" locations if we want to keep it simple:
the sandbox prototype, a sandbox property called "window"...
An alternative would be for FB to offer an API tiers code can use to
register their own getWindowFromSandbox() handler.

Back to debugging GM in particular, the new evalInSandbox() signature
is a blessing, even more so in case of concatenated scripts (the
so-called complex case -- GM @require tag). GM used to evalInSandbox()
a single string which was the concatenation of all needed source
files. If, instead, GM does evalInSandbox() each one of them in turn,
passing the proper filename/line number of the code being evaled,
everything works perfectly: all files appear in the debugger tab and
you can set breakpoints, etc, in anyone of them.
In other words, our original goal is reached with a very simple FB
core patch (attached)! :-)


--
Olivier

sandbox-debug.patch

johnjbarton

unread,
Aug 20, 2009, 2:08:12 PM8/20/09
to Firebug


On Aug 20, 4:59 am, Olivier Cornu <o.co...@gmail.com> wrote:
...
> In other words, our original goal is reached with a very simple FB
> core patch (attached)!  :-)

Thanks! R4051on branches/firebug1.5. In future please open a bug
report, the newsgroup info disappears from view rather quickly.
jjb

Olivier Cornu

unread,
Aug 21, 2009, 7:54:31 AM8/21/09
to fir...@googlegroups.com

Thank you for your help and support, John. :-)
Will do. By the way, there is a 2-years old bug report about this
topic (although it's tagged "chromebug") [1].

--
Olivier


[1] http://code.google.com/p/fbug/issues/detail?id=83

Olivier Cornu

unread,
Aug 30, 2009, 9:32:55 AM8/30/09
to fir...@googlegroups.com
> On Thu, Aug 20, 2009 at 20:08, johnjbarton<johnj...@johnjbarton.com> wrote:
>>
>> Thanks! R4051on branches/firebug1.5. In future please open a bug
>> report, the newsgroup info disappears from view rather quickly.

Follow-up and updates on this topic on this bug ticket:
http://code.google.com/p/fbug/issues/detail?id=83

--
Olivier

Reply all
Reply to author
Forward
0 new messages