rcrl
rcrl copied to clipboard
MacOS - ctor/dtor counting test doesn't work
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.
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%).
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 ?
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!
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;
}
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).