Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

PHP: Added support for exception breakpoints. #6366

Merged
merged 1 commit into from
Aug 31, 2023

Conversation

troizet
Copy link
Collaborator

@troizet troizet commented Aug 21, 2023

What has been done in this PR:
1) Added support for exception breakpoints. (Closes #5434)

Debugging examples:

  • without using exception breakpoint
simplescreenrecorder-2023-08-21_21.26.24.mp4
  • breakpoint on warning
simplescreenrecorder-2023-08-21_21.27.00.mp4
  • breakpoint on MyException class
simplescreenrecorder-2023-08-21_21.28.44.mp4

The code used in the example:

<?php

class MyException extends Exception
{}

function throwException()
{
    throw new MyException();
}

echo "Test exception breakpoint";


echo "Line breakpoint";

$foo = $bar['nope'];

try {
    throwException();
} catch (Exception $e) {}

echo "End test exception breakpoint";

2) Breakpoint_set and breakpoint_remove commands are used instead of breakpoint_update to change breakpoint state during debugging.

In the current implementation, enabling/disabling a breakpoint during debugging is done by setting the state attribute with the breakpoint_update command.
But for exception breakpoint the state attribute has no effect. I checked on versions of xdebug: v3.1.6, v3.2.0, v3.2.1.
I looked at how this functionality is implemented in PhpStorm and VSCode using the xdebug log file.
There breakpoint enable/disable is implemented via breakpoint_set/breakpoint_remove commands.

--- a/php/php.dbgp/src/org/netbeans/modules/php/dbgp/breakpoints/BreakpointRuntimeSetter.java
+++ b/php/php.dbgp/src/org/netbeans/modules/php/dbgp/breakpoints/BreakpointRuntimeSetter.java
@@ -66,7 +66,12 @@ public void propertyChange(PropertyChangeEvent event) {
             return;
         }
         Object source = event.getSource();
-        performCommand((Breakpoint) source, Lazy.UPDATE_COMMAND);
+
+        if (((Breakpoint)source).isEnabled()) {
+            performCommand((Breakpoint) source, Lazy.SET_COMMAND);
+        } else {
+            performCommand((Breakpoint) source, Lazy.REMOVE_COMMAND);
+        }
     }

For the same reason, I removed the breakpoint_set command for a disabled breakpoint when debugging starts.

--- a/php/php.dbgp/src/org/netbeans/modules/php/dbgp/packets/InitMessage.java
+++ b/php/php.dbgp/src/org/netbeans/modules/php/dbgp/packets/InitMessage.java
@@ -122,7 +122,11 @@ private void setBreakpoints(DebugSession session) {
         SessionId id = session.getSessionId();
         Breakpoint[] breakpoints = DebuggerManager.getDebuggerManager().getBreakpoints();
         for (Breakpoint breakpoint : breakpoints) {
-            if (!(breakpoint instanceof AbstractBreakpoint)) {
+            if (!(breakpoint instanceof AbstractBreakpoint) ) {
+                continue;
+            }
+            //do not set a breakpoint at debug start if it is not enabled
+            if (!breakpoint.isEnabled()) {
                 continue;
             }
             AbstractBreakpoint brkpnt = (AbstractBreakpoint) breakpoint;

3) Fixed a bug where the previous breakpoint was displayed as the current breakpoint in the breakpoint list if the current breakpoint was not found.

--- a/php/php.dbgp/src/org/netbeans/modules/php/dbgp/breakpoints/BreakpointModel.java
+++ b/php/php.dbgp/src/org/netbeans/modules/php/dbgp/breakpoints/BreakpointModel.java

@@ -119,15 +126,25 @@ public String getShortDescription(Object node) throws UnknownTypeException {
 
     public void setCurrentStack(Stack stack, DebugSession session) {
         if (stack == null) {
-            synchronized (myCurrentBreakpoints) {
-                AbstractBreakpoint breakpoint = myCurrentBreakpoints.remove(session);
-                fireChangeEvent(new ModelEvent.NodeChanged(this, breakpoint));
-            }
+            removeCurrentBreakpoint(session);
             return;
         }
         String currentCommand = stack.getCurrentCommandName();
         if (!foundLineBreakpoint(stack.getFileName().replace("file:///", "file:/"), stack.getLine() - 1, session)) { //NOI18N
-            foundFunctionBreakpoint(currentCommand, session);
+            if (!foundFunctionBreakpoint(currentCommand, session)) {
+                /**
+                 * Clear myCurrentBreakpoints because if the current breakpoints is not found,
+                 * the previous breakpoint will still be shown as current
+                 */
+                removeCurrentBreakpoint(session);
+            }
+        }
+    }
+
+    private void removeCurrentBreakpoint(DebugSession session) {
+        synchronized (myCurrentBreakpoints) {
+            AbstractBreakpoint breakpoint = myCurrentBreakpoints.remove(session);
+            fireChangeEvent(new ModelEvent.NodeChanged(this, breakpoint));
         }
     }

@troizet troizet changed the title Added support for exception breakpoints. PHP: Added support for exception breakpoints. Aug 21, 2023
@junichi11 junichi11 added the PHP [ci] enable extra PHP tests (php/php.editor) label Aug 21, 2023
@junichi11 junichi11 added this to the NB20 milestone Aug 21, 2023
@junichi11 junichi11 requested review from tmysik and junichi11 August 22, 2023 04:58
Comment on lines 47 to 48
epClassName.getAccessibleContext().setAccessibleName("pane");
epClassName.getAccessibleContext().setAccessibleDescription("pane");
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

// NOI18N

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Well, these are not friendly accessible descriptions, right...?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please, improve A11Y description of these elements (imagine, that you cannot see them - how would you describe them?), thanks.

@junichi11
Copy link
Member

@troizet Thank you for your work!
Please add the issue number to the commit message.
Please write an example code.

@tmysik
Copy link
Member

tmysik commented Aug 23, 2023

@troizet

Wow, very nice PR, thanks a lot for it! 👍

@troizet troizet force-pushed the exception_breakpoint branch from 31466f6 to 700157d Compare August 27, 2023 07:16
@troizet
Copy link
Collaborator Author

troizet commented Aug 27, 2023

@junichi11, @tmysik. Has corrected the shortcomings you pointed out. Thank you very much for the review!

@junichi11
Copy link
Member

Please add image files to the licenseinfo.xml. Thanks!

@tmysik
Copy link
Member

tmysik commented Aug 29, 2023

@troizet Please, resolve the remaining comments so we can merge this PR 👍 Thanks a lot for your work!

@troizet troizet force-pushed the exception_breakpoint branch from 700157d to f772ca2 Compare August 29, 2023 16:08
Copy link
Member

@junichi11 junichi11 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you for your work!

@tmysik tmysik self-requested a review August 30, 2023 08:54
Copy link
Member

@tmysik tmysik left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks! 👍

Breakpoint_set and breakpoint_remove commands are used instead of breakpoint_update to change breakpoint state during debugging.
Fixed a bug where the previous breakpoint was displayed as the current breakpoint if the current breakpoint was not found.
@troizet troizet force-pushed the exception_breakpoint branch from f772ca2 to 5f1c9da Compare August 30, 2023 12:07
@junichi11
Copy link
Member

Merging.

@junichi11 junichi11 merged commit d507933 into apache:master Aug 31, 2023
@ErikKrause
Copy link

Many thanks for this useful addition! However, how would I see the cause of (f.e) a warning, once the breakpoint is hit?

@troizet
Copy link
Collaborator Author

troizet commented Dec 15, 2023

how would I see the cause of (f.e) a warning, once the breakpoint is hit?

Unfortunately, there is no such opportunity at the moment.

@ErikKrause
Copy link

That's a pity. Is this planned?

@troizet
Copy link
Collaborator Author

troizet commented Dec 15, 2023

Is this planned?

Yes, that's in the plans.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
PHP [ci] enable extra PHP tests (php/php.editor)
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Please add "break on error" for PHP
4 participants