[Mono-list] How to debug C# code called from C via the Mono embedding API

Jean-Michel.Perraud at csiro.au Jean-Michel.Perraud at csiro.au
Sun Jul 10 21:12:29 EDT 2011


Hi,

I am looking for advice on how to debug a mix of C and C# code. I am trying to call .NET libraries from the R statistical package. It is early, prototyping days, making progress but I have encountered an issue I cannot yet figure out how to debug.  

Basically my main question is: how could I debug the C# code called by the R software through the Mono Embed API? I gather from older posts that the Mono debugger cannot attach to running process. I can use gdb with R, that helps somewhat for the C part of things, but not enough for C#. I make do with Console.WriteLine instead, for the time being.

If you can afford to get into the details of the issue (help welcome!), read on.

The exception occurs when using the Mono embedding API from R. Note that using equivalent code in a C test program outside of R succeeds. The C# code is:
public ITemporalSystemRunner Load(string filename)
{
	Console.WriteLine("TimeRSysRun: entered Load");
	Console.WriteLine("filename is null or empty: " + string.IsNullOrEmpty( filename));
	//Console.WriteLine(filename);     //  1/ if uncommented, an ArgumentException "Reentrant Fallback method invocation occurred" at System.Text.EncoderReplacementFallbackBuffer.Fallback
	var repo = new SystemSimulationXmlFilesRepository();
	Console.WriteLine("TimeRSysRun: repo created");
	var result = repo.Load(filename);    // 2/ "Object reference not set to an instance of an object" in System.String.memcpy2
	Console.WriteLine("TimeRSysRun: Loaded!");
	Console.WriteLine("Model in system: " + result.SysNetwork.Nodes[0].model.ToString());
	return result;
}

Below is information that hopefully describes in enough details the issue.

Regards,
J-M

################################################

###### platforms
Linux 2.6.39-2-amd64 #1 SMP Wed Jun 8 11:01:04 UTC 2011 x86_64 GNU/Linux
R version 2.13.0
Mono JIT compiler version 2.10.2 (r2.10.2/ce3b0b7 Wed Jul  6 15:47:29 EST 2011)
Copyright (C) 2002-2011 Novell, Inc and Contributors. www.mono-project.com
	TLS:           __thread
	SIGSEGV:       altstack
	Notifications: epoll
	Architecture:  amd64
	Disabled:      none
	Misc:          softdebug 
	LLVM:          supported, not enabled.
	GC:            Included Boehm (with typed GC and Parallel Mark)

###### The glue Code, (R and C):
>From R, an R object "loader" that has an external pointer to the MonoObject has previously been successfully created. I try to call a method that takes a string as an argument:
out <- .ncall(loader, "Load", xmlFile=xmlFile)

Having compiled 2.10.2 from source to get the .mdb (though I also have the debian experimental packages installed), I *think* this is what it is using:
/usr/local/lib/mono/gac/System/4.0.0.0__b77a5c561934e089/System.dll
/usr/local/lib/mono/gac/System/4.0.0.0__b77a5c561934e089/System.dll.mdb

The crux of the invocation in the C code is:
result = mono_runtime_invoke (method, obj, buildParams(p), &exception); // p is an R "list of arguments"

// In buildParams, in debug mode I actually temporarily hard code the char * value to the file name, but it fails too.
void ** mparams = malloc(nargs*sizeof(void*)); // returned by buildParams
// some iteration over arguments, including:
const char * val = "/home/xxxxx/data/TestSys/Configs/sysrun.xml";
mparams[i] = mono_string_new( domain, val);

###### The exceptions thrown:
### (1) if using Console.WriteLine(filename);
Exception thrown in the method invocation
Reentrant Fallback method invocation occured. It might be because either this FallbackBuffer is incorrectly shared by multiple threads, invoked inside Encoding recursively, or Reset invocation is forgotten.
  at System.Text.EncoderReplacementFallbackBuffer.Fallback (Int32 index) [0x00000] in <filename unknown>:0 
  at System.Text.EncoderReplacementFallbackBuffer.Fallback (Char charUnknown, Int32 index) [0x00000] in <filename unknown>:0 
  at System.Text.UTF8Encoding.GetFallbackChars (System.Char* chars, System.Char* start, System.Text.EncoderFallback fallback, System.Text.EncoderFallbackBuffer& buffer) [0x00000] in <filename unknown>:0 
  at System.Text.UTF8Encoding.InternalGetBytes (System.Char* chars, Int32 count, System.Byte* bytes, Int32 bcount, System.Text.EncoderFallback fallback, System.Text.EncoderFallbackBuffer& buffer, System.Char& leftOver, Boolean flush) [0x00000] in <filename unknown>:0 
  at System.Text.UTF8Encoding.InternalGetBytes (System.Char[] chars, Int32 charIndex, Int32 charCount, System.Byte[] bytes, Int32 byteIndex, System.Text.EncoderFallback fallback, System.Text.EncoderFallbackBuffer& buffer, System.Char& leftOver, Boolean flush) [0x00000] in <filename unknown>:0 
  at System.Text.UTF8Encoding.GetBytes (System.Char[] chars, Int32 charIndex, Int32 charCount, System.Byte[] bytes, Int32 byteIndex) [0x00000] in <filename unknown>:0 
  at System.IO.StreamWriter.Decode () [0x00000] in <filename unknown>:0 
  at System.IO.StreamWriter.LowLevelWrite (System.String s) [0x00000] in <filename unknown>:0 
  at System.IO.StreamWriter.Write (System.String value) [0x00000] in <filename unknown>:0 
  at System.IO.CStreamWriter.Write (System.String val) [0x00000] in <filename unknown>:0 
  at System.IO.TextWriter.WriteLine (System.String value) [0x00000] in <filename unknown>:0 
  at System.IO.SynchronizedWriter.WriteLine (System.String value) [0x00000] in <filename unknown>:0 
  at System.Console.WriteLine (System.String value) [0x00000] in <filename unknown>:0
  at TimeRSysRun.Loader.Load (System.String filename) [0x00000] in <filename unknown>:0

### (2) when using the Load method: "Object reference not set to an instance of an object" in System.String.memcpy2
Program received signal SIGSEGV, Segmentation fault.
Exception thrown in the method invocation
Object reference not set to an instance of an object
Program received signal SIGPWR, Power fail/restart.
[Switching to Thread 0x7ffff2a58700 (LWP 2695)]
0x00007ffff745b410 in sem_wait () from /lib/x86_64-linux-gnu/libpthread.so.0
(gdb) where
#0  0x00007ffff745b410 in sem_wait () from /lib/x86_64-linux-gnu/libpthread.so.0
#1  0x00007ffff3a11588 in mono_sem_wait (sem=0x7ffff3d31400, alertable=1) at mono-semaphore.c:113
#2  0x00007ffff395480d in finalizer_thread (unused=<value optimized out>) at gc.c:1066
// Call stack cut here...
(gdb) c
Continuing.
Program received signal SIGXCPU, CPU time limit exceeded.
0x00007ffff70fd7b4 in sigsuspend () from /lib/x86_64-linux-gnu/libc.so.6
(gdb) where
#0  0x00007ffff70fd7b4 in sigsuspend () from /lib/x86_64-linux-gnu/libc.so.6
#1  0x00007ffff3a37c63 in _GC_suspend_handler (sig=30) at pthread_stop_world.c:186
#2  0x00007ffff3a37ca7 in GC_suspend_handler (sig=30) at pthread_stop_world.c:211
#3  <signal handler called>
#4  0x00007ffff745b40e in sem_wait () from /lib/x86_64-linux-gnu/libpthread.so.0
#5  0x00007ffff3a11588 in mono_sem_wait (sem=0x7ffff3d31400, alertable=1) at mono-semaphore.c:113
#6  0x00007ffff395480d in finalizer_thread (unused=<value optimized out>) at gc.c:1066
// Call stack cut here...
 (gdb) c
Continuing.
  at System.String.memcpy2 (System.Byte* dest, System.Byte* src, Int32 size) [0x00000] in <filename unknown>:0 
  at System.String.CharCopy (System.Char* dest, System.Char* src, Int32 count) [0x00000] in <filename unknown>:0 
  at System.String.Concat (System.String str0, System.String str1) [0x00000] in <filename unknown>:0 
  at TIME.Tools.Persistence.InputOutputHelper.DeserializeFromXML[XmlSerializableSystemRunDefinition] (System.String fullPath, System.Type[] extraTypes) [0x00000] in <filename unknown>:0 
  at TIME.Tools.Persistence.DataMapping.SystemSimulationXmlFilesRepository.Load (System.String xmlFilename) [0x00000] in <filename unknown>:0 
  at TimeRSysRun.Loader.Load (System.String filename) [0x00000] in <filename unknown>:0


More information about the Mono-list mailing list