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

[QA] Offload System.loadLibrary call to background thread #3670

Merged
merged 5 commits into from
Oct 14, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
Loading