-
Notifications
You must be signed in to change notification settings - Fork 374
[ xdebug ] Add --xdebug option in PHP.wasm CLI and Playground CLI
#2346
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
--xdebug option in php-wasm cli--xdebug option in php-wasm CLI and wp-playground CLI
|
It couldn't be that easy. wp-playground cli crashes for PHP versions below As these functions are already in |
|
I faced a Heisenbug here. Changing with
Anyway, that's the following stack trace when running I added the following new functions in + _emscripten_sleep
+ execute_internal
+ ZEND_INCLUDE_OR_EVAL_SPEC_CONST_HANDLER
+ ZEND_INCLUDE_OR_EVAL_SPEC_TMPVAR_HANDLERBut it isn't enough |
|
Let's debug php 8.2 separately from adding the cli switch. Let's just say it's experimental in the option description |
|
Ah it's not 8.2 - it's below 8.2 |
|
Yep, unfortunately it concerns every php version below 8.2 |
|
|
|
Also, would |
|
Unfortunately, setting |
|
Would changing ASYNCIFY_ONLY to ASYNCIFY_ADD change anything? |
|
I replaced |
|
Would it break with just a sleep(1) call? Or fopen/fread? Or is it only for curl? |
|
It simply breaks because of import { runCLI } from "@wp-playground/cli";
await runCLI({ php: '8.1', xdebug: true });I do not call any sleep or curl, only these two lines. It works as expected when using the |
|
Aha! These two lines do a lot, like installing WordPress. Let's isolate the issue |
|
Thanks for the insights, I dug deeper and found out the error occurred when running I added a new option in
if (!options.dataSqlPath) {
if (!(await isWordPressInstalled(php))) {
await installWordPress(php);
}
if (!(await isWordPressInstalled(php))) {
throw new Error('WordPress installation has failed.');
}
}and my script stopped successfully at breakpoint for every PHP versions. All of this because it never ran So this is my new script : import { withPHPIniValues } from '@php-wasm/universal';
import { runCLI } from "@wp-playground/cli";
const cliServer = await runCLI({ php: '7.2', dataSqlPath: 'none', xdebug: true });
const result = await cliServer.playground.run( { scriptPath : `${process.cwd()}/php/xdebug.php` } );
console.log( result.text );
await cliServer.playground.request({
url: '/wp-admin/install.php?step=2',
method: 'POST',
body: {
language: 'en',
prefix: 'wp_',
weblog_title: 'My WordPress Website',
user_name: 'admin',
admin_password: 'password',
// The installation wizard demands typing the same password twice
admin_password2: 'password',
Submit: 'Install WordPress',
pw_weak: '1',
admin_email: '[email protected]',
},
})This code will break on Another thing I noticed : Two requests are appearing in
New stack when running |
|
What if we took WordPress out of the equation entirely and called php.runStream() directly? Or went through php wasm cli, not playground cli? What would be the simplest script that crashes it? Would it involve curl? Or would regular sleep or fread be enough? |
|
I think I'm onto something interesting! I cloned the wordpress directory into the root of my project and am currently step-debugging through the entire WordPress installation script.
This should probably allow us to detect a lot more @adamziel I haven’t yet managed to reproduce a minimal crashing example. |
|
I reproduced the crash with this script: <?php
// Create a multi handle
$multiHandle = curl_multi_init();
// Initialize individual curl handles
$handles = [];
// First request to WordPress.org API
$ch1 = curl_init();
curl_setopt($ch1, CURLOPT_URL, 'https://api.wordpress.org/core/version-check/1.7/');
curl_setopt($ch1, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch1, CURLOPT_FOLLOWLOCATION, true);
curl_setopt($ch1, CURLOPT_SSL_VERIFYPEER, false);
$handles['version_check'] = $ch1;
curl_multi_add_handle($multiHandle, $ch1);
// Second request to WordPress.org main site
$ch2 = curl_init();
curl_setopt($ch2, CURLOPT_URL, 'https://wordpress.org/');
curl_setopt($ch2, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch2, CURLOPT_FOLLOWLOCATION, true);
curl_setopt($ch2, CURLOPT_SSL_VERIFYPEER, false);
$handles['main_site'] = $ch2;
curl_multi_add_handle($multiHandle, $ch2);
// Execute all requests
$running = null;
do {
curl_multi_exec($multiHandle, $running);
curl_multi_select($multiHandle);
} while ($running > 0);
// Collect results
$results = [];
foreach ($handles as $key => $handle) {
$results[$key] = curl_multi_getcontent($handle);
curl_multi_remove_handle($multiHandle, $handle);
curl_close($handle);
}
// Close multi handle
curl_multi_close($multiHandle);
// Display results
echo "WordPress.org API Response:\n";
echo $results['version_check'] . "\n\n";
echo "WordPress.org Main Site (first 200 chars):\n";
echo substr($results['main_site'], 0, 200) . "...\n";And this CLI command |
|
I am now looking to find a way to conduct tests specifically for xdebug without creating new test files. |
|
The following test files are now tested with About Unfortunately, two Because it sometimes returned : - resource(3) of type (stream),
+ resource(1) of type ((null)), |
|
Good work here @mho22! I am away this week but I'll review in details on Monday.
So the process resource is unusable with xdebug loaded? That sounds like a bug. By "sometimes" do you mean it's non-deterministic? Or can it be reliably reproduced? Either way, let's log it separately and not block this PR on it - xdebug is optional and asyncify is still and added value. |
|
Actually it's a reasonably small pr that also looks good. Thank you! |
|
Yes it wasn't a huge PR after all for sure. Let's update #314 |
This is non-deterministic. I faced errors for PHP versions above 8.0 sometimes and then errors for every versions. I think we'll need proper attention on these tests in another issue. |
--xdebug option in php-wasm CLI and wp-playground CLI--xdebug option in php-wasm CLI and wp-playground CLI
## Motivation for the change, related issues Populates the new `php-wasm-xdebug-bridge` package which will connect Xdebug with Browser Devtools. [Roadmap](#2315) ## Related issues and pull requests - #2346 - #2398 - #2288 ## Implementation details - DBGP communication TCP server, which the bridge uses to communication between PHP.wasm XDebug and the CDP server. XDebug defaultly discusses on port 9003. While the DBGP server is set on port 9003 by default. - CDP Websocket Server, which communicates between the Browser Devtools and the DBGP server, with the help of a bridge. The default port is 9229. - XDebug <-> CDP Bridge, which ties the above implementations together. It plays with all the specificities of the DBGP protocol and the CDP protocol. - A `startBridge` function that will initialize the servers, get the soon-to-be-debugged files and return the built bridge. - A CLI tool that will start the bridge between the browser and a XDebug. ## Testing Instructions Create a `xdebug.php` PHP file at the root of the repository : ```php <?php $test = 42; // Set a breakpoint on this line echo "Output!\n"; function test() { echo "Hello Xdebug World!\n"; } test(); ``` ### From Wordpress-Playground repository 1. Run the `xdebug-bridge` command in a first terminal : ``` > npx nx run php-wasm-xdebug-bridge:dev ... Chrome connected! Initializing Xdebug receiver... XDebug receiver running on port 9003 Running a PHP script with Xdebug enabled... ``` 2. Run the `php-wasm-cli` command in a second terminal : ``` > nx run php-wasm-cli:dev --xdebug xdebug.php Output! Hello Xdebug World! ``` ### From non-related Playground project 1. Install dependencies ``` npm install @php-wasm/cli @php-wasm/xdebug-bridge ``` 2. Run the `xdebug-bridge` command in a first terminal : ``` > npx xdebug-bridge ... Chrome connected! Initializing Xdebug receiver... XDebug receiver running on port 9003 Running a PHP script with Xdebug enabled... ``` 3. Run the `@php-wasm/cli` command in a second terminal : ``` > npx cli --xdebug xdebug.php Output! Hello Xdebug World! ``` <img width="748" height="409" alt="screencapture" src="https://github.com/user-attachments/assets/b0232831-c9b3-4bb2-95aa-b1d51b72766e" /> --------- Co-authored-by: mho22 <[email protected]>
) ## Motivation for the change, related issues This pull request adds a `--experimental-devtools` option in `wp-playground/cli`. [Roadmap](#2315) ## Related issues and pull requests - #2408 - #2402 - #2398 - #2346 - #2288 ## Implementation details - Simple implementation of a Devtools option. It checks for a `experimentalDevtools` argument that starts the `xdebug-to-cdp-bridge` process. - Changes the `StartBridgeConfig` `getPHPFile` property type from `(path: string) => string` to `(path: string) => Promise<string>` and adapt the related code. ## Testing Instructions ### In WordPress-Playground repository 1. Write a script like the following `cli.ts` : ```typescript import { runCLI } from "./packages/playground/cli/src/run-cli"; const script = ` <?php $test = 42; echo "Output!\n"; function test() { echo "Hello Xdebug World!\n"; } test(); `; const cliServer = await runCLI({command: 'server', xdebug: true, experimentalDevtools: true}); cliServer.playground.writeFile('xdebug.php', script); const result = await cliServer.playground.run({scriptPath: `xdebug.php`}); console.log(result.text); ``` 2. Run the following command : ``` > node --no-warnings --experimental-wasm-stack-switching --experimental-wasm-jspi --loader=./packages/meta/src/node-es-module-loader/loader.mts cli.ts Starting a PHP server... Setting up WordPress undefined Resolved WordPress release URL: https://downloads.w.org/release/wordpress-6.8.2.zip Fetching SQLite integration plugin... Booting WordPress... Booted! Running the Blueprint... Running the Blueprint – 100% Finished running the blueprint WordPress is running on http://127.0.0.1:61290 Connect Chrome DevTools to CDP at: devtools://devtools/bundled/inspector.html?ws=localhost:9229 ... Chrome connected! Initializing Xdebug receiver... XDebug receiver running on port 9003 Running a PHP script with Xdebug enabled... ``` ### In a non-related Playground project 1. Install dependencies ``` npm install @wp-playground/cli ``` 2. Write a script like the following `cli.ts` : ```typescript import { runCLI } from "@wp-playground/cli"; const script = ` <?php $test = 42; echo "Output!\n"; function test() { echo "Hello Xdebug World!\n"; } test(); `; const cliServer = await runCLI({command: 'server', xdebug: true, experimentalDevtools: true}); await cliServer.playground.writeFile(`xdebug.php`, script); const result = await cliServer.playground.run({scriptPath: `xdebug.php`}); console.log(result.text); ``` 3. Run command : ``` > node cli.js Starting a PHP server... Setting up WordPress undefined Resolved WordPress release URL: https://downloads.w.org/release/wordpress-6.8.2.zip Fetching SQLite integration plugin... Booting WordPress... Booted! Running the Blueprint... Running the Blueprint – 100% Finished running the blueprint WordPress is running on http://127.0.0.1:61859 Connect Chrome DevTools to CDP at: devtools://devtools/bundled/inspector.html?ws=localhost:9229 ... Chrome connected! Initializing Xdebug receiver... XDebug receiver running on port 9003 Running a PHP script with Xdebug enabled... ``` <img width="920" height="471" alt="screencapture" src="https://github.com/user-attachments/assets/b3548d0e-f824-41c4-9148-3e4f106b4116" /> Note: It will need 23 step overs before leaving the `auto_prepend_file.php` and entering the `xdebug.php` script.
--xdebug option in php-wasm CLI and wp-playground CLI--xdebug option in PHP.wasm CLI and Playground CLI


Motivation for the change, related issues
This pull request adds a
--xdebugoption in :php-wasm/cliwp-playground/cliRoadmap
Related issues and pull requests
xdebugshared extension to PHP.wasm Node ASYNCIFY #2326xdebugdynamic extension to PHP.wasm Node JSPI #2248Implementation details
For PHP-WASM :
--xdebugargument.For WP-Playground :
ASYNCIFY_ONLYfunctions.xdebugoption.Testing Instructions
php/xdebug.phpFor PHP-WASM :
@php-wasm/cliis required.For WP-Playground :
@wp-playground/cliis required.