SFTtech / openage

Free (as in freedom) open source clone of the Age of Empires II engine 🚀
http://openage.dev
Other
12.69k stars 1.12k forks source link

Segfault on first launch (Debian buster) #1197

Closed DrissiReda closed 4 years ago

DrissiReda commented 4 years ago

I managed to install all dependencies and build everything without any problems.

Then when I try make run, a black window opens, then immediately closes and I get this output:

stack dump ``` INFO [py] launching openage v0.4.0-83-g6a5df2ad INFO [py] compiled by GNU 8.3.0 INFO launching engine with Path(Union(.root @ (b'cfg',), .root @ (b'assets',)):) and fps limit 0 INFO SDL audio subsystems initialized INFO Using audio device: default [freq=48000, format=32784, channels=2, samples=4096] INFO Initialized SDL video subsystems. INFO Warning: Ignoring XDG_SESSION_TYPE=wayland on Gnome. Use QT_QPA_PLATFORM=wayland to run on Wayland anyway. INFO Compiled with Qt 5.11.3 and run with Qt 5.11.3 INFO loading configuration files... INFO [py] loading config file [Union(.root @ (b'cfg',), .root @ (b'assets',))]:cfg/keybinds.oac... INFO Loading time [engine]: 0.282 s INFO Loading time [game]: 0.309 s SIGSEGV FATAL: terminate has been called current stack: Traceback (most recent call last): File ?, in __libc_start_main+0xeb [0x7fea95e8009b] File ?, in _Py_UnixMain+0x2e [0x6542de] File ?, in ? [0x653f7e] File ?, in PyRun_SimpleFileExFlags+0x17f [0x63180f] File ?, in PyRun_FileExFlags+0x97 [0x630ba7] File ?, in ? [0x630af2] File ?, in PyEval_EvalCode+0x23 [0x54dae3] File ?, in _PyEval_EvalCodeWithName+0x252 [0x54b7c2] File ?, in _PyEval_EvalFrameDefault+0x500 [0x54dff0] File ?, in ? [0x64e00d] File ?, in _PyEval_EvalFrameDefault+0x441a [0x551f0a] File ?, in ? [0x54acf0] File ?, in _PyFunction_FastCallKeywords+0x18c [0x5d847c] File ?, in _PyEval_EvalFrameDefault+0x42c3 [0x551db3] File ?, in _PyMethodDef_RawFastCallKeywords+0x224 [0x5d7b24] File ?, in ? [0x7fea9386a5bc] File ?, in ? [0x7fea93869bc1] File ?, in openage::run_game(openage::main_arguments const&)+0x4e8 [0x7fea92857eeb] File ?, in openage::Engine::run()+0x27 [0x7fea9284708d] File ?, in openage::Engine::loop()+0x102 [0x7fea928469da] File ?, in openage::gui::GUI::process_events()+0xd [0x7fea92915e01] File ?, in qtsdl::GuiEventQueue::process_callbacks()+0xc [0x7fea9291b1b4] File ?, in qtsdl::GuiEventQueueImpl::process_callbacks()+0x1c [0x7fea929205e2] File ?, in ? [0x7fea79b76401] File ?, in QEventDispatcherGlib::processEvents(QFlags)+0xf4 [0x7fea90854824] File ?, in g_main_context_iteration+0x2c [0x7fea8f76225c] File ?, in ? [0x7fea8f7621c8] File ?, in g_main_context_dispatch+0x2ae [0x7fea8f761f2e] File ?, in ? [0x7fea90855173] File ?, in QCoreApplicationPrivate::sendPostedEvents(QObject*, int, QThreadData*)+0x1cb [0x7fea908064db] File ?, in QCoreApplication::notifyInternal2(QObject*, QEvent*)+0x179 [0x7fea908034f9] File ?, in QObject::event(QEvent*)+0xe2 [0x7fea9082d0e2] File ?, in ? [0x7fea913dc099] File ?, in QQmlComponentPrivate::loadUrl(QUrl const&, QQmlComponent::CompilationMode)+0x186 [0x7fea913dbb16] File ?, in QQmlComponent::statusChanged(QQmlComponent::Status)+0x3e [0x7fea913d869e] File ?, in QMetaObject::activate(QObject*, int, int, void**)+0x8a3 [0x7fea9082c9a3] File ?, in QtPrivate::QSlotObject, void>::impl(int, QtPrivate::QSlotObjectBase*, QObject*, void**, bool*)+0x50 [0x7fea9292438f] File ?, in qtsdl::GuiSubtreeImpl::component_status_changed(QQmlComponent::Status)+0x102 [0x7fea92923d3c] File ?, in QQmlComponentPrivate::completeCreate()+0x57 [0x7fea913d91d7] File ?, in QQmlComponentPrivate::complete(QQmlEnginePrivate*, QQmlComponentPrivate::ConstructionState*)+0x81 [0x7fea913d90b1] File ?, in QQmlObjectCreator::finalize(QQmlInstantiationInterrupt&)+0x114 [0x7fea91461054] File ?, in QQmlBinding::update(QFlags)+0x213 [0x7fea91454353] File ?, in ? [0x7fea91457bc2] File ?, in QQmlBinding::evaluate(bool*)+0xd7 [0x7fea914530c7] File ?, in QQmlJavaScriptExpression::evaluate(QV4::CallData*, bool*)+0x1ff [0x7fea9144e4ff] File ?, in ? [0x7fea91397b94] File ?, in QV4::Runtime::method_loadProperty(QV4::ExecutionEngine*, QV4::Value const&, int)+0xa2 [0x7fea913a4712] File ?, in QV4::QObjectWrapper::getQmlProperty(QQmlContextData*, QV4::String*, QV4::QObjectWrapper::RevisionMode, bool*, bool) const+0x538 [0x7fea91387088] File ?, in ? [0x7fea91385bf3] File ?, in ? [0x7fea92a21229] File ?, in openage::gui::ActionModeLink::get_selection_size() const+0xc [0x7fea928fd376] File ?, in ? [0x7fea95e93840] File ?, in ? [0x7fea92930dac] File ?, in ? [0x7fea925b6901] File ?, in ? [0x7fea925b68c6] File ?, in openage::error::terminate_handler()+0x18d [0x7fea9293101f] handing over to the system... terminate called without an active exception ```

My machine:

CPU: i7 2640M RAM: 16Gb OS: Debian buster kernel: 4.19.0-1-amd64

heinezen commented 4 years ago

Can't replicate it yet, but it looks like this was introduced by #1154 . @MaanooAk Do you know what might cause this?

heinezen commented 4 years ago

It is either ecab22b2c5f227c38540be50cefd71648c1d11b9, 59239da34e60e8a6830a80f40ad4bc21d26aa2e8 or d7c9b15e6c0859875cfeeafc06a51e5b95acbc35 according to the bisect.

DrissiReda commented 4 years ago

I used the Age of Empires II with the Age of Conquerors extension installed on patch 1.0c if that helps

heinezen commented 4 years ago

We had time to test this on Debian now and it seems to be a bug in a library delivered with Debian and Ubuntu 19.04. The bug persists when using clang, although the stack trace is slightly more informative.

  File ?, in openage::gui::ActionModeLink::get_selection_size() const+0x32 [0x7f75f3ddd452]
  File ?, in openage::UnitSelection::get_units_count() const+0x1e [0x7f75f3c80d4e]
  File ?, in std::unordered_map<unsigned long, openage::UnitReference, std::hash<unsigned long>, std::equal_to<unsigned long>, std::allocator<std::pair<unsigned long const, openage::UnitReference> > >::size() const+0x15 [0x7f75f3c82735]
  File ?, in std::_Hashtable<unsigned long, std::pair<unsigned long const, openage::UnitReference>, std::allocator<std::pair<unsigned long const, openage::UnitReference> >, std::__detail::_Select1st, std::equal_to<unsigned long>, std::hash<unsigned long>, std::__detail::_Mod_range_hashing, std::__detail::_Default_ranged_hash, std::__detail::_Prime_rehash_policy, std::__detail::_Hashtable_traits<false, false, true> >::size() const+0xc [0x7f75f3c8274c]
  File ?, in ? [0x7f75f304f840]
  File ?, in ? [0x7f75f3e5f525]
  File ?, in ? [0x7f75f3408901]
  File ?, in ? [0x7f75f34088c6]
  File ?, in openage::error::terminate_handler()+0x371 [0x7f75f3e5f431]

The cause of the segfault is a call to units.size() in selection.h.

https://github.com/SFTtech/openage/blob/6a5df2adc8e64611b4f2aa240f9a9ba282e623bf/libopenage/unit/selection.h#L85

Somehow .size() and other calls like .empty() fail. I don't know the exact root cause here, but it seems to only affect Debian and Ubuntu 19.04 (and maybe 18.10). Ubuntu 19.10 and 18.04 LTS don't create these issues.

For a solution, we would have to test which library is the issue. Otherwise, you unfortunately have to wait until the distros upgrade their repos to a newer version of the libraries.

DrissiReda commented 4 years ago

Do you have the correct versions that work? I can try compiling them in a virtual environment as a temporary workaround

heinezen commented 4 years ago

The last working commit on Debian is fdb3b609e9e669d1577b07f4f5e53b9b11f5b4ed

You can try that until we figured out what's the main problem.

DrissiReda commented 4 years ago

alright I'll try that thanks

sandsmark commented 4 years ago

considering selection is a raw pointer in ActionModeLink I think it might be a dangling pointer at that point? Just looking at the diff in the PR I don't see any initialization at least. Throwing a {} after the declaration of selection should make it okay, though, since there seems to be appropriate nullchecks in place.

check if this fixes it:

diff --git libopenage/gui/game_control_link.h libopenage/gui/game_control_link.h
index 0aa1baab..c2963948 100644
--- libopenage/gui/game_control_link.h
+++ libopenage/gui/game_control_link.h
@@ -158,7 +158,7 @@ private slots:
        QString ability;
        QString population;
        bool population_warn;
-       const UnitSelection *selection;
+       const UnitSelection *selection = nullptr;

        QString selection_name;
        QString selection_icon;
@@ -307,13 +307,13 @@ private slots:
        virtual void on_core_adopted() override;
        virtual void componentComplete() override;

-       OutputModeLink *mode;
+       OutputModeLink *mode = nullptr;
        int effective_mode_index;
        int mode_index;
        QVariantList modes;
        // TODO: remove engine because it's already accessible through the game
-       EngineLink *engine;
-       GameMainLink *game;
+       EngineLink *engine = nullptr;
+       GameMainLink *game = nullptr;
        QString current_player_name;
        int current_civ_index;
 };
heinezen commented 4 years ago

@sandsmark That works!

Do you want to create a PR? :D