Skip to content

Conversation

@matthargett
Copy link

Found when running BabylonNative unit tests in Android simulator using NDK 28c, which automatically enables the fdsan sanitizer in clang. This was may have been generally causing instability during process exit on Android.

Will take out of draft when I'm done integration testing in BabylonNative.

      - calls into the Java Context APIs directly (no temporary wrapper objects whose destructors free the ref we still need),
      - stores a fresh global ref for the application context, and
      - re-resolves the AssetManager, deleting the local reference afterwards.
@matthargett matthargett marked this pull request as ready for review November 2, 2025 23:40
@matthargett matthargett requested a review from bghgary November 3, 2025 15:47
Copy link
Contributor

@bghgary bghgary left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Getting much closer now.

// Passing nullptr for appContext/assetManager clears cached globals so embedders can
// explicitly tear down between reloads, or supply only an asset manager when no stable
// Java Context is available (e.g., headless/unit-test harnesses).
void Initialize(JavaVM* javaVM, jobject appContext, jobject assetManager);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

With the new usage, we call Initialize with nullptr to tear down. This seems awkward. Maybe it be better to create a separate function called Uninitialize?

Comment on lines +85 to +86
if (applicationContext != nullptr)
{
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

When is it valid for someone to pass in a non-null context but applicationContext is null? If this happened, wouldn't GetAppContext return null later and cause a problem? Or maybe we are saying GetAppContext can return null now? I couldn't find any official documentation on whether getApplicationContext can return null.

Comment on lines +81 to +83
android::content::Context contextWrapper{context};
const auto applicationContextWrapper = contextWrapper.getApplicationContext();
jobject applicationContext = applicationContextWrapper;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The point of the wrapper objects is to hide the details of interacting with Java to make it easier. Saving all the wrappers in a separate object and using the jobjects directly makes the code awkward. If we actually must check for the existence of the applicationContext object, we can add an implicit boolean operator to avoid having to save the wrapper in a different variable.

Comment on lines +97 to +99
android::content::Context contextWrapper{context};
const auto assetsWrapper = contextWrapper.getAssets();
SetAssetManager(static_cast<jobject>(assetsWrapper));
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this different than what you have?

Suggested change
android::content::Context contextWrapper{context};
const auto assetsWrapper = contextWrapper.getAssets();
SetAssetManager(static_cast<jobject>(assetsWrapper));
SetAssetManager(android::content::Context{context}.getAssets());

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants