Bug on Posix IPC_STAT. Wrong number of attachments

tcak via Digitalmars-d-learn digitalmars-d-learn at puremagic.com
Sun Jan 18 08:06:37 PST 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




More information about the Digitalmars-d-learn mailing list