debug-php-wasm-side-modules
Installation
SKILL.md
Debugging PHP.wasm Side Modules
Patterns for diagnosing and fixing issues with dynamic PHP extensions
built as WASM side modules and loaded via dlopen.
_dlopen_js Must Be Synchronous
Emscripten marks _dlopen_js as async by default (isAsync = true).
With JSPI, this wraps the import with WebAssembly.Suspending. Even when
the implementation returns a plain value (not a Promise), the JSPI wrapper
corrupts the WASM call stack — V8's native stack bookkeeping
desynchronizes __stack_pointer in linear memory, causing heap corruption
that manifests later as zend_mm_panic in _efree.
Fix: Set _dlopen_js__async: false in the Emscripten JS library
(phpwasm-emscripten-library-dynamic-linking.js).