Description
PHP (at the very least PHP 5.6, PHP 7.4, and PHP 8.0) seems to be incompatible with mimalloc and faults after each command. Interestingly, most CLI commands are able to successfully provide their output but then fault at the end. The anomaly is php --help
which doesn't fault or error out. This occurs with both Secure Mode Mimalloc and "Normal" Mimalloc.
The problem seems to lie in munmap_chunk()
, according to the following verbose output:
mimalloc: process init: 0x7f7e28dceb80
mimalloc: secure level: 4
mimalloc: using 1 numa regions
mimalloc: option 'show_errors': 0
mimalloc: option 'show_stats': 1
mimalloc: option 'eager_commit': 1
mimalloc: option 'eager_region_commit': 1
mimalloc: option 'reset_decommits': 0
mimalloc: option 'large_os_pages': 0
mimalloc: option 'reserve_huge_os_pages': 0
mimalloc: option 'segment_cache': 0
mimalloc: option 'page_reset': 1
mimalloc: option 'abandoned_page_reset': 0
mimalloc: option 'segment_reset': 0
mimalloc: option 'eager_commit_delay': 1
mimalloc: option 'reset_delay': 100
mimalloc: option 'use_numa_nodes': 0
mimalloc: option 'os_tag': 100
mimalloc: option 'max_errors': 16
munmap_chunk(): invalid pointer
Aborted (core dumped)
I assume this then causes free()
to fail:
mimalloc: process init: 0x7fb2802d6b80
mimalloc: secure level: 4
mimalloc: using 1 numa regions
mimalloc: option 'show_errors': 0
mimalloc: option 'show_stats': 0
mimalloc: option 'eager_commit': 1
mimalloc: option 'eager_region_commit': 1
mimalloc: option 'reset_decommits': 0
mimalloc: option 'large_os_pages': 0
mimalloc: option 'reserve_huge_os_pages': 0
mimalloc: option 'segment_cache': 0
mimalloc: option 'page_reset': 1
mimalloc: option 'abandoned_page_reset': 0
mimalloc: option 'segment_reset': 0
mimalloc: option 'eager_commit_delay': 1
mimalloc: option 'reset_delay': 100
mimalloc: option 'use_numa_nodes': 0
mimalloc: option 'os_tag': 100
mimalloc: option 'max_errors': 16
free(): invalid pointer
Aborted (core dumped)
However, I'm also able to have mimalloc fault with a double free at other times:
mimalloc: process init: 0x7f9d6aa95b80
mimalloc: secure level: 4
mimalloc: using 1 numa regions
mimalloc: option 'show_errors': 0
mimalloc: option 'show_stats': 0
mimalloc: option 'eager_commit': 1
mimalloc: option 'eager_region_commit': 1
mimalloc: option 'reset_decommits': 0
mimalloc: option 'large_os_pages': 0
mimalloc: option 'reserve_huge_os_pages': 0
mimalloc: option 'segment_cache': 0
mimalloc: option 'page_reset': 1
mimalloc: option 'abandoned_page_reset': 0
mimalloc: option 'segment_reset': 0
mimalloc: option 'eager_commit_delay': 1
mimalloc: option 'reset_delay': 100
mimalloc: option 'use_numa_nodes': 0
mimalloc: option 'os_tag': 100
mimalloc: option 'max_errors': 16
double free or corruption (out)
Aborted (core dumped)
This is likely the same bug affecting #345.
This has been tested across two installations on Arch Linux using LD_PRELOAD
and /etc/ld.so.preload
to override PHP's usage of the default/in-built allocator.