Description
When an exception is thrown from a CURLOPT_WRITEFUNCTION callback, a memory leak is reported by macOS leaks.
Test case
<?php
$ch = curl_init('https://www.php.net/');
$data = '';
curl_setopt($ch, CURLOPT_RETURNTRANSFER, false);
curl_setopt($ch, CURLOPT_WRITEFUNCTION, function ($ch, $chunk) use (&$data) {
throw new Exception('cancel boom');
});
try {
curl_exec($ch);
} catch (Throwable $e) {
echo $e->getMessage(), PHP_EOL;
}
Expected result
No memory leaks should be reported after the exception is thrown and execution unwinds back to userland.
Actual result
macOS leaks reports:
Process XXXXX: 1 leak for 80 total leaked bytes.
ROOT LEAK: <malloc in asn1_item_flags_i2d>
Relevant stack trace:
curl_exec()
libcurl
OpenSSL
EVP_DigestVerifyFinal()
ossl_ecdsa_verify()
ECDSA_do_verify_new()
asn1_item_flags_i2d()
Environment
- PHP: master (debug build)
- SAPI: CLI
- macOS 26.4.1 (Apple Silicon)
- libcurl linked against OpenSSL
Leaks
Process: php [20123]
Path: /Users/USER/Downloads/*/php
Load Address: 0x102878000
Identifier: php
Version: 0
Code Type: ARM64
Platform: macOS
Parent Process: leaks [20122]
Target Type: live task
Date/Time: 2026-06-01 15:41:47.923 +0530
Launch Time: 2026-06-01 15:41:44.629 +0530
OS Version: macOS 26.4.1 (25E253)
Report Version: 7
Analysis Tool: /usr/bin/leaks
Physical footprint: 13.1M
Physical footprint (peak): 13.5M
Idle exit: untracked
----
leaks Report Version: 4.0, multi-line stacks
Process 20123: 3521 nodes malloced for 415 KB
Process 20123: 1 leak for 80 total leaked bytes.
STACK OF 1 INSTANCE OF 'ROOT LEAK: <malloc in asn1_item_flags_i2d>':
26 dyld 0x187513da4 start + 6992
25 php 0x1032ca894 main + 892 php_cli.c:1370
24 php 0x1032cb5fc do_cli + 2912 php_cli.c:947
23 php 0x102f78898 php_execute_script + 28 main.c:2686
22 php 0x102f785e0 php_execute_script_ex + 796 main.c:2646
21 php 0x1032c87ac zend_execute_script + 124 zend.c:1973
20 php 0x1030c34cc zend_execute + 316 zend_vm_execute.h:115618
19 php 0x1030c3120 execute_ex + 208 zend_vm_execute.h:110198
18 php 0x1031cc7b0 ZEND_DO_ICALL_SPEC_RETVAL_UNUSED_TAILCALL_HANDLER + 164 zend_vm_execute.h:54115
17 php 0x1029b731c zif_curl_exec + 748 interface.c:2344
16 libcurl.4.dylib 0x1a40c11dc curl_easy_perform + 276
15 libcurl.4.dylib 0x1a40e6c3c curl_multi_perform + 204
14 libcurl.4.dylib 0x1a40e6ef8 multi_runsingle + 528
13 libcurl.4.dylib 0x1a40b18b4 Curl_conn_connect + 80
12 libcurl.4.dylib 0x1a40b5ec8 cf_hc_connect + 684
11 libcurl.4.dylib 0x1a40b512c cf_setup_connect + 108
10 libcurl.4.dylib 0x1a411193c ssl_cf_connect + 328
9 libcurl.4.dylib 0x1a410a6e0 ossl_connect_common + 252
8 libssl.48.dylib 0x28b4d69b0 tls13_legacy_connect + 56
7 libssl.48.dylib 0x28b4d4890 tls13_handshake_perform + 444
6 libssl.48.dylib 0x28b4d3b88 tls13_server_certificate_verify_recv + 628
5 libcrypto.46.dylib 0x28a986aac EVP_DigestVerifyFinal + 216
4 libcrypto.46.dylib 0x28a974978 ossl_ecdsa_verify + 176
3 libcrypto.46.dylib 0x28a973730 ECDSA_do_verify_new + 316
2 libcrypto.46.dylib 0x28a9278b4 asn1_item_flags_i2d + 204
1 libsystem_malloc.dylib 0x1876e0678 _malloc + 96
0 libsystem_malloc.dylib 0x1876fc178 _malloc_zone_malloc_instrumented_or_legacy + 152
====
1 (80 bytes) ROOT LEAK: <malloc in asn1_item_flags_i2d 0xc59069400> [80]
PHP Version
PHP 8.6.0-dev (cli) (built: May 31 2026 11:39:37) (NTS DEBUG)
Copyright © The PHP Group and Contributors
Zend Engine v4.6.0-dev, Copyright © Zend by Perforce
with Zend OPcache v8.6.0-dev, Copyright ©, by Zend by Perforce
Operating System
macOS 26.4
Description
When an exception is thrown from a
CURLOPT_WRITEFUNCTIONcallback, a memory leak is reported by macOSleaks.Test case
Expected result
No memory leaks should be reported after the exception is thrown and execution unwinds back to userland.
Actual result
macOS
leaksreports:Relevant stack trace:
Environment
Leaks
PHP Version
Operating System
macOS 26.4