www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - Bug on Posix IPC_STAT. Wrong number of attachments

reply "tcak" <tcak gmail.com> writes:
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
Jan 18 2015
parent reply "tcak" <tcak gmail.com> writes:
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.
Jan 18 2015
parent reply "anonymous" <anonymous example.com> writes:
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?
Jan 18 2015
parent reply "tcak" <tcak gmail.com> writes:
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.
Jan 18 2015
parent reply "tcak" <tcak gmail.com> writes:
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.
Jan 18 2015
next sibling parent Mike Parker <aldacron gmail.com> writes:
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/
Jan 18 2015
prev sibling parent "anonymous" <anonymous example.com> writes:
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
Jan 19 2015