Compdigitec Labs

« | Home | »

fclose() freezes/hangs when run inside pthread on Android 2.1

By admin | June 25, 2012

There appears to be an obscure bug that has somehow recently activated on ARMv6, non-FPU builds of VLC for Android. This has been only observed on Android 2.1 and possibly on other Android 2.x platforms with ARMv6, non-FPU builds Android 2.2. On the other hand, it works perfectly on an Android 4.0 on a NEON device (same code), so it is probably specific to Android 2.2 and 2.1 (not tested on 1.6).

The obscure bug involves hanging during a fclose() call whilst being run inside a POSIX pthread_once thread. This obscure bug was causing hanging on startup of VLC for Android on an Android 2.1, no-FPU, no-NEON device. Further testing with the Android emulator also revealed that the Android 2.1 and 2.2 emulator crashes too, suggesting a bionic bug (Android 2.3 works fine). Here is a condensed, VLC-neutral version of the code from VLC core that is specific to this problem, adapted from src/posix/linux_cpu.c:

// arm-linux-androideabi-gcc --sysroot=/opt/android-ndk-r8/platforms/android-9/arch-arm -I. -g -march=armv6j -mtune=arm1136j-s -msoft-float android.c -o android
#include <stdio.h>
#include <string.h>
#include <pthread.h>
#include <stdlib.h>

/* getdelim and getline courtesy of VLC's compat/getdelim.c */
ssize_t getdelim(char**v1,size_t*v2,int v3,FILE*v4){char*A1=*v1;size_t A2=(A1 != NULL)?*v2:0;size_t A3 = 0;for(;;){if((A2 - A3) <= 2){A2=A2?(A2*2):256;A1=realloc(*v1,A2);if(A1 ==NULL)return-1;*v1=A1;*v2=A2;}int c=fgetc(v4);if(c==-1){if(A3==0||ferror(v4))return -1;break;}A1[A3++]=c;if(c==v3)break;}A1[A3]='\0';return A3;} ssize_t getline(char** a,size_t* b,FILE* c){return getdelim(a,b,'\n',c);}

static uint32_t cpu_flags = 0;

static void vlc_CPU_init (void) {
    FILE *info = fopen ("/proc/cpuinfo", "rt");
    if (info == NULL) return;
    char *line = NULL;
    size_t linelen = 0;
	// ...irrelevant code skipped...
    while (getline (&line, &linelen, info) != -1) {
        // stuff with the loop...
    fclose(info); /* hangs here */
	// ...parse and set cpu_flags...
    cpu_flags = 1;

unsigned vlc_CPU(void) {
    static pthread_once_t once = PTHREAD_ONCE_INIT;
    pthread_once (&once, vlc_CPU_init);
    return cpu_flags;

int main(void) {
    if(vlc_CPU() > 0)
        puts("Failure, or a.k.a. will never reach here");
    return 0;

Interestingly, after debugging there are two ways to workaround this bug:

  1. Comment out the fclose() on line 21 above, or
  2. Don’t run vlc_CPU_init() inside a thread – comment out line 29 and uncomment line 30 to run vlc_CPU_init() unthreaded.

Further research – “The stdio library uses locks internally” – yields that this may be a bug in bionic, Android’s own custom implementation of libc as well as pthreads. So far, the fact that fclose() works successfully if not run inside a pthread, as well as the knowledge that stdio has internal locks, may suggest a bug in the bionic implementation on Android 2.2 / 2.1 and below.

See also

If you found this article helpful or interesting, please help Compdigitec spread the word. Don’t forget to subscribe to Compdigitec Labs for more useful and interesting articles!

Topics: Linux | 1 Comment »

One Response to “fclose() freezes/hangs when run inside pthread on Android 2.1”

  1. Stay in Singapore Says:
    April 17th, 2024 at 15:03

    … [Trackback]

    […] Find More on that Topic: […]