View Full Version : shmget returning invalid segment size specified

11-06-2006, 07:31 PM
My OS is Fedora Core 5. The shmget funtion generates a EINVAL error which indicates that a invalid segment size was specified. A review of the shmget docs indicates that a possible cause of this problem is that SHMMAX is set below the size of the data size. I checked the kernel.shmmax value using sysctl. It was set at 33,554,433. My shared_data_size variable contained 9,216,964, which is well below SHMMAX.

Anybody have any suggestions?

int getsharedmem(void)
int cam = 0;
long long shm_key=0x7a6d2000;
size_t shared_data_size = sizeof(SharedData) +
sizeof(TriggerData) +
((*monitor[cam]->image_buffer_count)*(sizeof(struct timeval))) +
int shmid;
printf("Failed to shmget error = %s\n",strerror(errno));
if(errno == EINVAL)
printf("Invalid segment size specified\n");
else if(errno == EEXIST)
printf("Segment exists, cannot create it\n");
else if(errno == EIDRM)
printf("Segment is marked for deletion or was removed\n");
else if(errno == ENOENT)
printf("Segment does not exist\n");
else if(errno == EACCES)
printf("Permission denied\n");
else if(errno == ENOMEM)
printf("Not enough memory to create segment\n");

printf("monitor[%d]->mon_id = %d shared_data_size = %d\n",cam, monitor[cam]->mon_id,shared_data_size);
// The above errno returns "Invalid argument"
fprintf(stderr,"ERROR: Failed to shmget\n");
return 0;

11-07-2006, 05:48 AM
Seems more likely that the reason for the failure is that the size you request is larger than the size of the existing segment. Any chance that your shared_data_size calculation is incorrect? Perhaps the original program was compiled with different compiler settings and thus has different values for any of the sizeofs?

11-07-2006, 06:38 AM
> ((*monitor[cam]->image_buffer_count)*(sizeof(struct timeval))) +
> ((*monitor[cam]->image_buffer_count)*(*monitor[cam]->width)*(*monitor[cam]->height)*3);
Maybe declare a few more local variables to allow you to simplify this (and debug it better)

foo = *monitor[cam];
( foo->image_buffer_count * sizeof(struct timeval))) +
( foo->image_buffer_count * foo->width * foo->height * 3 );

11-07-2006, 03:27 PM
I've simplified the code and I still can't see what the problem is...

int getsharedmem(void)
#define THREE 3

size_t shared_data_size;
size_t sizeofSharedData;
size_t sizeofTriggerData;
long monitorImageBufferCount;
size_t sizeofStructTimeval;
long monitorWidth;
long monitorHeight;
int shmid;

sizeofSharedData = sizeof(SharedData);
sizeofTriggerData = sizeof(TriggerData);
monitorImageBufferCount = *monitor[cam]->image_buffer_count;
sizeofStructTimeval = sizeof(struct timeval);
monitorWidth = *monitor[cam]->width;
monitorHeight = *monitor[cam]->height;
shared_data_size = sizeofSharedData + sizeofTriggerData + (monitorImageBufferCount * sizeofStructTimeval) +
((monitorImageBufferCount * monitorWidth) * (monitorHeight) * THREE);
if(errno == EINVAL)
printf("shmget returned EINVAL, ");
else if(errno == EEXIST)
printf("shmget returned EEXIST, ");
else if(errno == EIDRM)
printf("shmget returned EIDRM, ");
else if(errno == ENOENT)
printf("shmget returned ENOENT, ");
else if(errno == EACCES)
printf("shmget returned EACCES, ");
else if(errno == ENOMEM)
printf("shmget returned ENOMEM, ");
printf("cam = %d\n", cam);
printf("sizeofSharedData = %d\n", sizeofSharedData);
printf("sizeofTriggerData = %d\n",sizeofTriggerData);
printf("monitorImageBufferCount = %ld\n", monitorImageBufferCount);
printf("sizeofSructTimveval = %d\n", sizeofStructTimeval);
printf("monitorWidth = %ld\n", monitorWidth);
printf("monitorHeight = %ld\n", monitorHeight);
printf("shared_data_size = %u\n", shared_data_size);
return 0;

and the output is :

shmget returned EINVAL, Invalid argument
cam = 0
sizeofSharedData = 312
sizeofTriggerData = 332
monitorImageBufferCount = 40
sizeofSructTimveval = 8
monitorWidth = 320
monitorHeight = 240
shared_data_size = 9216964

11-07-2006, 07:13 PM
After googling for a while, I found some info on a HP Unix site

32-bit applications can only attach to shared memory segments which exist in a 32-bit virtual address space. To create a memory segment that can be shared between 32-bit and 64-bit applications, the 64-bit application must specify the IPC_SHARE32 flag with the IPC_CREAT flag when invoking shmget(2).The IPC_SHARE32 flag causes the shared memory segment to be created in a 32-bit address space.
Thus, it dawned on me that my 64 bit AMD processor may be the source of the problem.

I could not find IPC_SHARE32 defined. So, I defined it as 001000 which I found in some obscure HP documentation. But using IPC_CREAT and IPC_SHARE32 still did not resolve the problem. I've also tried using a -m32 gcc compiler switch to force a 32 bit compile. This also, did not work.

jim mcnamara
11-08-2006, 05:15 AM
You're not on a PA RISC platform - what you saw is HPUX-dependant. IPC_SHARE32 was not defined, as you said.

From the manpage:
A new segment was to be created and size < SHMMIN or size > SHMMAX, or no new segment was to be created, a segment with given key existed, but size is greater than the size of that segment.

As Salem indicated - something in your variables has a problem. Did you go into debug and check during runtime the actual value of shared_data_size?

How you derive the number looks completely arbitrary to me. In other words do you have some alternative way of directly verifying how you got your number?

11-08-2006, 06:39 PM
The problem has been resolved.

First of all, this is an application that captures and displays a video stream from a ZoneMinder video server. The app resides and runs locally on the back end server. Another user on the ZM forum asked me if I was using the FC5 64 bit Libs and includes. My reply was "What 64 bit libs?". I then realized that I used FC 5 distro CD's from a previous install on a PII (32 bit) machine to install FC5 on my 64 bit AMD machine. I downloaded FC5 64 bit distro and installed it. The app now compiles and runs fine.

Thanx Jim, Salem, CornedBee for working with me on this one even though it was one of those dumb end user errors.