Fix atomic access to unaligned fields causing panics on 32bit systems #35
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
We access the "written" and "entries" fields in "Archiver" and "Extractor"
using atomic operations.
This operations require the fields to be 8 byte aligned.
Otherwise they panic at runtime.
On 32bit systems, int64 fields are not necessarily aligned to 8 bytes.
They may just be aligned to 4 bytes depending on the fields before them.
This currently causes fastzip to reproducably fail archiving and extraction
on 32bit systems.
Move the fields which are accessed via atomic operations
to the start of the struct to properly align them and avoid the problem.
See
https://go101.org/article/memory-layout.html
"The Alignment Requirement for 64-bit Word Atomic Operations"
However, on 32-bit architectures, the alignment guarantee
made by the standard Go compiler for 64-bit words is only 4 bytes.
64-bit atomic operations on a 64-bit word which is not 8-byte aligned
will panic at runtime.
...
The ways are described as the first (64-bit) word in a variable
or in an allocated struct, array, or slice can be relied upon to be 64-bit aligned.
See
https://pkg.go.dev/sync/atomic#pkg-note-BUG
On ARM, 386, and 32-bit MIPS, it is the caller's responsibility
to arrange for 64-bit alignment of 64-bit words accessed atomically.
The first word in a variable or in an allocated struct, array,
or slice can be relied upon to be 64-bit aligned.
Related
golang/go#11891
The panic behavior can easily be reproduced by running "go test" in fastzip
on Windows with go 1.17.6 i386 installed.