Description
Description
The following code:
https://github.com/php/php-src/blob/php-8.2.0RC6/TSRM/tsrm_win32.c#L613-L683
size_t size = 8192;
key_t key = IPC_PRIVATE; /* shm key */
oflag = IPC_CREAT | 0666;
if ((shmid = shmget(key, size, oflag)) < 0) {
zend_error_noreturn(E_CORE_ERROR, "shmget failed");
}
fprintf(stderr, "shmid %d\n", shmid);
Resulted in this output because nothing sets key
for IPC_PRIVATE:
shmid 0
But I expected this output instead:
shmid $distinct_nonzero_integer
If code calls shmget(IPC_PRIVATE) multiple times on Windows and gets IPC_PRIVATE as a result, applications would need distinct ids to distinguish them in operations managing the shared memory segments
- A symptom can be seen is that shmctl would fail to be set on the right shared memory segment because there are distinct segments with the same id of 0 https://github.com/php/php-src/blob/php-8.2.0RC6/TSRM/tsrm_win32.c#L722
- On linux with the real shmget() i'd get identifiers such as 3964933, 3964935 and pointers such as 0x7ff0dbe1f000, 0x7ff0eca55000 for multiple calls to fetch IPC_PRIVATE
Related to Bug in refactoring in PHP 8.2 Windows shmat() function #9829 - I believe TSRM/tsrm_win32.c for windows didn't attempt to support IPC_PRIVATE in PHP versions prior to that
Noticed while investigating krakjoe/apcu#445 when using more than one shared segment
if (flags & IPC_CREAT) {
shm_handle = CreateFileMapping(INVALID_HANDLE_VALUE, NULL, PAGE_READWRITE, high, low, key == IPC_PRIVATE ? NULL : shm_segment);
It seems like it should immediately choose a distinct id if key == IPC_PRIVATE
- it'd be clobbering the existing entry with the key 0, which would prevent detaching segments other than the most recent one created with IPC_PRIVATE
https://github.com/php/php-src/blob/php-8.2.0RC6/TSRM/tsrm_win32.c#L652-L657
https://man7.org/linux/man-pages/man2/shmget.2.html
RETURN VALUE [top](https://man7.org/linux/man-pages/man2/shmget.2.html#top_of_page)
On success, a valid shared memory identifier is returned. On
error, -1 is returned, and [errno](https://man7.org/linux/man-pages/man3/errno.3.html) is set to indicate the error.
DESCRIPTION
shmget() returns the identifier of the System V shared memory
segment associated with the value of the argument key. It may be
used either to obtain the identifier of a previously created
shared memory segment (when shmflg is zero and key does not have
the value IPC_PRIVATE), or to create a new set.
A new shared memory segment, with size equal to the value of size
rounded up to a multiple of PAGE_SIZE, is created if key has the
value IPC_PRIVATE or key isn't IPC_PRIVATE, no shared memory
segment corresponding to key exists, and IPC_CREAT is specified
in shmflg.
PHP Version
8.2. Possibly goes back to 7.4 for https://bugs.php.net/bug.php?id=79566 ?
Operating System
Windows