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.
This commit is contained in:
2022-09-27 17:05:08 +10:00
parent 78952518e7
commit b6a7541f87
5 changed files with 63 additions and 12 deletions

View File

@@ -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();
/**

View File

@@ -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;

View File

@@ -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;
}

View File

@@ -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);

View File

@@ -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;