Thread: shmget returning invalid segment size specified

  1. #1
    Registered User
    Join Date
    Mar 2005
    Location
    Mountaintop, Pa
    Posts
    1,058

    shmget returning invalid segment size specified

    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?

    Code:
    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))) +
                                      ((*monitor[cam]->image_buffer_count)*(*monitor[cam]->width)*(*monitor[cam]->height)*3);
            int shmid;
            if((shmid=shmget((shm_key&0xffffff00)|monitor[cam]->mon_id,shared_data_size,SHM_R))==-1)
            {
                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 EXIT_FAILURE;
             }
    return 0;
    }

  2. #2
    Cat without Hat CornedBee's Avatar
    Join Date
    Apr 2003
    Posts
    8,895
    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?
    All the buzzt!
    CornedBee

    "There is not now, nor has there ever been, nor will there ever be, any programming language in which it is the least bit difficult to write bad code."
    - Flon's Law

  3. #3
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,656
    > ((*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)

    Say
    foo = *monitor[cam];
    ( foo->image_buffer_count * sizeof(struct timeval))) +
    ( foo->image_buffer_count * foo->width * foo->height * 3 );
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

  4. #4
    Registered User
    Join Date
    Mar 2005
    Location
    Mountaintop, Pa
    Posts
    1,058
    I've simplified the code and I still can't see what the problem is...

    Code:
    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((shmid=shmget((shm_key&0xffffff00)|monitor[cam]->mon_id,shared_data_size,SHM_R))==-1)
        {
            printf("Dump:\n");
            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("%s\n",strerror(errno));
            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 EXIT_FAILURE;
        }
        return 0;
    }
    and the output is :
    Code:
    Dump:
    shmget returned EINVAL, Invalid argument
    cam = 0
    sizeofSharedData = 312
    sizeofTriggerData = 332
    monitorImageBufferCount = 40
    sizeofSructTimveval = 8
    monitorWidth = 320
    monitorHeight = 240
    shared_data_size = 9216964

  5. #5
    Registered User
    Join Date
    Mar 2005
    Location
    Mountaintop, Pa
    Posts
    1,058
    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.

  6. #6
    .
    Join Date
    Nov 2003
    Posts
    307
    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:
    EINVAL
    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?

  7. #7
    Registered User
    Join Date
    Mar 2005
    Location
    Mountaintop, Pa
    Posts
    1,058
    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.
    Last edited by BobS0327; 11-09-2006 at 06:06 AM.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Returning the file size
    By mmondok in forum C Programming
    Replies: 1
    Last Post: 03-02-2003, 06:05 PM
  2. Changing a Structures Members array size
    By Xei in forum C++ Programming
    Replies: 1
    Last Post: 11-07-2002, 07:45 PM
  3. shmget function
    By clancyPC in forum C Programming
    Replies: 5
    Last Post: 06-19-2002, 10:47 AM
  4. Tab Controls - API
    By -KEN- in forum Windows Programming
    Replies: 7
    Last Post: 06-02-2002, 09:44 AM
  5. File Size and File Size on Disk
    By DavidP in forum A Brief History of Cprogramming.com
    Replies: 4
    Last Post: 12-15-2001, 08:03 PM