-
Notifications
You must be signed in to change notification settings - Fork 374
[XDebug Bridge] Load Plugin file in Devtools if --auto-mount option enabled
#2442
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
Conversation
--auto-mount option--auto-mount option enabled
--auto-mount option enabled--auto-mount option enabled
|
I'll follow up here |
…nreachable` crashes when using Devtools (#2454) ## Motivation for the change, related issues I listed the two crashes I encountered while using Devtools in the comments. I am currently recompiling `php-wasm-node:asyncify`. ## Implementation details Added the following functions in `ASYNCIFY_ONLY_PREFIXED` : ```diff // NEEDED TO PREVENT THE FIRST CRASH + php_fopen_primary_script + persistent_stream_open_function + php_stream_open_for_zend + zend_error_zstr + zend_register_constant + zif_define // NEEDED TO PREVENT THE SECOND CRASH + zend_undefined_index ``` ## Testing Instructions Based on the instructions from #2442 One test is to step into the running files 68 times until breaking on `define( 'WP_DEBUG', false );`. The next step would crash previously. Not anymore. The second test is to quit the Devtools tab while it is running. It crashed previously. Not anymore.
|
I tested with the
This seems to be almost a good user experience right? Let's imagine we have a page with two iframes, one is the Playground and the second one is the devtools, with a button that could enable step debugging when you're ready to step debug your request? I don't know, just sharing my thoughts here. |
|
Thank you @mho22! This is pretty neat and I think we're not far off from v1. For v2, my worry is having to interact with devtools on every request. I wonder if we could make "break on the first line" configurable (enabled by default) and start CDP connection separately from the XDebug connection. That is, we could give the user the opportunity to navigate the codebase and set breakpoints without making a request first and without pausing on the very first line. |
| @@ -0,0 +1,58 @@ | |||
| export function findFirstDebuggableLine(content: string) { | |||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Let's document the intention here
|
|
||
| if (line === '') continue; | ||
|
|
||
| if (line.startsWith('/*')) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is somewhat naive – we're parsing PHP code using regular expressions. It works while it works but it will break in cases such as:
<?php /** Plugin name: Test */ weirdly_all_code_is_minified();
These may not be popular use-cases, but I'm sure they are out there. I'd worry .phar files would pose another challenge with this approach.
I'm more and more convinced we shouldn't try to figure this out for the user. Instead, let's just enable them to navigate their own plugin and set the breakpoint where they need.
My thinking goes towards:
- A way to browse the entire WordPress file structure in the chrome devtools – so core files and my plugins
- A limited mode that only exposes paths I've explicitly mounted, e.g. plugins, themes, uploads. This is tricky, e.g. how would we step through / into any WordPress core functions? Perhaps this is a good problem to solve for later and not for starters?
- A separation between browsing and debugging my code in devtools. It would be nice if we could connect via CDP just to poke around and find the right file without implicitly setting any breakpoints.
- A way to tell Playground either:
- "Break on the first line of PHP code" – which implies revealing the entire WordPress file structure in devtools
- "I will set my own breakpoints" – which allows the user to do what they need.
|
Great explorations @mho22! It's been a great stone to turn. This usage pattern would work in some cases, but it doesn't seem that great in the general scenario, especially with how it forces us into parsing PHP. It becomes clear to me that we've been looking in a wrong direction. Every XDebug-integrated IDE out there separates browsing the code and setting breakpoints from debugging the code. I think we should do the same thing. Then we'll be able to follow the established usage patterns instead of inventing new ways of debugging. |
|
@adamziel You're right. Let's forget that one, and focus on your suggestion instead. I already have an idea to integrate it. Let's close this pull request. |
… enabled (#2527) ## Motivation for the change, related issues Based on the following pull request : - #2442 The first approach was to load Devtools when running a file with Xdebug enabled PHP.wasm. Unfortunately, the user experience was not great. e.g. files were loaded only when executed. The new approach opens de Devtools Source panel with the relevant loaded files ready to be manipulated. Once the breakpoints are set, the PHP file can be executed and paused with Xdebug enabled PHP.wasm. ## Implementation details - DevTools Sources Opening : Devtools Source panel is automatically opened when bridge starts. - Console Instructions : A startup message guides users on how to debug with the bridge. - Source File Loading : Relevant PHP files are preloaded in DevTools for inspection and breakpoints. - Pending Breakpoints : Breakpoints set before Xdebug init are applied once the session starts. - URI Normalization : Paths are consistently mapped between Bridge, CDP, and DBGP. - CDP Command Buffer : CDP requests are buffered until the bridge is fully initialized. - `breakOnFirstLine` Option : Allows breaking on the first executed line when no breakpoints exist. - Test Coverage ## Testing Instructions with Xdebug Bridge 1. Run the devtools ``` npx xdebug-bridge ``` 2. Connect to the devtools ``` Starting XDebug Bridge... Connect Chrome DevTools to CDP at: devtools://devtools/bundled/inspector.html?ws=localhost:9229 ``` 3. Set a breakpoint in a file <img width="1920" height="656" alt="screenshot-001" src="https://github.com/user-attachments/assets/3591ea63-7344-4a53-98ee-6ff70440dbaf" /> 4. Run the PHP script with PHP.wasm CLI and Xdebug option ``` npx php-wasm-cli test.php --xdebug ``` <img width="1920" height="651" alt="screenshot-002" src="https://github.com/user-attachments/assets/e5c9049d-c556-41b3-b99c-a9a2000f5da4" /> 5. Resume script execution and repeat step 4 indefinitely <img width="1919" height="667" alt="screenshot-003" src="https://github.com/user-attachments/assets/aacfaf3d-0afb-497e-b5cd-8d3eb0ce98de" /> ## Testing Instructions with PHP.wasm CLI 1. Run the script with Xdebug and Devtools options ``` npx php-wasm-cli test.php --experimental-devtools --xdebug ``` 2. Connect to the devtools ``` Starting XDebug Bridge... Connect Chrome DevTools to CDP at: devtools://devtools/bundled/inspector.html?ws=localhost:9229 ``` 3. It will pause on the first breakable PHP code <img width="1920" height="651" alt="screenshot-002" src="https://github.com/user-attachments/assets/e5c9049d-c556-41b3-b99c-a9a2000f5da4" /> ## Testing Instructions with PHP.wasm Node 1. Write the following script ``` import { PHP } from '@php-wasm/universal'; import { loadNodeRuntime } from '@php-wasm/node'; import { startBridge } from '@php-wasm/xdebug-bridge'; const php = new PHP(await loadNodeRuntime('8.4', {withXdebug: true})); const bridge = await startBridge({phpInstance: php, breakOnFirstLine: true}); bridge.start(); await php.runStream({scriptPath: `test.php`}); ``` 1. Run the script with Node ``` node script.js ``` 3. Connect to the devtools ``` Starting XDebug Bridge... Connect Chrome DevTools to CDP at: devtools://devtools/bundled/inspector.html?ws=localhost:9229 ``` 4. It will pause on the first breakable PHP code <img width="1920" height="651" alt="screenshot-002" src="https://github.com/user-attachments/assets/e5c9049d-c556-41b3-b99c-a9a2000f5da4" /> ## Testing Instructions in `wordpress-playground` 1. Run the devtools ``` nx reset && nx run php-wasm-xdebug-bridge:dev --php-root /absolute/path/to/the/debuggable/directory ``` 2. Connect to the devtools ``` Starting XDebug Bridge... Connect Chrome DevTools to CDP at: devtools://devtools/bundled/inspector.html?ws=localhost:9229 ``` 3. Set a breakpoint in a file <img width="1920" height="656" alt="screenshot-001" src="https://github.com/user-attachments/assets/3591ea63-7344-4a53-98ee-6ff70440dbaf" /> 5. Run the PHP script ``` nx reset && nx run php-wasm-cli:dev /absolute/path/to/the/debuggable/directory/file.php --xdebug ``` <img width="1920" height="651" alt="screenshot-002" src="https://github.com/user-attachments/assets/e5c9049d-c556-41b3-b99c-a9a2000f5da4" /> 6. Resume script execution and repeat step 4 indefinitely <img width="1919" height="667" alt="screenshot-003" src="https://github.com/user-attachments/assets/aacfaf3d-0afb-497e-b5cd-8d3eb0ce98de" />







Motivation for the change, related issues
🚧 This draft is an experimental work in progress since I am not sure this should be the correct behavior. 🚧
When running
node node_modules/@wp-playground/cli/cli.js server --xdebug --experimental-devtools --auto-mountit returns :But nothing next. It doesn't run a php script with Xdebug enabled since no
playground.run()is called.This pull request aims to run a chosen script when using
--auto-mount. Sinceauto-mountwill smartly recognize a Plugin or a Theme, it should also debug the given Plugin script.Implementation details
if
--experimental-devtools,--xdebugand--auto-mount, the script will check if a Plugin is available inprocess.cwd()and debug it.Testing Instructions
In a empty directory named
recolor-wp-admin-plugin, add file :index.phpstyle.cssNow run :