[swift-users] Swift 3 Android hangs & crashes

Eric Wing ewmailing at gmail.com
Sun Nov 6 17:58:10 CST 2016

On 10/31/16, Eric Wing <ewmailing at gmail.com> wrote:
> Hello, I've been trying to get Swift 3 working on Android. (I
> previously had Swift 2.x working.)
> I have the baseline components built following the standard
> Android/Swift instructions.
> But when I go to make a trivial, but real Android
> app (i.e. start in Java Activity and use JNI/LoadLibrary to get to
> Swift), the Swift code seems to hang (freeze?) whenever my Swift code
> calls print("foo").
> Removing all print calls, allows my trivial code to run correctly. But in
> slightly more complicated test programs (which call into other C
> libraries), I'm getting program crashes. It looks like libc triggers
> some kind of abort call in these cases. I know these C libraries work
> in non-Swift cases.
> My best guess right now is since Swift print() is also broken, I think
> there might be some problem related to libc++ (and maybe its
> interaction with libc) which is used in the build process. (The
> Android NDK docs warn about std::cout buffering breaking if you have
> multiple static linked libc++, but I'm not statically linking it.)
> I'm currently using libc++_shared.
> I updated my repo a few days ago which includes a fix for NDK r13
> which I am using.
> Does this problem ring a bell for anybody?
> Or can somebody help me figure out how to start debugging this? I've
> been trying a lot of different things behind the scenes, but I'm
> starting to run out of ideas.
> Thanks,
> Eric

I discovered there is a serious deadlock bug in Android 5.0. flockfile
on stdout/stderr causes a deadlock. Swift print() ultimately calls
flockfile, which in turn causes a deadlock. I verified this by first
commenting out the lock functions in the print function, and then
later by commenting out the flockfile/funlockfile implementations in
the Stubs.cpp.

One of the comments here mentions this bug:

The workaround seems to be either to remove the call to flockfile() or
update to Android 5.1. I upgraded my device to 5.1 and the problem

But thanks to Android fragmentation, going to 5.1 this means we lose
another 13.1% of devices, leaving us only 40.6% of devices.

This does bring up another issue though, at least for print() and
anything stdout/stderr related on Android. On Android, sending
anything to stdout/stderr via the NDK is effectively useless because
they are effectively sent to /dev/null. (The ‘adb shell setprop
log.redirect-stdio true’ trick doesn’t work for the NDK. There is one
convoluted trick to redirect using pipes in your codebase, but that is
a different can of worms.)

In general, print() statements need to go through
__android_log_write() and __android_log_print() on Android for anybody
to see anything. Is this something we should implement in Swift?


More information about the swift-users mailing list