openETCS / modeling

WP3 Top Level Project: to cover all tasks related with modeling
31 stars 42 forks source link

C API (ERSA): crash on memset scade structure when using a 32bit platform #930

Closed didierersa closed 8 years ago

didierersa commented 8 years ago

Dear all,

The main operator structure defined in the latest code generated in srcAndBinary/Green openETCS Non-Vital Demonstrator/Source Code/Source Code ETCS Onboard Unit System/Generated_Code/KCG-ERSA seems to be too big to be declared on stack, resulting with crash when executing trivial things like that:

outC_EVC out; memset( &out, 0, sizeof( out ) );

The crash occurs at least on centos/redhat 6.x and the backtrace leads to the libc. My workstation is 64 bits so I didn't see it before, but I would like to know if somebody also have monitored this kind of issue.

jokaICS commented 8 years ago

It's not really necessary to clear the out struct explicitly; the code generated by SCADE ensures that all values in the output are valid after each cycle (and the init function will do proper initialization).

Anyway, to be sure: the crash happens during the memset? If the stack size is really a problem, than try to increase it with -Wl,--stack,SIZE_IN_BYTES (assuming you're using gcc).

stefan-karg commented 8 years ago

For my local build on my machine using the Microsoft Visual Studio C/C++ compiler, I also had to increase the stack size.

T12z commented 8 years ago

Just too add my50ct, no did not experience this when compiling the EVC on Linux (back in September). That was a 64bit machine. Back then the data segment occupied ~3MB, so that should not be a problem on Linux (as compared to MSW). And it sounds odd, as it should fail when putting it on the stack before setting it. Have you tried to declare out static?

didierersa commented 8 years ago

If I don't do the memset, a crash happens a bit later elsewhere inside generated code (brakingcurve) (on a memcpy).

The backtrace is quite explicit, only

outC_EVC out; memset( &out, 0, sizeof( out ) );

are called, and then directly libc stuff

I will try to increase the stack size. I will investigate a bit more (and I hope it is not a compiler bug or a libc bug...).

jokaICS commented 8 years ago

Well, do you really need it to be on stack (I presume out is a local var in a function)?

didierersa commented 8 years ago

Unfortunately yes if you do C in "embedded" style, ie with no allocation allowed (no malloc). And you want to have fully reentrant code, global "static" variable is also forbidden.

T12z commented 8 years ago

If I was not completely mistaken, I did notice reverse array copies in my generated code, and as such, memmove must be used!!

T12z commented 8 years ago

sorry, @didierersa context-hint: "my" == SDM / brakingcurve-stuff

jokaICS commented 8 years ago

Unfortunately yes if you do C in "embedded" style, ie with no allocation allowed (no malloc). And you want to have fully reentrant code, global "static" variable is also forbidden.

I agree with the principle; however, if you're using our envsim lib to communicate with the DMI, the principle is already breached, since we use static vars. So maybe it would be better to simply use a static context for a start?

didierersa commented 8 years ago

Seems like I don't have the choice anyway, so I will try it, but we really must be careful with global static variables... How will this code will be used if one day we decide to simulate several train in the same process (like in complete traffic with an interlocking/RBC simulator ?).

didierersa commented 8 years ago

Using a global "static" outC_EVC fixed the problem (and I can even do a memset, even if it is unnecessary), which indicates that it could effectively be linked with the stack and the size of outC_EVC. Good to know when building on 32bits platforms...