|
php.net | support | documentation | report a bug | advanced search | search howto | statistics | random bug | login |
[2021-03-26 19:38 UTC] calvin at cmpct dot info
Description:
------------
While initially trying to fix another issue (lack of check_liveness, see GH-6805), running a test script on Linux (Debian 9 and Fedora 33 tested), PHP crashes after freeing memory at the end of the script.
I thought it might have been an ODBC driver issue (specifically, the one for Db2i) or with my patches, but after checking out unpatched master, it appears the free and leak is in PHP, according to --enable-debug.
Test script:
---------------
<?php
echo "Hello\n";
$connection = new PDO('odbc:Driver=IBM i Access ODBC Driver;System=host', 'user', 'password', array(PDO::ATTR_PERSISTENT => true));
echo "connected\n";
$stmt = $connection->query("select job_name from table(QSYS2.ACTIVE_JOB_INFO(JOB_NAME_FILTER => 'QZDASOINIT'))");
if ($stmt) {
var_dump($stmt->fetchAll());
} else {
var_dump($connection->errorInfo());
}
echo "waiting 20 seconds and pconnecting again \n";
flush();
ob_flush();
sleep(20);
$connection = new PDO('odbc:Driver=IBM i Access ODBC Driver;System=host', 'user', 'password', array(PDO::ATTR_PERSISTENT => true));
$stmt = $connection->query("select job_name from table(QSYS2.ACTIVE_JOB_INFO(JOB_NAME_FILTER => 'QZDASOINIT'))");
if ($stmt) {
var_dump($stmt->fetchAll());
} else {
var_dump($connection->errorInfo());
}
?>
Actual result:
--------------
(On Debian)
[Fri Mar 26 16:21:38 2021] Script: '/home/calvin/test-pdo-odbc.php'
/home/calvin/php-src/Zend/zend_smart_str.c(153) : Freeing 0x00007f67dca79300 (224 bytes), script=/home/calvin/test-pdo-odbc.php
=== Total 1 memory leaks detected ===
*** Error in `/tmp/php/bin/php': free(): invalid size: 0x00007f67dca79300 ***
======= Backtrace: =========
/lib/x86_64-linux-gnu/libc.so.6(+0x70bfb)[0x7f67dfdc8bfb]
/lib/x86_64-linux-gnu/libc.so.6(+0x76fc6)[0x7f67dfdcefc6]
/lib/x86_64-linux-gnu/libc.so.6(+0x7780e)[0x7f67dfdcf80e]
/tmp/php/bin/php(+0x2b6e35)[0x55fec5183e35]
/tmp/php/bin/php(+0x2b7231)[0x55fec5184231]
/tmp/php/bin/php(+0x534235)[0x55fec5401235]
/tmp/php/bin/php(+0x52f231)[0x55fec53fc231]
/tmp/php/bin/php(+0x52f2fd)[0x55fec53fc2fd]
/tmp/php/bin/php(zend_hash_graceful_reverse_destroy+0xc3)[0x55fec53fdb18]
/tmp/php/bin/php(+0x534347)[0x55fec5401347]
/tmp/php/bin/php(+0x5178d7)[0x55fec53e48d7]
/tmp/php/bin/php(php_module_shutdown+0x3b)[0x55fec5350257]
/tmp/php/bin/php(+0x66cc3b)[0x55fec5539c3b]
/lib/x86_64-linux-gnu/libc.so.6(__libc_start_main+0xf1)[0x7f67dfd782e1]
/tmp/php/bin/php(_start+0x2a)[0x55fec4ff8fba]
======= Memory map: ========
55fec4ecd000-55fec5da7000 r-xp 00000000 08:01 29727 /tmp/php/bin/php
55fec5fec000-55fec60cd000 r--p 00f1f000 08:01 29727 /tmp/php/bin/php
55fec60cd000-55fec60d4000 rw-p 01000000 08:01 29727 /tmp/php/bin/php
55fec60d4000-55fec60f2000 rw-p 00000000 00:00 0
55fec6470000-55fec6641000 rw-p 00000000 00:00 0 [heap]
7f67d4000000-7f67d4021000 rw-p 00000000 00:00 0
7f67d4021000-7f67d8000000 ---p 00000000 00:00 0
7f67dbfad000-7f67dbfaf000 r-xp 00000000 08:01 133284 /usr/lib/x86_64-linux-gnu/gconv/ISO8859-1.so
7f67dbfaf000-7f67dc1ae000 ---p 00002000 08:01 133284 /usr/lib/x86_64-linux-gnu/gconv/ISO8859-1.so
7f67dc1ae000-7f67dc1af000 r--p 00001000 08:01 133284 /usr/lib/x86_64-linux-gnu/gconv/ISO8859-1.so
7f67dc1af000-7f67dc1b0000 rw-p 00002000 08:01 133284 /usr/lib/x86_64-linux-gnu/gconv/ISO8859-1.so
7f67dc1b0000-7f67dc303000 r-xp 00000000 08:01 7222 /opt/ibm/iaccess/lib64/libcwbcore.so
7f67dc303000-7f67dc503000 ---p 00153000 08:01 7222 /opt/ibm/iaccess/lib64/libcwbcore.so
7f67dc503000-7f67dc50c000 r--p 00153000 08:01 7222 /opt/ibm/iaccess/lib64/libcwbcore.so
7f67dc50c000-7f67dc510000 rw-p 0015c000 08:01 7222 /opt/ibm/iaccess/lib64/libcwbcore.so
7f67dc510000-7f67dc512000 rw-p 00000000 00:00 0
7f67dc512000-7f67dc523000 r-xp 00000000 08:01 173845 /usr/lib/x86_64-linux-gnu/libodbcinst.so.2.0.0
7f67dc523000-7f67dc722000 ---p 00011000 08:01 173845 /usr/lib/x86_64-linux-gnu/libodbcinst.so.2.0.0
7f67dc722000-7f67dc723000 r--p 00010000 08:01 173845 /usr/lib/x86_64-linux-gnu/libodbcinst.so.2.0.0
7f67dc723000-7f67dc724000 rw-p 00011000 08:01 173845 /usr/lib/x86_64-linux-gnu/libodbcinst.so.2.0.0
7f67dc724000-7f67dc727000 rw-p 00000000 00:00 0
7f67dc727000-7f67dc7f4000 r-xp 00000000 08:01 7221 /opt/ibm/iaccess/lib64/libcwbodbc.so
7f67dc7f4000-7f67dc9f3000 ---p 000cd000 08:01 7221 /opt/ibm/iaccess/lib64/libcwbodbc.so
7f67dc9f3000-7f67dc9fb000 r--p 000cc000 08:01 7221 /opt/ibm/iaccess/lib64/libcwbodbc.so
7f67dc9fb000-7f67dca00000 rw-p 000d4000 08:01 7221 /opt/ibm/iaccess/lib64/libcwbodbc.so
7f67dca00000-7f67dcc00000 rw-p 00000000 00:00 0
7f67dccb8000-7f67dccce000 r-xp 00000000 08:01 262160 /lib/x86_64-linux-gnu/libgcc_s.so.1
7f67dccce000-7f67dcecd000 ---p 00016000 08:01 262160 /lib/x86_64-linux-gnu/libgcc_s.so.1
7f67dcecd000-7f67dcece000 r--p 00015000 08:01 262160 /lib/x86_64-linux-gnu/libgcc_s.so.1
7f67dcece000-7f67dcecf000 rw-p 00016000 08:01 262160 /lib/x86_64-linux-gnu/libgcc_s.so.1
7f67dcecf000-7f67dd041000 r-xp 00000000 08:01 137490 /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.22
7f67dd041000-7f67dd241000 ---p 00172000 08:01 137490 /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.22
7f67dd241000-7f67dd24b000 r--p 00172000 08:01 137490 /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.22
7f67dd24b000-7f67dd24d000 rw-p 0017c000 08:01 137490 /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.22
7f67dd24d000-7f67dd251000 rw-p 00000000 00:00 0
7f67dd251000-7f67dd25a000 r-xp 00000000 08:01 166610 /usr/lib/x86_64-linux-gnu/libltdl.so.7.3.1
7f67dd25a000-7f67dd459000 ---p 00009000 08:01 166610 /usr/lib/x86_64-linux-gnu/libltdl.so.7.3.1
7f67dd459000-7f67dd45a000 r--p 00008000 08:01 166610 /usr/lib/x86_64-linux-gnu/libltdl.so.7.3.1
7f67dd45a000-7f67dd45b000 rw-p 00009000 08:01 166610 /usr/lib/x86_64-linux-gnu/libltdl.so.7.3.1
7f67dd45b000-7f67dd480000 r-xp 00000000 08:01 262220 /lib/x86_64-linux-gnu/liblzma.so.5.2.2
7f67dd480000-7f67dd67f000 ---p 00025000 08:01 262220 /lib/x86_64-linux-gnu/liblzma.so.5.2.2
7f67dd67f000-7f67dd680000 r--p 00024000 08:01 262220 /lib/x86_64-linux-gnu/liblzma.so.5.2.2
7f67dd680000-7f67dd681000 rw-p 00025000 08:01 262220 /lib/x86_64-linux-gnu/liblzma.so.5.2.2
7f67dd681000-7f67dd69a000 r-xp 00000000 08:01 262379 /lib/x86_64-linux-gnu/libz.so.1.2.8
7f67dd69a000-7f67dd899000 ---p 00019000 08:01 262379 /lib/x86_64-linux-gnu/libz.so.1.2.8
7f67dd899000-7f67dd89a000 r--p 00018000 08:01 262379 /lib/x86_64-linux-gnu/libz.so.1.2.8
7f67dd89a000-7f67dd89b000 rw-p 00019000 08:01 262379 /lib/x86_64-linux-gnu/libz.so.1.2.8
7f67dd89b000-7f67df117000 r-xp 00000000 08:01 143127 /usr/lib/x86_64-linux-gnu/libicudata.so.57.1
7f67df117000-7f67df316000 ---p 0187c000 08:01 143127 /usr/lib/x86_64-linux-gnu/libicudata.so.57.1
7f67df316000-7f67df317000 r--p 0187b000 08:01 143127 /usr/lib/x86_64-linux-gnu/libicudata.so.57.1
7f67df317000-7f67df318000 rw-p 0187c000 08:01 143127 /usr/lib/x86_64-linux-gnu/libicudata.so.57.1
7f67df318000-7f67df4ac000 r-xp 00000000 08:01 143134 /usr/lib/x86_64-linux-gnu/libicuuc.so.57.1
7f67df4ac000-7f67df6ab000 ---p 00194000 08:01 143134 /usr/lib/x86_64-linux-gnu/libicuuc.so.57.1
7f67df6ab000-7f67df6bd000 r--p 00193000 08:01 143134 /usr/lib/x86_64-linux-gnu/libicuuc.so.57.1
7f67df6bd000-7f67df6be000 rw-p 001a5000 08:01 143134 /usr/lib/x86_64-linux-gnu/libicuuc.so.57.1
7f67df6be000-7f67df6c0000 rw-p 00000000 00:00 0
7f67df6c0000-7f67df92b000 r-xp 00000000 08:01 143128 /usr/lib/x86_64-linux-gnu/libicui18n.so.57.1
7f67df92b000-7f67dfb2b000 ---p 0026b000 08:01 143128 /usr/lib/x86_64-linux-gnu/libicui18n.so.57.1
7f67dfb2b000-7f67dfb38000 r--p 0026b000 08:01 143128 /usr/lib/x86_64-linux-gnu/libicui18n.so.57.1
7f67dfb38000-7f67dfb3a000 rw-p 00278000 08:01 143128 /usr/lib/x86_64-linux-gnu/libicui18n.so.57.1
7f67dfb3a000-7f67dfb3b000 rw-p 00000000 00:00 0
7f67dfb3b000-7f67dfb53000 r-xp 00000000 08:01 262182 /lib/x86_64-linux-gnu/libpthread-2.24.so
7f67dfb53000-7f67dfd52000 ---p 00018000 08:01 262182 /lib/x86_64-linux-gnu/libpthread-2.24.so
7f67dfd52000-7f67dfd53000 r--p 00017000 08:01 262182 /lib/x86_64-linux-gnu/libpthread-2.24.so
7f67dfd53000-7f67dfd54000 rw-p 00018000 08:01 262182 /lib/x86_64-linux-gnu/libpthread-2.24.so
7f67dfd54000-7f67dfd58000 rw-p 00000000 00:00 0
7f67dfd58000-7f67dfeed000 r-xp 00000000 08:01 262166 /lib/x86_64-linux-gnu/libc-2.24.so
7f67dfeed000-7f67e00ed000 ---p 00195000 08:01 262166 /lib/x86_64-linux-gnu/libc-2.24.so
7f67e00ed000-7f67e00f1000 r--p 00195000 08:01 262166 /lib/x86_64-linux-gnu/libc-2.24.so
7f67e00f1000-7f67e00f3000 rw-p 00199000 08:01 262166 /lib/x86_64-linux-gnu/libc-2.24.so
7f67e00f3000-7f67e00f7000 rw-p 00000000 00:00 0
7f67e00f7000-7f67e01fa000 r-xp 00000000 08:01 134316 /usr/lib/x86_64-linux-gnu/libsqlite3.so.0.8.6
7f67e01fa000-7f67e03f9000 ---p 00103000 08:01 134316 /usr/lib/x86_64-linux-gnu/libsqlite3.so.0.8.6
7f67e03f9000-7f67e03fc000 r--p 00102000 08:01 134316 /usr/lib/x86_64-linux-gnu/libsqlite3.so.0.8.6
7f67e03fc000-7f67e03fe000 rw-p 00105000 08:01 134316 /usr/lib/x86_64-linux-gnu/libsqlite3.so.0.8.6
7f67e03fe000-7f67e03ff000 rw-p 00000000 00:00 0
7f67e03ff000-7f67e0462000 r-xp 00000000 08:01 173833 /usr/lib/x86_64-linux-gnu/libodbc.so.2.0.0
7f67e0462000-7f67e0661000 ---p 00063000 08:01 173833 /usr/lib/x86_64-linux-gnu/libodbc.so.2.0.0
7f67e0661000-7f67e0662000 r--p 00062000 08:01 173833 /usr/lib/x86_64-linux-gnu/libodbc.so.2.0.0
7f67e0662000-7f67e0669000 rw-p 00063000 08:01 173833 /usr/lib/x86_64-linux-gnu/libodbc.so.2.0.0
7f67e0669000-7f67e066d000 rw-p 00000000 00:00 0
7f67e066d000-7f67e081d000 r-xp 00000000 08:01 143148 /usr/lib/x86_64-linux-gnu/libxml2.so.2.9.4
7f67e081d000-7f67e0a1d000 ---p 001b0000 08:01 143148 /usr/lib/x86_64-linux-gnu/libxml2.so.2.9.4
7f67e0a1d000-7f67e0a25000 r--p 001b0000 08:01 143148 /usr/lib/x86_64-linux-gnu/libxml2.so.2.9.4
7f67e0a25000-7f67e0a27000 rw-p 001b8000 08:01 143148 /usr/lib/x86_64-linux-gnu/libxml2.so.2.9.4
7f67e0a27000-7f67e0a28000 rw-p 00000000 00:00 0
7f67e0a28000-7f67e0a2b000 r-xp 00000000 08:01 262169 /lib/x86_64-linux-gnu/libdl-2.24.so
7f67e0a2b000-7f67e0c2a000 ---p 00003000 08:01 262169 /lib/x86_64-linux-gnu/libdl-2.24.so
7f67e0c2a000-7f67e0c2b000 r--p 00002000 08:01 262169 /lib/x86_64-linux-gnu/libdl-2.24.so
7f67e0c2b000-7f67e0c2c000 rw-p 00003000 08:01 262169 /lib/x86_64-linux-gnu/libdl-2.24.so
7f67e0c2c000-7f67e0d2f000 r-xp 00000000 08:01 262170 /lib/x86_64-linux-gnu/libm-2.24.so
7f67e0d2f000-7f67e0f2e000 ---p 00103000 08:01 262170 /lib/x86_64-linux-gnu/libm-2.24.so
7f67e0f2e000-7f67e0f2f000 r--p 00102000 08:01 262170 /lib/x86_64-linux-gnu/libm-2.24.so
7f67e0f2f000-7f67e0f30000 rw-p 00103000 08:01 262170 /lib/x86_64-linux-gnu/libm-2.24.so
7f67e0f30000-7f67e0f32000 r-xp 00000000 08:01 262186 /lib/x86_64-linux-gnu/libutil-2.24.so
7f67e0f32000-7f67e1131000 ---p 00002000 08:01 262186 /lib/x86_64-linux-gnu/libutil-2.24.so
7f67e1131000-7f67e1132000 r--p 00001000 08:01 262186 /lib/x86_64-linux-gnu/libutil-2.24.so
7f67e1132000-7f67e1133000 rw-p 00002000 08:01 262186 /lib/x86_64-linux-gnu/libutil-2.24.so
7f67e1133000-7f67e113a000 r-xp 00000000 08:01 262184 /lib/x86_64-linux-gnu/librt-2.24.so
7f67e113a000-7f67e1339000 ---p 00007000 08:01 262184 /lib/x86_64-linux-gnu/librt-2.24.so
7f67e1339000-7f67e133a000 r--p 00006000 08:01 262184 /lib/x86_64-linux-gnu/librt-2.24.so
7f67e133a000-7f67e133b000 rw-p 00007000 08:01 262184 /lib/x86_64-linux-gnu/librt-2.24.so
7f67e133b000-7f67e134f000 r-xp 00000000 08:01 262183 /lib/x86_64-linux-gnu/libresolv-2.24.so
7f67e134f000-7f67e154e000 ---p 00014000 08:01 262183 /lib/x86_64-linux-gnu/libresolv-2.24.so
7f67e154e000-7f67e154f000 r--p 00013000 08:01 262183 /lib/x86_64-linux-gnu/libresolv-2.24.so
7f67e154f000-7f67e1550000 rw-p 00014000 08:01 262183 /lib/x86_64-linux-gnu/libresolv-2.24.so
7f67e1550000-7f67e1552000 rw-p 00000000 00:00 0
7f67e1552000-7f67e155a000 r-xp 00000000 08:01 262168 /lib/x86_64-linux-gnu/libcrypt-2.24.so
7f67e155a000-7f67e175a000 ---p 00008000 08:01 262168 /lib/x86_64-linux-gnu/libcrypt-2.24.so
7f67e175a000-7f67e175b000 r--p 00008000 08:01 262168 /lib/x86_64-linux-gnu/libcrypt-2.24.so
7f67e175b000-7f67e175c000 rw-p 00009000 08:01 262168 /lib/x86_64-linux-gnu/libcrypt-2.24.so
7f67e175c000-7f67e178a000 rw-p 00000000 00:00 0
7f67e178a000-7f67e17ad000 r-xp 00000000 08:01 262162 /lib/x86_64-linux-gnu/ld-2.24.so
7f67e18d0000-7f67e1921000 rw-p 00000000 00:00 0
7f67e1934000-7f67e1943000 r--p 00000000 08:01 6698 /opt/ibm/iaccess/mri2924/cwbcomsg.dll
7f67e1943000-7f67e194a000 r--s 00000000 08:01 133349 /usr/lib/x86_64-linux-gnu/gconv/gconv-modules.cache
7f67e194a000-7f67e19a7000 rw-p 00000000 00:00 0
7f67e19a8000-7f67e19a9000 rw-p 00000000 00:00 0
7f67e19a9000-7f67e19ad000 r--p 00000000 08:01 6691 /opt/ibm/iaccess/mri2924/cwbodmsg.dll
7f67e19ad000-7f67e19ae000 r--p 00023000 08:01 262162 /lib/x86_64-linux-gnu/ld-2.24.so
7f67e19ae000-7f67e19af000 rw-p 00024000 08:01 262162 /lib/x86_64-linux-gnu/ld-2.24.so
7f67e19af000-7f67e19b0000 rw-p 00000000 00:00 0
7ffd69d61000-7ffd69d82000 rw-p 00000000 00:00 0 [stack]
7ffd69d90000-7ffd69d92000 r--p 00000000 00:00 0 [vvar]
7ffd69d92000-7ffd69d94000 r-xp 00000000 00:00 0 [vdso]
ffffffffff600000-ffffffffff601000 r-xp 00000000 00:00 0 [vsyscall]
Aborted
PatchesPull RequestsHistoryAllCommentsChangesGit/SVN commits
|
|||||||||||||||||||||||||||
Copyright © 2001-2025 The PHP GroupAll rights reserved. |
Last updated: Fri Oct 24 16:00:02 2025 UTC |
FWIW, I can still reproduce this on 8.2 master (b582427ff53db38cac3e23d3c990814da418038c), but I think the symptom might have changed. Test program using MariaDB's ODBC driver (so we can discount IBM's weird driver), running on Fedora 35: ``` <?php $connection = new PDO('odbc:Driver=MariaDB;Database=<DB here>', 'username', 'password', array(PDO::ATTR_PERSISTENT => true)); ``` Gets: ``` $ /tmp/php/bin/php ../test-pdo-odbc-mariadb.php [Tue Feb 15 11:04:47 2022] Script: '/home/calvin/src/test-pdo-odbc-mariadb.php' /home/calvin/src/php-src/Zend/zend_smart_str.c(164) : Freeing 0x00007f2daa285300 (224 bytes), script=/home/calvin/src/test-pdo-odbc-mariadb.php === Total 1 memory leaks detected === munmap_chunk(): invalid pointer Aborted (core dumped) ``` The address of the leaked pointer changes, and it only leaks if the connection is successful; it will always crash with munmap_chunk() regardless. USE_ZEND_ALLOC=0 seems to make it work, but probably by covering it up.I think I have enough to explain how this happens: 1. PDO constructs a new connection string with spprintf, replaces and frees the old one 2. When dbh_free is called, the refcount is 2, but it hits the persistent connection early return, presumably for reuse ``` Breakpoint 2, dbh_free (dbh=0x186e180, free_persistent=false) at /home/calvin/src/php-src/ext/pdo/pdo_dbh.c:1432 1432 if (dbh->query_stmt) { (gdb) p *dbh $4 = {methods = 0x13707c0 <odbc_methods>, driver_data = 0x18ce950, username = 0x199e6b0 "lobsters", password = 0x19a5480 "password", is_persistent = 1, auto_commit = 1, is_closed = 0, alloc_own_columns = 1, in_txn = false, max_escaped_char_length = 0, oracle_nulls = 0, stringify = 0, skip_param_evt = 0, _reserved_flags = 0, data_source = 0x7ffff7685300 "Driver=MariaDB;Database=lobsters_dev;UID=lobsters;PWD=password", data_source_len = 36, error_code = "00000", error_mode = PDO_ERRMODE_EXCEPTION, native_case = PDO_CASE_NATURAL, desired_case = PDO_CASE_NATURAL, persistent_id = 0x19a5400 "PDO:DBH:DSN=odbc:Driver=MariaDB;Database=lobsters_dev:lobsters:password", persistent_id_len = 71, refcount = 2, cls_methods = {0x0, 0x0}, driver = 0x1370920 <pdo_odbc_driver>, def_stmt_ce = 0x194b610, def_stmt_ctor_args = {value = {lval = 0, dval = 0, counted = 0x0, str = 0x0, arr = 0x0, obj = 0x0, res = 0x0, ref = 0x0, ast = 0x0, zv = 0x0, ptr = 0x0, ce = 0x0, func = 0x0, ww = {w1 = 0, w2 = 0}}, u1 = {type_info = 0, v = {type = 0 '\000', type_flags = 0 '\000', u = {extra = 0}}}, u2 = {next = 0, cache_slot = 0, opline_num = 0, lineno = 0, num_args = 0, fe_pos = 0, fe_iter_idx = 0, property_guard = 0, constant_flags = 0, extra = 0}}, query_stmt = 0x0, query_stmt_zval = {value = {lval = 0, dval = 0, counted = 0x0, str = 0x0, arr = 0x0, obj = 0x0, res = 0x0, ref = 0x0, ast = 0x0, zv = 0x0, ptr = 0x0, ce = 0x0, func = 0x0, ww = {w1 = 0, w2 = 0}}, u1 = {type_info = 0, v = {type = 0 '\000', type_flags = 0 '\000', u = {extra = 0}}}, u2 = {next = 0, cache_slot = 0, opline_num = 0, lineno = 0, num_args = 0, fe_pos = 0, fe_iter_idx = 0, property_guard = 0, constant_flags = 0, extra = 0}}, default_fetch_type = PDO_FETCH_BOTH} (gdb) p dbh->refcount $5 = 2 (gdb) p free_persistent $6 = false (gdb) next 1437 if (dbh->is_persistent) { (gdb) next 1439 ZEND_ASSERT(!free_persistent || (dbh->refcount == 1)); (gdb) next 1441 if (!free_persistent && (--dbh->refcount)) { (gdb) next 1442 return; (gdb) p free_persistent $7 = false (gdb) p dbh->refcount $8 = 1 ``` This means the pefree for dbh->data_source never gets called when we want it to. 3. But this is CLI, so we're exiting anyways. It seems the PDO object is freed during the check for leaks, and the crash happens here inside of glibc (mixed up allocator? double free?) ``` Starting program: /tmp/php/bin/php ../test-pdo-odbc-mariadb.php [Thread debugging using libthread_db enabled] Using host libthread_db library "/lib64/libthread_db.so.1". [Tue Feb 15 12:06:10 2022] Script: '/home/calvin/src/test-pdo-odbc-mariadb.php' /home/calvin/src/php-src/Zend/zend_smart_str.c(164) : Freeing 0x00007ffff7685300 (224 bytes), script=/home/calvin/src/test-pdo-odbc-mariadb.php === Total 1 memory leaks detected === Breakpoint 1, dbh_free (dbh=0x186e180, free_persistent=true) at /home/calvin/src/php-src/ext/pdo/pdo_dbh.c:1451 1451 pefree((char *)dbh->data_source, dbh->is_persistent); (gdb) step __GI___libc_free (mem=0x7ffff7685300) at malloc.c:3240 Downloading -0.00 MB source file /usr/src/debug/glibc-2.34-25.fc35.x86_64/malloc/malloc.c 3240 { (gdb) step 3244 if (mem == 0) /* free(0) has no effect */ (gdb) step 3252 int err = errno; (gdb) step 3256 if (chunk_is_mmapped (p)) /* release mmapped memory. */ (gdb) step 3260 if (!mp_.no_dyn_threshold (gdb) step 3269 munmap_chunk (p); (gdb) step munmap_chunk (p=0x7ffff76852f0) at malloc.c:2935 2935 size_t pagesize = GLRO (dl_pagesize); (gdb) next 2936 INTERNAL_SIZE_T size = chunksize (p); (gdb) next 2938 assert (chunk_is_mmapped (p)); (gdb) next 2941 uintptr_t block = (uintptr_t) p - prev_size (p); (gdb) next 2942 size_t total_size = prev_size (p) + size; (gdb) next 2948 if (__glibc_unlikely ((block | total_size) & (pagesize - 1)) != 0 (gdb) next 2950 malloc_printerr ("munmap_chunk(): invalid pointer"); (gdb) next munmap_chunk(): invalid pointer ```