Skip to content

feat: disable JIT debugging by default#28

Merged
carlos-granados merged 4 commits into
php-debugger:mainfrom
carlos-granados:disable-jit-debugging-by-default
Apr 11, 2026
Merged

feat: disable JIT debugging by default#28
carlos-granados merged 4 commits into
php-debugger:mainfrom
carlos-granados:disable-jit-debugging-by-default

Conversation

@carlos-granados

@carlos-granados carlos-granados commented Mar 24, 2026

Copy link
Copy Markdown
Collaborator

This PR adds a new jit_debugging_enabled ini setting that allows you to disable some of the optimizations that we have added. When this is enabled you will be able to do JIT debugging even if you don't initially connect to any client by starting a connection using the xdebug_connect_to_client and xdebug_break functions or when an error or exception is raised. If you enable it then the performance gain is much smaller, instead of improving performance by 97% you will improve it by 60% (not bad in any case)

With this disabled I wanted to be able to disable even more operations so that we could save even more time but I found out that the only significant thing that we could add was not disabling the opcache optimizer, the other main source of overhead is the addition of the observer functions but this needs to be set up at the module initialization level, so we cannot actually disable it for each request depending on whether we connect or not

And the opcache optimizer is really only relevant for cgi/fpm processes, not cli processes, as opcache is not really useful for single use CLI commands and is usually disabled there, so I did not manage to really improve the current optimization by much

But what I was able to do is to get the vast majority of tests which had been marked as XFAIL to pass by setting this ini setting to enabled. There are still a couple which are still failing and where I need to take a deeper look. I also managed to get a few of the tests which had been skipped to pass by using this new setting or by changing some basic settings of the test setup

@carlos-granados carlos-granados added performance-check Add this label to run the performance CI workflow and removed performance-check Add this label to run the performance CI workflow labels Mar 24, 2026
@carlos-granados carlos-granados force-pushed the disable-jit-debugging-by-default branch from 1ed4f0a to d5e2d46 Compare March 24, 2026 20:10
@carlos-granados carlos-granados added performance-check Add this label to run the performance CI workflow and removed performance-check Add this label to run the performance CI workflow labels Mar 24, 2026
@carlos-granados carlos-granados force-pushed the disable-jit-debugging-by-default branch from d5e2d46 to 39ff765 Compare March 24, 2026 21:01
@carlos-granados carlos-granados marked this pull request as ready for review March 25, 2026 16:10
@pronskiy

Copy link
Copy Markdown
Member

@carlos-granados I wonder why benchmarks workflow didnt run on this one?

@carlos-granados carlos-granados added performance-check Add this label to run the performance CI workflow and removed performance-check Add this label to run the performance CI workflow labels Mar 28, 2026
@carlos-granados

Copy link
Copy Markdown
Collaborator Author

@pronskiy They had run but not for the latest version. They run when you tag the PR with the performance-check label but if the PR already had the label and you do a new push, you need to remove the label and add it again. This is the latest run which I just triggered:
https://github.com/php-debugger/php-debugger/actions/runs/23681266232

Looking at the results, there's something that I can't understand. The JIT version of the Symfony runs is faster than the non-JIT. That should not be the case because we are not setting observer_active to false and we are setting the ZEND_COMPILE_EXTENDED_STMT flag, so it should be much slower, which is what we are seeing for the bench and rector runs. I can't explain this, there must be something weird going on. Let me see if I can figure it out

@carlos-granados carlos-granados force-pushed the disable-jit-debugging-by-default branch from 9dd996c to 74b55f6 Compare March 28, 2026 09:02
@carlos-granados carlos-granados added performance-check Add this label to run the performance CI workflow and removed performance-check Add this label to run the performance CI workflow labels Mar 28, 2026
@carlos-granados carlos-granados force-pushed the disable-jit-debugging-by-default branch from 5ca5ce0 to c674431 Compare March 28, 2026 20:11
@carlos-granados carlos-granados added performance-check Add this label to run the performance CI workflow and removed performance-check Add this label to run the performance CI workflow labels Mar 28, 2026
@carlos-granados carlos-granados force-pushed the disable-jit-debugging-by-default branch from 229521f to 41cc9a2 Compare March 28, 2026 21:03
@carlos-granados carlos-granados added performance-check Add this label to run the performance CI workflow and removed performance-check Add this label to run the performance CI workflow labels Mar 28, 2026
@carlos-granados

Copy link
Copy Markdown
Collaborator Author

@pronskiy ok, I've finally understood what was going on. The issue is that for the cases that we were using to test performance, disabling the opcache optimizer actually improves performance as the code does not have to spend the time optimizing the opcache. In the end I think that opcache optimization is not relevant for our benchmark results, so I have disabled it everywhere and now we get coherent results. This is the latest benchmark run:

https://github.com/php-debugger/php-debugger/actions/runs/23696091215

Comment thread xdebug.c Outdated
Comment on lines 688 to 697
@@ -688,10 +697,6 @@ ZEND_DLEXPORT void xdebug_statement_call(zend_execute_data *frame)
xdebug_control_socket_dispatch();

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

xdebug_control_socket_dispatch(); would never be reached then, wouldn't it?

ctrl_socket dispatch should happen regardless as i understand

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

Yes, you are right, I had been testing some optimizations and moved this and forgot to move it back

Comment thread xdebug.c Outdated
xdebug_library_zend_shutdown();
}

ZEND_DLEXPORT void xdebug_init_oparray(zend_op_array *op_array)

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

This is unrelated cleanup, isn't it? Maybe move to a separate PR for clarity?

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

OK, will move to a separate PR

Comment thread src/debugger/debugger.c
RETURN_FALSE_IF_MODE_IS_NOT(XDEBUG_MODE_STEP_DEBUG);

if (!xdebug_is_debug_connection_active() && !XINI_DBG(jit_debugging_enabled)) {
RETURN_FALSE;

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Maybe add logging?

xdebug_log_ex(XLOG_CHAN_DEBUG, XLOG_INFO, "JIT-OFF",
        "xdebug_break() ignored: no active debug connection and "
        "xdebug.jit_debugging_enabled is not enabled");
php_error(E_NOTICE,
        "xdebug_break(): no active debug session and JIT debugging is disabled. "
        "Set xdebug.jit_debugging_enabled=1 to enable mid-request debugging");

or something along the lines

Comment thread src/debugger/debugger.c
RETURN_FALSE_IF_MODE_IS_NOT(XDEBUG_MODE_STEP_DEBUG);

if (!XINI_DBG(jit_debugging_enabled)) {
RETURN_FALSE;

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

same as above

@pronskiy

pronskiy commented Apr 2, 2026

Copy link
Copy Markdown
Member

"JIT" in PHP context exclusively means the JIT compiler. Calling this feature "JIT debugging" will confuse users: "does this control debugging the JIT? debugging with JIT enabled?". I was confused too.

How about something like "deferred_debugging" or "late_attach" or "on_demand_debugging" instead? The README section is well-written but the name itself creates ambiguity

@carlos-granados

Copy link
Copy Markdown
Collaborator Author

"JIT" in PHP context exclusively means the JIT compiler. Calling this feature "JIT debugging" will confuse users: "does this control debugging the JIT? debugging with JIT enabled?". I was confused too.

How about something like "deferred_debugging" or "late_attach" or "on_demand_debugging" instead? The README section is well-written but the name itself creates ambiguity

OK, let me think of something else 😄

@carlos-granados

Copy link
Copy Markdown
Collaborator Author

@pronskiy I decided to use on-demand, updated

@carlos-granados carlos-granados requested a review from pronskiy April 2, 2026 18:25
@carlos-granados carlos-granados force-pushed the disable-jit-debugging-by-default branch 2 times, most recently from b7bf398 to e32e6d7 Compare April 7, 2026 23:16
Comment thread xdebug.c Outdated
Comment thread xdebug.ini Outdated
Comment thread xdebug.ini
; .. note::
;
; This setting can additionally be configured through the
; ``XDEBUG_CONFIG``environment variable [1]. [1]

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Suggested change
; ``XDEBUG_CONFIG``environment variable [1]. [1]
; `XDEBUG_CONFIG` environment variable [1]. [1]

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

All the other comments in this file have these double `` not really sure why, so I think we better leave it as it is

Comment thread src/debugger/com.c
xdebug_log_ex(XLOG_CHAN_DEBUG, XLOG_ERR, "NOPERM", "No permission connecting to debugging client (%s). This could be SELinux related.", connection_attempts->d);
}

XG_BASE(statement_handler_enabled) = XG_DBG(remote_connection_enabled);

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

For the on-demand path where it was just flipped true by xdebug_connect_to_client(), will we reach this after the connection succeeds? otherwise we may end up with the flag bouncing false→true→false

Comment thread README.md
| Xdebug | **+35.3%** |
| PHP Debugger | **+1.3%** |

### On-Demand Debugging

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Should we also update the Xdebug compatibility table?

@carlos-granados carlos-granados requested a review from pronskiy April 9, 2026 16:56
# Conflicts:
#	.github/benchmark-files/benchmark.ini

# Conflicts:
#	README.md

# Conflicts:
#	src/base/base.c
@carlos-granados carlos-granados force-pushed the disable-jit-debugging-by-default branch from e976dc5 to 3d19c85 Compare April 9, 2026 16:59
@pronskiy

Copy link
Copy Markdown
Member

@carlos-granados LGTM 👍
I prefer squashing/rebasing for cleaner Git history, but we never discussed this. If you're okay with that I'l leave it to you to squash

@carlos-granados carlos-granados merged commit ac42e9d into php-debugger:main Apr 11, 2026
11 checks passed
@carlos-granados carlos-granados deleted the disable-jit-debugging-by-default branch April 11, 2026 12:06
@carlos-granados

Copy link
Copy Markdown
Collaborator Author

@carlos-granados LGTM 👍 I prefer squashing/rebasing for cleaner Git history, but we never discussed this. If you're okay with that I'l leave it to you to squash

Yes, squashing is my preferred option too, squashed and merged

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

performance-check Add this label to run the performance CI workflow

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants