OxBat commented on PR #586:
URL: https://github.com/apache/logging-log4cxx/pull/586#issuecomment-3811465278
Thanks for the challenge @swebb2066.
The difference is fundamental: **The current implementation is
mathematically broken even in a single-threaded (quiescent) scenario.**
Here is exactly why the current code causes a deterministic crash regardless
of concurrency, based on `AsyncAppender::dispatch`:
**The Mathematical Flaw**
The reader logic at Line 519 relies on a strict invariant:
```cpp
// Line 519 in AsyncAppender::dispatch
auto index = priv->dispatchedCount % priv->buffer.size();
```
If `priv->buffer.size()` changes via `setBufferSize` (Line 448), the result
of the modulus changes, but the data remains in the old slots. This invalidates
the mapping immediately.
**Scenario (Current Code Failure):**
1. **Initial State:** `BufferSize` = 10. `dispatchedCount` = 15.
- The data is physically stored at index **5** (`15 % 10`).
2. **Action:** We call `setBufferSize(20)`.
- Line 448: `priv->buffer.resize(20)` expands the vector. The existing
data stays at index 5. Indices 10-19 contain default-constructed/empty events.
3. **The Crash:** The dispatcher thread resumes at Line 519.
- It calculates: `15 % 20 = 15`.
- It accesses `buffer[15]`.
- **Result:** It reads an empty/invalid event instead of the real data at
index 5. This leads to data corruption or a crash when dereferencing `event`.
**My Fix (Drain & Re-align)**
My patch fixes this by "linearizing" the buffer during resize. It moves the
data from the old slots (e.g., index 5) to index 0, 1, 2... and resets the
atomic counters to match the new linear layout (`dispatchedCount` becomes 0).
1. It moves data from slot **5** to slot **0**.
2. It resets `dispatchedCount` to **0**.
3. Line 519 becomes: `0 % 20 = 0`. **Success**.
**Conclusion:**
- **Current Code:** Broken by design. It fails 100% of the time if the
buffer has wrapped, even if logging is paused.
- **My Fix:** Correct by design. It works reliably as long as the caller
respects the quiescence contract.
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: [email protected]
For queries about this service, please contact Infrastructure at:
[email protected]