Hello Hackers,
I've got a problem with a hybrid Linux Task. I want to create a little tool to tranfser data between two L4Linuxes easily. A tool similar to the famous netcat but using IPC instead of UDP/TCP. So far so good. Server is listen for client and client is sending data to the server (using long IPC transfering data as dwords). The problem is that the data doesn't arrive at the server task. There only an empty IPC message gets received (no IPC error).
After I've played around a while with debug messages I got strange results. Using debug messages (simple printf()) inbetween and the transfer succedes!
Digging a little deeper got me to the point that it must be a problem with the compiler. Using 'gcc -O0' generates working code too - 'gcc -O2' doesn't. Trying another compiler (gcc version 4.0.1 (Debian 4.0.1-2)) with -O2 got me also working code.
So my question is if really my gcc (version 3.3.5 (Debian 1:3.3.5-13)) is broken or the includes under l4/l4sys/.../ipc.h. Maybe the inline assembly isn't that clean? But just a guess. My GNU assembly knowlegde isn't that good.
Greets, Mathias
PS: I'm runing Debian sarge over here.
Hi Mathias,
On Monday 19 September 2005 17:45, Mathias Krause wrote:
I've got a problem with a hybrid Linux Task. I want to create a little tool to tranfser data between two L4Linuxes easily. A tool similar to the famous netcat but using IPC instead of UDP/TCP. So far so good. Server is listen for client and client is sending data to the server (using long IPC transfering data as dwords). The problem is that the data doesn't arrive at the server task. There only an empty IPC message gets received (no IPC error).
Try to debug this issue using the kernel debugger. What does the IPC log say (options I* and IR+, what msgdope is displayed)?
After I've played around a while with debug messages I got strange results. Using debug messages (simple printf()) inbetween and the transfer succedes!
Digging a little deeper got me to the point that it must be a problem with the compiler. Using 'gcc -O0' generates working code too - 'gcc -O2' doesn't. Trying another compiler (gcc version 4.0.1 (Debian 4.0.1-2)) with -O2 got me also working code.
Maybe the compiler optimizes some code away. I assume that you tried the last version of L4Linux 2.6 -- Adam changed many things to get hybrid tasks working.
So my question is if really my gcc (version 3.3.5 (Debian 1:3.3.5-13)) is broken or the includes under l4/l4sys/.../ipc.h. Maybe the inline assembly isn't that clean? But just a guess. My GNU assembly knowlegde isn't that good.
We cannot guarantee that the bindings are bug-free but they have been tested for a long time. Do you use any special compiler switches besides -O2? Do you use -fomit-frame-pointer? Try without. Do you use -fstrict- aliasing? Try with -fno-strict-aliasing as defined in l4/mk/binary.inc.
PS: I'm runing Debian sarge over here.
Should be fine. Actually I use gcc-3.4 but have used gcc-3.3 for a long time. gcc-4 is still not supported for the L4env tree.
If nothing helps you could send me the source/binary so I'm able to investigate a little bit more.
Frank
Hi Frank,
Frank Mehnert wrote:
Try to debug this issue using the kernel debugger. What does the IPC log say (options I* and IR+, what msgdope is displayed)?
Ok, here comes the (partially analysed) trace buffer. Task 26.x is the server waiting for the client 27.x to send data. You need to read it from the bottom upwards because trace buffer is filled this way (see numbers on the right side).
| ... | +++> 27.00 send dope=bf4bb110 (L4_IPC_Enot_existent) 3999 | ipc: 27.00 send-> 26.00 (00000000,00000000) TO=INF 3998 | 27.00 send dope=00000000 (OK) 3997 | ... Here the client gets a failure because the server already finished.
| ... | +++> 26.00 call dope=00004000 (OK) 5.00 (00000000,00000001) 3984 | ipc: 5.00 repl-> 26.00 (00000000,00000001) TO=0/INF 3983 | 5.00 rply dope=0000a000 (OK) 26.00 (00100003,004c001f) 3982 | ipc: 26.00 call-> 5.00 (00100003,004c001f) TO=INF/INF 3981 | ... Here the server already deregisters itself at names because he got a message with an empty buffer => means "end of transmition".
| ... | +++> 26.00 recv dope=00004000 (OK) 27.00 (00000000,00000000) 3966 | ipc: 26.00 recv from 27.00 TO=INF 3965 | ... Here the server starts waiting for the client to send data in a buffer sized 4k.
<<<start reading the trace buffer here>>>
Maybe the compiler optimizes some code away. I assume that you tried the last version of L4Linux 2.6 -- Adam changed many things to get hybrid tasks working.
It's a version a week old or so. It was very stable at this time (no changes in CVS for some time).
We cannot guarantee that the bindings are bug-free but they have been tested for a long time. Do you use any special compiler switches besides -O2? Do you use -fomit-frame-pointer? Try without. Do you use -fstrict- aliasing? Try with -fno-strict-aliasing as defined in l4/mk/binary.inc.
My CFLAGS are '-W -Wall -g -O2', so this should be ok, doesn't it?
BTW, I haven't found any library containing a l4_ipc_whatever() function. Are the assembler inlines the only way to make ipc calls?
PS: I'm runing Debian sarge over here.
Should be fine. Actually I use gcc-3.4 but have used gcc-3.3 for a long time. gcc-4 is still not supported for the L4env tree.
gcc-3.4 (gcc-Version 3.4.4 20050314 (prerelease) (Debian 3.4.3-13)) doesn't work for me too :(
If nothing helps you could send me the source/binary so I'm able to investigate a little bit more.
I'll send you a seperate message in a few minutes :)
Mathias
Hi Mathias,
On Monday 19 September 2005 18:37, Mathias Krause wrote:
Here the server already deregisters itself at names because he got a message with an empty buffer => means "end of transmition".
| ... | +++> 26.00 recv dope=00004000 (OK) 27.00 (00000000,00000000) 3966 | ipc: 26.00 recv from 27.00 TO=INF 3965 | ...
Here the server starts waiting for the client to send data in a buffer sized 4k.
4k direct IPC or indirect IPC? What message 27.00 send to 26.00 (events before 3965)? It seems that 27.00 did only send a short message containing two dwords.
Maybe the compiler optimizes some code away. I assume that you tried the last version of L4Linux 2.6 -- Adam changed many things to get hybrid tasks working.
It's a version a week old or so. It was very stable at this time (no changes in CVS for some time).
Ok, right.
We cannot guarantee that the bindings are bug-free but they have been tested for a long time. Do you use any special compiler switches besides -O2? Do you use -fomit-frame-pointer? Try without. Do you use -fstrict- aliasing? Try with -fno-strict-aliasing as defined in l4/mk/binary.inc.
My CFLAGS are '-W -Wall -g -O2', so this should be ok, doesn't it?
You should also add -fno-strict-aliasing. See the appropriate documentation of that option. I assume that you use DICE, and with DICE you _must_ use this option so far (Ron is about to change the whole DICE compiler but that takes much time).
BTW, I haven't found any library containing a l4_ipc_whatever() function. Are the assembler inlines the only way to make ipc calls?
Yes. Therefore, L4 sources should not be compiled using -O0 or -fno-inline. Hmm, until now we did not need to compile with -O0.
Frank
For the record: In l4_ipc_send() there was no "memory" clobber specified (l4_ipc_send() does not modify any memory in the sender's address space). In this case, the structure itself, not only a pointer to a structure has to be specified as input operand.
Frank
l4-hackers@os.inf.tu-dresden.de