You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
There's such a problem: you cannot run code twice in phpdbg with swow and curl enabled in windows.
This will only occur under Windows, it may related with windows DLL load/unload mechanism.
The curl extension dll in offical PHP binaries is linking against static curl and dynamic nghttp2 and libssh2, at most time they work fine.
libcat/Swow hooks some curl functions to make them work with coroutine, this meaning libcat/Swow binary will depend on curl and curl's dependencies like libssh2 or nghttp. I copied related config.w32 codes from curl extension's.
This seems work at most time, but enabling both curl and swow extension will cause libssh.dll cannot be unloaded at PHP module shutdown, the libssh2 dll's refcount seems not get cleaned normally, while one of libssh2 initializers is using static varibles as retval like codes below, it will return an address already free'd, this is the problem.
phpdbg will minit and mshutdown at every run, if we load only curl or swow extension, everything is ok, the procedure is
first php run start
minit->curl_global_init->_libssh2_openssl_crypto_init->_libssh2_EVP_aes_128_ctr will return addressA
rinit, rshutdown, payload PHP script run things
mshutdown->curl_global_cleanup->_libssh2_openssl_crypto_exit will free addressA
php_{curl,swow}.dll is free'd
libssh2.dll is free'd, its static varible is cleaned
second php run start
minit->curl_global_init->_libssh2_openssl_crypto_init->_libssh2_EVP_aes_128_ctr will return addressB
rinit, rshutdown, payload PHP script run things
mshutdown->curl_global_cleanup->_libssh2_openssl_crypto_exit will free addressB
...
But if we load both curl and swow extension, the procedure is
first php run start
minit->curl_global_init->_libssh2_openssl_crypto_init->_libssh2_EVP_aes_128_ctr will return addressA
rinit, rshutdown, payload PHP script run things
mshutdown->curl_global_cleanup->_libssh2_openssl_crypto_exit will free addressA
php_{curl,swow}.dll is free'd
libssh2.dll is *NOT* free'd due to refcount, its static varible is *NOT* cleaned
second php run start
minit->curl_global_init->_libssh2_openssl_crypto_init->_libssh2_EVP_aes_128_ctr will return addressA <- this address is not usable
rinit, rshutdown, payload PHP script run things
mshutdown->curl_global_cleanup->_libssh2_openssl_crypto_exit will free addressA <- double-free'd, program died
I'm not so familiar with windows DLL load/unload procedure, so I cannot fix this yet, help is needed.
Thus, I have two questions:
Why libssh2 DLL refcount is not cleaned when both swow and curl DLLs unloaded? How can I make it be free'd at that time?
Should we do minit and mshutdown before and after single phpbdg run? Is this a good design? If it is, how can we ensure every modules is cleaned up their own or their dependencies' static variable? If not, how can we get capability to real rerun a php file in phpdbg?
bugSomething isn't workinghelp wantedExtra attention is neededdiscussionDiscuss things in this issue
1 participant
Heading
Bold
Italic
Quote
Code
Link
Numbered list
Unordered list
Task list
Attach files
Mention
Reference
Menu
reacted with thumbs up emoji reacted with thumbs down emoji reacted with laugh emoji reacted with hooray emoji reacted with confused emoji reacted with heart emoji reacted with rocket emoji reacted with eyes emoji
-
There's such a problem: you cannot run code twice in phpdbg with swow and curl enabled in windows.
This will only occur under Windows, it may related with windows DLL load/unload mechanism.
The curl extension dll in offical PHP binaries is linking against static curl and dynamic nghttp2 and libssh2, at most time they work fine.
libcat/Swow hooks some curl functions to make them work with coroutine, this meaning libcat/Swow binary will depend on curl and curl's dependencies like libssh2 or nghttp. I copied related config.w32 codes from curl extension's.
This seems work at most time, but enabling both curl and swow extension will cause libssh.dll cannot be unloaded at PHP module shutdown, the libssh2 dll's refcount seems not get cleaned normally, while one of libssh2 initializers is using static varibles as retval like codes below, it will return an address already free'd, this is the problem.
For detail, here is two examples:
phpdbg will minit and mshutdown at every run, if we load only curl or swow extension, everything is ok, the procedure is
But if we load both curl and swow extension, the procedure is
I'm not so familiar with windows DLL load/unload procedure, so I cannot fix this yet, help is needed.
Thus, I have two questions:
Beta Was this translation helpful? Give feedback.
All reactions