[racket-dev] Building Racket with the Android NDK
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