Thread: problem with sending array of struct over shared memory

  1. #1
    Registered User
    Join Date
    May 2008
    Posts
    14

    problem with sending array of struct over shared memory

    First of all, Hello to the comunity!
    I hope someone will be able to help or at least give me some hint/guide on what I'm doing wrong here.
    Here is the code:
    Code:
    #include <stdlib.h>
    #include <stdio.h>
     
    #include <sys/types.h>
    #include <sys/ipc.h>
    #include <sys/shm.h>
     
    #define KEY (5679)
     
    typedef struct _command
    {
            int x;
            int y;
            int xo;
            int yo;
            int lock;
    } command[20];
     
    main ()
    {
            int shmid, shmkeyid, i, size;
            command *tuio_cmd;
            size = sizeof( *tuio_cmd);
     
            shmid = shmget (KEY, size, 0666 | IPC_CREAT);
            if (shmid != -1)
            {
                    tuio_cmd = shmat (shmid, NULL, 0);
                    if (tuio_cmd != (void *) -1)
                    {
                            printf ("Memory attached at:%X size:%d\n", (int) tuio_cmd, size);
                            tuio_cmd[0]->lock = 0;
                            while (1)
                            {
                                    if (tuio_cmd[0]->lock)
                                    {
                                    if (tuio_cmd[0]->xo != 0)
                                            for( i=0; i<20; i++ )
                                                    printf ("X:%d,Y:%d,Xo:%d,Yo:%d\n", tuio_cmd[i]->x,tuio_cmd[i]->y, tuio_cmd[i]->xo, tuio_cmd[i]->yo);
                                    else
                                            for( i=0; i<20; i++ )
                                                    printf ("X:%d,Y:%d\n", tuio_cmd[i]->x,tuio_cmd[i]->y);
     
                                    tuio_cmd[0]->lock = 0;
                                    }
                            }
                            if (shmdt (tuio_cmd) == -1)
                            {
                                    fprintf (stderr, "shmdt failed\n");
                                    exit (EXIT_FAILURE);
                            }
                            if (shmctl (shmid, IPC_RMID, 0) == -1)
                            {
                                    fprintf (stderr, "shmctl(IPC_RMID) failed\n");
                                    exit (EXIT_FAILURE);
                            }
                    }
            else fprintf(stdout,"error attaching memory\n");
            }
            else fprintf(stdout,"error in allocating shm\n");
            return 0;
    }
    I'm trying to send array of struct over the shared memory, and after all day I can't find why this won't work. (don't look at locking It's remaining of old one dimensional struct, I still need to implement semaphores)

  2. #2
    Registered User
    Join Date
    Apr 2008
    Posts
    396
    What are you expecting exactly? your shared segment seems to be created correctly.
    After that, there is an infinite loop due to the 'tuio_cmd[0]->lock' condition never satisfied
    (or is it unlocked by another process? in this case, the code is missing)

  3. #3
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    There is also no guarantee that the compiler will re-read lock here:
    Code:
                            while (1)
                            {
                                    if (tuio_cmd[0]->lock)
                                    {
                                    if (tuio_cmd[0]->xo != 0)
                                            for( i=0; i<20; i++ )
                                                    printf ("X:%d,Y:%d,Xo:%d,Yo:%d\n", tuio_cmd[i]->x,tuio_cmd[i]->y, tuio_cmd[i]->xo, tuio_cmd[i]->yo);
                                    else
                                            for( i=0; i<20; i++ )
                                                    printf ("X:%d,Y:%d\n", tuio_cmd[i]->x,tuio_cmd[i]->y);
     
                                    tuio_cmd[0]->lock = 0;
                                    }
                            }
    Making the struct, or the lock member into a "volatile" should make the compiler re-read the data as needed.

    --
    Mats
    Compilers can produce warnings - make the compiler programmers happy: Use them!
    Please don't PM me for help - and no, I don't do help over instant messengers.

  4. #4
    Registered User
    Join Date
    May 2008
    Posts
    14
    Thanks for trying to help, I posted this code also on the irc C channel and there I take a laugh from some ppl. That confused me totally, as now after trying to do this for all day I'm not sure even If I wrote one single line correct. The thing is that this used to be my first atempt of sending some "tuio" commands over the shared memory with struct (single, no array, and it worked btw). That's why there is lock still there, and I didn't even try to change that as I'm stuck here: tuio_cmd = shmat (shmid, NULL, 0);
    I'm not sure if I did that right .. so plz don't look at the program logic, It's not that what is giving me headache. It seams that I can't get 20 arrays of struct this way, as only first (to say this way [0]) array is parsed ok. Right now I'm really tired and my head hearts, so I'm not even sure which version of code I posted,as I changed every single bit at least 10 times. I'll post toomorrow more precise and clean code, with client side too. Anyway I need to know If I'm not doing some "stupid" mistake in getting the struct out of shm.
    thnx again in advance
    Last edited by jet-plane; 05-07-2008 at 04:45 PM.

  5. #5
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    It's hard to say if you are doing something wrong or not, since we don't see the other half, which I expect it the part that actually fills in the shared memory.

    --
    Mats
    Compilers can produce warnings - make the compiler programmers happy: Use them!
    Please don't PM me for help - and no, I don't do help over instant messengers.

  6. #6
    Registered User
    Join Date
    May 2008
    Posts
    14
    hmm here is the other half, and to repeat myself .. the lock is there just for the moment, as I wanted to try if it's working.

    Code:
    #include <stdlib.h>
    #include <stdio.h>
    
    #include <sys/types.h>
    #include <sys/ipc.h>
    #include <sys/shm.h>
    
    #define KEY (5679)
    
    typedef struct _command
    {
    	int x;
    	int y;
    	int xo;
    	int yo;
    	int lock;
    } command[20], *command_ptr;
    
    main ()
    {
    	int shmid, *shm_ptr, i, size;
    	command *tuio_cmd;
    	size = sizeof( *tuio_cmd);
    
    	shmid = shmget (KEY, size, 0666 | IPC_CREAT);
    	if (shmid != -1)
    	{
    		shm_ptr = shmat (shmid, NULL, 0);
    		tuio_cmd = *shm_ptr;
    		if (tuio_cmd != (void *) -1)
    		{
    			for( i=0; i<20; i++ )
    				{
    				tuio_cmd[i]->lock = 1;
    				tuio_cmd[i]->x = i;
    				tuio_cmd[i]->y = i;
    				tuio_cmd[i]->x = i;
    				tuio_cmd[i]->y = i;
    				}
    		}
    	else fprintf(stdout,"error attaching memory\n");
    	}
    	else fprintf(stdout,"error in allocating shm\n");
    return 0;
    }
    Actually this part I wrote just to test the fist program, as I'll send the data with python script. And to be more sure I'm not doing some python mistake I tried this way also. But with no luck. Here is also a simple python implementation of how I intend to send the data :

    Code:
    import shm
    import sys
    import ctypes
    class comm(ctypes.Structure):
        _fields_ = [
    	    ('x',ctypes.c_int),
    	    ('y',ctypes.c_int),
    	    ('xo',ctypes.c_int),
    	    ('yo',ctypes.c_int),
    	    ('lock',ctypes.c_int)
        ]
    x = int(sys.argv[1])
    y = int(sys.argv[2])
    if len(sys.argv) >3:
        xo = int(sys.argv[3])
        yo = int(sys.argv[4])
    key = 5679
    mem = shm.memory(shm.getshmid(key))
    mem.attach()
    comm_array_class = comm * 20
    an_array = comm_array_class()
    if len(sys.argv) >3:
        #kom=comm(x=x,y=y,xo=xo,yo=yo,lock=1)
        for i in range(20):
    	    an_array[i].x = x
                an_array[i].y = y
                an_array[i].xo = xo
    	    an_array[i].yo = yo
    	    an_array[i].lock = 1
        mem.write(an_array)
        print "Sent:",x,y,xo,yo;
    else:
        for i in range(20):
    	    an_array[i].x = x
                an_array[i].y = y
    	    an_array[i].lock = 1
        mem.write(an_array)

  7. #7
    Registered User
    Join Date
    Apr 2008
    Posts
    396
    I'm stuck here: tuio_cmd = shmat (shmid, NULL, 0);
    I'm not sure if I did that right ..
    What error do you get exactly? I pass this point when I try your code and enter the loop.

  8. #8
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    And what output do you get?

    By the way:
    Code:
    tuio_cmd[0]->xo != 0
    will always be true for this code:
    Code:
    			for( i=0; i<20; i++ )
    				{
    				tuio_cmd[i]->lock = 1;
    				tuio_cmd[i]->x = i;
    				tuio_cmd[i]->y = i;
    				tuio_cmd[i]->x = i;
    				tuio_cmd[i]->y = i;
    				}
    Even if you change code to set xo and yo, the first array element (indexed with [0]) will sitll be zero. Since that's one condition in the midst of your "while-loop", it may affect what you see and how that corresponds to what you expect?

    --
    Mats
    Compilers can produce warnings - make the compiler programmers happy: Use them!
    Please don't PM me for help - and no, I don't do help over instant messengers.

  9. #9
    Registered User
    Join Date
    May 2008
    Posts
    14
    Ok here Is the output after I send it data with python script .. the other program is segfaulting now, obviously I changed something there.
    Gdb output: Program received signal SIGSEGV, Segmentation fault. - 0x080484ce in main () at p2.c:34
    34 tuio_cmd[i]->lock = 1;
    If I put breakpoint there, It's segfaulting after 12 loops, as its doesn't have enough memory to write .. and It's showing in the output as there is breaking and starting to output random data.
    But back to the main issue, the thing that's driving me crazy is this following almost random output from shared memory - which I get from python and other C program when It was working.
    (this should send 200 200 200 200 to first array of the tuio struct,and then fill the others with i from 1 to 20)
    shmsend.py 200 200 200 200
    output:
    Memory attached at:B7FB1000 size:400
    X:200,Y:200,Xo:200,Yo:200
    X:1,Y:1,Xo:0,Yo:0
    X:2,Y:2,Xo:0,Yo:0
    X:3,Y:3,Xo:0,Yo:0
    X:4,Y:4,Xo:0,Yo:0
    X:5,Y:5,Xo:0,Yo:0
    X:6,Y:6,Xo:0,Yo:0
    X:7,Y:7,Xo:0,Yo:0
    X:8,Y:8,Xo:0,Yo:0
    X:9,Y:9,Xo:0,Yo:0
    X:10,Y:10,Xo:0,Yo:0
    X:5,Y:7,Xo:22,Yo:0
    X:-160678444,Y:-2008677909,Xo:0,Yo:0
    X:32,Y:655394,Xo:184,Yo:62400
    X:1601399924,Y:1601463655,Xo:1919181921,Yo:1718580 063
    X:157536133,Y:20,Xo:0,Yo:410
    X:-1996488699,Y:-1983685147,Xo:666668534,Yo:0
    X:1358916351,Y:360,Xo:1342606216,Yo:16248808
    X:42304783,Y:-2088042496,Xo:824,Yo:-2062565243
    X:-1947896016,Y:231555,Xo:264275200,Yo:102788

    Argh, now it doesn't work anymore, and I didn't change anything .. maybe it was showing old memory here.. (now its outputing just the first line right 200 200 200 200, and the rest is 0 and random after 12 loop)
    eh its giving me the filling of quantum mechanics.. changing without any cause.
    Last edited by jet-plane; 05-08-2008 at 01:34 AM.

  10. #10
    Registered User
    Join Date
    Apr 2008
    Posts
    396
    I think your problem comes from the initialization of tuio_cmd:

    Code:
    	shmid = shmget (KEY, size, 0666 | IPC_CREAT);
    	if (shmid != -1)
    	{
    		shm_ptr = shmat (shmid, NULL, 0);
    		tuio_cmd = *shm_ptr;          // <- no need to dereference here
    		if (tuio_cmd != (void *) -1)
    		{
    			for( i=0; i<20; i++ )
    As this var is a command*, the result of shmat() is directly this address
    'tuio_cmd=(command*)shm_ptr;'.

  11. #11
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    Quote Originally Posted by jet-plane View Post
    Ok here Is the output after I send it data with python script .. the other program is segfaulting now, obviously I changed something there.
    Gdb output: Program received signal SIGSEGV, Segmentation fault. - 0x080484ce in main () at p2.c:34
    34 tuio_cmd[i]->lock = 1;
    If I put breakpoint there, It's segfaulting after 12 loops, as its doesn't have enough memory to write .. and It's showing in the output as there is breaking and starting to output random data.
    I think that's explained in the next post.
    But back to the main issue, the thing that's driving me crazy is this following almost random output from shared memory - which I get from python and other C program when It was working.
    (this should send 200 200 200 200 to first array of the tuio struct,and then fill the others with i from 1 to 20)
    shmsend.py 200 200 200 200
    output:
    Memory attached at:B7FB1000 size:400
    X:200,Y:200,Xo:200,Yo:200
    X:1,Y:1,Xo:0,Yo:0
    X:2,Y:2,Xo:0,Yo:0
    X:3,Y:3,Xo:0,Yo:0
    X:4,Y:4,Xo:0,Yo:0
    X:5,Y:5,Xo:0,Yo:0
    X:6,Y:6,Xo:0,Yo:0
    X:7,Y:7,Xo:0,Yo:0
    X:8,Y:8,Xo:0,Yo:0
    X:9,Y:9,Xo:0,Yo:0
    X:10,Y:10,Xo:0,Yo:0
    X:5,Y:7,Xo:22,Yo:0
    X:-160678444,Y:-2008677909,Xo:0,Yo:0
    X:32,Y:655394,Xo:184,Yo:62400
    X:1601399924,Y:1601463655,Xo:1919181921,Yo:1718580 063
    X:157536133,Y:20,Xo:0,Yo:410
    X:-1996488699,Y:-1983685147,Xo:666668534,Yo:0
    X:1358916351,Y:360,Xo:1342606216,Yo:16248808
    X:42304783,Y:-2088042496,Xo:824,Yo:-2062565243
    X:-1947896016,Y:231555,Xo:264275200,Yo:102788

    Argh, now it doesn't work anymore, and I didn't change anything .. maybe it was showing old memory here.. (now its outputing just the first line right 200 200 200 200, and the rest is 0 and random after 12 loop)
    eh its giving me the filling of quantum mechanics.. changing without any cause.
    My thoughts are that the python is slower than the C code, and you're just getting ahead of the python code.

    --
    Mats
    Compilers can produce warnings - make the compiler programmers happy: Use them!
    Please don't PM me for help - and no, I don't do help over instant messengers.

  12. #12
    Registered User
    Join Date
    May 2008
    Posts
    14
    Thats not the python problem, as now after I fixed the wrong dereferencing in second C program,
    I got the same output (which I think I got in the first place as maybe I didn't recompile it after I was experimenting on changing various things). Anyway now If I run it :
    gdb ./arr_send_struct
    break 37
    run
    c <-- repeat 12 x
    :::::
    Breakpoint 1, main () at arr_send_struct.c:37
    37 tuio_cmd[i]->lock = 1;
    (gdb) c
    Continuing.

    Program received signal SIGSEGV, Segmentation fault.
    0x080484cc in main () at arr_send_struct.c:37
    37 tuio_cmd[i]->lock = 1;
    :::::::::::
    and the output of ./arr_struct
    X:0,Y:0
    X:1,Y:1
    X:2,Y:2
    X:3,Y:3
    X:4,Y:4
    X:5,Y:5
    X:6,Y:6
    X:7,Y:7
    X:8,Y:8
    X:9,Y:9
    X:10,Y:10
    X:5,Y:7
    X:-160678444,Y:-2008677909
    X:32,Y:655394
    X:1601399924,Y:1601463655
    X:157536133,Y:20
    X:-1996488699,Y:-1983685147
    X:1358916351,Y:360
    X:42304783,Y:-2088042496
    X:-1947896016,Y:231555

  13. #13
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    Can you add a printout of size using &#37;d and tuio_cmd[i] using %p?

    Do this on both sides [or you can use gdb to find out the values], and post the results?

    --
    Mats
    Compilers can produce warnings - make the compiler programmers happy: Use them!
    Please don't PM me for help - and no, I don't do help over instant messengers.

  14. #14
    Registered User
    Join Date
    May 2008
    Posts
    14
    ok I added / uncommented printf ("Memory attached at:&#37;X size:%d\n", (int) tuio_cmd, size);
    and in second prog. I added
    printf("tuio_cmd[i]:%p\n",tuio_cmd[i]);
    after tuio_cmd[i]->yo = i; (I edited this also as it was wrong)

    Its saying :
    ./arr_send_struct
    Memory attached at:B7F1B000 size:400
    tuio_cmd[i]:0xb7f1b000
    tuio_cmd[i]:0xb7f1b190
    tuio_cmd[i]:0xb7f1b320
    tuio_cmd[i]:0xb7f1b4b0
    tuio_cmd[i]:0xb7f1b640
    tuio_cmd[i]:0xb7f1b7d0
    tuio_cmd[i]:0xb7f1b960
    tuio_cmd[i]:0xb7f1baf0
    tuio_cmd[i]:0xb7f1bc80
    tuio_cmd[i]:0xb7f1be10
    tuio_cmd[i]:0xb7f1bfa0
    Segmentation fault

    ./arr_struct
    Memory attached at:B7EF7000 size:400
    X:0,Y:0,tuio_cmd[i]:0xb7ef7000
    X:1,Y:1,tuio_cmd[i]:0xb7ef7190
    X:0,Y:0,tuio_cmd[i]:0xb7ef7320
    X:3,Y:3,tuio_cmd[i]:0xb7ef74b0
    X:4,Y:4,tuio_cmd[i]:0xb7ef7640
    X:5,Y:5,tuio_cmd[i]:0xb7ef77d0
    X:6,Y:6,tuio_cmd[i]:0xb7ef7960
    X:7,Y:7,tuio_cmd[i]:0xb7ef7af0
    X:8,Y:8,tuio_cmd[i]:0xb7ef7c80
    X:9,Y:9,tuio_cmd[i]:0xb7ef7e10
    X:10,Y:10,tuio_cmd[i]:0xb7ef7fa0
    X:5,Y:7,tuio_cmd[i]:0xb7ef8130
    X:-160678444,Y:-2008677909,tuio_cmd[i]:0xb7ef82c0
    X:32,Y:655394,tuio_cmd[i]:0xb7ef8450
    X:1601399924,Y:1601463655,tuio_cmd[i]:0xb7ef85e0
    X:157536133,Y:20,tuio_cmd[i]:0xb7ef8770
    X:-1996488699,Y:-1983685147,tuio_cmd[i]:0xb7ef8900
    X:1358916351,Y:360,tuio_cmd[i]:0xb7ef8a90
    X:42304783,Y:-2088042496,tuio_cmd[i]:0xb7ef8c20
    X:-1947896016,Y:231555,tuio_cmd[i]:0xb7ef8db0

  15. #15
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    Ok, that explains what you are seeing. I'm not quite sure what's wrong with your code, but essentially, you allocate 400 bytes of shared memory (which is correct for 5 * 20 -> 100 int (4 bytes each) values).

    Then your array is jumping 0x190 each time - 0x190 = 400 bytes.

    Ah, got it:
    Code:
    tuio_cmd[i]->lock
    needs to be
    Code:
    (*tuio_cmd)[i].lock
    And of course the same change elsewhere. Or, you could do:
    Code:
    command_ptr *p = &(*tuio_cmd)[i];
    
    p->lock = ...
    --
    Mats
    Compilers can produce warnings - make the compiler programmers happy: Use them!
    Please don't PM me for help - and no, I don't do help over instant messengers.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Link List math
    By t014y in forum C Programming
    Replies: 17
    Last Post: 02-20-2009, 06:55 PM
  2. Fixing my program
    By Mcwaffle in forum C Programming
    Replies: 5
    Last Post: 11-05-2008, 03:55 AM
  3. Replies: 2
    Last Post: 07-11-2008, 07:39 AM
  4. RE: client/server shared memory problem
    By hampycalc in forum C Programming
    Replies: 0
    Last Post: 03-10-2006, 02:26 PM
  5. Binary Search Trees Part III
    By Prelude in forum A Brief History of Cprogramming.com
    Replies: 16
    Last Post: 10-02-2004, 03:00 PM

Tags for this Thread