question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

macOS OpenGL initialization / security entitlements

See original GitHub issue

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:

  1. direct from terminal
  2. inside lldb
  3. macOS launchd when double-clicked in the Finder
  4. also macOS launchd when launched from the terminal with the open command

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:

  1. In OCC/Core/Graphic3d.py, ShadersFolder() is called which in turn calls the binary object function _Graphic3d.Graphic3d_ShaderProgram_ShadersFolder(*args)
  2. This function is in oce/Graphic3d_ShaderProgram.cxx and 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.

Issue Analytics

  • State:closed
  • Created 4 years ago
  • Comments:8 (3 by maintainers)

github_iconTop GitHub Comments

1reaction
michaelgalecommented, Jan 7, 2020

@jmwright @adam-urbanczyk Good news! All fixed!

I added some logic to run.py to introspect the full absolute path of the application, lookup the CSF_ShadersDirectory env variable, and perform a runtime substitution of the env variable with the full path. It only does this if it detects the sys.platform == “darwin”. I also added some platform specific logic to initialize QApplication–this silences nuisance warnings about initializing pyqtgraph after QApplication. The application bundle launches in all contexts and includes pretty dock icons for macOS. Next, I’ll make a DMG builder script with signing and pretty icons so that macOS users should hopefully be able to download and install in one turnkey step just like any other macOS app.

0reactions
michaelgalecommented, Jan 10, 2020

This issue can be closed since the PR #111 addresses this problem with run time substitution of the environment variable for CSF Shaders. Platform specific guards ensure that this occurs only for macOS targets.

Read more comments on GitHub >

github_iconTop Results From Across the Web

Issue running openGL via headless mac mini - Apple Developer
I am currently trying to use EC2 mac instances to run a CI/CD pipeline which involves running tests with electron/selenium.
Read more >
Cannot run GUI/OpenGL on headless macOS EC2 Instance
Hello, I am currently trying to use EC2 mac instances to run a CI/CD pipeline which involves running tests with electron/selenium.
Read more >
How do I set up OpenGL on a Mac? - Quora
Open Xcode located in "/Developer/Applications/" · Choose "New Project" from the file menu · Choose "Command Line Tool" under the Application template for...
Read more >
macos 10.14 run error :: Rise to Ruins Bugs - Steam Community
Rise to Ruins InDev 32 Unstable 2d Attempting to initialize Steamworks Fetching local language files.
Read more >
The GLUT API for OpenGL Configuration - InformIT
Begin by going to XCode and creating a new project, ... ( "GLUT Configuration Example" ); // initialize our opengl (context is now...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found