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]

Reply via email to