52

I didn't find a way to debug Greasemonkey scripts with the Firebug extension.

Does anyone know how to do this ?

Thanks.

Brock Adams
  • 90,639
  • 22
  • 233
  • 295
WolveFred
  • 1,623
  • 3
  • 14
  • 15

10 Answers10

26

Updatier: The Mene+Shuman fix now is busted with Firefox 30 and Firebug 2. Firefox 31 may provide workarounds (will investigate). In the meantime, use the "General workaround strategies" listed below.


Update: This answer is now obsolete.

If you open about:config and
set extensions.firebug.filterSystemURLs to false
then you can use Firebug to debug the Greasemonkey script just like any other.

This works irregardless of the @grant mode.

See Mene's answer -- with an assist from Shuman.



Old answer:

Because Greasemonkey operates in a sandbox, Firebug cannot see it. There is no easy way around this.

General workaround strategies:

  1. Test all parts of a GM script that don't use GM_ functions, in Firebug's JavaScript console first. Minimize use of GM_ functions and don't use GM_log() at all.

  2. All of Firebug's console functions work great from within a GM script.

Community
  • 1
  • 1
Brock Adams
  • 90,639
  • 22
  • 233
  • 295
  • 1
    Greasemonkey can now be debugged like any js. See my answer for more details. – Mene Mar 25 '14 at 13:26
  • the answer is obsolete now – Mukesh Agarwal Jul 24 '19 at 13:30
  • @MukeshAgarwal, Yes Firebug is obsolete for most users, but believe it or not some people still use old versions of Firefox or equivalents like *Pale Moon*. Anyway, see [meta] for how we handle "obsolete" posts. (They're generally left up for people using antique tools, and for historical purposes.) – Brock Adams Jul 24 '19 at 13:52
  • @GeroldBroser, I haven't yet worked around the changes in Firefox (and have no personal need). Until someone answers your new question, (A) use the "Old answer" strategies here and/or (B) Load the script in Tampermonkey on Chrome and use Chrome's debugging to get through your script's issues AMAP. – Brock Adams Aug 01 '19 at 14:15
  • Thx, however, for your reply, but [AMAP](https://en.wikipedia.org/wiki/Advanced_Modular_Armor_Protection)? – Gerold Broser Aug 01 '19 at 15:46
  • 1
    @GeroldBroser, Sure. But much more commonly: "As much as possible". – Brock Adams Aug 01 '19 at 15:56
9

Note: this answer refers to old versions of Firefox. Firebug is no longer available, but lives on in the Developer Edition of Firefox.


Current Firefox and Firebug can now debug current Greasemonkey scripts just like any other javascript. Just find your *.user.js script in the dropdown menu. The console also works.

This works at least on Firefox 28.0 and Firebug 1.12.7; I haven't tried earlier versions.

Screenshot of limited-case debugging


Note: In order to get it to work, you probably have to set extensions.firebug.filterSystemURLs to false. See "Profiling Greasemonkey scripts" in the Firebug, bug tracker. (Thanks to Shuman)

0xC0000022L
  • 20,597
  • 9
  • 86
  • 152
Mene
  • 3,739
  • 21
  • 40
  • Are you sure? You can *see* the GM scripts but breakpoints, watches, etc. do not work -- especially on scripts that aren't in `@grant none` mode and/or use event listeners. If you have a recipe that works for actual debugging, post details. – Brock Adams Mar 25 '14 at 22:40
  • I haven't done anything special. I created a new script and I debugged it. Breakpoints work fine (as you can see in the screenshot) and in another script I also used events: addEventListener('click',...), dispatchEvent, fireEvent, as well as a MutationObserver. All in a GM that has `@grant none`. Everything worked as expected. – Mene Mar 25 '14 at 23:44
  • I just rechecked and I wasn't able to get it to work on any but the simplest of scripts. Breakpoints and watches did not work on any of the three scripts I have running on this page, for example. ([Here's one of the scripts, you can test for yourself](http://stackapps.com/q/3082/7653).) – Brock Adams Mar 26 '14 at 00:27
  • I have tested it on Firefox 28 and Firebug 1.12.8 and it just **works** – Ferran Salguero May 06 '14 at 13:51
  • 1
    it worked on my firefox 29 and firebug 1.12.8 yesterday, but magically it doesn't work today ( just doensn't see the userscript in the dropdown menu anymore no matter what i try) ... orz – Shuman Jun 14 '14 at 04:44
  • 2
    @BrockAdams holycr*p finally got it working by setting `extensions.firebug.filterSystemURLs` to `false` in `about:config`, see [this](https://code.google.com/p/fbug/issues/detail?id=83) – Shuman Jun 14 '14 at 04:56
  • 1
    @Shuman, Excellent and verified; thanks! Edited this info into the two applicable answers. – Brock Adams Jun 14 '14 at 06:16
  • 7
    just now my firefox auto updated to 30.0 and firebug to 2.0, and i can't debug GM again. before i figured out why, i have to downgrade firebug to 1.12.8 then it works. don't know how to make it work in firebug [2.0](http://www.softwareishard.com/blog/firebug/firebug-2-support-for-dynamic-scripts/) right now – Shuman Jun 14 '14 at 16:12
8
var e = document.createElement("script");

e.src = 'http://www.xxxxxxxx.com/yyyyyyyy.js';
e.type="text/javascript";
document.getElementsByTagName("head")[0].appendChild(e);

you can add this to your xxx.user.js, and install it in greasemonkey.

Then, you can debug your js as you wish.

bigml
  • 97
  • 1
  • 1
7

None of the other solutions here worked for me, but Jan Odvarko's answer on how to debug Firefox extensions worked perfectly for GreaseMonkey scripts as well:

On Firefox 19 or later, it's possible to use the built-in JS debugger on the browser itself. Go to about:config and set the following two prefs:

devtools.chrome.enabled: true
devtools.debugger.remote-enabled: true

After you restart the browser, you can access the Browser Debugger through Tools > Web Developer > Browser Toolbox.

(note that you must accept the incoming connection)

See more at: https://developer.mozilla.org/en-US/docs/Mozilla/Debugging/Debugging_JavaScript#JavaScript_Debugger

Then just search for the name of your userscript and start debugging.

Gerold Broser
  • 14,080
  • 5
  • 48
  • 107
Hjulle
  • 2,471
  • 1
  • 22
  • 34
  • Since FF 57's WebExtensions and, hence, [Greasemonkey 4, user scripts are not stored as files in the profile folder but in a SQLite DB](https://stackoverflow.com/a/48851793/1744774) and I do not find them in the Browser Debugger's _Open file..._ box. – Gerold Broser Jul 31 '19 at 17:47
7

It can be done using native Firefox debugger as it was mentioned before. Below is the instruction for modern versions of Firefox.

Set the following preferences in about:config:

devtools.chrome.enabled: true
devtools.debugger.remote-enabled: true
devtools.debugger.prompt-connection: false

Open the global script debugger window via ToolsWeb DeveloperBrowser ToolboxDebugger (or Ctrl+Shift+Alt+I) .

Search for the name of your userscript and start debugging.

Annarfych
  • 537
  • 4
  • 10
  • What does "modern" mean? >= FF 57 (with WebExtensions), too? Since [Greasemonkey 4 user scripts are not stored as files in the profile folder but in a SQLite DB](https://stackoverflow.com/a/48851793/1744774) and I do not find them in the Browser Debugger's _Open file..._ box. – Gerold Broser Jul 31 '19 at 18:27
3

-- This answer is obsolete, please use @Brock Adams solution above --

Load your main script externally, instead of running it via GM. So you're just using GM to inject the script.

This is a bit of a hybrid between @bigml and @Yuval's solution and it uses jquery. It also works in frames.

// ==UserScript==
// @name          My GM script
// @include     The website I want this to run on
// @require http://ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js 
// ==/UserScript==
$(document).ready(function() {
            // fetch jquery dependent scripts using $.getScript()
});
sijpkes
  • 168
  • 10
  • 1
    Hmm, you are using Jquery to load Jquery from google's CDN.. Does it make sense? – Matej Apr 02 '13 at 23:53
  • 4
    No it doesn't, matejkranny. It's amazing it has taken 10 months for anyone to notice that one! I've amended it accordingly. – sijpkes Apr 08 '13 at 06:03
  • Have an upvote for the diligence in updating the answer in order to make it known that this no longer works. – 0xC0000022L May 04 '20 at 09:01
3

Note: ChromeBug no longer exists. The Developer Edition of Firefox is an alternative.


Chromebug can see sandboxed scripts, http://getfirebug.com/wiki/index.php/Chromebug_User_Guide, but I've not tried it on Greasemonkey.

0xC0000022L
  • 20,597
  • 9
  • 86
  • 152
johnjbarton
  • 1,857
  • 1
  • 13
  • 12
1

Note: this answer refers to old versions of Firefox. Firebug is no longer available, but lives on in the Developer Edition of Firefox.


I've tried ChromeBug, it doesn't seem to work.

With FireBug I have had the starting point of success by adding "debugger" to my GM code. This causes a breakpoint and I can inspect variables on the stack, but the right file is not shown so I can't step or anything.

I have had the best success with FirebugMonkey (https:// addons.mozilla.org/en-US/firefox/addon/13623/), which I just got working to do basic debugging of GreaseMonkey scripts thanks to some explanation in a recent comment on the extension page by f0rsvinn. Here are the instructions I just posted at http://groups.google.com/group/greasemonkey-users/browse_thread/thread/994cfa58c79d222:

It never occurred to me that the way it works is by creating its own sandbox around the script rather than using Greasemonkey's, you actually have to turn GM off. There are some GM aspect things that will not work though because the script really isn't in GreaseMonkey. As an example, GM_getValue returns undefined.

Still, it works for basic debugging - and is way better than nothing.

Usage steps are as follows:

  1. Install FireBug 1.5.4 (later versions do not seem to work)
  2. Install FireBugMonkey
  3. Use the Script Manager in FireBugMonkey to select the files you want to debug
  4. Disable GreaseMonkey (scripts will run inside FireBugMonkey, not
  5. GreaseMonkey)
  6. Enable FireBugMonkey
  7. Enable scripts in FireBug

The scripts you added in the ScriptManager should be visible in the FireBug scripts list.

0xC0000022L
  • 20,597
  • 9
  • 86
  • 152
studgeek
  • 14,272
  • 6
  • 84
  • 96
1

Similar to @bigml's suggestion, you can run it unprivileged if you setup a local webserver (apache) to serve the userscript file, then in your userscript add something along the lines:

if (typeof GM_addStyle == "undefined") {
    loadScript("http://localhost/path/to/script.user.js");
}
else {
    runScript();
}

function loadScript(url) {
     var script = document.createElement('script');
     script.type = 'text/javascript';
     script.src = url;
     document.getElementsByTagName('head')[0].appendChild(res);
}

function runScript() {
     // ... whatever your userscript does ...
}

Of course you wouldn't be running in a privileged context. But this way you can easily continuously debug the script as any other script.

Brock Adams
  • 90,639
  • 22
  • 233
  • 295
Yuval
  • 3,207
  • 32
  • 45
  • 1
    Good. You meant "bigml's suggestion" in fact ! Of course, this method implies we don't use the GM functions. – WolveFred Mar 10 '12 at 14:58
  • Great solution, there are loads of simple web servers out there, like Python's SimpleHTTPServer, or better, WEBrick in Ruby. – stellarpower Aug 17 '16 at 13:59
0

As the others have said, you can setup a simple HTTP server and serve it to your page using Greasemonkey like so:

function loadScript(url) {
    var script = document.createElement('script');
    script.type = 'text/javascript';
    script.src = url;
    document.getElementsByTagName('head')[0].appendChild(script);
}

WEBrick and Python -m SimpleHTTPServer are good for this. We can also expose the GM_... functions to the script by adding a custom event handler to the document within GreaseMonkey:

function gMHandler(e){
    GM_log(e.detail.message);
    e.detail.response = "Hi!"
}

document.addEventListener("gM", gMHandler, false);

and then in the served script, raising this event on an arbitrary DOM element will run the handler and modify the element's response parameter:

$(document).ready(function() {
    var event = new CustomEvent(
        "gM", 
        {
            detail: { message: "Hello World!" }
            bubbles: true,
            cancelable: true,
        }
    );

    document.getElementById("AnyElement").dispatchEvent(event);
    alert("Response was: " + event.detail.response);
});
stellarpower
  • 332
  • 3
  • 13