1

I have a library in Haskell that I have generated wrappers for via FFI and Swig. I have also managed to cross-compile a shared library that I can load from Java. The wrapped library contains some functions and input/output types for these.

On my Arch machine I am able to use my library from Java. However, when I now tried it out on Android, it segfaults. After some investigation, It seems that if the input object has no fields, it sometimes work. I think it's a problem with data marshalling. However it's hard to debug. In the crash log I find this

W/linker  ( 4783): libAPIsJava.so has text relocations. This is wasting memory and prevents security hardening. Please fix.

and this

--------- beginning of crash
F/libc    ( 4783): Fatal signal 11 (SIGSEGV), code 1, fault addr 0x200019 in tid 4783 (api.flic.io.api)
I/Icing   ( 1689): Indexing 17F83E8EEF17AFFA030207AF16B79084CE236092 from com.google.android.googlequicksearchbox
I/DEBUG   (  357): *** *** *** *** *** *** *** *** *** *** *** *** ***     *** *** ***
I/DEBUG   (  357): Build fingerprint:     'google/shamu/shamu:5.1/LMY47D/1743759:user/release-keys'
I/DEBUG   (  357): Revision: '33696'
I/DEBUG   (  357): ABI: 'arm'
I/DEBUG   (  357): pid: 4783, tid: 4783, name: api.flic.io.api  >>> app.api.flic.io.api <<<
I/DEBUG   (  357): signal 11 (SIGSEGV), code 1 (SEGV_MAPERR), fault addr 0x200019
I/DEBUG   (  357):     r0 af2033d4  r1 af2033d0  r2 00000000  r3 00200018
I/DEBUG   (  357):     r4 a2bbf950  r5 af2033dc  r6 af2029a0  r7 af202fff
I/DEBUG   (  357):     r8 a2af06b0  r9 00200019  sl af2033c8  fp af2030a4
I/DEBUG   (  357):     ip b6e627dc  sp bec8eee0  lr af2029b0  pc a0b4d248  cpsr 800d0010
I/DEBUG   (  357): 
I/DEBUG   (  357): backtrace:
I/DEBUG   (  357):     #00 pc 01be4248  /data/app/app.api.flic.io.api-2/lib/arm/libAPIsJava.so

However, Issuing arm-linux-androideabi-addr2line -f -e libAPIsJava.so 01be4248, the output is

$a
/tmp/ghc27404_0/ghc27404_3.bc:? 

Which is not of much help. What I would really like is to run the app with valgrind, is something like that possible?

Update: I have now installed valgrind and tried to run the app. However I get

valgrind: mmap(0x108000, 42770432) failed in UME with error 22 (Invalid argument).
valgrind: this can be caused by executables with very large text, data or bss segments.

Which seems to be a no-go.

prinsen
  • 748
  • 6
  • 16
  • 1
    I think that valgrind error means valgrind was build incorrectly, see https://bugs.kde.org/show_bug.cgi?id=138424#c13. Is it possible to use gdb? – Reid Barton Jul 21 '15 at 17:53
  • 2
    Presumably either you are doing something wrong or there is a bug somewhere, and in either case it is going to be hard to make progress without an actual description of what you are doing (the code you are building, how you are building it, how you built ghc, etc.) One other thing that may help narrow down the possibilities slightly is to try other environments if possible, like Android on x86 (emulator) or a regular Linux distribution on ARM, if you have the hardware for it. – Reid Barton Jul 21 '15 at 17:57
  • It's a fairly long progress to build this. I generate a Haskell library using TH, generate FFI exports for some functions, generate C++ structs and Storable instances for the Haskell data types, generate SWIG files for the C++ code, builds the Swig Java library using automake and libtool, statically linking the whole GHC runtime and all the cabal libraries, some modified to polyfill some glibc functions that's missing from Bionic and then loading it in an Android app, landing at a stripped 62 MB .so file, I hope it's just a small, hard to find problem – prinsen Jul 21 '15 at 18:11
  • As I have been able to build Haskell executables with my toolchain that uses the Haskell library and run those on the device, and used the Java library on my PC, I have some faith in the build process. However, Android leaves me with very little information. I will look at the post about building valgrind – prinsen Jul 21 '15 at 18:13
  • Indeed, if I output the entry point address of memcheck-arm-linux it is Entry point address: 0x76f30 I followed http://stackoverflow.com/questions/16450650/android-valgrind-build-fails/19255251#19255251. I defined LD in the script as /opt/ghc/android-14/arm-linux-androideabi-4.8/bin/arm-linux-androideabi-ld, which is GNU ld (GNU Binutils) 2.23.2 – prinsen Jul 21 '15 at 19:18
  • I was able to run gdb on the device and it looks like it's the strings that are messing things up. I compiled a C++ version (code here http://pastebin.com/4ZpuWjrV) that also shows some strange behavior with string conversion. The lat string is correctly received by haskell, but lon becomes garbage (A%11N~D%03h%013%1b%01F) – prinsen Jul 22 '15 at 23:15

1 Answers1

2

It turned out the problem was that my cross compile toolchain (https://github.com/neurocyte/ghc-android) has a bug in its hsc2hs script. It's implemented as a wrapper that calls /usr/bin/hsc2hs with some flags. However, it wasn't using the --cc and --ld flag, so the resulting .hs file targeted my build host. By adding these flags, everything works great!

prinsen
  • 748
  • 6
  • 16