Skip to content
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

Sentry replay Native Crash java.lang.IndexOutOfBoundsException #4234

Open
vooban-work opened this issue Nov 5, 2024 · 6 comments
Open

Sentry replay Native Crash java.lang.IndexOutOfBoundsException #4234

vooban-work opened this issue Nov 5, 2024 · 6 comments
Assignees

Comments

@vooban-work
Copy link

vooban-work commented Nov 5, 2024

What React Native libraries do you use?

Expo (mobile only), React Navigation, Hermes, Expo Application Services (EAS)

Are you using sentry.io or on-premise?

sentry.io (SaS)

@sentry/react-native SDK Version

6.1.0

How does your development environment look like?

I'm using VSCode with EAS to build the native app and live update to push code.

info Fetching system and libraries information...
(node:53467) [DEP0040] DeprecationWarning: The `punycode` module is deprecated. Please use a userland alternative instead.
(Use `node --trace-deprecation ...` to show where the warning was created)
System:
  OS: macOS 14.7
  CPU: (12) arm64 Apple M2 Max
  Memory: 12.67 GB / 96.00 GB
  Shell:
    version: "5.9"
    path: /bin/zsh
Binaries:
  Node:
    version: 21.1.0
    path: ~/.nvm/versions/node/v21.1.0/bin/node
  Yarn:
    version: 1.22.22
    path: /opt/homebrew/bin/yarn
  npm:
    version: 10.2.0
    path: ~/.nvm/versions/node/v21.1.0/bin/npm
  Watchman: Not Found
Managers:
  CocoaPods:
    version: 1.16.2
    path: /opt/homebrew/bin/pod
SDKs:
  iOS SDK:
    Platforms:
      - DriverKit 24.1
      - iOS 18.1
      - macOS 15.1
      - tvOS 18.1
      - visionOS 2.1
      - watchOS 11.1
  Android SDK: Not Found
IDEs:
  Android Studio: 2024.2 AI-242.23339.11.2421.12550806
  Xcode:
    version: 16.1/16B40
    path: /usr/bin/xcodebuild
Languages:
  Java:
    version: 17.0.10
    path: /usr/bin/javac
  Ruby:
    version: 2.6.10
    path: /usr/bin/ruby
npmPackages:
  "@react-native-community/cli": Not Found
  react:
    installed: 18.3.1
    wanted: 18.3.1
  react-native:
    installed: 0.74.5
    wanted: 0.74.5
  expo:
    "expo": "51.0.35",
    "expo-application": "5.9.1",
    "expo-auth-session": "5.5.2",
    "expo-background-fetch": "12.0.1",
    "expo-camera": "15.0.16",
    "expo-constants": "16.0.2",
    "expo-crypto": "13.0.2",
    "expo-dev-client": "4.0.27",
    "expo-device": "6.0.2",
    "expo-file-system": "17.0.1",
    "expo-font": "12.0.10",
    "expo-image-manipulator": "12.0.5",
    "expo-image-picker": "15.0.7",
    "expo-insights": "0.7.0",
    "expo-linking": "6.3.1",
    "expo-localization": "15.0.3",
    "expo-network": "6.0.1",
    "expo-notifications": "0.28.18",
    "expo-screen-orientation": "7.0.5",
    "expo-secure-store": "13.0.2",
    "expo-sqlite": "14.0.6",
    "expo-system-ui": "3.0.7",
    "expo-task-manager": "11.8.2",
    "expo-updates": "0.25.25",
    "expo-web-browser": "13.0.3",
  react-native-macos: Not Found
npmGlobalPackages:
  "*react-native*": Not Found
Android:
  hermesEnabled: Not found
  newArchEnabled: Not found
iOS:
  hermesEnabled: Not found
  newArchEnabled: Not found

Sentry.init()

Sentry.init({
    _experiments: {
      replaysSessionSampleRate: 1.0,
      replaysOnErrorSampleRate: 1.0,
    },
    attachStacktrace: true,
    attachThreads: true,
    attachScreenshot: areMoreTraceNeeded,
    dsn: env.SENTRY_DSN,
    enableNativeNagger: true,
    enableNdkScopeSync: true,
    environment: env.SENTRY_ENVIRONMENT,
    enableAppStartTracking: true,
    enableUserInteractionTracing: true,
    enableNativeFramesTracking: true,
    enableStallTracking: true,
    autoSessionTracking: true,
    attachViewHierarchy: true,
    enableAutoSessionTracking: true,
    integrations: [
      navigationIntegration,
      reactNativeTracingIntegration({
        traceFetch: true,
        traceXHR: true,
      }),
      mobileReplayIntegration({
        maskAllText: false,
        maskAllImages: false,
        maskAllVectors: false,
      }),
      hermesProfilingIntegration({
        platformProfilers: true,
      }),
      appStartIntegration({
        standalone: false,
      }),
    ],
    sendDefaultPii: true,
    profilesSampleRate: 1.0,
    tracesSampleRate: 1.0,
    sendClientReports: true,
    enableNativeCrashHandling: true,
    patchGlobalPromise: true,
    autoInitializeNativeSdk: true,
    release: env.SENTRY_RELEASE_NAME,
    dist: Updates.updateId || env.SENTRY_RELEASE_NAME,
    tracePropagationTargets: [env.API_URL, env.WS_URL, /^\//, /\/api\/graphql/],
    debug: isDevClient, // trace sentry logs into console
    beforeSend: (event, hint) => {
      if (isDevClient) console.debug('[Sentry @Console]', hint.originalException || hint.syntheticException);
      _set(event, 'extra.dev', dev.identifier);
      return event;
    },
  });

Steps to Reproduce

  • Just need to have the replaySessionsSampleRates to 1, call expo-updates "reloadAsync()" and once is reloaded, make the app go background on Sentry v6.

But here are the steps I did:

  1. Make a an app or an update without sampleRate of Sentry replays _experiments: { replaysSessionSampleRate: 0, replaysOnErrorSampleRate: 0, },
  2. Make sure once you got the app updated to reboot the app once more, the issue occurs once the update is installed
  3. Make an update that actives the replays sampleRate _experiments: { replaysSessionSampleRate: 1, replaysOnErrorSampleRate: 1, },
  4. Push the update, reload using import { reloadAsync } from 'expo-updates';
  5. Once the update is running, get your app in background, the app crashes like below (actual result)
  • The exception never occurs if Sentry Replays sample rate is at 0
  • If kept with 1 it won't crash if I do not call ExpoUpdates.reloadAsync(), once I call it even if I do not have a pending updates, once the app reboots if I go background, it will crash again then reboot, then I'm good to set it background again, and so on...

I tried to run await Sentry.flush() before running await ExpoUpdates.reloadAsync() without success

Expected Result

To be able to uses replay session on all sessions? We were using replays on v5 but migrating v5 to v6 we get those native exception below.

Actual Result

--------- beginning of crash
11-05 06:36:06.203 16547 16547 E AndroidRuntime: FATAL EXCEPTION: main
11-05 06:36:06.203 16547 16547 E AndroidRuntime: Process: com.vooban.app.dev2, PID: 16547
11-05 06:36:06.203 16547 16547 E AndroidRuntime: java.lang.RuntimeException: Unable to stop activity {com.vooban.app.dev2/com.vooban.app.dev2.MainActivity}: java.lang.IndexOutOfBoundsException: Index: 1, Size: 1
11-05 06:36:06.203 16547 16547 E AndroidRuntime:        at android.app.ActivityThread.callActivityOnStop(ActivityThread.java:5713)
11-05 06:36:06.203 16547 16547 E AndroidRuntime:        at android.app.ActivityThread.performStopActivityInner(ActivityThread.java:5649)
11-05 06:36:06.203 16547 16547 E AndroidRuntime:        at android.app.ActivityThread.handleStopActivity(ActivityThread.java:5750)
11-05 06:36:06.203 16547 16547 E AndroidRuntime:        at android.app.servertransaction.StopActivityItem.execute(StopActivityItem.java:43)
11-05 06:36:06.203 16547 16547 E AndroidRuntime:        at android.app.servertransaction.ActivityTransactionItem.execute(ActivityTransactionItem.java:45)
11-05 06:36:06.203 16547 16547 E AndroidRuntime:        at android.app.servertransaction.TransactionExecutor.executeLifecycleState(TransactionExecutor.java:176)
11-05 06:36:06.203 16547 16547 E AndroidRuntime:        at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:97)
11-05 06:36:06.203 16547 16547 E AndroidRuntime:        at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2438)
11-05 06:36:06.203 16547 16547 E AndroidRuntime:        at android.os.Handler.dispatchMessage(Handler.java:106)
11-05 06:36:06.203 16547 16547 E AndroidRuntime:        at android.os.Looper.loopOnce(Looper.java:226)
11-05 06:36:06.203 16547 16547 E AndroidRuntime:        at android.os.Looper.loop(Looper.java:313)
11-05 06:36:06.203 16547 16547 E AndroidRuntime:        at android.app.ActivityThread.main(ActivityThread.java:8663)
11-05 06:36:06.203 16547 16547 E AndroidRuntime:        at java.lang.reflect.Method.invoke(Native Method)
11-05 06:36:06.203 16547 16547 E AndroidRuntime:        at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:567)
11-05 06:36:06.203 16547 16547 E AndroidRuntime:        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1135)
11-05 06:36:06.203 16547 16547 E AndroidRuntime: Caused by: java.lang.IndexOutOfBoundsException: Index: 1, Size: 1
11-05 06:36:06.203 16547 16547 E AndroidRuntime:        at java.util.ArrayList.get(ArrayList.java:437)
11-05 06:36:06.203 16547 16547 E AndroidRuntime:        at android.view.WindowManagerGlobal.setStoppedState(WindowManagerGlobal.java:790)
11-05 06:36:06.203 16547 16547 E AndroidRuntime:        at android.app.Activity.performStop(Activity.java:8530)
11-05 06:36:06.203 16547 16547 E AndroidRuntime:        at android.app.ActivityThread.callActivityOnStop(ActivityThread.java:5705)
11-05 06:36:06.203 16547 16547 E AndroidRuntime:        ... 14 more
@vooban-work
Copy link
Author

vooban-work commented Nov 5, 2024

Hey,

So a little bit of investigation led me to try to set autoInitializeNativeSdk: false for just one live update.

Once I reloaded my app on this new liveUpdate from EAS, the crash did not occur when the app was background and I was able to send a fake crash to sentry.io and see that my replay was there too. So, it looks like the SDK did not reboot after the live update (js code push), so I was able to use the same one, as long I do not reboot the app.

However, I cannot keep it that way because it has no way to auto start from fresh boot. I need SDK to stop when I call ExpoUpdates.reloadAsync(). I still call flush just before it, but it does nothing.

import {  flush as SentryFlushPendingEventsBeforeExpoUpdatesAsync } from '@sentry/react-native';
import { reloadAsync } from 'expo-updates';

export const _reloadNativeApp = async (): Promise<void> => {
  await SentryFlushPendingEventsBeforeExpoUpdatesAsync();
  await reloadAsync();
};

Btw, I read here that close is not available on react-native, so even if you removed it from the documentation, it would be better to clean your types too
Image

@krystofwoldrich
Copy link
Member

krystofwoldrich commented Nov 6, 2024

Hi @vooban-work,
thank you for the message and the details.


The #1279 is an old issue, the RN SDK has close() which you can use, related implementation.

Can you try with close() and let us know if the error still occurs?


In RN SDK V5 have you used the flush or close functions before Expo.reloadAsync?

What was the V5 version?


Would you be able to share with us the missing part of the stack trace?

11-05 06:36:06.203 16547 16547 E AndroidRuntime:        ... 14 more

@krystofwoldrich krystofwoldrich moved this from Needs Discussion to Needs More Information in Mobile & Cross Platform SDK Nov 6, 2024
@vooban-work
Copy link
Author

Can you try with close() and let us know if the error still occurs?

yes I tried it, it did not resolve the issue, so that's why I thought the method did not do anything like the issue #1279 said.

In RN SDK V5 have you used the flush or close functions before Expo.reloadAsync?

no, before this issue we never had to use flush or close. sentry was able to close the first instance and open a new one on the new update

What was the V5 version?

5.34.0

- "@sentry/integrations": "7.110.1",
- "@sentry/react-native": "5.34.0",
- "@sentry/tracing": "7.110.1",
+ "@sentry/integrations": "7.114.0",
+ "@sentry/react-native": "6.1.0",
+ "@sentry/tracing": "7.114.0",

here the json sentry issue, hope it helps
sentry-log.json

Image

@romtsn
Copy link
Member

romtsn commented Nov 20, 2024

@vooban-work we'll try to reproduce and fix the issue this week, thanks for all the details!

@krystofwoldrich
Copy link
Member

New steps to reproduce from #4241

The bug occurs after updating sentry from 5.31.1 to 6.1.0.
Nothing has changed in the native code for the bug to occur.

Two conditions must be true for the bug to occur:

A foreground service must be running.
The values replaysSessionSampleRate and replaysOnErrorSampleRate , must be different from 0.
if one of these conditions is not true, the bug will not occur.
here's how the bug occurs.
-When I open the app for the first time, everything works fine, and when I put the app in the background, everything works.
-I close the app and the service remains active.
-I open the app a second time,
-As soon as I set the app to background, it crashes instantly.

==> to recap, with no service running in background, the app doesn't crash, and when replaysSessionSampleRate and replaysOnErrorSampleRate are equal to 0, the app doesn't crash.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
Status: No status
Status: Needs Investigation
Development

No branches or pull requests

3 participants