Closed StevenLevine closed 3 years ago
Steven, great report! Should be easy to fix, will look at it soon.
Appears that I fixed this back in 2020 while working for Chromium, see 09b0eaa459fe7b3f2c61eb670d8f56c8c0a29ad2.
Closing. Feel free to reopen if the problem reappears.
Also linking this to #75 and #76 which are related.
This issue was detected while porting php 7.x. The external symptoms are that a libcx assertion fails with:
Opened log at 2019-09-07 19:59:50.59 Process ID: 0x2b45 (11077) Parent PID: 0x1b (27) Type: 2 Exe hmte : 0x245e (D:\INTERNET\PHP7\PHP.EXE) First arg : D:\Internet\php7\php.exe Second arg: -c ./php7.ini --version Cur dir : D:\Internet\php7 CRT Module: LIBCN0 hmod=0xe23 (D:\USR\LIB\LIBCN0.DLL) __libc_logInit: addr 0x1d2850ed iObj=0 offObj=0x450ed Millsecond Timestamp. | Thread ID. | | Call Nesting Level. | | | Log Group. | | | | Message Type. | | | | | errno in hex (0xface if not available). | | | | | | Function Name. | | | | | | | Millisconds In function (Optional). v v v v v v v v xxxxxxxx tt nn gggg dddd eeee function [(ms)]: message LIBCx version : 0.6.6 LIBCx module : D:\USR\LIB\LIBCX0.DLL (hmod=2bc6) 1a93197f 01 ff 0000 Asrt: Assertion Failed!!! 1a93197f 01 ff 0000 Asrt: Function:
1a93197f 01 ff 0000 Asrt: File: D:/Users/dmik/rpmbuild/BUILD/libcx-0.6.6/src/mmap/mmap.c
1a93197f 01 ff 0000 Asrt: Line: 1257
1a93197f 01 ff 0000 Asrt: Expr: arc == NO_ERROR
1a93197f 01 ff 0000 Asrt: 487
The reason the assertion triggered is because DosFreeMem was asked free a block that was not allocated by DosAllocMem
php's zend wants a 2MB object aligned on a 2MB boundary for its private heap, so it does:
0x21030000 = mmap(0x200000)
However since this address is not on a 2MB boundary, php unmaps the object with
munmap(0x21030000, 0x200000)
and allocates a 2MB + 2MB - 4KB object with
0x21030000 = mmap(0x3FF000)
and calculates the aligned address of the aligned heap object within the allocated object as
0x21200000
Next php unmaps the memory before the object with
munmap(0x21030000, 0x1D0000)
and unmaps the memory after the object with
munmap(0x21400000, 0x2F000)
The result is a usable 2MB aligned heap object starting at 0x21200000.
Everything is fine until php attempts to shut down. The destructor attempts to unmap the aligned 2MB heap with
munmap(0x21200000,0x200000)
and libcx notices that the ref count has gone to zero and attempts to free the allocated memory with
DosFreeMem(0x21200000)
The fails with error 487 because this is not the correct address. Libcx should have freed the allocated memory with
DosFreeMem(0x21030000)
because this was the address returned by the original DosAllocMem.