From d44a91e316de29de56fedd061bdca1fe0a5ef41b Mon Sep 17 00:00:00 2001 From: Markus Hintersteiner Date: Wed, 2 Nov 2022 17:01:22 +0100 Subject: [PATCH 1/3] Fix NoSuchElementException in CircularFifoQueue when cloning a Scope --- sentry/src/main/java/io/sentry/Scope.java | 2 +- .../java/io/sentry/SynchronizedQueue.java | 14 +++++++++++ sentry/src/test/java/io/sentry/ScopeTest.kt | 25 +++++++++++++++++++ 3 files changed, 40 insertions(+), 1 deletion(-) diff --git a/sentry/src/main/java/io/sentry/Scope.java b/sentry/src/main/java/io/sentry/Scope.java index 16a9f535e2..0d5904fc6a 100644 --- a/sentry/src/main/java/io/sentry/Scope.java +++ b/sentry/src/main/java/io/sentry/Scope.java @@ -97,7 +97,7 @@ public Scope(final @NotNull SentryOptions options) { this.fingerprint = new ArrayList<>(scope.fingerprint); this.eventProcessors = new CopyOnWriteArrayList<>(scope.eventProcessors); - final Queue breadcrumbsRef = scope.breadcrumbs; + final Breadcrumb[] breadcrumbsRef = scope.breadcrumbs.toArray(new Breadcrumb[0]); Queue breadcrumbsClone = createBreadcrumbsList(scope.options.getMaxBreadcrumbs()); diff --git a/sentry/src/main/java/io/sentry/SynchronizedQueue.java b/sentry/src/main/java/io/sentry/SynchronizedQueue.java index 6236f052df..5e07606cfb 100644 --- a/sentry/src/main/java/io/sentry/SynchronizedQueue.java +++ b/sentry/src/main/java/io/sentry/SynchronizedQueue.java @@ -131,4 +131,18 @@ public E remove() { return decorated().remove(); } } + + @Override + public Object[] toArray() { + synchronized (lock) { + return decorated().toArray(); + } + } + + @Override + public T[] toArray(T[] object) { + synchronized (lock) { + return decorated().toArray(object); + } + } } diff --git a/sentry/src/test/java/io/sentry/ScopeTest.kt b/sentry/src/test/java/io/sentry/ScopeTest.kt index 290aeb02d6..ad6979f3a0 100644 --- a/sentry/src/test/java/io/sentry/ScopeTest.kt +++ b/sentry/src/test/java/io/sentry/ScopeTest.kt @@ -217,6 +217,31 @@ class ScopeTest { assertTrue(clone.attachments is CopyOnWriteArrayList) } + @Test + fun `copying scope won't crash if there are a lot of breadcrumbs`() { + val options = SentryOptions().apply { + maxBreadcrumbs = 10000 + } + val scope = Scope(options) + for (i in 0..options.maxBreadcrumbs) { + scope.addBreadcrumb(Breadcrumb.info("item")) + } + + // remove one breadcrumb after the other on an extra thread + Thread({ + while (scope.breadcrumbs.isNotEmpty()) { + scope.breadcrumbs.remove() + } + }, "thread-breadcrumb-remover").start() + + // clone in the meantime + while (scope.breadcrumbs.isNotEmpty()) { + Scope(scope) + } + + // expect no exception to be thrown ¯\_(ツ)_/¯ + } + @Test fun `clear scope resets scope to default state`() { val scope = Scope(SentryOptions()) From f4e6d9ce06811009151ce1a01c9886b4982f1a51 Mon Sep 17 00:00:00 2001 From: Markus Hintersteiner Date: Wed, 2 Nov 2022 17:13:45 +0100 Subject: [PATCH 2/3] Rename test description --- sentry/src/test/java/io/sentry/ScopeTest.kt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sentry/src/test/java/io/sentry/ScopeTest.kt b/sentry/src/test/java/io/sentry/ScopeTest.kt index ad6979f3a0..f8fdb5d91d 100644 --- a/sentry/src/test/java/io/sentry/ScopeTest.kt +++ b/sentry/src/test/java/io/sentry/ScopeTest.kt @@ -218,12 +218,12 @@ class ScopeTest { } @Test - fun `copying scope won't crash if there are a lot of breadcrumbs`() { + fun `copying scope won't crash if there are concurrent operations`() { val options = SentryOptions().apply { maxBreadcrumbs = 10000 } val scope = Scope(options) - for (i in 0..options.maxBreadcrumbs) { + for (i in 0 until options.maxBreadcrumbs) { scope.addBreadcrumb(Breadcrumb.info("item")) } From ace734c9495529217bee3e6c73766031e9a660f5 Mon Sep 17 00:00:00 2001 From: Markus Hintersteiner Date: Wed, 2 Nov 2022 17:27:45 +0100 Subject: [PATCH 3/3] Update Changelog --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index e1f159dc54..d885e51810 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,7 @@ ### Fixes - Use correct set-cookie for the HTTP Client response object ([#2326](https://github.com/getsentry/sentry-java/pull/2326)) +- Fix NoSuchElementException in CircularFifoQueue when cloning a Scope ([#2328](https://github.com/getsentry/sentry-java/pull/2328)) ### Features