Last Comment Bug 757282 - Pause when an exception is hit
: Pause when an exception is hit
Status: RESOLVED FIXED
[fixed-in-fx-team]
:
Product: Firefox
Classification: Client Software
Component: Developer Tools: Debugger (show other bugs)
: 15 Branch
: All All
: P2 normal (vote)
: Firefox 15
Assigned To: Panos Astithas [:past]
:
Mentors:
Depends on: 755346
Blocks: 760564
  Show dependency treegraph
 
Reported: 2012-05-21 17:08 PDT by Thaddee Tyl [:espadrine]
Modified: 2012-06-03 13:49 PDT (History)
6 users (show)
See Also:
Crash Signature:
(edit)
QA Whiteboard:
Iteration: ---
Points: ---
Has Regression Range: ---
Has STR: ---


Attachments
WIP (7.62 KB, patch)
2012-05-24 12:48 PDT, Panos Astithas [:past]
no flags Details | Diff | Review
Patch v2 (17.51 KB, patch)
2012-05-25 09:39 PDT, Panos Astithas [:past]
rcampbell: feedback+
Details | Diff | Review
Patch v3 (27.92 KB, patch)
2012-05-30 12:09 PDT, Panos Astithas [:past]
rcampbell: review+
Details | Diff | Review
Patch v4 (27.58 KB, patch)
2012-06-01 09:21 PDT, Panos Astithas [:past]
rcampbell: review+
Details | Diff | Review
Patch v5 (27.75 KB, patch)
2012-06-02 08:57 PDT, Panos Astithas [:past]
no flags Details | Diff | Review
Patch v6 (28.06 KB, patch)
2012-06-02 14:20 PDT, Panos Astithas [:past]
no flags Details | Diff | Review
Patch v7 (28.47 KB, patch)
2012-06-03 03:11 PDT, Panos Astithas [:past]
rcampbell: review+
Details | Diff | Review
v6-v7 diff (2.36 KB, patch)
2012-06-03 03:12 PDT, Panos Astithas [:past]
vporof: feedback+
Details | Diff | Review

Description Thaddee Tyl [:espadrine] 2012-05-21 17:08:22 PDT
The debugger currently does not have a feature to break (pause JS execution)
as soon as an exception is thrown.

That feature is available on all other major browser.
It is very useful to get the whole context of an uncaught exception.
Comment 1 Rob Campbell [:rc] (:robcee) 2012-05-23 07:26:29 PDT
spidermonkey API requirement? Possibly be able to either install an onError or Debugger object in the browser to invoke the debugger.

Need to investigate, may not be able to get for version 1.
Comment 2 Panos Astithas [:past] 2012-05-24 04:51:09 PDT
There is Debugger.onExceptionUnwind which does what we need here. We may also use Debugger.onError for other errors, but I'm not sure if it's ready yet.
Comment 3 Panos Astithas [:past] 2012-05-24 12:48:11 PDT
Created attachment 626919 [details] [diff] [review]
WIP

Made some progress in both frontend and backend.
Comment 4 Panos Astithas [:past] 2012-05-25 06:40:00 PDT
I'll base this on top of the scope refactoring patch, in order to avoid rebasing.
Comment 5 Panos Astithas [:past] 2012-05-25 09:39:49 PDT
Created attachment 627257 [details] [diff] [review]
Patch v2

This is working, but has no tests and I need some feedback on UI and protocol additions.

I've used a checkbox toolbar button with the same configuration icon we use in the page inspector. My plan was to make it work the same as the inspector, a menu with various options. But I don't know if it would be better to keep it as a separate button as long as we only have one option. I also recall that Paul spent quite some time trying to get l10n and a11y right with that. In case we keep it as a button and not a menu, we will need shorlander to provide us with a new icon (webkit has a cross between a stop sign and a pause button, which seems nice).

Jim, I added another protocol operation to let the client configure the server actor:

{
  "to": "conn0.context710",
  "type": "configure",
  "pauseOnExceptions": true
}
{
  "from": "conn0.context710"
}

I imagine us adding more options in that packet in the future, although I can't think of one right now.
Comment 6 Rob Campbell [:rc] (:robcee) 2012-05-29 07:53:21 PDT
Comment on attachment 627257 [details] [diff] [review]
Patch v2

I think this approach looks ok (without having actually building the patch).

One question: The Debugger UI has to be "up" in order for this option to take effect, right? If you set that thing, the debugger won't popup on any page with a JS Exception? That's probably the right thing to do as it could get pretty annoying hitting exceptions on pages you didn't mean to debug, but it does require a bit of forethought.

As for the "gear" icon vs. a checkbox, I think a single checkbox is enough. When we get more options, we can add the gear menu.
Comment 7 Panos Astithas [:past] 2012-05-29 08:20:20 PDT
(In reply to Rob Campbell [:rc] (:robcee) from comment #6)
> Comment on attachment 627257 [details] [diff] [review]
> Patch v2
> 
> I think this approach looks ok (without having actually building the patch).
> 
> One question: The Debugger UI has to be "up" in order for this option to
> take effect, right? If you set that thing, the debugger won't popup on any
> page with a JS Exception? That's probably the right thing to do as it could
> get pretty annoying hitting exceptions on pages you didn't mean to debug,
> but it does require a bit of forethought.

Right, the Debugger server has to be running first.

> As for the "gear" icon vs. a checkbox, I think a single checkbox is enough.
> When we get more options, we can add the gear menu.

OK, but where do I put the checkbox? Right in the toolbar?
Comment 8 Rob Campbell [:rc] (:robcee) 2012-05-29 11:26:03 PDT
I would say yes, for now.
Comment 9 Jim Blandy :jimb 2012-05-29 12:26:30 PDT
I think adding a "pauseOnException":true property to the "type":"resume" packet is a better way to go here.

This approach avoids adding more long-lived server-side state. Certainly, we need to establish an onExceptionUnwind handler until the next pause, but that's the same kind of handling required for the 'next' and 'step' operations, so the onExceptionUnwind handler addition/removal should just slot right in to that existing code. And doesn't require any additional packets to set/clear/query the state.

Having the client set a "pauseOnException" property on the resume packet keeps the modal state in the client, where the UI is, so that seems preferable.
Comment 10 Panos Astithas [:past] 2012-05-30 12:09:18 PDT
Created attachment 628418 [details] [diff] [review]
Patch v3

Changed the protocol to use the 'resume' packet for transferring the pauseOnExceptions flag and used a checkbox for the UI. Added lots of tests.
Comment 11 Panos Astithas [:past] 2012-05-30 12:13:12 PDT
Try run:
https://tbpl.mozilla.org/?tree=Try&rev=87ca368fc263
Comment 12 Rob Campbell [:rc] (:robcee) 2012-05-30 14:59:28 PDT
Comment on attachment 628418 [details] [diff] [review]
Patch v3

   /**
+   * Inform the debugger client whether the debuggee should be paused whenever
+   * an exception is thrown.
+   */
+  updatePauseOnExceptions: function SF_updatePauseOnExceptions(aFlag) {

should have a @param entry. (I know...)

+        // Special additions to the innermost scope.
+        if (env == frame.environment) {
+          // Add any thrown exception.
+          if (aDepth == 0 && this.exception) {
+            let excVar = scope.addVar("<exception>");
+            if (typeof this.exception == "object") {

this is getting pretty nesty. OK.

Can this.exception be of any type other than "object"? Presumably since you added an "else".

tested this out locally and it works well, at least for my fairly limited test code.
Comment 13 Rob Campbell [:rc] (:robcee) 2012-05-30 14:59:51 PDT
one other thing: we're not saving the state of that checkbox. We might want to do that in a follow-up.
Comment 14 Panos Astithas [:past] 2012-06-01 09:21:52 PDT
Created attachment 629217 [details] [diff] [review]
Patch v4

(In reply to Rob Campbell [:rc] (:robcee) from comment #12)
>    /**
> +   * Inform the debugger client whether the debuggee should be paused
> whenever
> +   * an exception is thrown.
> +   */
> +  updatePauseOnExceptions: function SF_updatePauseOnExceptions(aFlag) {
> 
> should have a @param entry. (I know...)

Added.

> +        // Special additions to the innermost scope.
> +        if (env == frame.environment) {
> +          // Add any thrown exception.
> +          if (aDepth == 0 && this.exception) {
> +            let excVar = scope.addVar("<exception>");
> +            if (typeof this.exception == "object") {
> 
> this is getting pretty nesty. OK.
> 
> Can this.exception be of any type other than "object"? Presumably since you
> added an "else".

Yes, this is the case for 'throw "error";' or 'throw 42;'.

(In reply to Rob Campbell [:rc] (:robcee) from comment #13)
> one other thing: we're not saving the state of that checkbox. We might want
> to do that in a follow-up.

Indeed, filed bug 760564.
Comment 15 Panos Astithas [:past] 2012-06-01 09:25:42 PDT
Try run: https://tbpl.mozilla.org/?tree=Try&rev=10460200df94
Comment 16 Rob Campbell [:rc] (:robcee) 2012-06-01 11:27:27 PDT
Comment on attachment 629217 [details] [diff] [review]
Patch v4

+  pauseOnExceptions: function TC_pauseOnExceptions(aFlag, aOnResponse) {
+    this._pauseOnExceptions = aFlag;
+    // If the debuggee is paused, the value of the flag will be communicated in
+    // the next resumption. Otherwise we have to force a pause in order to send
+    // the flag.

good, as per jimb's request in irc, I think.
Comment 17 Dave Camp (:dcamp) 2012-06-01 16:34:16 PDT
Try run failed with:
TEST-UNEXPECTED-FAIL | chrome://mochitests/content/browser/browser/devtools/debugger/test/browser_dbg_pause-exceptions.js | Should have the right property name for the exception. - Got this, expected <exception>
TEST-UNEXPECTED-FAIL | chrome://mochitests/content/browser/browser/devtools/debugger/test/browser_dbg_pause-exceptions.js | Should have the right property value for the exception. - Got [object HTMLButtonElement], expected [object Error]
Comment 18 Panos Astithas [:past] 2012-06-02 08:57:53 PDT
Created attachment 629481 [details] [diff] [review]
Patch v5

I think this should fix the test failures. Try run:
https://tbpl.mozilla.org/?tree=Try&rev=b83d9cd7db3e
Comment 19 Panos Astithas [:past] 2012-06-02 14:20:37 PDT
Created attachment 629520 [details] [diff] [review]
Patch v6

The previous change wasn't enough, but I'm confident about this one:
https://tbpl.mozilla.org/?tree=Try&rev=ffbdf53b8eee

The patches I've been sending to try have been showing a decreasing failure rate in an increasing number of runs:
50%
21%
14%

Maybe this one will get us to 0%.
Comment 20 Panos Astithas [:past] 2012-06-03 03:11:20 PDT
Created attachment 629584 [details] [diff] [review]
Patch v7

OK, fine, the previous version didn't make a dent (16% failure rate, only in debug builds), but this one seems to have fixed it locally.

The problem was that I was clearing the exception in SF__afterFramesCleared which is triggered by a timeout, after the 'framescleared' event is received. In the test, we get in some cases SF__afterFramesCleared called from the previous resumption to happen after the 'framesadded' event for the next pause happened. Instead of just tweaking the test to accommodate that case, I moved the clearing of the stored exception to happen in the 'framescleared' handler, not the timeout event handler it triggers.

Try run: https://tbpl.mozilla.org/?tree=Try&rev=2f710b7ac280
Comment 21 Panos Astithas [:past] 2012-06-03 03:12:42 PDT
Created attachment 629585 [details] [diff] [review]
v6-v7 diff

This is the actual change for easier review. Victor can you verify?
Comment 22 Victor Porof [:vporof][:vp] 2012-06-03 03:29:34 PDT
Comment on attachment 629585 [details] [diff] [review]
v6-v7 diff

Review of attachment 629585 [details] [diff] [review]:
-----------------------------------------------------------------

Lol. Ok!
Comment 23 Rob Campbell [:rc] (:robcee) 2012-06-03 06:13:28 PDT
Comment on attachment 629584 [details] [diff] [review]
Patch v7

sequencing is hard.
Comment 24 Panos Astithas [:past] 2012-06-03 06:45:01 PDT
https://hg.mozilla.org/integration/fx-team/rev/e60ac3f6119d
Comment 25 Rob Campbell [:rc] (:robcee) 2012-06-03 13:49:02 PDT
https://hg.mozilla.org/mozilla-central/rev/e60ac3f6119d

Note You need to log in before you can comment on or make changes to this bug.