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

[SR-1366] Android: Global variables aren’t reinitialized #43975

Open
swift-ci opened this issue Apr 29, 2016 · 0 comments
Open

[SR-1366] Android: Global variables aren’t reinitialized #43975

swift-ci opened this issue Apr 29, 2016 · 0 comments
Labels
Android Platform: Android bug A deviation from expected or documented behavior. Also: expected but undesirable behavior.

Comments

@swift-ci
Copy link
Collaborator

swift-ci commented Apr 29, 2016

Previous ID SR-1366
Radar None
Original Reporter ewmailing (JIRA User)
Type Bug
Additional Detail from JIRA
Votes 0
Component/s
Labels Bug, Android
Assignee None
Priority Medium

md5: 80de7a0099cf1128ccac0b8ffe6264e3

Issue Description:

This one is tricky. I hope I explain it correctly. The problem is fundamentally due to a bad design decision by Android, but everybody using the NDK has to deal with it in some way.

The problem is that in the NDK (C/C++), global and static variables are not always reinitialized. So in C, if I do something like this in C:

_Bool g_appDone = false;

// program starts here from Java called via JNI
void MyMainEntry()
{
    while(!g_appDone)
    {
        // will set g_appDone=true when the user quits the app
        main_loop();
    }
}

The very first time through, g_appDone is initialized to false.

But here’s the problem. When an Android app exits, Android does not necessarily release the NDK memory, nor reinitialize everything fully when the user relaunches the app.

So on the next run, g_appDone is still set to true from the previous run. This will screw up the above app which expects the variable to be reinitialized.

The only time this works is when the user force kills an app, the OS decides its time to reap all the memory, or the app crashes.

This affects all global and static variables in the NDK. C++ destructors for globals are not run either when the app exits.

As an implementation detail of Android, it may be worth knowing that all code via the NDK is built into a shared library, loaded explicitly by the user code via LoadLibrary from the Java side. Apparently, Android doesn’t bother to unload its native libraries on application lifecycle exit, nor free up the memory immediately.

Anyway, it appears Swift is affected by this same thing. I wrote an app using the same above construct and reproduced the exact same problem.

var g_appDone = false;

// program starts here from Java
func MyMainEntry()
{
    while(!g_appDone)
    {
        // will set g_appDone=true when the user quits the app
        main_loop();
    }
}

I don’t know if it is possible for Swift to do something to avoid this problem, but it would be great if it could.

Already, it is forcing me to write cross-platform Swift code in kind of strange ways by funneling all global variables through a special re-init function and no longer assuming that declaration initialization is enough.

I am also concerned about what other things may be affected. For example, I don’t know if let (global) variables are going to be affected by this, particularly for example, if they are backed by structs that may have used mutating.

@swift-ci swift-ci transferred this issue from apple/swift-issues Apr 25, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Android Platform: Android bug A deviation from expected or documented behavior. Also: expected but undesirable behavior.
Projects
None yet
Development

No branches or pull requests

1 participant