[racket-dev] Building Racket with the Android NDK

From: Jan Wedekind (jan at wedesoft.de)
Date: Sat Aug 25 15:04:45 EDT 2012

Hi,
I managed to run a statically linked version of Racket on Android before [1]. 
Now I built a dynamically linked version of Racket (version 5.3.0) using the 
Android NDK:

     #!/bin/sh
     NDK=$HOME/android-ndk-r8b
     PATH=$PATH:/tmp/ndk-racket/bin
     ARCHIVE=$HOME/racket-5.3.0.tar.bz2
     $NDK/build/tools/make-standalone-toolchain.sh --platform=android-9 
--install-dir=/tmp/ndk-racket
     rm -Rf $HOME/build
     mkdir -p $HOME/build/host
     cd $HOME/build/host
     tar xjf $ARCHIVE
     BUILD_HOST=$HOME/build/host/racket*
     cd $BUILD_HOST/src
     ./configure
     make
     make install
     mkdir -p $HOME/build/cross
     cd $HOME/build/cross
     tar xjf $ARCHIVE
     BUILD_CROSS=$HOME/build/cross/racket*
     cd $BUILD_CROSS/src
     cp /usr/share/misc/config.sub lt
     cp /usr/share/misc/config.guess lt
     cp /usr/share/misc/config.sub foreign/libffi
     cp /usr/share/misc/config.guess foreign/libffi
     sed -i 's/FNDELAY/O_NONBLOCK/g' racket/src/schpriv.h
     ./configure --host=arm-linux-androideabi --enable-sgc CFLAGS="-g 
-march=armv7-a -mfloat-abi=softfp" LDFLAGS="-Wl,--fix-cortex-a8"
     make \
       RUN_THIS_RACKET_CGC=$BUILD_HOST/src/racket/racketcgc \
       RUN_THIS_RACKET_MMM=$BUILD_HOST/src/racket/racket3m \
       RUN_THIS_RACKET_MAIN_VARIANT=$BUILD_HOST/src/racket/racket3m \
       HOSTCC=/usr/bin/gcc \
       HOSTCFLAGS="-g -O2 -Wall -pthread -I./include" \
       STRIP_DEBUG="echo"
     make \
       RUN_THIS_RACKET_CGC=$BUILD_HOST/src/racket/racketcgc \
       RUN_THIS_RACKET_MMM=$BUILD_HOST/src/racket/racket3m \
       RUN_THIS_RACKET_MAIN_VARIANT=$BUILD_HOST/src/racket/racket3m \
       HOSTCC=/usr/bin/gcc \
       HOSTCFLAGS="-g -O2 -Wall -pthread -I./include" \
       STRIP_DEBUG="echo"
       install

However when running it on Android, the program keeps reporting segmentation 
faults:

     SIGSEGV MAPERR si_code 1 fault on addr 0xdeadbaad
     SIGSEGV MAPERR si_code 1 fault on addr 0xdeadbaad
     SIGSEGV MAPERR si_code 1 fault on addr 0xdeadbaad
     ...

I tried to debug it using 'gdbserver'. I.e. on the Android phone I run

     ./gdbserver 192.168.1.277:1234 ./racket3m

where 192.168.1.277 is the IP of the client. And on the client PC I run

     $NDK/toolchains/arm-linux-androideabi-4.4.3/prebuilt/linux-x86/bin/arm-linux-androideabi-gdb
     (gdb) target remote 192.168.1.1:1234
     (gdb) file ~/build/cross/racket-5.3.0/src/racket/racket3m
     (gdb) cont

where 192.168.1.1 is the IP address of the Android phone. However then the 
program reports the following segmentation fault instead:

     Program received signal SIGSEGV, Segmentation fault.
     0x00282540 in scheme_gmp_tls_unload (s=0x4031cedc, data=0x0) at 
./gmp/gmp.c:5813
     5813      s[0] = 0;
     (gdb) l
     5808    void scheme_gmp_tls_unload(intptr_t *s, void *data)
     5809    {
     5810      current_total_allocation = (uintptr_t)s[0];
     5811      max_total_allocation = (uintptr_t)s[1];
     5812      gmp_tmp_current = (tmp_stack *)s[2];
     5813      s[0] = 0;
     5814      gmp_mem_pool = data;
     5815    }

According to [2] this is a GC write barrier and one needs to ignore 
semgentation faults as follows

     (gdb) handle SIGSEGV nostop noprint

But in that case it is not possible to debug the initial segmentation fault 
though.
Does anybody have some information on what's going on or an suggestion on how 
to approach this problem?
Any suggestions are welcome.

Best regards
Jan

[1] http://www.wedesoft.de/racket-on-android.html
[2] http://lists.racket-lang.org/dev/archive/2009-July/001068.html

Posted on the dev mailing list.