mirror of
https://github.com/php/php-src.git
synced 2025-08-15 13:38:49 +02:00
Fix GH-9650: Can't initialize heap: [0x000001e7]
Closes GH-9721.
This commit is contained in:
parent
c53b065c48
commit
8d65c2fee5
2 changed files with 70 additions and 44 deletions
1
NEWS
1
NEWS
|
@ -7,6 +7,7 @@ PHP NEWS
|
|||
(cmb)
|
||||
. Fixed bug GH-9918 (License information for xxHash is not included in
|
||||
README.REDIST.BINS file). (Akama Hitoshi)
|
||||
. Fixed bug GH-9650 (Can't initialize heap: [0x000001e7]). (Michael Voříšek)
|
||||
|
||||
- MBString:
|
||||
. Fixed bug GH-9535 (The behavior of mb_strcut in mbstring has been changed in
|
||||
|
|
|
@ -416,11 +416,61 @@ stderr_last_error(char *msg)
|
|||
/* OS Allocation */
|
||||
/*****************/
|
||||
|
||||
static void zend_mm_munmap(void *addr, size_t size)
|
||||
{
|
||||
#ifdef _WIN32
|
||||
if (VirtualFree(addr, 0, MEM_RELEASE) == 0) {
|
||||
/** ERROR_INVALID_ADDRESS is expected when addr is not range start address */
|
||||
if (GetLastError() != ERROR_INVALID_ADDRESS) {
|
||||
#if ZEND_MM_ERROR
|
||||
stderr_last_error("VirtualFree() failed");
|
||||
#endif
|
||||
return;
|
||||
}
|
||||
SetLastError(0);
|
||||
|
||||
MEMORY_BASIC_INFORMATION mbi;
|
||||
if (VirtualQuery(addr, &mbi, sizeof(mbi)) == 0) {
|
||||
#if ZEND_MM_ERROR
|
||||
stderr_last_error("VirtualQuery() failed");
|
||||
#endif
|
||||
return;
|
||||
}
|
||||
addr = mbi.AllocationBase;
|
||||
|
||||
if (VirtualFree(addr, 0, MEM_RELEASE) == 0) {
|
||||
#if ZEND_MM_ERROR
|
||||
stderr_last_error("VirtualFree() failed");
|
||||
#endif
|
||||
}
|
||||
}
|
||||
#else
|
||||
if (munmap(addr, size) != 0) {
|
||||
#if ZEND_MM_ERROR
|
||||
fprintf(stderr, "\nmunmap() failed: [%d] %s\n", errno, strerror(errno));
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifndef HAVE_MREMAP
|
||||
static void *zend_mm_mmap_fixed(void *addr, size_t size)
|
||||
{
|
||||
#ifdef _WIN32
|
||||
return VirtualAlloc(addr, size, MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE);
|
||||
void *ptr = VirtualAlloc(addr, size, MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE);
|
||||
|
||||
if (ptr == NULL) {
|
||||
/** ERROR_INVALID_ADDRESS is expected when fixed addr range is not free */
|
||||
if (GetLastError() != ERROR_INVALID_ADDRESS) {
|
||||
#if ZEND_MM_ERROR
|
||||
stderr_last_error("VirtualAlloc() fixed failed");
|
||||
#endif
|
||||
}
|
||||
SetLastError(0);
|
||||
return NULL;
|
||||
}
|
||||
ZEND_ASSERT(ptr == addr);
|
||||
return ptr;
|
||||
#else
|
||||
int flags = MAP_PRIVATE | MAP_ANON;
|
||||
#if defined(MAP_EXCL)
|
||||
|
@ -431,15 +481,11 @@ static void *zend_mm_mmap_fixed(void *addr, size_t size)
|
|||
|
||||
if (ptr == MAP_FAILED) {
|
||||
#if ZEND_MM_ERROR && !defined(MAP_EXCL)
|
||||
fprintf(stderr, "\nmmap() failed: [%d] %s\n", errno, strerror(errno));
|
||||
fprintf(stderr, "\nmmap() fixed failed: [%d] %s\n", errno, strerror(errno));
|
||||
#endif
|
||||
return NULL;
|
||||
} else if (ptr != addr) {
|
||||
if (munmap(ptr, size) != 0) {
|
||||
#if ZEND_MM_ERROR
|
||||
fprintf(stderr, "\nmunmap() failed: [%d] %s\n", errno, strerror(errno));
|
||||
#endif
|
||||
}
|
||||
zend_mm_munmap(ptr, size);
|
||||
return NULL;
|
||||
}
|
||||
return ptr;
|
||||
|
@ -483,23 +529,6 @@ static void *zend_mm_mmap(size_t size)
|
|||
#endif
|
||||
}
|
||||
|
||||
static void zend_mm_munmap(void *addr, size_t size)
|
||||
{
|
||||
#ifdef _WIN32
|
||||
if (VirtualFree(addr, 0, MEM_RELEASE) == 0) {
|
||||
#if ZEND_MM_ERROR
|
||||
stderr_last_error("VirtualFree() failed");
|
||||
#endif
|
||||
}
|
||||
#else
|
||||
if (munmap(addr, size) != 0) {
|
||||
#if ZEND_MM_ERROR
|
||||
fprintf(stderr, "\nmunmap() failed: [%d] %s\n", errno, strerror(errno));
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
/***********/
|
||||
/* Bitmask */
|
||||
/***********/
|
||||
|
@ -682,13 +711,21 @@ static void *zend_mm_chunk_alloc_int(size_t size, size_t alignment)
|
|||
zend_mm_munmap(ptr, size);
|
||||
ptr = zend_mm_mmap(size + alignment - REAL_PAGE_SIZE);
|
||||
#ifdef _WIN32
|
||||
offset = ZEND_MM_ALIGNED_OFFSET(ptr, alignment);
|
||||
zend_mm_munmap(ptr, size + alignment - REAL_PAGE_SIZE);
|
||||
ptr = zend_mm_mmap_fixed((void*)((char*)ptr + (alignment - offset)), size);
|
||||
offset = ZEND_MM_ALIGNED_OFFSET(ptr, alignment);
|
||||
if (offset != 0) {
|
||||
zend_mm_munmap(ptr, size);
|
||||
return NULL;
|
||||
offset = alignment - offset;
|
||||
}
|
||||
zend_mm_munmap(ptr, size + alignment - REAL_PAGE_SIZE);
|
||||
ptr = zend_mm_mmap_fixed((void*)((char*)ptr + offset), size);
|
||||
if (ptr == NULL) { // fix GH-9650, fixed addr range is not free
|
||||
ptr = zend_mm_mmap(size + alignment - REAL_PAGE_SIZE);
|
||||
if (ptr == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
offset = ZEND_MM_ALIGNED_OFFSET(ptr, alignment);
|
||||
if (offset != 0) {
|
||||
ptr = (void*)((char*)ptr + alignment - offset);
|
||||
}
|
||||
}
|
||||
return ptr;
|
||||
#else
|
||||
|
@ -1847,11 +1884,7 @@ static zend_mm_heap *zend_mm_init(void)
|
|||
|
||||
if (UNEXPECTED(chunk == NULL)) {
|
||||
#if ZEND_MM_ERROR
|
||||
#ifdef _WIN32
|
||||
stderr_last_error("Can't initialize heap");
|
||||
#else
|
||||
fprintf(stderr, "\nCan't initialize heap: [%d] %s\n", errno, strerror(errno));
|
||||
#endif
|
||||
fprintf(stderr, "Can't initialize heap\n");
|
||||
#endif
|
||||
return NULL;
|
||||
}
|
||||
|
@ -2978,11 +3011,7 @@ ZEND_API zend_mm_heap *zend_mm_startup_ex(const zend_mm_handlers *handlers, void
|
|||
chunk = (zend_mm_chunk*)handlers->chunk_alloc(&tmp_storage, ZEND_MM_CHUNK_SIZE, ZEND_MM_CHUNK_SIZE);
|
||||
if (UNEXPECTED(chunk == NULL)) {
|
||||
#if ZEND_MM_ERROR
|
||||
#ifdef _WIN32
|
||||
stderr_last_error("Can't initialize heap");
|
||||
#else
|
||||
fprintf(stderr, "\nCan't initialize heap: [%d] %s\n", errno, strerror(errno));
|
||||
#endif
|
||||
fprintf(stderr, "Can't initialize heap\n");
|
||||
#endif
|
||||
return NULL;
|
||||
}
|
||||
|
@ -3025,11 +3054,7 @@ ZEND_API zend_mm_heap *zend_mm_startup_ex(const zend_mm_handlers *handlers, void
|
|||
if (!storage) {
|
||||
handlers->chunk_free(&tmp_storage, chunk, ZEND_MM_CHUNK_SIZE);
|
||||
#if ZEND_MM_ERROR
|
||||
#ifdef _WIN32
|
||||
stderr_last_error("Can't initialize heap");
|
||||
#else
|
||||
fprintf(stderr, "\nCan't initialize heap: [%d] %s\n", errno, strerror(errno));
|
||||
#endif
|
||||
fprintf(stderr, "Can't initialize heap\n");
|
||||
#endif
|
||||
return NULL;
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue