I am using mono in a C++ project which uses mono/C# as it's "scripting" language.
It went quiet well for a while and was like shooting fish in a barrel to implement simply now I get division faults as the project continues to grow.
int MonoAPI::runMain(const std::vector<std::string>& launchArguments, std::shared_ptr<MonoAllocator> allocator) { // Expect through all assemblies and search for the "MonoMain" class (MonoClass*) auto mainClass = this->resolveFramworkClass( "MonoMain" ); if (mainClass == nullptr) { throw std::logic_error( "Unable to find the master course inside the mono framework library." ); } auto desc = mono_method_desc_new( ":Master" , true); car method = mono_method_desc_search_in_class(desc, mainClass); if (method == nullptr) { throw std::logic_error( "Unable to find the master entry point method within the mono framework library." ); } auto argc = static_cast<int>(launchArguments.size() + 1); // Scope guard merely ensures that the argc assortment is being freed when leaving the role scope motorcar args = ScopeGuardHandle<char**>(new char* [argc], [](auto x) { delete[] ten; }); for (automobile i = 0; i < launchArguments.size(); i++) { args.handle()[i] = const_cast<char*>(launchArguments[i].c_str()); } // Allocator provides a special identifier to the managed world used in internal calls for identification (uint64_t) motorcar objectHandle = std::to_string(allocator->getHandle()); args.handle()[launchArguments.size()] = const_cast<char*>(objectHandle.c_str()); MonoObject* ex = nullptr; // From now on the native C++ application will simply execute code during internal calls as this blocks the main thread auto exitCode = mono_runtime_run_main(method, argc, args.handle(), &ex); if (ex != nullptr) { this->logErrorMessage( "Fatal exception occurred in managed code: " + MonoAPI::formatManagedException(ex)); } return exitCode; }
I also moved creation of byte arrays to managed code and provide them via fixed(byte* v = myByteArray)
to internal calls in dangerous contexts.
This kind of solved the problem for linux only I don't know if it just delays the segfault further away during application runtime simply considering the gc_perform_collection
role does not execute.
Unhandled exception "vt was nullptr" (or only a segfault with linux using gdb only with the aforementioned stacktrace):
No exception being thrown.
Mono JIT compiler version half-dozen.0.0 (Visual Studio congenital mono) Copyright (C) 2002-2014 Novell, Inc, Xamarin Inc and Contributors. world wide web.mono-project.com TLS: __thread SIGSEGV: normal Notification: Thread + polling Architecture: amd64 Disabled: none Misc: softdebug Interpreter: yes LLVM: supported, not enabled. Suspend: preemptive GC: sgen (concurrent by default)
Exception thrown at 0x00007FFDCC9B581B (mono-2.0-sgen.dll) in application.exe: 0xC0000005: Access violation reading location 0x0000000000000008. Unhandled exception thrown: read admission violation. **vt** was nullptr.
mono-ii.0-sgen.dll!copy_object_no_checks(_MonoObject * obj, _SgenGrayQueue * queue) Line 69 C [Inline Frame] mono-2.0-sgen.dll!major_copy_or_mark_object_with_evacuation(_MonoObject * * obj, _MonoObject *) Line 86 C mono-2.0-sgen.dll!major_scan_vtype_with_evacuation(_MonoObject * full_object, char * starting time, unsigned __int64 desc, _SgenGrayQueue * queue) Line 64 C mono-2.0-sgen.dll!sgen_client_cardtable_scan_object(_MonoObject * obj, unsigned char * cards, ScanCopyContext ctx) Line 1271 C mono-two.0-sgen.dll!sgen_cardtable_scan_object(_MonoObject * obj, unsigned __int64 block_obj_size, unsigned char * cards, ScanCopyContext ctx) Line 583 C mono-2.0-sgen.dll!sgen_los_scan_card_table(CardTableScanType scan_type, ScanCopyContext ctx, int job_index, int job_split_count) Line 669 C mono-2.0-sgen.dll!job_scan_los_mod_union_card_table(void * worker_data_untyped, _SgenThreadPoolJob * job) Line 1501 C mono-2.0-sgen.dll!sgen_workers_enqueue_job(int generation, _SgenThreadPoolJob * job, int enqueue) Line 185 C mono-2.0-sgen.dll!major_copy_or_mark_from_roots(_SgenGrayQueue * gc_thread_gray_queue, unsigned __int64 * old_next_pin_slot, CopyOrMarkFromRootsMode fashion, SgenObjectOperations * object_ops_nopar, SgenObjectOperations * object_ops_par) Line 2112 C mono-2.0-sgen.dll!major_finish_collection(_SgenGrayQueue * gc_thread_gray_queue, const char * reason, int is_overflow, unsigned __int64 old_next_pin_slot, int forced) Line 2212 C mono-2.0-sgen.dll!major_finish_concurrent_collection(int forced) Line 2461 C mono-ii.0-sgen.dll!sgen_perform_collection_inner(unsigned __int64 requested_size, int generation_to_collect, const char * reason, int forced_serial, int stw) Line 2550 C [Inline Frame] mono-2.0-sgen.dll!sgen_perform_collection(unsigned __int64) C mono-two.0-sgen.dll!sgen_ensure_free_space(unsigned __int64 size, int generation) Line 2511 C mono-2.0-sgen.dll!sgen_los_alloc_large_inner(MonoVTable * vtable, unsigned __int64 size) Line 386 C mono-2.0-sgen.dll!sgen_alloc_obj_nolock(MonoVTable * vtable, unsigned __int64 size) Line 170 C mono-2.0-sgen.dll!mono_gc_alloc_vector(MonoVTable * vtable, unsigned __int64 size, unsigned __int64 max_length) Line 1324 C mono-ii.0-sgen.dll!mono_jit_runtime_invoke(_MonoMethod * method, void * obj, void * * params, _MonoObject * * exc, _MonoError * mistake) Line 3169 C [Inline Frame] mono-2.0-sgen.dll!do_runtime_invoke(_MonoMethod *) Line 2980 C [Inline Frame] mono-2.0-sgen.dll!mono_runtime_try_invoke(_MonoMethod *) Line 3087 C mono-2.0-sgen.dll!do_try_exec_main(_MonoMethod * method, _MonoArray * args, _MonoObject * * exc) Line 5034 C [Inline Frame] mono-2.0-sgen.dll!mono_runtime_try_exec_main(_MonoMethod *) C mono-2.0-sgen.dll!mono_runtime_run_main(_MonoMethod * method, int argc, char * * argv, _MonoObject * * exc) Line 4533 C
I am using mono in a C++ project which uses mono/C# as it's "scripting" language.
It went quiet well for a while and was like shooting fish in a barrel to implement simply now I get division faults as the project continues to grow.
What I'g basically doing:
This involves loading resources in native code and transporting them mainly in elementary structs, strings or arrays to the managed world during internal calls.
No pointers to managed references are kept in retention by the native implementation and no pointers to
MonoString*
orMonoArray*
are being kept after the internal call completes.I also moved creation of byte arrays to managed code and provide them via
fixed(byte* v = myByteArray)
to internal calls in dangerous contexts.This kind of solved the problem for linux only I don't know if it just delays the segfault further away during application runtime simply considering the
gc_perform_collection
role does not execute.No objects are created in native lawmaking, but strings (
mono_string_new
) and a couple of smaller arrays viamono_array_new
and just during internal calls.Electric current Behavior
Unhandled exception "vt was nullptr" (or only a segfault with linux using gdb only with the aforementioned stacktrace):
Expected Behavior
No exception being thrown.
On which platforms did y'all notice this
[?] macOS
[x] Linux
[x] Windows
Version Used:
Stacktrace