Skip to content

Potential memory leak when exception is thrown from CURLOPT_WRITEFUNCTION callback #22198

@arshidkv12

Description

@arshidkv12

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

Metadata

Metadata

Assignees

No one assigned

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions