| FazBrowse GitHub Viewer | Trending | | Home |
| Tools: [Download Repo ZIP] [Original HTTPS Page] |
Sorry, something went wrong.
Codex Review SummaryThis comment shows the latest Codex review activity on this pull request.
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings. |
Sorry, something went wrong.
There was a problem hiding this comment.
Sorry, something went wrong.
There was a problem hiding this comment.
Here are some automated review suggestions for this pull request.
Reviewed commit: 71c668aa20
ℹ️ About Codex in GitHubCodex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you
If Codex has suggestions, it will comment; otherwise it will react with 👍.
When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".
Sorry, something went wrong.
Sorry, something went wrong.
CI Test ResultsRun: #37782741352 | Commit: ad32032 | Duration: 17m 47s (longest job)
Status Overview
Legend: ✅ passed | ❌ failed | ⚪ skipped | 🚫 cancelled Summary: Total: 32 | Passed: 32 | Failed: 0 Updated: 2026-10-08 13:48:01 UTC |
Sorry, something went wrong.
|
@jbachorik thanks for the review. All five are addressed in e30f3d0:
Re the gtest-tsan-arm64 failure on 31ab198: it was CallTraceStorageTest.PutWithExistingIdNoInfiniteLoopWhenFull hitting its fixed 10 s deadline under TSan on a slow runner. That test is untouched by this PR, and the same job passed on 6320a58, which contains 31ab198 unchanged. The new push re-runs CI. |
Sorry, something went wrong.
StringDictionary::clearAll() waited for all RefCountGuards to clear, but on timeout the drain only logged a warning and returned. clearAll() then cleared all three buffers anyway, freeing overflow nodes and arena chunks that a guarded lookup could still be reading or writing. clearStandby() had the same problem one rotation later: it cleared its target without any drain, so a guard that outlived rotate()'s timed-out drain could still be using the buffer. Add RefCountGuard::tryWaitForRefCountsToClear(), which waits only for guards on the given resources and reports a timeout instead of swallowing it. clearAll() now drains just its own three buffers, so traffic on the other dictionaries can neither delay nor fail the reset, and on timeout leaves the dictionary entirely unchanged and returns false. clearStandby() drains its target and skips the clear on timeout. Profiler::start() logs a dictionary it could not reset and only signals a ContextValueCache reset when the context-value map was really reset. Remove waitForAllRefCountsToClear(), which no longer has callers, and update the StringDictionary design doc, which still described the removed-then-restored _accepting recheck and claimed the arena made a stale read safe. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Profiler::start() calls Counters::reset() right after resetting the dictionaries. That erased the DICTIONARY_DRAIN_TIMEOUTS increment of a reset skipped on a drain timeout, and zeroed the DICTIONARY_PAGES and DICTIONARY_BYTES gauges although the dictionaries keep their root tables and first arena chunks, and all of their storage when the reset was skipped. Freeing that storage later drove the gauges negative. Each dictionary buffer now tracks its live overflow tables and arena chunks and can re-add them to the gauges. Profiler::start() does so for all three dictionaries after Counters::reset(), and re-adds one drain timeout per skipped reset. The dictionary and counter reset steps move into resetDictionaries() and resetCounters() so a gtest can run them. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
StringDictionary::clearAll() and clearStandby() now only report whether they reset; Profiler turns a skipped reset into DICTIONARY_DRAIN_TIMEOUTS and a warning, in resetRecordingState() for start() and in rotateDictsAndRun() for the standby clears. Before, clearAll() counted but did not log, clearStandby() did both, and Profiler logged and then had to re-add the count that its own Counters::reset() had erased. resetRecordingState() now covers the whole reset sequence of a fresh start(), so the count no longer travels between helpers. Remove _class_map_lock: nothing else takes it, so holding it around clearAll() synchronised nothing. Say that DICTIONARY_KEYS counts keys newly assigned since the last clearStandby(), not buffer contents. In the StringDictionary design doc, rewrite the intro that still called a missed racing reader harmless because of the arena, and qualify the "no entry lost during rotate()" invariant for a timed-out drain. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
There was a problem hiding this comment.
Thanks for cleaning this up. Looking good!
Sorry, something went wrong.
| Back | FazBrowse Home | New Git URL |
What does this PR do?:
Stops StringDictionary from freeing or resetting buffer storage while a guarded accessor may still be using it.
Motivation:
PROF-16136. clearAll() disabled new accesses, called waitForAllRefCountsToClear() and then cleared all buffers unconditionally. On timeout (~500 ms) the drain only logged a warning, so a lookup that had already passed the _accepting recheck could resume into freed overflow SBTable nodes or arena chunks.
Two things made this more likely than the ticket describes:
Additional Notes:
How to test the change?:
New gtests:
Results:
For Datadog employees:
credentials of any kind, I've requested a security review (run the dd:platform-security-review
skill, or file a request via the PSEC review form).
bewaire also runs automatically on every PR.
🤖 Generated with Claude Code