Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Workaround for ogre crash on shutdown #1033

Merged
merged 15 commits into from
Aug 16, 2024
49 changes: 44 additions & 5 deletions ogre/src/OgreRenderEngine.cc
Original file line number Diff line number Diff line change
Expand Up @@ -36,8 +36,12 @@ typedef khronos_intptr_t GLintptr;
#include <Winsock2.h>
#endif

#include <dlfcn.h>

# include <sstream>

#include <OgreDynLib.h>

#include <gz/plugin/Register.hh>

#include <gz/common/Console.hh>
Expand Down Expand Up @@ -66,6 +70,32 @@ class gz::rendering::OgreRenderEnginePrivate
using namespace gz;
using namespace rendering;

// Unloading the RenderSystem_GL plugin was found to cause a crash when the
// rendering thread exits. This only happens on Ubuntu 24.04 when running
// ogre using system debs, see
// https:/gazebosim/gz-rendering/issues/1007
// To workaround ths issue, we adapt the code for loading the ogre plugin here.
// We load the RenderSystem_GL library manually and store it in gz-rendering.
// On shutdown, ogre root will uninstall this plugin and delete the GL
// render system objects. However, gz-rendering does not unload this plugin.
// \todo(iche033) Find a proper way to unload the library without causing a
// crash.
typedef void (*DLL_START_PLUGIN)(void);
scpeters marked this conversation as resolved.
Show resolved Hide resolved
DYNLIB_HANDLE glPluginHandle;

void loadGLPlugin(const std::string &_pluginName)
{
#ifdef _WIN32
glPluginHandle = DYNLIB_LOAD(_pluginName.c_str());
#else
glPluginHandle = dlopen(_pluginName.c_str(), RTLD_LAZY | RTLD_LOCAL);
#endif
DLL_START_PLUGIN pFunc = (DLL_START_PLUGIN)DYNLIB_GETSYM(
glPluginHandle, "dllStartPlugin");
pFunc();
return;
}

//////////////////////////////////////////////////
OgreRenderEnginePlugin::OgreRenderEnginePlugin()
{
Expand Down Expand Up @@ -118,9 +148,9 @@ void OgreRenderEngine::Destroy()

if (ogreRoot)
{
// TODO(anyone): do we need to catch segfault on delete?
try
{
// TODO(anyone): do we need to catch segfault on delete?
delete this->ogreRoot;
}
catch (...)
Expand Down Expand Up @@ -458,17 +488,26 @@ void OgreRenderEngine::LoadPlugins()

for (piter = plugins.begin(); piter != plugins.end(); ++piter)
{

bool isGLPlugin = std::string(*piter).find("RenderSystem_GL")
!= std::string::npos;
try
{
// Load the plugin into OGRE
this->ogreRoot->loadPlugin(*piter+extension);
// Load the plugin
if (isGLPlugin)
loadGLPlugin(*piter+extension);
else
this->ogreRoot->loadPlugin(*piter+extension);
}
catch(Ogre::Exception &e)
{
try
{
// Load the debug plugin into OGRE
this->ogreRoot->loadPlugin(*piter+"_d"+extension);
// Load the debug plugin
if (isGLPlugin)
loadGLPlugin(*piter+"_d"+extension);
else
this->ogreRoot->loadPlugin(*piter+"_d"+extension);
}
catch(Ogre::Exception &ed)
{
Expand Down