-
-
Notifications
You must be signed in to change notification settings - Fork 385
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
scenegraph/Serializer.h: load of misaligned address #5687
Comments
Found one more place. We are missing 1 byte of padding after pioneer/src/scenegraph/BinaryConverter.cpp Lines 292 to 317 in 8b02b62
Also: we have to insert 4 bytes of padding somewhere in here (either at the end or after reading |
And one more example. After reading pioneer/src/scenegraph/CollisionGeometry.cpp Lines 57 to 69 in 8b02b62
|
The serializer API should encapsulate the alignment and padding concerns instead of making it the responsibility of the caller to call the right methods in the right order and carefully count the bytes. |
This is a very well-documented issue, and I highly appreciate the time you took to delve deeply into the problem and propose solutions. There are several in-progress efforts to modernize other parts of the codebase (mostly rendering related) which will necessitate a higher-level redesign/reconsideration of how certain parts of the SGM format operate, and for that reason (among others) a rewrite to use Protobuf et. al. is not a candidate solution at this time. In the interest of completeness, I should point out that 8-byte alignment is not a hardware or software requirement for any operations of the serialization facilities except the very few sections of That being said, some simple benchmarking shows that invoking
This is possibly because the Pioneer user directory is now |
I indeed was searching in the wrong place - the root of the git repo. |
Observed behaviour
UndefinedBehaviorSanitizer complains about "load of misaligned address" during game starttup. I see about a dozen messages like below.
Expected behaviour
No misaligned reads
Note: the C++ standard allows compilers to assume misaligned reads (just like any other undefined behaviour) never happen. The compiler is than allowed to make an arbitrarily long and complex chain of logic deductions from that and use this information to mangle your code until it is completely unrecognisable. We should probably fix this.
Steps to reproduce
CXXFLAGS="-fsanitize=address,pointer-compare,pointer-subtract,undefined" LDFLAGS="$CXXFLAGS" cmake -S . -B build/
Note: this command assumes you are in the git root dirrectory rather than in build/make -C build/
make -C build/ build-data
UBSAN_OPTIONS=print_stacktrace=1 ./pioneer
My complier: g++ (GCC) 13.2.1 20231205 (Red Hat 13.2.1-6)
My pioneer version (and OS): 8b02b62 built from source (and Fedora release 39)
My output.txt (required) and game save (optional, but recommended) stdout&stderr.txt (note: there was no output.txt so I just captured stdout&stderr). No save necessary - the errors happen before the game shows the main menu.
Observations
I have found two places where we forgot to insert padding in the SGM format, but it would surprise me if there are not many more
linear
because float wants to be 4-byte aligned. Plus: we are missing 4 bytes of padding at the end - just in case something later in the file contains a double or int64.pioneer/src/scenegraph/Thruster.cpp
Lines 130 to 137 in 8b02b62
pioneer/src/scenegraph/Serializer.h
Lines 180 to 190 in 8b02b62
Possible fixes
Use memcpy() instead of reinterpret_cast()
Make the public API of Serializer::Writer and Serializer::Reader always insert padding to the 8 byte boundary after writing/reading. This might be somewhat inefficient in terms of file size, but is relatively easy to implement.
Make the public API of Serializer::Writer and Serializer::Reader calculate the minimum necessary padding for the next field and insert the padding before writing/reading
Fix Thruster::Save&Thruster::Load, Writer::Blob & Reader::Blob and many other places to insert&skip the necessary padding. This is fragile - eventually someone will make a similar mistake again.
Stop reinventing the wheel and replace Serializer with https://capnproto.org, https://protobuf.dev or https://flatbuffers.dev
Note: every option other than 1 will require bumping
SGM_VERSION
to a new version.The text was updated successfully, but these errors were encountered: