Skip to content

Conversation

@cgcote
Copy link

@cgcote cgcote commented Dec 22, 2025

What does this PR do?

Use lazy initialization to prevent concurrent duplicate reads

Multiple threads could concurrently read lastFatalAnrSent as null before
any writes occurred, causing duplicate ANR reports to be sent. The property
was implemented as a getter that read from disk on every access, allowing
race conditions where multiple threads would all see null and attempt to
report the same ANR.

Changed lastFatalAnrSent from a property getter to a lazy-initialized
property. This ensures the file is read exactly once in a thread-safe manner,
and the value is cached in memory for all subsequent accesses.

Use lazy initialization to prevent concurrent duplicate reads

  ## Problem
  Multiple threads could concurrently read `lastFatalAnrSent` as null before
  any writes occurred, causing duplicate ANR reports to be sent. The property
  was implemented as a getter that read from disk on every access, allowing
  race conditions where multiple threads would all see null and attempt to
  report the same ANR.

  ## Solution
  Changed `lastFatalAnrSent` from a property getter to a lazy-initialized
  property. This ensures the file is read exactly once in a thread-safe manner,
  and the value is cached in memory for all subsequent accesses.
@datadog-official
Copy link

datadog-official bot commented Dec 22, 2025

🎯 Code Coverage
Patch Coverage: 80.00%
Overall Coverage: 66.24% (-0.10%)

View detailed report

This comment will be updated automatically if new data arrives.
🔗 Commit SHA: 43f5e12 | Docs | Datadog PR Page | Was this helpful? Give us feedback!

@codecov-commenter
Copy link

Codecov Report

❌ Patch coverage is 80.00000% with 1 line in your changes missing coverage. Please review.
✅ Project coverage is 71.24%. Comparing base (cc0f647) to head (43f5e12).
⚠️ Report is 23 commits behind head on develop.

Files with missing lines Patch % Lines
...n/com/datadog/android/core/internal/CoreFeature.kt 80.00% 0 Missing and 1 partial ⚠️
Additional details and impacted files
@@             Coverage Diff             @@
##           develop    #3071      +/-   ##
===========================================
+ Coverage    71.16%   71.24%   +0.08%     
===========================================
  Files          878      878              
  Lines        32129    32130       +1     
  Branches      5432     5432              
===========================================
+ Hits         22862    22889      +27     
+ Misses        7714     7707       -7     
+ Partials      1553     1534      -19     
Files with missing lines Coverage Δ
...n/com/datadog/android/core/internal/CoreFeature.kt 84.90% <80.00%> (+0.04%) ⬆️

... and 36 files with indirect coverage changes

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@cgcote cgcote marked this pull request as ready for review December 22, 2025 12:52
@cgcote cgcote requested a review from a team as a code owner December 22, 2025 12:52
@cgcote
Copy link
Author

cgcote commented Dec 23, 2025

@codex review

@DataDog DataDog deleted a comment from chatgpt-codex-connector bot Dec 23, 2025
Copy link

@chatgpt-codex-connector chatgpt-codex-connector bot left a comment

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment on lines +242 to +246
internal val lastFatalAnrSent: Long? by lazy {
val file = File(storageDir, LAST_FATAL_ANR_SENT_FILE_NAME)
if (file.existsSafe(internalLogger)) {
file.readTextSafe(Charsets.UTF_8, internalLogger)?.toLongOrNull()
} else {

Choose a reason for hiding this comment

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

P1 Badge Cache not refreshed after ANR timestamp writes

The new lazy cache for lastFatalAnrSent (CoreFeature) is only computed once and never updated when writeLastFatalAnrSent/deleteLastFatalAnrSent mutate the backing file. If handleAnrCrash is invoked again in the same process after the first write (e.g., iterating over multiple ApplicationExitInfo entries), the duplicate check will still read the stale cached value (often null) and can emit the same ANR repeatedly. The previous getter reread the file on every access, so the in-memory value always reflected the latest write.

Useful? React with 👍 / 👎.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants