-
-
Notifications
You must be signed in to change notification settings - Fork 464
feat(anr): Profile main thread when ANR and report ANR profiles to Sentry #4899
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Conversation
|
🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <[email protected]>
| final AnrProfileManager provider = new AnrProfileManager(options); | ||
| anrProfile = provider.load(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Bug: AnrProfilingIntegration and AnrV2Integration concurrently access the same QueueFile without synchronization.
Severity: CRITICAL | Confidence: 1.00
🔍 Detailed Analysis
The AnrProfilingIntegration (writer) and AnrV2Integration (reader) concurrently access the same underlying QueueFile at options.getCacheDirPath() + "anr_profile" without any synchronization. This violates the explicit contract of QueueFile which states, "Only one instance should access a given file at a time." Concurrent unsynchronized access can lead to data corruption, lost stack traces, or file format inconsistencies due to conflicting writes and reads to the shared file header and data structures.
💡 Suggested Fix
Implement a synchronization mechanism (e.g., file-level locking) to ensure exclusive access to the QueueFile, or refactor to use a single QueueFile instance managed by a central component.
🤖 Prompt for AI Agent
Review the code at the location below. A potential bug has been identified by an AI
agent.
Verify if this is a real issue. If it is, propose a fix; if not, explain why it's not
valid.
Location:
sentry-android-core/src/main/java/io/sentry/android/core/AnrV2Integration.java#L326-L327
Potential issue: The `AnrProfilingIntegration` (writer) and `AnrV2Integration` (reader)
concurrently access the same underlying `QueueFile` at `options.getCacheDirPath() +
"anr_profile"` without any synchronization. This violates the explicit contract of
`QueueFile` which states, "Only one instance should access a given file at a time."
Concurrent unsynchronized access can lead to data corruption, lost stack traces, or file
format inconsistencies due to conflicting writes and reads to the shared file header and
data structures.
Did we get this right? 👍 / 👎 to inform future reviews.
Reference_id: 2623394
| } | ||
| } catch (IOException e) { | ||
| logger.log(ERROR, "Failed to create stacktrace queue", e); | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Bug: AnrProfileManager instances created in AnrV2Integration are not closed, leading to file descriptor leaks.
Severity: CRITICAL | Confidence: 1.00
🔍 Detailed Analysis
Instances of AnrProfileManager created within AnrV2Integration.applyAnrProfile() are not properly closed. Each AnrProfileManager creates an underlying QueueFile which holds a RandomAccessFile resource. Since AnrProfileManager does not implement Closeable and its ObjectQueue field is never closed, these RandomAccessFile instances remain open indefinitely. This leads to file descriptor leaks, which can exhaust system resources and cause failures, especially if multiple ANR events occur.
💡 Suggested Fix
Ensure AnrProfileManager implements Closeable and its close() method is called after use, for example, by wrapping its instantiation and usage in a try-with-resources block.
🤖 Prompt for AI Agent
Review the code at the location below. A potential bug has been identified by an AI
agent.
Verify if this is a real issue. If it is, propose a fix; if not, explain why it's not
valid.
Location:
sentry-android-core/src/main/java/io/sentry/android/core/anr/AnrProfileManager.java#L47
Potential issue: Instances of `AnrProfileManager` created within
`AnrV2Integration.applyAnrProfile()` are not properly closed. Each `AnrProfileManager`
creates an underlying `QueueFile` which holds a `RandomAccessFile` resource. Since
`AnrProfileManager` does not implement `Closeable` and its `ObjectQueue` field is never
closed, these `RandomAccessFile` instances remain open indefinitely. This leads to file
descriptor leaks, which can exhaust system resources and cause failures, especially if
multiple ANR events occur.
Did we get this right? 👍 / 👎 to inform future reviews.
Reference_id: 2623394
sentry-android-core/src/main/java/io/sentry/android/core/anr/AnrCulpritIdentifier.java
Show resolved
Hide resolved
sentry-android-core/src/main/java/io/sentry/android/core/anr/AggregatedStackTrace.java
Outdated
Show resolved
Hide resolved
Performance metrics 🚀
|
| Revision | Plain | With Sentry | Diff |
|---|---|---|---|
| ee747ae | 415.92 ms | 470.15 ms | 54.23 ms |
| 9fbb112 | 401.87 ms | 515.87 ms | 114.00 ms |
| 9fbb112 | 404.51 ms | 475.65 ms | 71.14 ms |
| 604a261 | 380.65 ms | 451.27 ms | 70.62 ms |
| 674d437 | 355.28 ms | 504.18 ms | 148.90 ms |
| 33a08cc | 267.08 ms | 340.45 ms | 73.37 ms |
| 27d7cf8 | 309.43 ms | 364.27 ms | 54.85 ms |
| 96449e8 | 361.30 ms | 423.39 ms | 62.09 ms |
| c8125f3 | 397.65 ms | 485.14 ms | 87.49 ms |
| ee747ae | 382.73 ms | 435.41 ms | 52.68 ms |
App size
| Revision | Plain | With Sentry | Diff |
|---|---|---|---|
| ee747ae | 1.58 MiB | 2.10 MiB | 530.95 KiB |
| 9fbb112 | 1.58 MiB | 2.11 MiB | 539.18 KiB |
| 9fbb112 | 1.58 MiB | 2.11 MiB | 539.18 KiB |
| 604a261 | 1.58 MiB | 2.10 MiB | 533.42 KiB |
| 674d437 | 1.58 MiB | 2.10 MiB | 530.94 KiB |
| 33a08cc | 1.58 MiB | 2.12 MiB | 555.28 KiB |
| 27d7cf8 | 1.58 MiB | 2.12 MiB | 549.42 KiB |
| 96449e8 | 1.58 MiB | 2.11 MiB | 539.35 KiB |
| c8125f3 | 1.58 MiB | 2.10 MiB | 532.32 KiB |
| ee747ae | 1.58 MiB | 2.10 MiB | 530.95 KiB |
sentry-android-core/src/main/java/io/sentry/android/core/anr/AnrCulpritIdentifier.java
Show resolved
Hide resolved
…ntry-java into markushi/feat/anr-profiling
| options); | ||
| chunk.setSentryProfile(profile); | ||
|
|
||
| options.getLogger().log(SentryLevel.DEBUG, ""); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
| anrProfile = provider.load(); | ||
| } catch (Throwable t) { | ||
| options.getLogger().log(SentryLevel.INFO, "Could not retrieve ANR profile"); | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Bug: Concurrent File Access Causes Data Corruption
Creating a new AnrProfileManager instance in applyAnrProfile while AnrProfilingIntegration may still be running creates a race condition. Both instances open file handles to the same anr_profile file, potentially corrupting data as AnrProfilingIntegration writes while AnrV2Integration reads and closes the queue file, leading to concurrent access issues with the underlying QueueFile.
📜 Description
Adds ANR (Application Not Responding) profiling integration that profiles the main thread when an ANR is detected and reports the captured profiles to Sentry.
Key Changes:
AnrProfilingIntegrationto capture profiles during ANR eventsAnrProfileManagerto manage ANR profile lifecycleAnrCulpritIdentifierto identify the culprit code causing ANR💡 Motivation and Context
This feature enables better ANR diagnostics by capturing profiling data at the time of ANR detection, allowing developers to identify performance bottlenecks and problematic code paths causing application hangs.
💚 How did you test it?
📝 Checklist
sendDefaultPIIis enabled.🔮 Next steps