-
Notifications
You must be signed in to change notification settings - Fork 7.7k
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
Fix persistent procedural ODBC connections not getting closed (8.1) #12132
Fix persistent procedural ODBC connections not getting closed (8.1) #12132
Conversation
Like oci8, procedural ODBC uses an apply function on the hash list to enumerate persistent connections and close the specific one. However, this function take zvals, not resources. However, it was getting casted as such, causing it to interpret the pointer incorrectly. This could have caused other issues, but mostly manifested as failing to close the connection even fi it matched. The function now takes a zval and gets the resource from that. In addition, it also removes the cast of the function pointer and moves casting to the function body, to avoid possible confusion like this in refactors again. It also cleans up style and uses constants in the function body.
While this issue affects any driver, getting a driver into a state that persists across persistent connections is driver specific, be it wedged or just some connection variables. As such, just make an SQL Server specific test, since that's the driver used in CI.
@NattyNarwhal This causes a leak in nightly (only PHP 8.3 and master): https://github.com/php/php-src/actions/runs/6104241625/job/16566001830
I think the ODBC extension isn't tested in ASAN on push, which is why it's not caught there. Can you have a look? /cc @Girgias |
My initial guess is the connection isn't being freed properly (since this code didn't work almost a decade, quite possible). Another possibility, it might be on the database driver side (either as a false positive, or a driver bug). Last time I tried ASan, it didn't seem to like the DB2 driver. I can't remember if Valgrind was easier to deal with when I last tried that... |
I can't seem to repro on macOS (noted that the test is using ZTS), I'll check out Linux. |
Yup, can reproduce w/ driver 18 on Fedora 38/amd64:
|
I'm personally leaning towards "driver issue", since all the IDs in the ODBC functions are IIRC opaque integers, not pointers. The truncated stack trace for the |
@NattyNarwhal Looking up that error, |
I agree. I'm just not sure where to report the issue, is there a public facing bug tracker, or someone within MS that we can forward this to? |
I've tried to see where it could be reported. I'm not sure which is the better place, as they both don't seem particularly fitting. https://learn.microsoft.com/en-us/sql/connect/odbc/microsoft-odbc-driver-for-sql-server?view=sql-server-ver16 The SQL Server ODBC driver is not open source, correct? This will make it hard to provide a proper stack trace. However, they should be able to reproduce the issue with a PHP build. I will mark the test as XFAIL with ASAN for now. |
Like oci8, procedural ODBC uses an apply function on the hash list to enumerate persistent connections and close the specific one. However, this function take zvals, not resources. However, it was getting casted as such, causing it to interpret the pointer incorrectly. This could have caused other issues, but mostly manifested as failing to close the connection even fi it matched.
The function now takes a zval and gets the resource from that. In addition, it also removes the cast of the function pointer and moves casting to the function body, to avoid possible confusion like this in refactors again. It also cleans up style and uses constants in the function body.
(This PR is GH-12096, but rebased onto PHP 8.1 instead.)