[Bf-blender-cvs] [b6a7541f87c] master: GHOST: exit with an error when GHOST cannot be initialized

Campbell Barton noreply at git.blender.org
Tue Sep 27 09:15:48 CEST 2022


Commit: b6a7541f87c5ed07634eb829af3abdb8239aca18
Author: Campbell Barton
Date:   Tue Sep 27 17:05:08 2022 +1000
Branches: master
https://developer.blender.org/rBb6a7541f87c5ed07634eb829af3abdb8239aca18

GHOST: exit with an error when GHOST cannot be initialized

When the GHOST back-end Blender was built with isn't supported,
Blender would crash on startup without any useful information.
This could happen when building X11 only, then running on Wayland.

Now show a list of the GHOST back-ends that were attempted and exit
with an error code instead of crashing.

===================================================================

M	intern/ghost/GHOST_ISystem.h
M	intern/ghost/intern/GHOST_C-api.cpp
M	intern/ghost/intern/GHOST_ISystem.cpp
M	source/blender/windowmanager/intern/wm_playanim.c
M	source/blender/windowmanager/intern/wm_window.c

===================================================================

diff --git a/intern/ghost/GHOST_ISystem.h b/intern/ghost/GHOST_ISystem.h
index da6233456c3..05ed089809a 100644
--- a/intern/ghost/GHOST_ISystem.h
+++ b/intern/ghost/GHOST_ISystem.h
@@ -117,9 +117,10 @@ class GHOST_ISystem {
  public:
   /**
    * Creates the one and only system.
+   * \param verbose: report back-ends that were attempted no back-end could be loaded.
    * \return An indication of success.
    */
-  static GHOST_TSuccess createSystem();
+  static GHOST_TSuccess createSystem(bool verbose);
   static GHOST_TSuccess createSystemBackground();
 
   /**
diff --git a/intern/ghost/intern/GHOST_C-api.cpp b/intern/ghost/intern/GHOST_C-api.cpp
index 0026a33bfc2..69fc6b5f2d0 100644
--- a/intern/ghost/intern/GHOST_C-api.cpp
+++ b/intern/ghost/intern/GHOST_C-api.cpp
@@ -24,7 +24,7 @@
 
 GHOST_SystemHandle GHOST_CreateSystem(void)
 {
-  GHOST_ISystem::createSystem();
+  GHOST_ISystem::createSystem(true);
   GHOST_ISystem *system = GHOST_ISystem::getSystem();
 
   return (GHOST_SystemHandle)system;
diff --git a/intern/ghost/intern/GHOST_ISystem.cpp b/intern/ghost/intern/GHOST_ISystem.cpp
index 13eccf661f5..304d7f0abe6 100644
--- a/intern/ghost/intern/GHOST_ISystem.cpp
+++ b/intern/ghost/intern/GHOST_ISystem.cpp
@@ -33,8 +33,13 @@ GHOST_ISystem *GHOST_ISystem::m_system = nullptr;
 
 GHOST_TBacktraceFn GHOST_ISystem::m_backtrace_fn = nullptr;
 
-GHOST_TSuccess GHOST_ISystem::createSystem()
+GHOST_TSuccess GHOST_ISystem::createSystem(bool verbose)
 {
+  /* When GHOST fails to start, report the back-ends that were attempted.
+   * A Verbose argument could be supported in printing isn't always desired. */
+  const char *backends_attempted[8] = {nullptr};
+  int backends_attempted_num = 0;
+
   GHOST_TSuccess success;
   if (!m_system) {
 
@@ -52,15 +57,23 @@ GHOST_TSuccess GHOST_ISystem::createSystem()
     /* Pass. */
 #elif defined(WITH_GHOST_X11) && defined(WITH_GHOST_WAYLAND)
     /* Special case, try Wayland, fall back to X11. */
-    try {
-      m_system = has_wayland_libraries ? new GHOST_SystemWayland() : nullptr;
+    if (has_wayland_libraries) {
+      backends_attempted[backends_attempted_num++] = "WAYLAND";
+      try {
+        m_system = new GHOST_SystemWayland();
+      }
+      catch (const std::runtime_error &) {
+        delete m_system;
+        m_system = nullptr;
+      }
     }
-    catch (const std::runtime_error &) {
-      delete m_system;
+    else {
       m_system = nullptr;
     }
+
     if (!m_system) {
       /* Try to fallback to X11. */
+      backends_attempted[backends_attempted_num++] = "X11";
       try {
         m_system = new GHOST_SystemX11();
       }
@@ -70,6 +83,7 @@ GHOST_TSuccess GHOST_ISystem::createSystem()
       }
     }
 #elif defined(WITH_GHOST_X11)
+    backends_attempted[backends_attempted_num++] = "X11";
     try {
       m_system = new GHOST_SystemX11();
     }
@@ -78,14 +92,21 @@ GHOST_TSuccess GHOST_ISystem::createSystem()
       m_system = nullptr;
     }
 #elif defined(WITH_GHOST_WAYLAND)
-    try {
-      m_system = has_wayland_libraries ? new GHOST_SystemWayland() : nullptr;
+    if (has_wayland_libraries) {
+      backends_attempted[backends_attempted_num++] = "WAYLAND";
+      try {
+        m_system = new GHOST_SystemWayland();
+      }
+      catch (const std::runtime_error &) {
+        delete m_system;
+        m_system = nullptr;
+      }
     }
-    catch (const std::runtime_error &) {
-      delete m_system;
+    else {
       m_system = nullptr;
     }
 #elif defined(WITH_GHOST_SDL)
+    backends_attempted[backends_attempted_num++] = "SDL";
     try {
       m_system = new GHOST_SystemSDL();
     }
@@ -94,10 +115,24 @@ GHOST_TSuccess GHOST_ISystem::createSystem()
       m_system = nullptr;
     }
 #elif defined(WIN32)
+    backends_attempted[backends_attempted_num++] = "WIN32";
     m_system = new GHOST_SystemWin32();
 #elif defined(__APPLE__)
+    backends_attempted[backends_attempted_num++] = "COCOA";
     m_system = new GHOST_SystemCocoa();
 #endif
+
+    if ((m_system == nullptr) && verbose) {
+      fprintf(stderr, "GHOST: failed to initialize display for back-end(s): [");
+      for (int i = 0; i < backends_attempted_num; i++) {
+        if (i != 0) {
+          fprintf(stderr, ", ");
+        }
+        fprintf(stderr, "'%s'", backends_attempted[i]);
+      }
+      fprintf(stderr, "]\n");
+    }
+
     success = m_system != nullptr ? GHOST_kSuccess : GHOST_kFailure;
   }
   else {
@@ -115,7 +150,7 @@ GHOST_TSuccess GHOST_ISystem::createSystemBackground()
   if (!m_system) {
 #if !defined(WITH_HEADLESS)
     /* Try to create a off-screen render surface with the graphical systems. */
-    success = createSystem();
+    success = createSystem(false);
     if (success) {
       return success;
     }
diff --git a/source/blender/windowmanager/intern/wm_playanim.c b/source/blender/windowmanager/intern/wm_playanim.c
index bb19ba4748f..bf793ee41a0 100644
--- a/source/blender/windowmanager/intern/wm_playanim.c
+++ b/source/blender/windowmanager/intern/wm_playanim.c
@@ -1539,6 +1539,14 @@ static char *wm_main_playanim_intern(int argc, const char **argv)
     GHOST_SetBacktraceHandler((GHOST_TBacktraceFn)BLI_system_backtrace);
 
     g_WS.ghost_system = GHOST_CreateSystem();
+
+    if (UNLIKELY(g_WS.ghost_system == NULL)) {
+      /* GHOST will have reported the back-ends that failed to load. */
+      fprintf(stderr, "GHOST: unable to initialize, exiting!\n");
+      /* This will leak memory, it's preferable to crashing. */
+      exit(1);
+    }
+
     GHOST_AddEventConsumer(g_WS.ghost_system, consumer);
 
     playanim_window_open("Blender Animation Player", start_x, start_y, ibuf->x, ibuf->y);
diff --git a/source/blender/windowmanager/intern/wm_window.c b/source/blender/windowmanager/intern/wm_window.c
index 89bf2b82426..a4f92da2774 100644
--- a/source/blender/windowmanager/intern/wm_window.c
+++ b/source/blender/windowmanager/intern/wm_window.c
@@ -1546,6 +1546,13 @@ void wm_ghost_init(bContext *C)
 
   g_system = GHOST_CreateSystem();
 
+  if (UNLIKELY(g_system == NULL)) {
+    /* GHOST will have reported the back-ends that failed to load. */
+    fprintf(stderr, "GHOST: unable to initialize, exiting!\n");
+    /* This will leak memory, it's preferable to crashing. */
+    exit(1);
+  }
+
   GHOST_Debug debug = {0};
   if (G.debug & G_DEBUG_GHOST) {
     debug.flags |= GHOST_kDebugDefault;



More information about the Bf-blender-cvs mailing list