Javascript required
Skip to content Skip to sidebar Skip to footer

Exception Thrown: Read Access Violation. **ptr** Was Nullptr. 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:

  1. C++ executable starts upwardly, sets up a couple of things so creates the mono runtime:
                          //              A re-create of the mono framework is existence shipped along with the application            mono_set_dirs(monoLibPath.string().c_str(), monoEtcPath.string().c_str());            mono_set_assemblies_path(monoFrameworkAssembliesPath.string().c_str());            this->domain = mono_jit_init_version(              "MonoAPI"            ,                          "4.v"            );            mono_domain_set_config(this->domain, (monoEtcPath /                          "4.five"            ).string().c_str(), "auto.config");                          //              Register internal calls with mono_add_internal_call            MonoAPI::registerMonoInternalCalls();                          //              Load all framework assemblies shipped with the application                                      //              Only a subset of the framework is currently being used because I practise not demand the full one                                      //              - mscorlib.dll                          //              - System.Configuration.dll                          //              - System.Core.dll                          //              - Organization.dll                          //              - Arrangement.Runtime.Serialization.dll                          //              - System.ServiceModel.Internals.dll                          //              - Organization.Xml.dll            for            (auto& entry : std::filesystem::recursive_directory_iterator(monoFrameworkAssembliesPath)) {            if            (std::filesystem::is_regular_file(entry)) {            const            auto            fullPath = monoFrameworkAssembliesPath / entry.path();            if            (!std::regex_search(fullPath.filename().string(), MonoAPI::MONO_ASSEMBLY_EXTENSION_REGEX)) {            continue;                 }                          //              Load assembly via mono_domain_assembly_open and go a few infos nigh it            this->loadFrameworkAssembly(fullPath.string());             }         }                          //              This assembly provides the layer which "speaks" with the C++ application via internal calls and also provides the managed entry point            this->loadFrameworkAssembly(monoAPIAssemblyPath.cord());
  1. The C++ application easily command over to the managed globe:
            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;     }
  1. Managed application is running and "speaks" via internal calls to the native part.
    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* or MonoArray* 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 via mono_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):
image

Expected Behavior

No exception being thrown.

On which platforms did y'all notice this

[?] macOS
[x] Linux
[x] Windows

Version Used:

            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)                      

Stacktrace

            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                      

truchanasfrearpok.blogspot.com

Source: https://github.com/mono/mono/issues/16731