Skip to content

Commit

Permalink
[QA] Offload System.loadLibrary call to background thread (#3670)
Browse files Browse the repository at this point in the history
* Offload System.loadLibrary call to background thread

* Update Changelog

* Update CHANGELOG.md
  • Loading branch information
markushi authored Oct 14, 2024
1 parent a9c767e commit 6259a9f
Show file tree
Hide file tree
Showing 2 changed files with 41 additions and 14 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
- Deprecate `enableTracing` option ([#3777](https://github.com/getsentry/sentry-java/pull/3777))
- Vendor `java.util.Random` and replace `java.security.SecureRandom` usages ([#3783](https://github.com/getsentry/sentry-java/pull/3783))
- Fix potential ANRs due to NDK scope sync ([#3754](https://github.com/getsentry/sentry-java/pull/3754))
- Fix potential ANRs due to NDK System.loadLibrary calls ([#3670](https://github.com/getsentry/sentry-java/pull/3670))

## 7.15.0

Expand Down
Original file line number Diff line number Diff line change
@@ -1,23 +1,40 @@
package io.sentry.android.ndk;

import io.sentry.android.core.SentryAndroidOptions;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;
import org.jetbrains.annotations.ApiStatus;
import org.jetbrains.annotations.NotNull;

@ApiStatus.Internal
public final class SentryNdk {

private static final @NotNull CountDownLatch loadLibraryLatch = new CountDownLatch(1);

private SentryNdk() {}

static {
// On older Android versions, it was necessary to manually call "`System.loadLibrary` on all
// transitive dependencies before loading [the] main library."
// The dependencies of `libsentry.so` are currently `lib{c,m,dl,log}.so`.
// See
// https://android.googlesource.com/platform/bionic/+/master/android-changes-for-ndk-developers.md#changes-to-library-dependency-resolution
System.loadLibrary("log");
System.loadLibrary("sentry");
System.loadLibrary("sentry-android");
new Thread(
() -> {
// On older Android versions, it was necessary to manually call "`System.loadLibrary`
// on all
// transitive dependencies before loading [the] main library."
// The dependencies of `libsentry.so` are currently `lib{c,m,dl,log}.so`.
// See
// https://android.googlesource.com/platform/bionic/+/master/android-changes-for-ndk-developers.md#changes-to-library-dependency-resolution
try {
System.loadLibrary("log");
System.loadLibrary("sentry");
System.loadLibrary("sentry-android");
} catch (Throwable t) {
// ignored
// if loadLibrary() fails, the later init() will throw an exception anyway
} finally {
loadLibraryLatch.countDown();
}
},
"SentryNdkLoadLibs")
.start();
}

private static native void initSentryNative(@NotNull final SentryAndroidOptions options);
Expand All @@ -31,14 +48,23 @@ private SentryNdk() {}
*/
public static void init(@NotNull final SentryAndroidOptions options) {
SentryNdkUtil.addPackage(options.getSdkVersion());
initSentryNative(options);
try {
if (loadLibraryLatch.await(2000, TimeUnit.MILLISECONDS)) {
initSentryNative(options);

// only add scope sync observer if the scope sync is enabled.
if (options.isEnableScopeSync()) {
options.addScopeObserver(new NdkScopeObserver(options));
}
// only add scope sync observer if the scope sync is enabled.
if (options.isEnableScopeSync()) {
options.addScopeObserver(new NdkScopeObserver(options));
}

options.setDebugImagesLoader(new DebugImagesLoader(options, new NativeModuleListLoader()));
options.setDebugImagesLoader(new DebugImagesLoader(options, new NativeModuleListLoader()));
} else {
throw new IllegalStateException("Timeout waiting for Sentry NDK library to load");
}
} catch (InterruptedException e) {
throw new IllegalStateException(
"Thread interrupted while waiting for NDK libs to be loaded", e);
}
}

/** Closes the NDK integration */
Expand Down

0 comments on commit 6259a9f

Please sign in to comment.