Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions statsd/buffered_metric_context.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import (
// and Timing. Since those 3 metric types behave the same way and are sampled
// with the same type they're represented by the same class.
type bufferedMetricContexts struct {
_ [4]byte // Aligin to a 4-byte boundary

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have a concern that this approach can move the problem, but not eliminate it.

Aggregator is heap-allocated so it starts at an 8-byte aligned base address. On 32-bit the layout of aggregator up to histograms sums to offset 64 (83 + 4 + 123), so histograms.nbContext is fine. The problem is distributions and timings, which follow histograms at offset 64 + sizeof(bufferedMetricContexts). If that size is not a multiple of 8, the nbContext field in distributions/timings falls at a 4-byte but not 8-byte aligned address.

If we add 4 bytes at the start of the struct, it moves nbContext to offset 4 within bufferedMetricContexts, but then histograms starts at base+64, histograms.nbContext is now at base+68 so not aligned.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you for your detailed comment.

You are right. I wanted to fix this panic on a 32-bit binary with Go 1.22.4:

panic: unaligned 64-bit atomic operation

The panic happened around atomic.AddUint64(&bc.nbContext, ...) .

But I now understand that my fix is not enough.
Adding 4 bytes before nbContext may only move the alignment problem to another field, as you said.

Also, some things have changed on my side since I opened this PR.
So I will debug this again in my current environment.

I will check the struct layout with GOARCH=386.
If my understanding is correct, a better fix may be to keep nbContext as the first field, and add [4]byte padding after randomLock .

Thank you again for explaining this carefully.

nbContext uint64
mutex sync.RWMutex
values bufferedMetricMap
Expand Down