From d257c6161fb907d7bfe23e22983be1fcf276f948 Mon Sep 17 00:00:00 2001 From: Gabriel Studer <gabriel.studer@unibas.ch> Date: Thu, 7 Feb 2019 12:52:29 +0100 Subject: [PATCH] resolve segfault commit 1268b4b4632a6b897568ef98cc74fbf1beb796d5 just shifted the problem. DNG nicely shut down but a unit test segfaulted. I did not investigate in depth what exactly happened. However, the cleanup at Python shutdown seems to be necessary. The problem is that the scene destructor might have already been called when the cleanup at Python exit happens and the pointers to the scene observers point into Nirvana. So by explicitely defining the Scene destructor that kills all observer pointers and bound gfx objects, the likelihood for bad things happening when the RemoveAll function is called on the Singleton again is reduced. --- modules/gfx/pymod/export_scene.cc | 16 +++++++++++++++- modules/gfx/src/scene.cc | 7 +++++++ modules/gfx/src/scene.hh | 1 + 3 files changed, 23 insertions(+), 1 deletion(-) diff --git a/modules/gfx/pymod/export_scene.cc b/modules/gfx/pymod/export_scene.cc index 11d0f49d5..b810b9122 100644 --- a/modules/gfx/pymod/export_scene.cc +++ b/modules/gfx/pymod/export_scene.cc @@ -87,6 +87,10 @@ void scene_set_hemi_p(Scene* s, tuple p) } // anon ns +void clear_scene() { + Scene::Instance().RemoveAll(); +} + void export_Scene() { def("Scene",get_scene,return_value_policy<reference_existing_object>()); @@ -264,5 +268,15 @@ void export_Scene() .add_property("hemi_params",scene_get_hemi_p,scene_set_hemi_p) ; -} +// we need to make sure there are no pending references to Python objects +// tied to the scene singleton. The destructor of +// scene may be called after Python is shutdown which results +// in a segfault. +scope().attr("__dict__")["atexit"]=handle<>(PyImport_ImportModule("atexit")); + +def("_clear_scene", &clear_scene); +object r=scope().attr("_clear_scene"); +scope().attr("atexit").attr("register")(r); + +} diff --git a/modules/gfx/src/scene.cc b/modules/gfx/src/scene.cc index 7631d2123..9aeb22a01 100644 --- a/modules/gfx/src/scene.cc +++ b/modules/gfx/src/scene.cc @@ -151,6 +151,13 @@ Scene::Scene(): transform_.SetTrans(Vec3(0,0,-100)); } +Scene::~Scene() +{ + // cleanup all observers / gfx_nodes when scene is destructed + observers_.clear(); + this->RemoveAll(); +} + void Scene::SetFog(bool f) { fog_flag_=f; diff --git a/modules/gfx/src/scene.hh b/modules/gfx/src/scene.hh index 4205263fc..adacb4ca9 100644 --- a/modules/gfx/src/scene.hh +++ b/modules/gfx/src/scene.hh @@ -548,6 +548,7 @@ private: Scene(); Scene(const Scene&) {} Scene& operator=(const Scene&) {return *this;} + ~Scene(); // The GL Context gets typically handled externally, e.g. using QT when // calling InitGL(), RenderGL() etc. However, there is no guarantee that the -- GitLab