|
php.net | support | documentation | report a bug | advanced search | search howto | statistics | random bug | login |
[2018-11-23 14:08 UTC] svbussww at 126 dot com
Description: ------------ php - 7.2.12 php - 7.3.0RC5 php.ini No extensions are turned on Test script: --------------- Test script http://jxcraft.net/Test.zip, VC12 Project, php7ts.dll From https://windows.php.net/download/ ,not actually working, because I've cutted some parts from working project. Script works from time to time and crashes very often. Actual result: -------------- Can't initialize heap: [0x000001e7] Attempt to access invalid address. Problem event name: APPCRASH Application Name: Test.exe Application version: 0.0.0.0 Application time stamp: 5bf4612b Fault module name: php7ts.dll Fault module version: 7.2.12.0 Fault module timestamp: 5be3d4fd Exception code: c0000005 Abnormal offset: 000000000001f648 Operating system version: 6.1.7601.2.1.0.256.1 Locale ID: 2052 Other information 1: e3c7 Additional information 2: e3c7d0ab13feedaa62f1ab674aea779c Additional information 3: ffa7 Additional information 4: ffa7101e299bb1a426430e84b351f5c2 PatchesFix-Multi-Thread-Allocation-Alignment-Memory-Failure (last revision 2018-11-29 16:46 UTC by svbussww at 126 dot com)Pull RequestsHistoryAllCommentsChangesGit/SVN commits
|
|||||||||||||||||||||||||||||||||||||
Copyright © 2001-2025 The PHP GroupAll rights reserved. |
Last updated: Sat Nov 01 17:00:02 2025 UTC |
The problem persists after using the standard method Environment is Windows 7 SP1 + VS2017 Enterprise Test code DWORD WINAPI ThreadProc(LPVOID lpParameter) { ts_resource(0); ts_free_thread(); return 0; } int main(){ php_embed_init(0, NULL); for (;;){ HANDLE Thread = CreateThread(NULL, 0, ThreadProc, NULL, 0, NULL); if (Thread != NULL) CloseHandle(Thread); } php_embed_shutdown(); return 0; } Debug Problem event name: APPCRASH Application Name: Test.exe Application version: 0.0.0.0 Application timestamp: 5bfc6f7c Fault module name: php7ts.dll Fault module version: 7.2.12.0 Fault module timestamp: 5be3d4fd Exception code: c0000005 Abnormal offset: 000000000001f648 OS version: 6.1.7601.2.1.0.256.1 Locale ID: 2052 Other information 1:e3c7 Additional information 2:e3c7d0ab13feedaa62f1ab674aea779c Other information 3: db03 Other information 4: db03925cc4db17c3dff9789e6103f141 Can't initialize heap: [0x000001e7] Attempt to access invalid address. Exception thrown at 0x000007FEEAD5F648 (in php7ts.dll) (in Test.exe): 0xC0000005: An access violation occurred while reading location 0x0000000000000000. Stack php7ts.dll!_emalloc(unsigned __int64 size) Line 2425 php7ts.dll!cwd_globals_ctor(_virtual_cwd_globals * cwd_g) Line 391 php7ts.dll!allocate_new_resource(_tsrm_tls_entry * * thread_resources_ptr, unsigned long thread_id) Line 315 php7ts.dll!ts_resource_ex(int id, unsigned long * th_id) Line 395 Test.exe!ThreadProc(void * lpParameter) Line 9The bug has been found file Zend/zend_alloc.c function zend_mm_chunk_alloc_int zend_mm_mmap After not aligned zend_mm_mmap_fixed Call failed is return 0 The cause of the bug zend_mm_mmap The allocated memory address is released. In the case of multithreading, it may be preempted by other threads. This causes the subsequent zend_mm_mmap_fixed function to allocate memory and cause the program to crash. Temporary solution static void *zend_mm_chunk_alloc_int(size_t size, size_t alignment) { LOOP:; void *ptr = zend_mm_mmap(size); if (ptr == NULL) { return NULL; } else if (ZEND_MM_ALIGNED_OFFSET(ptr, alignment) == 0) { #ifdef MADV_HUGEPAGE madvise(ptr, size, MADV_HUGEPAGE); #endif return ptr; } else { size_t offset; /* chunk has to be aligned */ 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); if(ptr == NULL) goto LOOP; offset = ZEND_MM_ALIGNED_OFFSET(ptr, alignment); if (offset != 0) { zend_mm_munmap(ptr, size); return NULL; } return ptr; #else offset = ZEND_MM_ALIGNED_OFFSET(ptr, alignment); if (offset != 0) { offset = alignment - offset; zend_mm_munmap(ptr, offset); ptr = (char*)ptr + offset; alignment -= offset; } if (alignment > REAL_PAGE_SIZE) { zend_mm_munmap((char*)ptr + size, alignment - REAL_PAGE_SIZE); } # ifdef MADV_HUGEPAGE madvise(ptr, size, MADV_HUGEPAGE); # endif #endif return ptr; } } I hope the development team can solve this bug as soon as possible.Fix the temporary plan static void *zend_mm_chunk_alloc_int(size_t size, size_t alignment) { void *ptr = zend_mm_mmap(size); if (ptr == NULL) { return NULL; } else if (ZEND_MM_ALIGNED_OFFSET(ptr, alignment) == 0) { #ifdef MADV_HUGEPAGE madvise(ptr, size, MADV_HUGEPAGE); #endif return ptr; } else { size_t offset; /* chunk has to be aligned */ zend_mm_munmap(ptr, size); LOOP:; ptr = zend_mm_mmap(size + alignment - REAL_PAGE_SIZE); if (ptr == NULL) return NULL; #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); if(ptr == NULL) goto LOOP; offset = ZEND_MM_ALIGNED_OFFSET(ptr, alignment); if (offset != 0) { zend_mm_munmap(ptr, size); return NULL; } return ptr; #else offset = ZEND_MM_ALIGNED_OFFSET(ptr, alignment); if (offset != 0) { offset = alignment - offset; zend_mm_munmap(ptr, offset); ptr = (char*)ptr + offset; alignment -= offset; } if (alignment > REAL_PAGE_SIZE) { zend_mm_munmap((char*)ptr + size, alignment - REAL_PAGE_SIZE); } # ifdef MADV_HUGEPAGE madvise(ptr, size, MADV_HUGEPAGE); # endif #endif return ptr; } }