Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Memory leak detected in generated C code #159

Closed
ToddFincannon opened this issue Nov 4, 2021 · 1 comment · Fixed by #160 or #190
Closed

Memory leak detected in generated C code #159

ToddFincannon opened this issue Nov 4, 2021 · 1 comment · Fixed by #160 or #190
Assignees
Labels
Milestone

Comments

@ToddFincannon
Copy link
Collaborator

Emscripten revealed a memory leak in code that SDEverywhere generates. A WebAssembly module typically allocates all the memory for the heap at the beginning, unlike a C program requests more RAM from the OS if necessary. After a few runs, the EPS WebAssembly module would run out of memory. This was clearly rooted in a memory leak in the C code that SDEverywhere generates.

@ToddFincannon ToddFincannon self-assigned this Nov 4, 2021
@ToddFincannon ToddFincannon changed the title emr Memory leak detected in generated WebAssembly code Nov 4, 2021
@ToddFincannon
Copy link
Collaborator Author

The Valgrind tool suite for Linux instruments malloc and free in the C standard library to find memory leaks and buffer overflows. There is a Mac port but it currently does not work. Instead, compile the C code on Linux and run the tests there.

sudo apt install valgrind
gcc -g -O0 x.c -o x
valgrind --leak-check=full --log-file=err ./x

This might work with Clang, but since gcc is already available, we can just use that. For SDEverywhere, we need to modify the compiler and options in the makefile. The -g option includes debug information. The -O0 option disables all optimizations.

I modified the SDEverywhere main.c file to suppress output and run the model twice. valgrind reports:

LEAK SUMMARY:
   definitely lost: 196,096 bytes in 6,128 blocks
   indirectly lost: 322,672 bytes in 6,128 blocks

along with stack traces for each memory leak indicating a problem in __new_fixed_delay.

This is typically called in initLevels where fixed delay equations are interleaved with other equations. We need to initialize them on every call to initLevels but only allocate the internal memory buffers once. This can be accomplished by passing the FixedDelay point into __new_fixed_delay and checking to see if it is NULL. If so, we need to allocate memory. After the first call, the pointer will no longer be NULL, and we can skip the allocations. This relies on the way that __new_fixed_delay is used in SDEverywhere, where the pointer to the FixedDelay structure is allocated statically, and thus is initialized to NULL.

After making this change, the memory leak was resolved. I tested it with 10 runs just to make sure.

LEAK SUMMARY:
   definitely lost: 0 bytes in 0 blocks
   indirectly lost: 0 bytes in 0 blocks

@ToddFincannon ToddFincannon changed the title Memory leak detected in generated WebAssembly code Memory leak detected in generated C code Nov 4, 2021
@chrispcampbell chrispcampbell added this to the 0.6.0 milestone Nov 19, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment