Closed
Description
Describe the bug
atomic.panicUnaligned
will occur due to unaligned struct member size
. This occurs since the size of the endpoints
sync.Map is variable, depending on the machine word size. On 64-bit archs, sync.Map is 32 bytes. On 32-bit archs, sync.Map is 20 bytes - resulting in the misalignment of the subsequent members in the EndpointCache
struct:
type EndpointCache struct {
endpoints sync.Map
endpointLimit int64
// size is used to count the number elements in the cache.
// The atomic package is used to ensure this size is accurate when
// using multiple goroutines.
size int64
}
$ GOARCH=386 go run foo.go
size of EndpointCache.endpoints: 20
offset of EndpointCache.endpoints: 0
offset of EndpointCache.endpointLimit: 20
offset of EndpointCache.size: 28
panic: unaligned 64-bit atomic operation
goroutine 1 [running]:
runtime/internal/atomic.panicUnaligned()
/usr/lib/go-1.21/src/runtime/internal/atomic/unaligned.go:8 +0x2d
runtime/internal/atomic.Xadd64(0x9ca201c, 0x1)
/usr/lib/go-1.21/src/runtime/internal/atomic/atomic_386.s:125 +0x11
main.main()
/tmp/foo/foo.go:30 +0x1e6
exit status 2
Expected Behavior
No panic to occur.
Current Behavior
The following test fails on 32-bit archs:
=== RUN TestEndpointCache_Get_prune
--- FAIL: TestEndpointCache_Get_prune (0.00s)
panic: unaligned 64-bit atomic operation [recovered]
panic: unaligned 64-bit atomic operation
goroutine 6 [running]:
testing.tRunner.func1.2({0x81c33c0, 0x822a528})
/usr/lib/go-1.21/src/testing/testing.go:1545 +0x2ab
testing.tRunner.func1()
/usr/lib/go-1.21/src/testing/testing.go:1548 +0x43e
panic({0x81c33c0, 0x822a528})
/usr/lib/go-1.21/src/runtime/panic.go:914 +0x1ec
runtime/internal/atomic.panicUnaligned()
/usr/lib/go-1.21/src/runtime/internal/atomic/unaligned.go:8 +0x2d
runtime/internal/atomic.Xadd64(0xa0140dc, 0x1)
/usr/lib/go-1.21/src/runtime/internal/atomic/atomic_386.s:125 +0x11
github.com/aws/aws-sdk-go-v2/service/internal/endpoint-discovery.(*EndpointCache).Add(0xa0140c0, {{0x81eb800, 0x3}, {0xa0140f0, 0x2, 0x2}})
/home/daniel/Work/Debian/golang-github-aws-aws-sdk-go-v2/service/internal/endpoint-discovery/cache.go:76 +0xd1
github.com/aws/aws-sdk-go-v2/service/internal/endpoint-discovery.TestEndpointCache_Get_prune(0xa1280f0)
/home/daniel/Work/Debian/golang-github-aws-aws-sdk-go-v2/service/internal/endpoint-discovery/cache_test.go:11 +0x25b
testing.tRunner(0xa1280f0, 0x81fda70)
/usr/lib/go-1.21/src/testing/testing.go:1595 +0x120
created by testing.(*T).Run in goroutine 1
/usr/lib/go-1.21/src/testing/testing.go:1648 +0x3dd
FAIL github.com/aws/aws-sdk-go-v2/service/internal/endpoint-discovery 0.004s
FAIL
Reproduction Steps
Force test to execute as a 32-bit GOARCH, e.g.
GOARCH=386 go test ./...
Possible Solution
Reorder the struct members so that the size
member, which is used in atomic operations, is 64-bit aligned.
Additional Information/Context
No response
AWS Go SDK V2 Module Versions Used
github.com/aws/aws-sdk-go-v2/service/internal/endpoint-discovery github.com/aws/[email protected]
github.com/aws/aws-sdk-go-v2/service/internal/endpoint-discovery github.com/aws/[email protected]
github.com/aws/aws-sdk-go-v2/service/internal/endpoint-discovery [email protected]
github.com/aws/[email protected] github.com/aws/[email protected]
github.com/aws/[email protected] github.com/google/[email protected]
github.com/aws/[email protected] github.com/jmespath/[email protected]
github.com/aws/[email protected] github.com/google/[email protected]
Compiler and Version used
go version go1.21.1 linux/amd64
Operating System and version
Linux xps15 6.5.0-21-generic #21-Ubuntu SMP PREEMPT_DYNAMIC Wed Feb 7 14:17:40 UTC 2024 x86_64 x86_64 x86_64 GNU/Linux
Activity