getsentry / sentry-xamarin

Sentry for Xamarin Native and Xamarin.Forms
https://docs.sentry.io/platforms/dotnet/guides/xamarin/
44 stars 11 forks source link

Unhandled Exception : System.IO.IOException: Sharing violation on path ..../Sentry/xxxxx.envelope #129

Closed khalilyamoun closed 2 years ago

khalilyamoun commented 2 years ago

Environment

Xamarin.Android Sentry-Xamarin : 1.4.3 Sentry-dotnet : 3.23.1

   SentryXamarin.Init(options =>
            {
                options.BeforeBreadcrumb = this.BeforeBreadcrumb;
                options.Dsn = Constants.SentryAndoridDsn;
                options.Environment = Constants.SentryEnvironment;
                options.AddXamarinFormsIntegration();
                options.AttachScreenshots = true;
                options.TracesSampleRate = 0.05;
            });

Steps to Reproduce

  1. Open the app
  2. Restart the app (Init should be re-called)

Expected Result

App should restart normally.

Actual Result

[mono-rt] [ERROR] FATAL UNHANDLED EXCEPTION: System.IO.IOException: Sharing violation on path /data/user/0/com.package.packagename.dev/files/.local/share/Sentry/2307E3E05F3949AB506007C7897275B7007CF6F7/1667542777_4035__442129975.envelope
[mono-rt]   at System.IO.FileStream..ctor (System.String path, System.IO.FileMode mode, System.IO.FileAccess access, System.IO.FileShare share, System.Int32 bufferSize, System.Boolean anonymous, System.IO.FileOptions options) [0x001aa] in /Users/builder/jenkins/workspace/archive-mono/2020-02/android/release/mcs/class/corlib/System.IO/FileStream.cs:239 
[mono-rt]   at System.IO.FileStream..ctor (System.String path, System.IO.FileMode mode, System.IO.FileAccess access, System.IO.FileShare share, System.Int32 bufferSize, System.IO.FileOptions options) [0x00000] in /Users/builder/jenkins/workspace/archive-mono/2020-02/android/release/mcs/class/corlib/System.IO/FileStream.cs:106 
[mono-rt]   at (wrapper remoting-invoke-with-check) System.IO.FileStream..ctor(string,System.IO.FileMode,System.IO.FileAccess,System.IO.FileShare,int,System.IO.FileOptions)
[mono-rt]   at System.IO.FileSystem.CopyFile (System.String sourceFullPath, System.String destFullPath, System.Boolean overwrite) [0x00025] in /Users/builder/jenkins/workspace/archive-mono/2020-02/android/release/external/corefx/src/System.IO.FileSystem/src/System/IO/FileSystem.Unix.cs:54 
[mono-rt]   at System.IO.File.Copy (System.String sourceFileName, System.String destFileName, System.Boolean overwrite) [0x00056] in /Users/builder/jenkins/workspace/archive-mono/2020-02/android/release/external/corefx/src/System.IO.FileSystem/src/System/IO/File.cs:74 
[mono-rt]   at Sentry.Internal.FileSystem.MoveFile (System.String sourceFileName, System.String destFileName, System.Boolean overwrite) [0x00003] in /_/src/Sentry/Internal/FileSystem.cs:34 
[mono-rt]   at Sentry.Internal.Http.CachingTransport.TryPrepareNextCacheFileAsync (System.Threading.CancellationToken cancellationToken) [0x000c3] in /_/src/Sentry/Internal/Http/CachingTransport.cs:386 
[mono-rt]   at Sentry.Internal.Http.CachingTransport.ProcessCacheAsync (System.Threading.CancellationToken cancellation) [0x000d2] in /_/src/Sentry/Internal/Http/CachingTransport.cs:270 
[mono-rt]   at Sentry.Internal.BackgroundWorker.DoFlushAsync (System.Threading.CancellationToken cancellationToken) [0x001dd] in /_/src/Sentry/Internal/BackgroundWorker.cs:288 
[mono-rt]   at Sentry.Internal.BackgroundWorker.FlushAsync (System.TimeSpan timeout) [0x000c3] in /_/src/Sentry/Internal/BackgroundWorker.cs:220 
[mono-rt]   at Sentry.Internal.BackgroundWorker.FlushAsync (System.TimeSpan timeout) [0x00238] in /_/src/Sentry/Internal/BackgroundWorker.cs:236 
[mono-rt]   at Sentry.Internal.Hub.Dispose () [0x00020] in /_/src/Sentry/Internal/Hub.cs:431 
[mono-rt]   at Sentry.SentrySdk.UseHub (Sentry.IHub hub) [0x0000b] in /_/src/Sentry/SentrySdk.cs:114 
[mono-rt]   at Sentry.SentrySdk.Init (Sentry.SentryOptions options) [0x00000] in /_/src/Sentry/SentrySdk.cs:109 
[mono-rt]   at Sentry.SentryXamarin.Init (Sentry.SentryXamarinOptions options) [0x00000] in D:\a\sentry-xamarin\sentry-xamarin\Src\Sentry.Xamarin\SentryXamarin.cs:46 
[mono-rt]   at Sentry.SentryXamarin.Init (System.Action`1[T] configureOptions) [0x00080] in D:\a\sentry-xamarin\sentry-xamarin\Src\Sentry.Xamarin\SentryXamarin.cs:37 
[mono-rt]   at com.package.packagename.Utils.AndroidSentryHandler.InitSentry () [0x00013] in AndroidSentryHandler.cs:76 
[mono-rt]   at package.packagename.Utils.AndroidSentryHandler..ctor () [0x00008] in AndroidSentryHandler.cs:17 
[mono-rt]   at package.packagename.SplashActivity.Initialize () [0x0001e] in SplashActivity.cs:255 
[mono-rt]   at package.packagename.SplashActivity.OnCreate (Android.OS.Bundle savedInstanceState) [0x00163] in SplashActivity.cs:107 
[mono-rt]   at System.Runtime.CompilerServices.AsyncMethodBuilderCore+<>c.<ThrowAsync>b__7_0 (System.Object state) [0x00000] in /Users/builder/jenkins/workspace/archive-mono/2020-02/android/release/mcs/class/referencesource/mscorlib/system/runtime/compilerservices/AsyncMethodBuilder.cs:1021 
[mono-rt]   at Android.App.SyncContext+<>c__DisplayClass2_0.<Post>b__0 () [0x00000] in /Users/runner/work/1/s/xamarin-android/src/Mono.Android/Android.App/SyncContext.cs:36 
[mono-rt]   at Java.Lang.Thread+RunnableImplementor.Run () [0x00008] in /Users/runner/work/1/s/xamarin-android/src/Mono.Android/Java.Lang/Thread.cs:36 
[mono-rt]   at Java.Lang.IRunnableInvoker.n_Run (System.IntPtr jnienv, System.IntPtr native__this) [0x00008] in /Users/runner/work/1/s/xamarin-android/src/Mono.Android/obj/Release/monoandroid10/android-30/mcw/Java.Lang.IRunnable.cs:84 
[mono-rt]   at Android.Runtime.JNINativeWrapper.Wrap_JniMarshal_PP_V (_JniMarshal_PP_V callback, System.IntPtr jnienv, System.IntPtr klazz) [0x00005] in /Users/runner/work/1/s/xamarin-android/src/Mono.Android/Android.Runtime/JNINativeWrapper.g.cs:22 
[mono-rt]   at (wrapper native-to-managed) Android.Runtime.JNINativeWrapper.Wrap_JniMarshal_PP_V(intptr,intptr)
mattjohnsonpint commented 2 years ago

A sharing violation would indicate that more than one thread is trying to access the same file simultaneously, which would be quite strange indeed.

I've not seen any other reports of this, neither with Xamarin nor any other .NET project types.

When you say "Init should be re-called" - this should only happen if you're actually entering the onCreate stage again - which should only happen if the app was completely terminated the first time.

From the Android docs here:

image

Sentry should be initialized in onCreate (of the main activity), not in onStart, onResume, onRestart or the onCreate of an activity other than the main one for the app.

I do see SplashActivity.OnCreate in your call stack, but I'm not sure whether that's the main activity of your application (such as MainActivity we show in our readme), or if that's being launched from somewhere else. Perhaps you are launching your splash screen from onRestart? Can you clarify, and perhaps put a more complete example together?

Thanks.

mattjohnsonpint commented 2 years ago

@lucas-zimerman - Are you available to help investigate? Thanks.

lucas-zimerman commented 2 years ago

@lucas-zimerman - Are you available to help investigate? Thanks.

Sure. But here are a few questions in advance.

One assumption that I have is that the app is partially restarted (the Android activity is restarted but the .NET code stays unchanged)

Ideally the SDK shouldn't crash the app when SentryXamarin.Init is invoked but I'll investigate what could be causing this issue.

khalilyamoun commented 2 years ago

@mattjohnsonpint @lucas-zimerman - Here's what's happening.

Keep in mind that :

khalilyamoun commented 2 years ago

@mattjohnsonpint, when you say "I've not seen any other reports of this, neither with Xamarin nor any other .NET project types."

mattjohnsonpint commented 2 years ago

Thanks for the detailed response. I'm glad you found a workaround, but I'd still like to get this resolved fully.

It does sound like you're initializing Sentry when it is already initialized. Ideally you'd only be initializing once.

One quick test you can do is to check SentrySdk.IsEnabled, such as:

if (!SentrySdk.IsEnabled)
{
    SentryXamarin.Init(... your init options ...);
}

This won't hurt, but it shouldn't be required, as we detect and handle such a condition internally.

You say that it started after updating to Sentry.Xamarin 1.4.3. Can you please tell me which version you ran before that? When did it last work?

Thanks.

mattjohnsonpint commented 2 years ago

I did a bit more investigation, and indeed if Sentry is initialized twice with caching enabled, there is a potential for conflict on the cache files. This could manifest as a sharing violation on Android. See https://github.com/getsentry/sentry-dotnet/issues/2033 for more details.

We'll leave this open for Sentry.Xamarin and re-visit after resolving that.

Thanks.