rcrl icon indicating copy to clipboard operation
rcrl copied to clipboard

MacOS - ctor/dtor counting test doesn't work

Open onqtam opened this issue 7 years ago • 4 comments

For some reason this test (which exports a function called test_ctor_dtor_order() and calls it from RCRL-submitted code) for the order of construction and destruction of variables from a vars section doesn't work on MacOS - this is the output of a failing build - it is as if the function was never called! The weird thing is that it doesn't crash or assert or anything like that - the compiled plugin is copied and loaded successfully...

and the MORE weird thing is that I have no problems calling such exported functions in the demo application (the host_app target) that is the focus of the repository itself

and the EVEN MORE weird thing is that before doing this test with exported symbols I was just inspecting the stdout output when loading the plugin and when unloading it (this commit is with the changes from text-based testing to an exported function) and it... didn't work on MacOS (but output redirecting works perfectly fine for the host_app target)

I tried not to reuse the same plugin.cpp filename for the plugin for the host_app target and the rcrl_compiler_tests target but that didn't help. Maybe the host_app target just works because of some CMake flags inherited from one of the third parties it links against (perhaps glfw?).

So I'm giving up - I cannot waste any more hours on that platform - hopefully someone else helps me.

onqtam avatar Feb 12 '18 16:02 onqtam

Well, the behavior is rather chaotic, and non debugger friendly.

If you place a breakpoint at line 35 (at rcrl::submit_code) and then execute step by step; then g_pushed_ints is almost always correctly populated (however this might fail with a failure rate of approx 5%).

image

If you place a breakpoint only at line 56 (REQUIRE(g_pushed_ints.size() == 2)), but no breakpoint at line 35, then g_pushed_ints is almost never correctly populated (but I'm almost certain I saw it work some rare times).

Could the issue be related to tiny-process-library ?

pthom avatar Nov 12 '18 21:11 pthom

Not sure... It might be a good idea to try for a couple of minutes to swap it out in favor of another process library - or perhaps even get rid of processes entirely (just for the test) and do a blocking compilation operation just to see if the test passes reliably then.

https://github.com/onqtam/rcrl/blob/master/src/rcrl/rcrl.cpp#L193

that is the point of compilation - which can be swapped out with a call to std::system(), and the other functions that use the pointer to the process - like is_compiling() - they can be turned into a stub - just for the test.

However I do not have access to a mac and also no time... if someone else tries this - would be interesting!

onqtam avatar Nov 12 '18 21:11 onqtam

You are right, tinyprocess is probably out of the equation. I can reproduce the issue with standard std::system calls.

My current findings are that it can help to sleep for a while after the call to std::system !

If the sleep duration is around 800ms, then the success rate is about 80% (even without debugging, and even in release compilation) If the sleep duration is < 100ms then the success rate is < 5%.

This is probably os related (disk cache, process, os-wide security settings ?)

See code below, where I added a call to this_thread::sleep

bool is_compiling() { return false; }
bool try_get_exit_status_from_compile(int& exitcode) {
    exitcode = 0;
    last_compile_successful = true;
    return true;
}
...
...

bool submit_code(string code, Mode default_mode, bool* used_default_mode) {
  ...
  ...
   std::string cmd = "cmake --build " RCRL_BUILD_FOLDER " --target " RCRL_PLUGIN_NAME
        #ifdef RCRL_CONFIG
            " --config " RCRL_CONFIG
        #endif // multi config IDE
        #if defined(RCRL_CONFIG) && defined(_MSC_VER)
            " -- /verbosity:quiet"
        #endif // Visual Studio;
    ;

    /*
    compiler_process = unique_ptr<TinyProcessLib::Process>(
            new TinyProcessLib::Process(cmd.c_str(),
                                        "", output_appender, output_appender));
    */

    std::cout << "calling std::system :" << cmd << "\n";
    int result = std::system(cmd.c_str());
    std::cout << "std::system result:" << result << "\n";
    std::this_thread::sleep_for(800ms);   // this duration of this sleep (if >=600ms) increases the chance of success 
    return true;
}

pthom avatar Nov 12 '18 22:11 pthom

Thanks for narrowing it down! But still no clue as to why exactly it is happening (at least now I know why the same code worked almost always when in demo mode - manually entered code by the user - and not in the tests).

onqtam avatar Nov 13 '18 06:11 onqtam