Thread overview
Bug on Posix IPC_STAT. Wrong number of attachments
Jan 18, 2015
tcak
Jan 18, 2015
tcak
Jan 18, 2015
anonymous
Jan 19, 2015
tcak
Jan 19, 2015
tcak
Jan 19, 2015
Mike Parker
Jan 19, 2015
anonymous
January 18, 2015
I create a shared memory by using shmget. And attach to it by using shmat.

Finally, I use shmctl to get statistics to learn number of attachments to
that shared memory. According to documentation (linux.die.net/man/2/shmat), number of attachments should be 1.

Same codes, C returns 1, D returns 0. It took me 2 days until realising this.

I put C and D codes, and makefile for quick testing.

Ubuntu 64-bit. Kernel: 3.13.0-44-generic

I checked the shmid_ds at both "core.sys.posix.sys.shm" and "/usr/include/bits/shm.h". They look similar. Although C definition makes a difference based on 32 and 64 bits, D's definition doesn't care about. Because I am on 64-bit kernel, they should be same.



main.c
==========================
#include <stdio.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <fcntl.h>

void main(){
	// allocate
	int id = shmget( IPC_PRIVATE, 4096, IPC_CREAT | S_IRUSR | S_IWUSR );

	// if failed, leave
	if( id == -1 ){
		printf("shmget failed\n");
		return;
	}

	// attach
	void* ptr = shmat( id, 0, 0 );

	// if failed, leave
	if( ptr == (void*)-1 ){
		printf("shmat failed\n");
		shmctl( id, IPC_RMID, 0 );
		return;
	}

	// stat
	struct shmid_ds stat;

	// get statistics
	int res = shmctl( id, IPC_STAT, &stat );
	printf("STAT: %d\n", res);

	// get number of attachments
	printf("NATTCH: %d\n", (unsigned short)stat.shm_nattch);

	// detach
	shmdt( ptr );

	// remove
	shmctl( id, IPC_RMID, 0 );
}


main.d
===============================
import std.stdio;

private import core.sys.posix.sys.mman;
private import core.sys.posix.sys.shm;
private import core.sys.posix.unistd;
private import core.sys.posix.sys.stat;
private static import core.stdc.errno;
private static import core.stdc.time;

void main(){
	// allocate
	int id = shmget( IPC_PRIVATE, 4096, IPC_CREAT | S_IRUSR | S_IWUSR );

	// if failed, leave
	if( id == -1 ){
		writeln("shmget failed");
		return;
	}

	// attach
	void* ptr = shmat( id, null, 0 );

	// if failed, leave
	if( ptr == cast(void*)-1 ){
		writeln("shmat failed");
		shmctl( id, IPC_RMID, null );
		return;
	}

	// stat
	shmid_ds stat;

	// get statistics
	int res = shmctl( id, IPC_STAT, &stat );
	writeln("STAT: ", res);

	// get number of attachments
	writeln("NATTCH: ", stat.shm_nattch);

	// detach
	shmdt( ptr );

	// remove
	shmctl( id, IPC_RMID, null );
}



makefile
==============================
all:
	dmd main.d -of"dprog"
	gcc main.c -o cprog

clear:
	rm cprog
	rm dprog


January 18, 2015
On Sunday, 18 January 2015 at 16:06:39 UTC, tcak wrote:
> I create a shared memory by using shmget. And attach to it by using shmat.
>
> Finally, I use shmctl to get statistics to learn number of attachments to
> that shared memory. According to documentation (linux.die.net/man/2/shmat), number of attachments should be 1.
>
> Same codes, C returns 1, D returns 0. It took me 2 days until realising this.
>
> I put C and D codes, and makefile for quick testing.
>
> Ubuntu 64-bit. Kernel: 3.13.0-44-generic
>
> I checked the shmid_ds at both "core.sys.posix.sys.shm" and "/usr/include/bits/shm.h". They look similar. Although C definition makes a difference based on 32 and 64 bits, D's definition doesn't care about. Because I am on 64-bit kernel, they should be same.
>
>
>
> main.c
> ==========================
> #include <stdio.h>
> #include <sys/types.h>
> #include <sys/ipc.h>
> #include <sys/shm.h>
> #include <fcntl.h>
>
> void main(){
> 	// allocate
> 	int id = shmget( IPC_PRIVATE, 4096, IPC_CREAT | S_IRUSR | S_IWUSR );
>
> 	// if failed, leave
> 	if( id == -1 ){
> 		printf("shmget failed\n");
> 		return;
> 	}
>
> 	// attach
> 	void* ptr = shmat( id, 0, 0 );
>
> 	// if failed, leave
> 	if( ptr == (void*)-1 ){
> 		printf("shmat failed\n");
> 		shmctl( id, IPC_RMID, 0 );
> 		return;
> 	}
>
> 	// stat
> 	struct shmid_ds stat;
>
> 	// get statistics
> 	int res = shmctl( id, IPC_STAT, &stat );
> 	printf("STAT: %d\n", res);
>
> 	// get number of attachments
> 	printf("NATTCH: %d\n", (unsigned short)stat.shm_nattch);
>
> 	// detach
> 	shmdt( ptr );
>
> 	// remove
> 	shmctl( id, IPC_RMID, 0 );
> }
>
>
> main.d
> ===============================
> import std.stdio;
>
> private import core.sys.posix.sys.mman;
> private import core.sys.posix.sys.shm;
> private import core.sys.posix.unistd;
> private import core.sys.posix.sys.stat;
> private static import core.stdc.errno;
> private static import core.stdc.time;
>
> void main(){
> 	// allocate
> 	int id = shmget( IPC_PRIVATE, 4096, IPC_CREAT | S_IRUSR | S_IWUSR );
>
> 	// if failed, leave
> 	if( id == -1 ){
> 		writeln("shmget failed");
> 		return;
> 	}
>
> 	// attach
> 	void* ptr = shmat( id, null, 0 );
>
> 	// if failed, leave
> 	if( ptr == cast(void*)-1 ){
> 		writeln("shmat failed");
> 		shmctl( id, IPC_RMID, null );
> 		return;
> 	}
>
> 	// stat
> 	shmid_ds stat;
>
> 	// get statistics
> 	int res = shmctl( id, IPC_STAT, &stat );
> 	writeln("STAT: ", res);
>
> 	// get number of attachments
> 	writeln("NATTCH: ", stat.shm_nattch);
>
> 	// detach
> 	shmdt( ptr );
>
> 	// remove
> 	shmctl( id, IPC_RMID, null );
> }
>
>
>
> makefile
> ==============================
> all:
> 	dmd main.d -of"dprog"
> 	gcc main.c -o cprog
>
> clear:
> 	rm cprog
> 	rm dprog


Here is what I did to solve the problem. In D code, I defined my own shmid_ds struct (Structure is taken from /usr/include/bits/shm.h)

// from /usr/include/bits/shm.h
/* Type to count number of attaches.  */
alias shmatt_t = c_ulong;

/* Data structure describing a shared memory segment.  */
version( X86_64 ){
	struct my_shmid_ds{
	    ipc_perm shm_perm;		/* operation permission struct */
	    size_t shm_segsz;			/* size of segment in bytes */
	    time_t shm_atime;			/* time of last shmat() */
	    time_t shm_dtime;			/* time of last shmdt() */
	    time_t shm_ctime;			/* time of last change by shmctl() */
	    pid_t shm_cpid;			/* pid of creator */
	    pid_t shm_lpid;			/* pid of last shmop */
	    shmatt_t shm_nattch;		/* number of current attaches */
	    c_ulong __glibc_reserved4;
	    c_ulong __glibc_reserved5;
	};
}
else{
	struct my_shmid_ds{
	    ipc_perm shm_perm;		/* operation permission struct */
	    size_t shm_segsz;			/* size of segment in bytes */
	    time_t shm_atime;			/* time of last shmat() */
	    c_ulong __glibc_reserved1;
	    time_t shm_dtime;			/* time of last shmdt() */
	    c_ulong __glibc_reserved2;
	    time_t shm_ctime;			/* time of last change by shmctl() */
	    c_ulong __glibc_reserved3;
	    pid_t shm_cpid;			/* pid of creator */
	    pid_t shm_lpid;			/* pid of last shmop */
	    shmatt_t shm_nattch;		/* number of current attaches */
	    c_ulong __glibc_reserved4;
	    c_ulong __glibc_reserved5;
	};
}



Then, I changed the type of "stat" variable:

my_shmid_ds stat;



Finally, need to do a casting (Doing this came to me so stupid after writing it in C):

int res = shmctl( id, IPC_STAT, cast( core.sys.posix.sys.shm.shmid_ds* )(&stat) );


After these, it works perfectly. I hope this can be fixed in next version.
January 18, 2015
On Sunday, 18 January 2015 at 18:07:05 UTC, tcak wrote:
> After these, it works perfectly. I hope this can be fixed in next version.

Please file a bug at <https://issues.dlang.org/>. And since you seem to know how to fix it, maybe you can make a pull request via GitHub, too?
January 19, 2015
On Sunday, 18 January 2015 at 22:25:39 UTC, anonymous wrote:
> On Sunday, 18 January 2015 at 18:07:05 UTC, tcak wrote:
>> After these, it works perfectly. I hope this can be fixed in next version.
>
> Please file a bug at <https://issues.dlang.org/>. And since you seem to know how to fix it, maybe you can make a pull request via GitHub, too?

https://issues.dlang.org/show_bug.cgi?id=14007

I am not familiar with Github's pull system etc. So, I will prepare the fixed code and attach it on issue.
January 19, 2015
On Monday, 19 January 2015 at 04:18:47 UTC, tcak wrote:
> On Sunday, 18 January 2015 at 22:25:39 UTC, anonymous wrote:
>> On Sunday, 18 January 2015 at 18:07:05 UTC, tcak wrote:
>>> After these, it works perfectly. I hope this can be fixed in next version.
>>
>> Please file a bug at <https://issues.dlang.org/>. And since you seem to know how to fix it, maybe you can make a pull request via GitHub, too?
>
> https://issues.dlang.org/show_bug.cgi?id=14007
>
> I am not familiar with Github's pull system etc. So, I will prepare the fixed code and attach it on issue.

Fixed shm.d file is put on issue page. If someone could put a pull request on Github with it.

shmid_ds is on version(linux) part is fixed up on it, and works properly. But tested on 64-bit system only.
January 19, 2015
On 1/19/2015 2:35 PM, tcak wrote:
> On Monday, 19 January 2015 at 04:18:47 UTC, tcak wrote:
>> On Sunday, 18 January 2015 at 22:25:39 UTC, anonymous wrote:
>>> On Sunday, 18 January 2015 at 18:07:05 UTC, tcak wrote:
>>>> After these, it works perfectly. I hope this can be fixed in next
>>>> version.
>>>
>>> Please file a bug at <https://issues.dlang.org/>. And since you seem
>>> to know how to fix it, maybe you can make a pull request via GitHub,
>>> too?
>>
>> https://issues.dlang.org/show_bug.cgi?id=14007
>>
>> I am not familiar with Github's pull system etc. So, I will prepare
>> the fixed code and attach it on issue.
>
> Fixed shm.d file is put on issue page. If someone could put a pull
> request on Github with it.
>

https://help.github.com/articles/creating-a-pull-request/

January 19, 2015
On Monday, 19 January 2015 at 05:35:46 UTC, tcak wrote:
> Fixed shm.d file is put on issue page. If someone could put a pull request on Github with it.
>
> shmid_ds is on version(linux) part is fixed up on it, and works properly. But tested on 64-bit system only.

Aand it's in: https://github.com/D-Programming-Language/druntime/commit/43199cdb8fa302613ba9f1dd48646083a85cb272