[Mono-dev] Lack of information using mono with valgrind

Rafael Teixeira monoman at gmail.com
Tue Jun 6 21:49:32 UTC 2017

Sorry, Pierre, but you are misunderstanding completely what mono is: it is
a runtime environment for code expressed in a virtual machine's bytecode,
that is compiled on the fly (most of time) to native code, without any
possible direct translation of source symbols in the original C# code
compiled to bytecodes to the native code it is generating, specially if
compiled for release and with optimizations enabled.

You can use the mono debug to try to follow your logic step by step and see
if you can pinpoint the problem, you can even debug from inside the
MonoDevelop IDE, which is normally easier to deal than the console-base

Also I remember people discussing using valgrind with mono, but normally to
find problems inside mono itself, not in managed programs. Maybe when
precompiling the bytecode to native code (using aot) it may be possible to
have some tool map the C# source code to the generated code but I don't if
such mapping tool exists... Anyway some guidance is found at
(see the rest of that page for more info on debugging your code)

Valgrind is written in C, and can't be compiled with mcs.

As it seems that your program is pure C#, there are only two ways to leak
memory: bugs in mono itself, or the program is not freeing resources that
allocate in the native side of things (like forgetting to close/free open
files, network channels, etc..)

Also it is important to note that managed programs written in C# (and other
languages) have their memory management automated by a garbage collector
(the GC_ functions in yours valgring stack are part of it), so a dedicated
thread tries to free memory in the background, but if you have tight loops
allocating lots of new objects it may pile up and the background GC thread
may not be able to free the memory as fast as needed so you'll see memory
consumption rise steeply and maybe even causing the program to abort saying
there is no more memory. Also allocating objects in the global scope
(static fields) make them be kept in memory during all the execution of the
program, never freeing the memory they use.

Hope it helps,

Rafael Teixeira

On Tue, Jun 6, 2017 at 5:32 PM, Pierre-Louis PREVOST <plprevost at sii.fr>

> Dear community members,
> I try investigating memory leaks on a program that I wrote in C# which is
> executed under mono 4.2.4.
> To reach that aim:
> - I downloaded the valgrind sources (version 3.12) from valgrind.org and
> successfully compiled & installed it on my platform which is running under
> OS Linux x86.
> - I compiled my C# program using xbuild and "DebugSymbols" property set to
> true
> - I launched the executable using the following commands:
> export G_SLICE=always-malloc
> export G_DEBUG=gc-friendly
> valgrind --tool=memcheck -v --leak-check=full --show-leak-kinds=all
> --log-file=log.${PID} --smc-check=all --suppressions=mono.supp
> --main-stacksize=1250000000 mono --debug --runtime=v4.0 --config
> myProgram.exe.config myProgram.exe
> Now I expect to see some valgrind reports in the log file indicating me
> what function(s) from the source leaks and how much.
> But instead of that, I only see memory leaks from mono and not further. It
> looks like mono is filtering the information from the applicative and only
> gives me insufficiant details in terms of granularity.
> For instance, I get this stack from valgrind:
> ==30182== Use of uninitialised value of size 4
> ==30182== at 0x825FC15: GC_base (in /opt/myPath/bin/mono-boehm)
> ==30182== by 0x825D431: GC_mark_and_push_stack (in
> /opt/myPath/bin/mono-boehm)
> ==30182== by 0x825D5A4: GC_push_all_eager (in /opt/myPath/bin/mono-boehm)
> ==30182== by 0x8265E16: GC_push_all_stacks (in /opt/myPath/bin/mono-boehm)
> ==30182== by 0x825ED21: GC_mark_some (in /opt/myPath/bin/mono-boehm)
> ==30182== by 0x8258017: GC_stopped_mark (in /opt/myPath/bin/mono-boehm)
> ==30182== by 0x8258416: GC_try_to_collect_inner (in
> /opt/myPath/bin/mono-boehm)
> ==30182== by 0x825871B: GC_collect_or_expand (in
> /opt/myPath/bin/mono-boehm)
> ==30182== by 0x8258BAF: GC_allocobj (in /opt/myPath/bin/mono-boehm)
> ==30182== by 0x825BDC5: GC_generic_malloc_inner (in
> /opt/myPath/bin/mono-boehm)
> ==30182== by 0x825BE79: GC_generic_malloc (in /opt/myPath/bin/mono-boehm)
> ==30182== by 0x825C07A: GC_malloc (in /opt/myPath/bin/mono-boehm)
> This basically tells me that mono uses (4 bytes ??) of uninitialised value
> right?
> Shall I conclude that mono is leaking? (which I doubt). Or shall I
> conclude that my program is leaking but mono cannot tell me which
> namespace/function is leaking? (which I most likely presume).
> Do I use the right options of valgrind? If not, what should I use instead?
> Do I have to recompile valgrind using mcs? If it's the case how?
> Thank you in advance,
> Pierre.
> _______________________________________________
> Mono-devel-list mailing list
> Mono-devel-list at lists.dot.net
> http://lists.dot.net/mailman/listinfo/mono-devel-list
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.dot.net/pipermail/mono-devel-list/attachments/20170606/724d8f70/attachment-0001.html>

More information about the Mono-devel-list mailing list