Skip to content

Conversation

@slapin
Copy link
Contributor

@slapin slapin commented Dec 26, 2025

If page load is in progress, page load can
crash as the load finaliser is executed after unload.

To test the reproduction I create ImGui Button which runs WorldPartition's unloadPage with PageID calculated using current camera position. Before this change it resulted in the following backtrace in unlucky case:

Thread 1 "Editor" received signal SIGSEGV, Segmentation fault.
0x00007ffff7f00f91 in Ogre::Page::handleResponse (this=0x5555586a96d0, res=0x7fffe8006900, srcQ=0x0) at /media/slapin/library/ogre3/ogre/Components/Paging/src/OgrePage.cpp:233
233	            loadImpl();
(gdb) bt

#0  0x00007ffff7f00f91 in Ogre::Page::handleResponse (this=0x5555586a96d0, res=0x7fffe8006900, srcQ=0x0) at /media/slapin/library/ogre3/ogre/Components/Paging/src/OgrePage.cpp:233
#1  0x00007ffff7f00aa0 in operator() (__closure=0x7fffffffd830) at /media/slapin/library/ogre3/ogre/Components/Paging/src/OgrePage.cpp:186
#2  0x00007ffff7f02476 in std::__invoke_impl<void, Ogre::Page::load(bool)::<lambda()>::<lambda()>&>(std::__invoke_other, struct {...} &) (__f=...) at /usr/include/c++/11/bits/invoke.h:61
#3  0x00007ffff7f02208 in std::__invoke_r<void, Ogre::Page::load(bool)::<lambda()>::<lambda()>&>(struct {...} &) (__fn=...) at /usr/include/c++/11/bits/invoke.h:154
#4  0x00007ffff7f01ff6 in std::_Function_handler<void(), Ogre::Page::load(bool)::<lambda()>::<lambda()> >::_M_invoke(const std::_Any_data &) (__functor=...) at /usr/include/c++/11/bits/std_function.h:290
#5  0x00007ffff7173b42 in std::function<void ()>::operator()() const (this=0x7fffffffd830) at /usr/include/c++/11/bits/std_function.h:590
#6  0x00007ffff7173565 in Ogre::DefaultWorkQueueBase::processMainThreadTasks (this=0x5555562b0ff0) at /media/slapin/library/ogre3/ogre/OgreMain/src/OgreWorkQueue.cpp:176
#7  0x00007ffff701aaf3 in Ogre::Root::_fireFrameEnded (this=0x5555562acfe0, evt=...) at /media/slapin/library/ogre3/ogre/OgreMain/src/OgreRoot.cpp:685
#8  0x00007ffff701ac11 in Ogre::Root::_fireFrameEnded (this=0x5555562acfe0) at /media/slapin/library/ogre3/ogre/OgreMain/src/OgreRoot.cpp:712
#9  0x00007ffff701b162 in Ogre::Root::renderOneFrame (this=0x5555562acfe0) at /media/slapin/library/ogre3/ogre/OgreMain/src/OgreRoot.cpp:792
#10 0x00007ffff701b089 in Ogre::Root::startRendering (this=0x5555562acfe0) at /media/slapin/library/ogre3/ogre/OgreMain/src/OgreRoot.cpp:779
#11 0x00005555555c341e in main () at /media/slapin/library/ogre3/ogre-projects/world2/src/editor/main.cpp:835

Closes: #3530

@slapin
Copy link
Contributor Author

slapin commented Dec 26, 2025

Both QtCreator and VSCode are unusable pieces of crap and can't be used to make PRs.

@slapin slapin force-pushed the paging-prevent-load-unload-clash branch 2 times, most recently from c054d80 to 34700a5 Compare December 26, 2025 09:34
@slapin slapin marked this pull request as ready for review December 26, 2025 09:35
@slapin slapin force-pushed the paging-prevent-load-unload-clash branch from 34700a5 to 2687823 Compare December 26, 2025 09:40
@slapin slapin marked this pull request as draft December 26, 2025 14:17
@slapin slapin force-pushed the paging-prevent-load-unload-clash branch 2 times, most recently from 98bfd86 to b379a51 Compare December 26, 2025 14:47
@slapin
Copy link
Contributor Author

slapin commented Dec 26, 2025

using boolean does not solve the problem

@slapin
Copy link
Contributor Author

slapin commented Dec 26, 2025

solution with future had much more impact, however

PageResponse pres = any_cast<PageResponse>(res->getData());

// final loading behaviour
if (res->succeeded())
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
if (res->succeeded() && !mInUnload)

the cleanup should still run

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

looks like mInUpload is already non-zero when handleResponse hits and crashes.
but unload() effect is still there. So I guess if it did not crash on first handleResponse it will crash on second one. At least it looks like it. So just boolean is not enough. Or it should be cleared by some different condition...

Copy link
Contributor Author

@slapin slapin Dec 26, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

looks like if I clear it in load() the problem is no longer reproducible...

@slapin slapin force-pushed the paging-prevent-load-unload-clash branch from b379a51 to 2e33334 Compare December 26, 2025 18:11
@slapin
Copy link
Contributor Author

slapin commented Dec 26, 2025

Tested a bit and was not able to reproduce the problem so getting it out of draft...

@slapin slapin force-pushed the paging-prevent-load-unload-clash branch from 2e33334 to 6ee43ff Compare December 26, 2025 18:15
If page load is in progress, page load can
crash as the load finalizer is executed after unload.
Using additional boolean to prevent this.

To test the reproduction I create ImGui Button which runs
WorldPartition's unloadPage with PageID calculated using
current camera position. Before this change it resulted in
the following backtrace in unlucky case:

    Thread 1 "Editor" received signal SIGSEGV, Segmentation fault.
    0x00007ffff7f00f91 in Ogre::Page::handleResponse (this=0x5555586a96d0, res=0x7fffe8006900, srcQ=0x0) at /media/slapin/library/ogre3/ogre/Components/Paging/src/OgrePage.cpp:233
    233	            loadImpl();
    (gdb) bt

    #0  0x00007ffff7f00f91 in Ogre::Page::handleResponse (this=0x5555586a96d0, res=0x7fffe8006900, srcQ=0x0) at /media/slapin/library/ogre3/ogre/Components/Paging/src/OgrePage.cpp:233
    OGRECave#1  0x00007ffff7f00aa0 in operator() (__closure=0x7fffffffd830) at /media/slapin/library/ogre3/ogre/Components/Paging/src/OgrePage.cpp:186
    OGRECave#2  0x00007ffff7f02476 in std::__invoke_impl<void, Ogre::Page::load(bool)::<lambda()>::<lambda()>&>(std::__invoke_other, struct {...} &) (__f=...) at /usr/include/c++/11/bits/invoke.h:61
    OGRECave#3  0x00007ffff7f02208 in std::__invoke_r<void, Ogre::Page::load(bool)::<lambda()>::<lambda()>&>(struct {...} &) (__fn=...) at /usr/include/c++/11/bits/invoke.h:154
    OGRECave#4  0x00007ffff7f01ff6 in std::_Function_handler<void(), Ogre::Page::load(bool)::<lambda()>::<lambda()> >::_M_invoke(const std::_Any_data &) (__functor=...) at /usr/include/c++/11/bits/std_function.h:290
    OGRECave#5  0x00007ffff7173b42 in std::function<void ()>::operator()() const (this=0x7fffffffd830) at /usr/include/c++/11/bits/std_function.h:590
    OGRECave#6  0x00007ffff7173565 in Ogre::DefaultWorkQueueBase::processMainThreadTasks (this=0x5555562b0ff0) at /media/slapin/library/ogre3/ogre/OgreMain/src/OgreWorkQueue.cpp:176
    OGRECave#7  0x00007ffff701aaf3 in Ogre::Root::_fireFrameEnded (this=0x5555562acfe0, evt=...) at /media/slapin/library/ogre3/ogre/OgreMain/src/OgreRoot.cpp:685
    OGRECave#8  0x00007ffff701ac11 in Ogre::Root::_fireFrameEnded (this=0x5555562acfe0) at /media/slapin/library/ogre3/ogre/OgreMain/src/OgreRoot.cpp:712
    OGRECave#9  0x00007ffff701b162 in Ogre::Root::renderOneFrame (this=0x5555562acfe0) at /media/slapin/library/ogre3/ogre/OgreMain/src/OgreRoot.cpp:792
    OGRECave#10 0x00007ffff701b089 in Ogre::Root::startRendering (this=0x5555562acfe0) at /media/slapin/library/ogre3/ogre/OgreMain/src/OgreRoot.cpp:779
    OGRECave#11 0x00005555555c341e in main () at /media/slapin/library/ogre3/ogre-projects/world2/src/editor/main.cpp:835

Closes: #3550
@slapin slapin force-pushed the paging-prevent-load-unload-clash branch from 6ee43ff to 52bc11f Compare December 26, 2025 18:16
@slapin slapin marked this pull request as ready for review December 26, 2025 18:19
@slapin
Copy link
Contributor Author

slapin commented Dec 26, 2025

Reproduced the problem again. With the same backtrace.

@slapin slapin marked this pull request as draft December 26, 2025 20:39
@slapin
Copy link
Contributor Author

slapin commented Dec 26, 2025

It is very hard to reproduce now but still reproducible.

@slapin
Copy link
Contributor Author

slapin commented Dec 27, 2025

For some reason it is no longer possible to reproduce this under valgrind or it is super rare to do...

@slapin
Copy link
Contributor Author

slapin commented Dec 28, 2025

Still can't reproduce, removing from draft. If I can reproduce it again will debug again...

@slapin slapin marked this pull request as ready for review December 28, 2025 11:25
@paroj
Copy link
Member

paroj commented Dec 28, 2025

even if this is incomplete, the changes here are necessary..

@paroj paroj merged commit ee74d2c into OGRECave:master Dec 28, 2025
6 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Need to make terrain chunk recreation safe

2 participants