[Mono-dev] mono_method_desc_search_in_image problem, and some question...
Hi, I am trying to embed mono... and I ran into a problem with the code: monoMethodDesc = mono_method_desc_new("Script:Main", 0); method = mono_method_desc_search_in_image(monoMethodDesc, monoEngine->image); It is returning a method on the cs code: public class Script { static public void Main () { ScriptEngine.report("--Main Called "); } } but it is also returning a method on the cs code (with the wrong class name): public class Script*2* { static public void Main () { ScriptEngine.report("--Main Called "); } } while it should only return for: monoMethodDesc = mono_method_desc_new("Script2:Main", 0); Am i doing something wrong or is this a bug? It seem that mono_method_desc_search_in_image is returning a value if the actual class name is starting with the given class name so, the same method is returned if I look for "Script:Main" but the declared class is "Script:Main", "Script_test:Main" or "Script2:Main"... and a question: is there a way to know if mono_domain_unload was successful or not? I am creating an app domain per script so that I can recompile and reload the script at will... I do not detect any error, but the new script seems not to replace the old one... Basically, I am doing: res = mono_domain_set(rootDomain, FALSE); mono_domain_unload(monoEngine->domain); monoEngine->domain = mono_domain_create_appdomain("ScriptEngine-sub", NULL); data = readFile(f, &dataLen); fclose(f); monoEngine->image = mono_image_open_from_data_with_name(data, dataLen, TRUE /* copy data */, &status, FALSE /* ref only */, monoEngine->fileName); free(data); if (status != MONO_IMAGE_OK || monoEngine->image == NULL) { return FALSE; } // load the assembly monoEngine->assembly = mono_assembly_load_from_full(monoEngine->image, monoEngine->fileName, &status, FALSE); if (status != MONO_IMAGE_OK || monoEngine->assembly == NULL) { mono_image_close(monoEngine->image); return FALSE; } but it does not seem to work. The code that runs is always the first loaded one!! I also added the following code to my engine: mono_trace_set_log_handler(monoLogCallback, NULL); mono_trace_set_print_handler(monoPrintCallback); mono_trace_set_printerr_handler(monoPrintCallback); mono_trace_set_level_string ("debug"); but it is reporting debug info only on the first run... is there a way to having it working on every run? Lastly, Is there a way to compile cs source without launching a system("msc.code.cs -target:library"); thanks in advance Pierre ___ Mono-list maillist -mono-l...@lists.dot.net http://lists.dot.net/mailman/listinfo/mono-list ___ Mono-devel-list mailing list Mono-devel-list@lists.dot.net http://lists.dot.net/mailman/listinfo/mono-devel-list
Re: [Mono-dev] mono_method_desc_search_in_image problem, and some question...
Thanks for the answer. > you 100% sure the old files are all overwritten? Yes, I have checked the file time... and also included a remove(fileName); to be sure! >There are a couple of different ways to get compiled binary at runtime without a system() call Which ones? I have tried something: calling mono_image_open_from_data_with_name and mono_assembly_load_from_full with a different file name on every compile and it is working!!! so, the following code is not reloading properly: monoEngine->fileName = strdup("code.dll"); monoEngine->image = mono_image_open_from_data_with_name(data, dataLen, TRUE /* copy data */, &status, FALSE /* ref only */, monoEngine->fileName); if (status != MONO_IMAGE_OK || monoEngine->image == NULL) { } monoEngine->assembly = mono_assembly_load_from_full(monoEngine->image, monoEngine->fileName, &status, FALSE); if (status != MONO_IMAGE_OK || monoEngine->assembly == NULL) { } but, the same with a different file name on every run (only the monoEngine->fileName creation differ) is working: static int version = 1; ... sprintf(monoEngine->fileName, "code%03d.dll", version); version ++; monoEngine->image = mono_image_open_from_data_with_name(data, dataLen, TRUE /* copy data */, &status, FALSE /* ref only */, monoEngine->fileName); if (status != MONO_IMAGE_OK || monoEngine->image == NULL) { } monoEngine->assembly = mono_assembly_load_from_full(monoEngine->image, monoEngine->fileName, &status, FALSE); if (status != MONO_IMAGE_OK || monoEngine->assembly == NULL) { } Is there a wait to be introduced after a mono_domain_unload? It is like doing mono_domain_unload, mono_image_open_from_data_with_name and mono_assembly_load_from_full with the same file name is detected and the unload is not performed > This is more likely to be a problem outside of mono. I do agree... but I am running out of idea on why!!! and for mono_method_desc_search_in_image? is it bug? Pierre On 13/02/2018 07:15, R Zaghi wrote: I think we need to know a bit more about what you are doing in the code exactly but as a quick first guess if you are recompiling using a system() call then are you 100% sure the old files are all overwritten? There are a couple of different ways to get compiled binary at runtime without a system() call which I prefer but if you are using a system() call then have you tried two separate calls with two parallel binaries loaded as a start to debug your code? This is more likely to be a problem outside of mono. Ramin Ramin Zaghi *Mosaic3DX™ | User Interface Technology* St John's Innovation Centre, Cowley Road, Cambridge, CB4 0WS, UK* * *E*:**rza...@mosaic3dx.com <mailto:rza...@mosaic3dx.com> *T*: +44 1223 421 311 http://linkedin.com/in/raminzaghi On Tue, 13 Feb 2018 at 01:27, pierre <mailto:pierre.saun...@ppmodeler.com>> wrote: Hi, I am trying to embed mono... and I ran into a problem with the code: monoMethodDesc = mono_method_desc_new("Script:Main", 0); method = mono_method_desc_search_in_image(monoMethodDesc, monoEngine->image); It is returning a method on the cs code: public class Script { static public void Main () { ScriptEngine.report("--Main Called "); } } but it is also returning a method on the cs code (with the wrong class name): public class Script*2* { static public void Main () { ScriptEngine.report("--Main Called "); } } while it should only return for: monoMethodDesc = mono_method_desc_new("Script2:Main", 0); Am i doing something wrong or is this a bug? It seem that mono_method_desc_search_in_image is returning a value if the actual class name is starting with the given class name so, the same method is returned if I look for "Script:Main" but the declared class is "Script:Main", "Script_test:Main" or "Script2:Main"... and a question: is there a way to know if mono_domain_unload was successful or not? I am creating an app domain per script so that I can recompile and reload the script at will... I do not detect any error, but the new script seems not to replace the old one... Basically, I am doing: res = mono_domain_set(rootDomain, FALSE); mono_domain_unload(monoEngine->domain); monoEngine->domain = mono_domain_create_appdomain("ScriptEngine-sub", NULL); data = readFile(f, &dataLen); fclose(f); monoEngine->image = mono_image_open_from_data
Re: [Mono-dev] mono_method_desc_search_in_image problem, and some question...
Hi, Anyone about this?? if I run "mono_domain_unload(domain);" and after do assembly = mono_assembly_load_from_full(image, referenceName, &status, FALSE); it is not working properly if referenceName is kept from one launch to the next... I think the code bellow is showing it... or am I doing something wrong?? may be it is linked to the "[DllImport ("__Internal"..." which blocking the unloading of the assembly? And a question: Is there a way to debug a running assembly (embeded)? On python and lua, you can register a function that is called on every line executed... I totally understand it is different for mono, but what are my options? where can I find documentations about debugging from and embedding application? Thanks, Pierre The source to test is (mono_test.c): /**/ #include #include #include #include #include #include #include #include #include /**/ /* */ /**/ #define TRUE 1 #define FALSE 0 #define BYTE unsigned char #define gMalloc malloc #define gFree free BYTE *readFile(FILE *f, size_t *size) { BYTE *buffer; size_t i; fseek(f, 0, SEEK_END); *size = ftell(f); fseek(f, 0, SEEK_SET); buffer = (BYTE *) gMalloc(*size); if(buffer == NULL) return NULL; i = fread(buffer, 1, *size, f); if(i != *size) { gFree(buffer); return NULL; } return buffer; } /**/ /* */ /**/ static MonoDomain *rootDomain; static MonoDomain *domain; static MonoImage *image; static MonoAssembly *assembly; /**/ /* */ /**/ __declspec(dllexport) void mono_report(char* str) { printf("%s\n", str); } /**/ /* */ /**/ static int monoScriptCompile(char *fileName, char *referenceName) { int res; char *ret, *strErr, *str; char buffer[256]; FILE *f; BYTE *data; size_t dataLen; MonoImageOpenStatus status; MonoAssemblyName *aName; if(domain != NULL) { res = mono_domain_set(rootDomain, FALSE); if(!res) { printf("Failed to set root domain\n"); return FALSE; } mono_domain_unload(domain); mono_gc_collect(mono_gc_max_generation()); } domain = NULL; image = NULL; assembly = NULL; domain = mono_domain_create_appdomain("ScriptSubDomain", NULL); res = mono_domain_set(domain, FALSE); if(!res) { printf("Failed to set domain\n"); return FALSE; } sprintf(buffer, "%s.dll", fileName); f = fopen(buffer, "rb"); if(f == NULL) { printf("Cannot open file: %s\n", buffer); return FALSE; } data = readFile(f, &dataLen); fclose(f); // open the assembly from the data we read, so we never lock files image = mono_image_open_from_data_with_name(data, dataLen, TRUE /* copy data */, &status, FALSE /* ref only */, referenceName); gFree(data); if (status != MONO_IMAGE_OK || image == NULL) { printf("Cannot create image from data\n"); return FALSE; } // load the assembly assembly = mono_assembly_load_from_full(image, referenceName, &status, FALSE); if (status != MONO_IMAGE_OK || assembly == NULL) { printf("failed to load assembly\n"); mono_image_close(image); return FALSE; } aName = mono_assembly_get_name(assembly); printf("Assembly Name: %s\n", mono_stringify_assembly_name(aName)); res = mono_domain_set(rootDomain, FALSE); return TRUE; } /**/ /* */ /**/ static int monoScriptRun(void) { int res, base; char *ret, *strErr; MonoMethodDesc* monoMethodDesc; MonoMethod* method; MonoObject *exception; if(domain == NULL || assembly == NULL) { printf("Run Failed: Not compiled\n"); return FALSE; } if (!mono_domain_set(domain, FALSE)) { printf("Run Failed: set domain failed\n"); return FALSE; } monoMethodDesc = mono_method_desc_new("Script:Main", 0); if(monoMethodDesc == NULL) { printf("mono_method_desc_new failed\n" );
[Mono-dev] soft debug
Hi, Parsing the code of Mono.Debugger.Soft there is one thing I cannot figure out: what is the expected reply when the debugger receives an event (command set: 64, command: 100)? The command packet contains a list of events, each with its own unique req_id (and there is an id in the header of the command packet). If I reply with a reply with no additional data with no error (and no attached data), the application crashes... and I am not using the req_id of each event. Where can I find either the description of the reply I should send or the code that is doing it? and I think there is a bug: in the filemono <https://github.com/mono/mono>/mono <https://github.com/mono/mono/tree/master/mono>/mini <https://github.com/mono/mono/tree/master/mono/mini>/_debugger-agent.c_, in the function process_event, line 3747, there is: case EVENT_KIND_VM_START: buffer_add_domainid (&buf, mono_get_root_domain ()); break; but in mono <https://github.com/mono/mono>/mcs <https://github.com/mono/mono/tree/master/mcs>/class <https://github.com/mono/mono/tree/master/mcs/class>/Mono.Debugger.Soft <https://github.com/mono/mono/tree/master/mcs/class/Mono.Debugger.Soft>/Mono.Debugger.Soft <https://github.com/mono/mono/tree/master/mcs/class/Mono.Debugger.Soft/Mono.Debugger.Soft>/Connection.cs, line 1318: if (kind == EventKind.VM_START) { events [i] = new EventInfo (etype, req_id) { ThreadId = thread_id }; //EventHandler.VMStart (req_id, thread_id, null);* * }... while it shouold be: if (kind == EventKind.VM_START) { longid= r.ReadId (); events [i] = new EventInfo (etype, req_id) { ThreadId = thread_id }; it is not causing trouble because the VM_START is always sent alone, but if this change, decoding the next events will have troubles thanks in advance, Pierre ___ Mono-devel-list mailing list Mono-devel-list@lists.dot.net http://lists.dot.net/mailman/listinfo/mono-devel-list
[Mono-dev] strange bug in debug mode..
Hi, I have embedded mono. One of my function is declared in cs as: [MethodImplAttribute(MethodImplOptions.InternalCall)] static extern private float mono_jsonVal_asNumber(IntPtr jsonVal); and in the embedding program, I have mono_add_internal_call("jsonVal::mono_jsonVal_asNumber(intptr)", mono_jsonVal_asNumber); Every thing is running fine. but if in the softDebugger, I do a CMD_SET_EVENT_REQUEST with command CMD_EVENT_REQUEST_SET on event EVENT_KIND_METHOD_EXIT, then instead of having the right returned number, in mono, I always get 0. Running the same without subscribing to method exist work fine (or without SDB). Regards, Pierre ___ Mono-devel-list mailing list Mono-devel-list@lists.dot.net http://lists.dot.net/mailman/listinfo/mono-devel-list
[Mono-dev] MONO_TYPE_CLASS vs MONO_TYPE_OBJECT
Hi, the following cs code (using my own libraries): jsonVal val = json.fromString(str); gives in SDB (using command (CMD_SET_STACK_FRAME, CMD_STACK_FRAME_GET_VALUES)): local variables 'val' of type MONO_TYPE_CLASS value: 4 I don't understand why the type is MONO_TYPE_CLASS and not MONO_TYPE_OBJECT??? What can we do in SDB with a value of type MONO_TYPE_CLASS? Thanks for the help, Pierre ___ Mono-devel-list mailing list Mono-devel-list@lists.dot.net http://lists.dot.net/mailman/listinfo/mono-devel-list
[Mono-dev] Func parameter in embedded mono
Hi, I am looking for info on how I can setup a callback in an embedded mono? so, I can define in C#, something like: Class Widget { private IntPtr _native; [MethodImplAttribute(MethodImplOptions.InternalCall)] static extern private void mono_set_callback(IntPtr widget, Func callback); public void setCallback(Funccallback) { mono_set_callback(_native, callback); } } Is that correct? what will be my C function? void mono_set_callback(mono_widget_object *widget, *callback) { ... } and how can I call the callback from C? There is mono_runtime_invoke but it need an object (or NULL if static) and a method... thanks, Pierre ___ Mono-devel-list mailing list Mono-devel-list@lists.dot.net http://lists.dot.net/mailman/listinfo/mono-devel-list
[Mono-dev] add_internal_call with int32[]
Hi, I am having trouble with the following code: [MethodImplAttribute(MethodImplOptions.InternalCall)] static extern private void mono_testObj_fromInts(object testObj, Int32[] from); public void fromInts(Int32[] from) { mono_testObj_fromInts(this, (Int32[])from); } and in the embedder: mono_add_internal_call("testObj::mono_testObj_fromInts(object,int32[])", mono_testObj_fromInts); when run, I got the error: An exception was thrown when calling Script:Main: (System.MissingMethodException) Attempted to access a missing method. StackTrace: at (wrapper managed-to-native) testObj.mono_testObj_fromInts(object,int[]) of course, if I change the mono_add_internal_call to use int[] it is working... but, if I do that, and if I have understood properly, on some systems, int is mapped to int32_t and on other to int64_t. How can I make the mono_add_internal_call to work with int or int32 or int64? Thanks, Pierre ___ Mono-devel-list mailing list Mono-devel-list@lists.dot.net http://lists.dot.net/mailman/listinfo/mono-devel-list
Re: [Mono-dev] add_internal_call with int32[]
Yes, this is working... but how can I do If I have an int32_t array in the embedder (on a linux64 system for example, where int is mapped to int64_t)? or the opposite, If I have an int64_t array in the embedder (on a windows64 system where int is mapped to int32_t)? On 30/04/2018 17:10, Jonathan Mitchell wrote: Try mono_add_internal_call("testObj::mono_testObj_fromInts(object,int[])", mono_testObj_fromInts); It’s very handy to have some utility code to iterate over a managed class and dump out the native method signatures. It can save a lot of time when you have complex signatures. Jonathan On 30 Apr 2018, at 16:05, pierre <mailto:pierre.saun...@ppmodeler.com>> wrote: Hi, I am having trouble with the following code: [MethodImplAttribute(MethodImplOptions.InternalCall)] static extern private void mono_testObj_fromInts(object testObj, Int32[] from); public void fromInts(Int32[] from) { mono_testObj_fromInts(this, (Int32[])from); } and in the embedder: mono_add_internal_call("testObj::mono_testObj_fromInts(object,int32[])", mono_testObj_fromInts); when run, I got the error: An exception was thrown when calling Script:Main: (System.MissingMethodException) Attempted to access a missing method. StackTrace: at (wrapper managed-to-native) testObj.mono_testObj_fromInts(object,int[]) of course, if I change the mono_add_internal_call to use int[] it is working... but, if I do that, and if I have understood properly, on some systems, int is mapped to int32_t and on other to int64_t. How can I make the mono_add_internal_call to work with int or int32 or int64? Thanks, Pierre ___ Mono-devel-list mailing list Mono-devel-list@lists.dot.net <mailto:Mono-devel-list@lists.dot.net> http://lists.dot.net/mailman/listinfo/mono-devel-list ___ Mono-devel-list mailing list Mono-devel-list@lists.dot.net http://lists.dot.net/mailman/listinfo/mono-devel-list ___ Mono-devel-list mailing list Mono-devel-list@lists.dot.net http://lists.dot.net/mailman/listinfo/mono-devel-list
[Mono-dev] Lack of information using mono with valgrind
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=125000 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@lists.dot.net http://lists.dot.net/mailman/listinfo/mono-devel-list