Hello there, some people reported our current 0.51 build experiences issue on newer Linux distributions. An easy way to patch your downloaded game is provided right below. There is also a conference this Sunday that will be viewable online.
Conference this Sunday for Debian
So, on Sunday November 22th (tomorrow) at 19:30 UTC there will be a 45 minutes conference entitled:
Building a community as a service: how to stop suffering from “that code is meant to be forked”
Here is the fourth cover:
Earlier id Tech engines were well known to have seen their source code opened when they were replaced and thus unprofitable. While this was a huge benefit for mankind, game developers still suffer today from design choices and mindset induced by the fact such code base was meant to die. 20 years later we will focus on id Tech 3 heritage, how both the market, open source communities and game development practices evolved, and embark in the journey of the required transition from dead code dump to an ecosystem as a service.
I’ll be the speaker, the live stream is there.
If you miss the appointment, don’t worry! The video will be available online after the broadcast, and a full transcript will be published.
How to patch your game if you have trouble running it on recent Linux distribution
Issue was confirmed on Fedora, Arch Linux, Debian testing (Debian stable not having the problem) and derivatives. As distributions are shipping updates, more are likely to break.
The symptom is easy to notice: the game segfaults immediately at startup before being able to do anything. Yes that’s pretty bad.
TL,DR: if you experience the bug, here is an easy way to download a patcher:
wget http://dl.unvanquished.net/hotfix/unvanquished_0.51.1_patch chmod +x unvanquished_0.51.1_patch
Then you can run the game with the patcher this way:
This will work out of the box if you’ve downloaded and installed the game using our game updater with default options. If you’ve used the universal zip, the easier for you is to store the patcher right to the
daemon binary and run it from that directory.
The patcher is a launcher that patches a copy of the binary then runs it (and leaves the broken one unmodified). So until 0.52 is out, use this simple launcher.
You can also pass
daemonded as parameter to patch and run the server, you can pass all the usual game command line options after that.
It’s also possible to rebuild the binaries, but that involves more work and on our side we are focusing on the upcoming 0.52 release.
People just wanting to fix definitely their binaries can do this (better make a backup before!):
printf '\x8b\x74\x24\x20\x48\x31\xc0\x85\xf6\x0f\x94\xc0\xeb\x3f' \ | dd of=daemon bs=1 seek=2186551 count=14 conv=notrunc printf '\x8b\x74\x24\x20\x48\x31\xc0\x85\xf6\x0f\x94\xc0\xeb\x3f' \ | dd of=daemonded bs=1 seek=738855 count=14 conv=notrunc
More details about the problem, if you like to dive deep into the matrix
Yes, this is true witchcraft. For geeky geeks, here are some explanations from our master wizard slipher:
The crash is caused by a mistake or shortcoming in the implementation of the “Dual ABI” concept in libstdc++. For this bug, the relevant dual-ABI class is
std::error_category(which has the dual ABI because it has a member function returning an
std::string). Following this commit, stdlibc++ defines two versions of
error_category. For new builds, the headers point to the new version which is defined in an inline namespace
_V2. The inline namespace changes the mangled name of symbols in compiled code, while there is no change to source code which uses
The 0.51 release was apparently built with GCC 4.9, which predates the introduction of the dual ABI. This means it gets linked to the backwards-compatibility symbols when using new solibs. A build using GCC 5+ should have the headers pointing at the new ABI, and thereby avoid the problem (it links to
std::_V2::system_category()and avoids constructing any backwards-compatibility objects). So nothing need be done to avoid the problem in new releases (although I’ll remove the call to
default_error_conditionin any case, since it does not make sense to use it).
I reproduced the crash using
libstdc++.so.6.0.28; I believe
libstdc++.so.6.0.21should be the first version that contains the dual ABI changes and therefore risks hitting the bug.
And here he gave more explanations again:
I doubt there is anything to be done on the libstdc++ side. It is probably impossible to make a build that can work with both of the
error_categoryABIs, and the new one has been out for a long time now.
The conjecture from my previous comment that it depends on the random value in the RDX register at the time of the call to
error_category::equivalent(which was supposed to be a call to
error_category::default_error_condition) was correct. On Mageia, RDX happened to contain a readable address, while on Debian Buster it contained 4.
error_category::default_error_conditionis supposed to return an
error_conditionstruct consisting of an integer code and a pointer to an
error_category. The ABI dictates that the integer code goes in RAX and the pointer in RDX.
error_category::equivalentreturns a boolean which goes in RAX. It returns false, having compared against random junk. And it so happens that in this solib build, the last thing that gets put in RDX by
error_category::equivalentis the address of
std::system_category(), an instance of
error_category. So by pure luck, a valid and correct
error_conditionis returned and the train is back on the rails.
I could make a binary patch for the 0.51
daemonto bypass the problem by replacing a few instructions in
CreateCrashDumpPath, if it would be helpful.
This is really helpful of indeed, so he wrote that
dd spell and you can do it yourself or use the patcher.
And you can still play Unvanquished while waiting for 0.52!