C Board  

Go Back   C Board > General Programming Boards > C Programming

Reply
 
LinkBack Thread Tools Display Modes
Old 05-07-2008, 02:41 PM   #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)
jet-plane is offline   Reply With Quote
Old 05-07-2008, 04:06 PM   #2
Registered User
 
Join Date: Apr 2008
Posts: 278
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)
root4 is offline   Reply With Quote
Old 05-07-2008, 04:10 PM   #3
Kernel hacker
 
Join Date: Jul 2007
Location: Farncombe, Surrey, England
Posts: 15,686
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.
matsp is offline   Reply With Quote
Old 05-07-2008, 04:39 PM   #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.
jet-plane is offline   Reply With Quote
Old 05-07-2008, 04:43 PM   #5
Kernel hacker
 
Join Date: Jul 2007
Location: Farncombe, Surrey, England
Posts: 15,686
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.
matsp is offline   Reply With Quote
Old 05-07-2008, 04:53 PM   #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)
jet-plane is offline   Reply With Quote
Old 05-07-2008, 04:59 PM   #7
Registered User
 
Join Date: Apr 2008
Posts: 278
Quote:
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.
root4 is offline   Reply With Quote
Old 05-07-2008, 05:00 PM   #8
Kernel hacker
 
Join Date: Jul 2007
Location: Farncombe, Surrey, England
Posts: 15,686
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.
matsp is offline   Reply With Quote
Old 05-08-2008, 12:54 AM   #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.
jet-plane is offline   Reply With Quote
Old 05-08-2008, 01:22 AM   #10
Registered User
 
Join Date: Apr 2008
Posts: 278
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;'.
root4 is offline   Reply With Quote
Old 05-08-2008, 02:43 AM   #11
Kernel hacker
 
Join Date: Jul 2007
Location: Farncombe, Surrey, England
Posts: 15,686
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.
Quote:
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.
matsp is offline   Reply With Quote
Old 05-08-2008, 03:10 AM   #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
jet-plane is offline   Reply With Quote
Old 05-08-2008, 03:15 AM   #13
Kernel hacker
 
Join Date: Jul 2007
Location: Farncombe, Surrey, England
Posts: 15,686
Can you add a printout of size using %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.
matsp is offline   Reply With Quote
Old 05-08-2008, 03:28 AM   #14
Registered User
 
Join Date: May 2008
Posts: 14
ok I added / uncommented printf ("Memory attached at:%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
jet-plane is offline   Reply With Quote
Old 05-08-2008, 03:34 AM   #15
Kernel hacker
 
Join Date: Jul 2007
Location: Farncombe, Surrey, England
Posts: 15,686
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.
matsp is offline   Reply With Quote
Reply

Tags
array, linux, shared memory, struct

Thread Tools
Display Modes

Forum Jump

Similar Threads
Thread Thread Starter Forum Replies Last Post
Link List math t014y C Programming 17 02-20-2009 06:55 PM
Fixing my program Mcwaffle C Programming 5 11-05-2008 03:55 AM
Dynamic array of structures containing yet another dynamic array of structures innqubus C Programming 2 07-11-2008 07:39 AM
RE: client/server shared memory problem hampycalc C Programming 0 03-10-2006 02:26 PM
Binary Search Trees Part III Prelude A Brief History of Cprogramming.com 16 10-02-2004 03:00 PM


All times are GMT -6. The time now is 11:24 PM.


Powered by vBulletin® Version 3.8.1
Copyright ©2000 - 2009, Jelsoft Enterprises Ltd.
Search Engine Optimization by vBSEO 3.3.0 RC2

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22