-
Notifications
You must be signed in to change notification settings - Fork 188
Description
When building a standalone binary of the CQ-Editor for macOS, the app may or may not crash depending on its launch context. That is:
- direct from terminal
- inside
lldb - macOS
launchdwhen double-clicked in the Finder - also macOS
launchdwhen launched from the terminal with theopencommand
Each mechanism may or may not trigger macOS gatekeeper security and execute the app inside a "sandbox" with path randomization. This path randomization is usually transparent from the point of view of the python introspection, but at a lower level, the oce core accesses the file system to initialize the OpenGL driver as follows:
- In
OCC/Core/Graphic3d.py,ShadersFolder()is called which in turn calls the binary object function_Graphic3d.Graphic3d_ShaderProgram_ShadersFolder(*args) - This function is in
oce/Graphic3d_ShaderProgram.cxxand it is as follows:
// =======================================================================
// function : ShadersFolder
// purpose :
// =======================================================================
const TCollection_AsciiString& Graphic3d_ShaderProgram::ShadersFolder()
{
static Standard_Boolean THE_IS_DEFINED = Standard_False;
static TCollection_AsciiString THE_SHADERS_FOLDER;
if (!THE_IS_DEFINED)
{
THE_IS_DEFINED = Standard_True;
OSD_Environment aDirEnv ("CSF_ShadersDirectory");
THE_SHADERS_FOLDER = aDirEnv.Value();
if (THE_SHADERS_FOLDER.IsEmpty())
{
OSD_Environment aCasRootEnv ("CASROOT");
THE_SHADERS_FOLDER = aCasRootEnv.Value();
#ifdef OCE_INSTALL_DATA_DIR
if (THE_SHADERS_FOLDER.IsEmpty()) {
THE_SHADERS_FOLDER = OCE_INSTALL_DATA_DIR;
}
#endif
if (!THE_SHADERS_FOLDER.IsEmpty())
{
THE_SHADERS_FOLDER += "/src/Shaders";
}
}
if (THE_SHADERS_FOLDER.IsEmpty())
{
std::cerr << "Both environment variables CSF_ShadersDirectory and CASROOT are undefined!\n"
<< "At least one should be defined to use standard GLSL programs.\n";
Standard_Failure::Raise ("CSF_ShadersDirectory and CASROOT are undefined");
return THE_SHADERS_FOLDER;
}
const OSD_Path aDirPath (THE_SHADERS_FOLDER);
OSD_Directory aDir (aDirPath);
const TCollection_AsciiString aProgram = THE_SHADERS_FOLDER + "/Declarations.glsl";
OSD_File aProgramFile (aProgram);
if (!aDir.Exists()
|| !aProgramFile.Exists())
{
std::cerr << "Standard GLSL programs are not found in: " << THE_SHADERS_FOLDER.ToCString() << std::endl;
Standard_Failure::Raise ("CSF_ShadersDirectory or CASROOT is set incorrectly");
return THE_SHADERS_FOLDER;
}
}
return THE_SHADERS_FOLDER;
}Depending on runtime sandboxing, the path that this function infers may turn out to be incorrect or obscured. Therefore, when it tests Exists() at the end of the function it raises the error. It is difficult to tell if this function falls back on the hardcoded OCE_INSTALL_DATA_DIR since that will defined when oce is built. If it is, then it is yet another mechanism to not find the Shaders folder.
At the end of the day, the program crashes because OpenGL does not get initialized since it cannot find its Shaders/etc. resources in oce/src.
The secondary mechanism of failure related to #108 is that the evaluation of security entitlements delays OpenGL driver initialization and creates a fatal race condition during app initialization due to early requests to draw axis lines in the 3D viewer.