7

I am trying to load a shared library using: System.loadLibrary("sharedC"); sharedC is dependent on 2 other shared libraries sharedA and sharedB, all three were made using the standalone toolchain and are included as prebuilt shared libraries. I load sharedA and sharedB before sharedC and I know of no other dependencies. But when I try to load sharedC, I get a SEGV. When I run strace, this is what I get:

writev(3, [{"\3", 1}, {"dalvikvm\0", 9}, {"Trying to load lib /data/data/com.exa
mple.hellojni/lib/libsharedC.so 0x44e8ce28\n\0", 83}], 3) = 93
stat64("/data/data/com.example.hellojni/lib/libsharedC.so", {st_dev=makedev(31
, 1), st_ino=499, st_mode=S_IFREG|0644, st_nlink=1, st_uid=1000, st_gid=1000, st
_blksize=4096, st_blocks=24487, st_size=12536908, st_atime=2012/03/22-21:49:35,
st_mtime=2012/03/22-14:48:00, st_ctime=2012/03/22-21:49:41}) = 0
open("/data/data/com.example.hellojni/lib/libsharedC.so", O_RDONLY|O_LARGEFILE
) = 27
lseek(27, 0, SEEK_SET)                  = 0
read(27, "\177ELF\1\1\1\0\0\0\0\0\0\0\0\0\3\0(\0\1\0\0\0°\235\31\0004\0\0\0\4I┐\
0\2\0\0\0054\0 \0\5\0(\0\25\0\24\0\1\0\0pΦ\224║\0Φ\224║\0Φ\224║\0@X\2\0@X\2\0\4\
0\0\0\4\0\0\0\1\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0(φ╝\0(φ╝\0\5\0\0\0\0\20\0\0\1\0\0\0
(φ╝\0(²╝\0(²╝\0\234G\2\0\20\202\2\0\6\0\0\0\0\20\0\0\2\0\0\0°»╛\0°┐╛\0°┐╛\0\10\1
\0\0\10\1\0\0\6\0\0\0\4\0\0\0Qσtd\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\7\0\0\
0\4\0\0\0\33@\0\0fJ\0\0\0\0\0\0┴G\0\0$,\0\0\222\27\0\0#\2\0\0j)\0\0\1&\0\0\0045\
0\0\16.\0\0"..., 4096) = 4096
lseek(27, -8, SEEK_END)                 = 12536900
read(27, "\1\0\0\0\0\0\0\0", 8)         = 8
mmap2(0x82000000, 12550144, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_ANONYMOUS, -1,
0) = 0x82000000
mmap2(0x82000000, 12381480, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_FIXED, 27, 0) =
 0x82000000
mprotect(0x82000000, 12382208, PROT_READ|PROT_WRITE|PROT_EXEC) = 0
mmap2(0x82bcf000, 152772, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED, 27, 0xbce
) = 0x82bcf000
mmap2(0x82bf5000, 12088, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_ANONYMO
US, -1, 0) = 0x82bf5000
close(27)                               = 0
mprotect(0x82000000, 12382208, PROT_READ|PROT_EXEC) = 0
getuid32()                              = 10030
geteuid32()                             = 10030
getgid32()                              = 10030
getegid32()                             = 10030
mprotect(0x41868000, 4096, PROT_READ|PROT_WRITE) = 0
mprotect(0x41868000, 4096, PROT_READ)   = 0
mprotect(0x41868000, 4096, PROT_READ|PROT_WRITE) = 0
mprotect(0x41868000, 4096, PROT_READ)   = 0
mprotect(0x41868000, 4096, PROT_READ|PROT_WRITE) = 0
mprotect(0x41868000, 4096, PROT_READ)   = 0
mprotect(0x41868000, 4096, PROT_READ|PROT_WRITE) = 0
mprotect(0x41868000, 4096, PROT_READ)   = 0
mprotect(0x41868000, 4096, PROT_READ|PROT_WRITE) = 0
mprotect(0x41868000, 4096, PROT_READ)   = 0
mprotect(0x41868000, 4096, PROT_READ|PROT_WRITE) = 0
mprotect(0x41868000, 4096, PROT_READ)   = 0
mprotect(0x41868000, 4096, PROT_READ|PROT_WRITE) = 0
mprotect(0x41868000, 4096, PROT_READ)   = 0
mprotect(0x41868000, 4096, PROT_READ|PROT_WRITE) = 0
mprotect(0x41868000, 4096, PROT_READ)   = 0
mprotect(0x41868000, 4096, PROT_READ|PROT_WRITE) = 0
mprotect(0x41868000, 4096, PROT_READ)   = 0
mprotect(0x41868000, 4096, PROT_READ|PROT_WRITE) = 0
mprotect(0x41868000, 4096, PROT_READ)   = 0
mprotect(0x41868000, 4096, PROT_READ|PROT_WRITE) = 0
mprotect(0x41868000, 4096, PROT_READ)   = 0
mprotect(0x41868000, 4096, PROT_READ|PROT_WRITE) = 0
mprotect(0x41868000, 4096, PROT_READ)   = 0
mprotect(0x41868000, 4096, PROT_READ|PROT_WRITE) = 0
mprotect(0x41868000, 4096, PROT_READ)   = 0
mprotect(0x41868000, 4096, PROT_READ|PROT_WRITE) = 0
mprotect(0x41868000, 4096, PROT_READ)   = 0
mprotect(0x41868000, 4096, PROT_READ|PROT_WRITE) = 0
mprotect(0x41868000, 4096, PROT_READ)   = 0
mprotect(0x41868000, 4096, PROT_READ|PROT_WRITE) = 0
mprotect(0x41868000, 4096, PROT_READ)   = 0
mprotect(0x41868000, 4096, PROT_READ|PROT_WRITE) = 0
mprotect(0x41868000, 4096, PROT_READ)   = 0
mprotect(0x41868000, 4096, PROT_READ|PROT_WRITE) = 0
mprotect(0x41868000, 4096, PROT_READ)   = 0
mprotect(0x41868000, 4096, PROT_READ|PROT_WRITE) = 0
mprotect(0x41868000, 4096, PROT_READ)   = 0
mprotect(0x41868000, 4096, PROT_READ|PROT_WRITE) = 0
mprotect(0x41868000, 4096, PROT_READ)   = 0
mprotect(0x41868000, 4096, PROT_READ|PROT_WRITE) = 0
mprotect(0x41868000, 4096, PROT_READ)   = 0
mprotect(0x41868000, 4096, PROT_READ|PROT_WRITE) = 0
mprotect(0x41868000, 4096, PROT_READ)   = 0
mprotect(0x41868000, 4096, PROT_READ|PROT_WRITE) = 0
mprotect(0x41868000, 4096, PROT_READ)   = 0
mprotect(0x41868000, 4096, PROT_READ|PROT_WRITE) = 0
mprotect(0x41868000, 4096, PROT_READ)   = 0
mprotect(0x41868000, 4096, PROT_READ|PROT_WRITE) = 0
mprotect(0x41868000, 4096, PROT_READ)   = 0
mprotect(0x41868000, 4096, PROT_READ|PROT_WRITE) = 0
mprotect(0x41868000, 4096, PROT_READ)   = 0
mprotect(0x41868000, 4096, PROT_READ|PROT_WRITE) = 0
mprotect(0x41868000, 4096, PROT_READ)   = 0
mprotect(0x41868000, 4096, PROT_READ|PROT_WRITE) = 0
mprotect(0x41868000, 4096, PROT_READ)   = 0
mprotect(0x41868000, 4096, PROT_READ|PROT_WRITE) = 0
mprotect(0x41868000, 4096, PROT_READ)   = 0
mprotect(0x41868000, 4096, PROT_READ|PROT_WRITE) = 0
mprotect(0x41868000, 4096, PROT_READ)   = 0
mprotect(0x41868000, 4096, PROT_READ|PROT_WRITE) = 0
mprotect(0x41868000, 4096, PROT_READ)   = 0
mprotect(0x41868000, 4096, PROT_READ|PROT_WRITE) = 0
mprotect(0x41868000, 4096, PROT_READ)   = 0
mprotect(0x41868000, 4096, PROT_READ|PROT_WRITE) = 0
mprotect(0x41868000, 4096, PROT_READ)   = 0
mprotect(0x41868000, 4096, PROT_READ|PROT_WRITE) = 0
mprotect(0x41868000, 4096, PROT_READ)   = 0
mprotect(0x41868000, 4096, PROT_READ|PROT_WRITE) = 0
mprotect(0x41868000, 4096, PROT_READ)   = 0
recv(-2136444848, ptrace: umoven: I/O error
0x1, 2147483647, 0)   = 0
mprotect(0x41868000, 4096, PROT_READ|PROT_WRITE) = 0
mprotect(0x41868000, 4096, PROT_READ)   = 0
recv(-2136444848, ptrace: umoven: I/O error
0x1, 2147483647, 0)   = 0
mprotect(0x41868000, 4096, PROT_READ|PROT_WRITE) = 0
mprotect(0x41868000, 4096, PROT_READ)   = 0
mprotect(0x41868000, 4096, PROT_READ|PROT_WRITE) = 0
mprotect(0x41868000, 4096, PROT_READ)   = 0
...
mprotect(0x42f02000, 4096, PROT_READ|PROT_WRITE) = 0
mprotect(0x42f02000, 4096, PROT_READ)   = 0
getcwd(0, 0)                            = -1 ERANGE (Math result not representab
le)
brk(0x37f000)                           = 0x37f000
lstat64(".", {st_dev=makedev(0, 1), st_ino=1, st_mode=S_IFDIR|0755, st_nlink=13,
 st_uid=0, st_gid=0, st_blksize=4096, st_blocks=0, st_size=0, st_atime=0, st_mti
me=2012/03/22-21:46:13, st_ctime=2012/03/22-21:46:13}) = 0
lstat64("/", {st_dev=makedev(0, 1), st_ino=1, st_mode=S_IFDIR|0755, st_nlink=13,
 st_uid=0, st_gid=0, st_blksize=4096, st_blocks=0, st_size=0, st_atime=0, st_mti
me=2012/03/22-21:46:13, st_ctime=2012/03/22-21:46:13}) = 0
getuid32()                              = 10030
--- SIGSEGV (Segmentation fault) @ 0 (0) ---
sigaction(SIGUSR1, {SIG_IGN}, {SIG_DFL}, 0) = 0
SYS_224(0, 0xbea811a0, 0xbea811a0, 0)   = 224
socket(PF_UNIX, SOCK_STREAM, 0)         = 27
connect(27, {sa_family=AF_UNIX, path=@android:debuggerd}, 20) = 0
write(27, "α\0\0\0", 4)                 = 4
read(27, 0xbea811cc, 1)                 = ? ERESTARTSYS (To be restarted)
read(27, "", 1)                         = 0
close(27)                               = 0
sigaction(SIGSEGV, {SIG_IGN}, {0xb0001d45, [], SA_RESTART}, 0) = 0
sigreturn()                             = ? (mask now [HUP QUIT TRAP ABRT BUS])
--- SIGSEGV (Segmentation fault) @ 0 (0) ---
Process 224 detached

Any thoughts on what is going wrong?

Update 1

Ok, debugging a stack trace is new to me, but please follow along and tell me if I am doing it wrong or otherwise?

Interesting, it seems like I am the SEGV is happening outside my code?? Looks like it is happening in libgnustl_shared.so.

So this is my stack trace:

03-23 23:37:14.213: I/DEBUG(28): *** *** *** *** *** *** *** *** ***
*** *** *** *** *** *** ***
03-23 23:37:14.213: I/DEBUG(28): Build fingerprint: 'generic/sdk/
generic/:2.1-update1/ECLAIR/35983:eng/test-keys'
03-23 23:37:14.224: I/DEBUG(28): pid: 332, tid: 332  >>>
com.example.hellojni <<<
03-23 23:37:14.224: I/DEBUG(28): signal 11 (SIGSEGV), fault addr
00000000
03-23 23:37:14.224: I/DEBUG(28):  r0 00000000  r1 00000000  r2
80808080  r3 00000000
03-23 23:37:14.224: I/DEBUG(28):  r4 00000000  r5 bea8154c  r6
bea81600  r7 00000000
03-23 23:37:14.224: I/DEBUG(28):  r8 bea81820  r9 41971894  10
00000354  fp bea814fc
03-23 23:37:14.224: I/DEBUG(28):  ip 80a81058  sp bea814c0  lr
80a63cd8  pc afe0e7c8  cpsr 40000010
03-23 23:37:14.313: I/DEBUG(28):          #00  pc 0000e7c8  /system/
lib/libc.so
03-23 23:37:14.313: I/DEBUG(28):          #01  pc 00063cd4  /data/data/
com.example.hellojni/lib/libgnustl_shared.so
03-23 23:37:14.323: I/DEBUG(28): code around pc:
03-23 23:37:14.323: I/DEBUG(28): afe0e7b8 e31c0003 1afffff6 e1a00002
e59f20d8
03-23 23:37:14.323: I/DEBUG(28): afe0e7c8 e490c004 e0433000 f5d0f040
e04c13a2
03-23 23:37:14.323: I/DEBUG(28): afe0e7d8 e0011002 e1d1100c 0490c004
1a000022
03-23 23:37:14.323: I/DEBUG(28): code around lr:
03-23 23:37:14.323: I/DEBUG(28): 80a63cc8 e1a05000 e1a00001 e1a04001
ebff27d0
03-23 23:37:14.323: I/DEBUG(28): 80a63cd8 e1a01004 e1a02000 e1a00005
e8bd4070
03-23 23:37:14.323: I/DEBUG(28): 80a63ce8 eaffffa0 e590c000 e92d45f0
e51ce00c
03-23 23:37:14.323: I/DEBUG(28): stack:
03-23 23:37:14.323: I/DEBUG(28):     bea81480  001479d0  [heap]
03-23 23:37:14.323: I/DEBUG(28):     bea81484  bea81820  [stack]
03-23 23:37:14.323: I/DEBUG(28):     bea81488  41971894  /dev/ashmem/
dalvik-LinearAlloc (deleted)
03-23 23:37:14.323: I/DEBUG(28):     bea8148c  00000354
03-23 23:37:14.334: I/DEBUG(28):     bea81490  bea814fc  [stack]
03-23 23:37:14.334: I/DEBUG(28):     bea81494  00147a24  [heap]
03-23 23:37:14.334: I/DEBUG(28):     bea81498  00000006
03-23 23:37:14.334: I/DEBUG(28):     bea8149c  80a63b58  /data/data/
com.example.hellojni/lib/libgnustl_shared.so
03-23 23:37:14.334: I/DEBUG(28):     bea814a0  00000006
03-23 23:37:14.334: I/DEBUG(28):     bea814a4  bea81548  [stack]
03-23 23:37:14.334: I/DEBUG(28):     bea814a8  80a82110
03-23 23:37:14.334: I/DEBUG(28):     bea814ac  00000000
03-23 23:37:14.334: I/DEBUG(28):     bea814b0  bea81820  [stack]
03-23 23:37:14.334: I/DEBUG(28):     bea814b4  80a63bcc  /data/data/
com.example.hellojni/lib/libgnustl_shared.so
03-23 23:37:14.334: I/DEBUG(28):     bea814b8  df002777
03-23 23:37:14.334: I/DEBUG(28):     bea814bc  e3a070ad
03-23 23:37:14.344: I/DEBUG(28): #00 bea814c0  bea814d4  [stack]
03-23 23:37:14.344: I/DEBUG(28):     bea814c4  00000000
03-23 23:37:14.344: I/DEBUG(28): #01 bea814c8  bea81548  [stack]
03-23 23:37:14.344: I/DEBUG(28):     bea814cc  bea81548  [stack]
03-23 23:37:14.344: I/DEBUG(28):     bea814d0  bea81600  [stack]
03-23 23:37:14.344: I/DEBUG(28):     bea814d4  8131f228  /data/data/
com.example.hellojni/lib/libsharedB.so
03-23 23:37:14.344: I/DEBUG(28):     bea814d8  afe39190  /system/lib/
libc.so
03-23 23:37:14.344: I/DEBUG(28):     bea814dc  bea8152c  [stack]
03-23 23:37:14.344: I/DEBUG(28):     bea814e0  001479a0  [heap]
03-23 23:37:14.344: I/DEBUG(28):     bea814e4  bea81548  [stack]
03-23 23:37:14.344: I/DEBUG(28):     bea814e8  80a8211c
03-23 23:37:14.344: I/DEBUG(28):     bea814ec  001479a0  [heap]
03-23 23:37:14.344: I/DEBUG(28):     bea814f0  bea81548  [stack]
03-23 23:37:14.344: I/DEBUG(28):     bea814f4  bea81548  [stack]
03-23 23:37:14.344: I/DEBUG(28):     bea814f8  bea8151c  [stack]
03-23 23:37:14.344: I/DEBUG(28):     bea814fc  8131eb8c  /data/data/
com.example.hellojni/lib/libsharedB.so
03-23 23:37:14.344: I/DEBUG(28):     bea81500  bea8152c  [stack]
03-23 23:37:14.344: I/DEBUG(28):     bea81504  0000272e
03-23 23:37:14.344: I/DEBUG(28):     bea81508  80a82124
03-23 23:37:14.344: I/DEBUG(28):     bea8150c  80a8211c
03-23 23:37:14.884: D/Zygote(30): Process 332 terminated by signal
(11)
03-23 23:37:14.893: I/ActivityManager(52): Process
com.example.hellojni (pid 332) has died.
03-23 23:37:14.966: I/UsageStats(52): Unexpected resume of
com.android.launcher while already resumed in com.example.hellojni

I tried this to understand it better based on reading android-ndk-r7b/ docs/NDK-STACK.html

adb.exe logcat | C:\ndk\android-ndk-r7b\ndk-stack.exe -sym C:\ndk
\android-ndk-r7_google\samples\hello-jni\obj\local\armeabi

********** Crash dump: **********
Build fingerprint: 'generic/sdk/generic/:2.1-update1/ECLAIR/35983:eng/
test-keys'

pid: 332, tid: 332  >>> com.example.hellojni <<<
signal 11 (SIGSEGV), fault addr 00000000
Stack frame #00  pc 0000e7c8  /system/lib/libc.so
Stack frame #01  pc 00063cd4  /data/data/com.example.hellojni/lib/
libgnustl_shared.so: Unable to locate routine information for address
63cd4 in module C:\ndk\android-ndk-r7_google\samples\hello-jni\obj
\local\armeabi/libgnustl_shared.so

So, I am not sure what to do now. I didn't create libgnustl_shared.so, it is just part of the ndk. Prior to this point, I had loaded a few other shared libraries. This happened when loading the last library which is dependent on the other shared libraries and on libgnustl_shared.so, which I loaded first.

What other info is needed to debug this problem correctly?

Update 2

To describe my project better, I have 6 shared libraries I am loading.

The first is libgnustl_shared.so, it loads fine. The next is libpcre.so. This is a prebuilt shared library. It loads fine. Here is the readelf from it:

File: libpcre.so

Dynamic section at offset 0x16d8c contains 23 entries:
  Tag        Type                         Name/Value
 0x00000001 (NEEDED)                     Shared library: [libc.so]
 0x00000001 (NEEDED)                     Shared library: [libdl.so]
 0x0000000e (SONAME)                     Library soname: [libpcre.so]
 0x00000010 (SYMBOLIC)                   0x0
 0x00000019 (INIT_ARRAY)                 0x17d78
 0x0000001b (INIT_ARRAYSZ)               8 (bytes)
 0x0000001a (FINI_ARRAY)                 0x17d80
 0x0000001c (FINI_ARRAYSZ)               12 (bytes)
 0x00000004 (HASH)                       0xb4
 0x00000005 (STRTAB)                     0x858
 0x00000006 (SYMTAB)                     0x318
 0x0000000a (STRSZ)                      1095 (bytes)
 0x0000000b (SYMENT)                     16 (bytes)
 0x00000003 (PLTGOT)                     0x17e64
 0x00000002 (PLTRELSZ)                   192 (bytes)
 0x00000014 (PLTREL)                     REL
 0x00000017 (JMPREL)                     0xcf8
 0x00000011 (REL)                        0xca0
 0x00000012 (RELSZ)                      88 (bytes)
 0x00000013 (RELENT)                     8 (bytes)
 0x00000016 (TEXTREL)                    0x0
 0x6ffffffa (RELCOUNT)                   7
 0x00000000 (NULL)                       0x0

The next is libsharedA.so. This is a prebuilt shared library. It loads fine. Here is the readelf from it:

File: libsharedA.so

Dynamic section at offset 0xd536c contains 25 entries:
  Tag        Type                         Name/Value
 0x00000001 (NEEDED)                     Shared library:
[libgnustl_shared.so]
 0x00000001 (NEEDED)                     Shared library: [libm.so]
 0x00000001 (NEEDED)                     Shared library: [libc.so]
 0x00000001 (NEEDED)                     Shared library: [libdl.so]
 0x0000000e (SONAME)                     Library soname:
[libsharedA.so]
 0x00000010 (SYMBOLIC)                   0x0
 0x00000019 (INIT_ARRAY)                 0xd6054
 0x0000001b (INIT_ARRAYSZ)               16 (bytes)
 0x0000001a (FINI_ARRAY)                 0xd6064
 0x0000001c (FINI_ARRAYSZ)               16 (bytes)
 0x00000004 (HASH)                       0xd4
 0x00000005 (STRTAB)                     0x50cc
 0x00000006 (SYMTAB)                     0x175c
 0x0000000a (STRSZ)                      8630 (bytes)
 0x0000000b (SYMENT)                     16 (bytes)
 0x00000003 (PLTGOT)                     0xd6454
 0x00000002 (PLTRELSZ)                   1832 (bytes)
 0x00000014 (PLTREL)                     REL
 0x00000017 (JMPREL)                     0x7ca4
 0x00000011 (REL)                        0x7284
 0x00000012 (RELSZ)                      2592 (bytes)
 0x00000013 (RELENT)                     8 (bytes)
 0x00000016 (TEXTREL)                    0x0
 0x6ffffffa (RELCOUNT)                   219
 0x00000000 (NULL)                       0x0

The next is libsharedB.so. This is a prebuilt shared library. It loads fine. Here is the readelf from it:

File: libsharedB.so

Dynamic section at offset 0xea6278 contains 28 entries:
  Tag        Type                         Name/Value
 0x00000001 (NEEDED)                     Shared library:
[libsharedA.so]
 0x00000001 (NEEDED)                     Shared library: [libpcre.so]
 0x00000001 (NEEDED)                     Shared library:
[libgnustl_shared.so]
 0x00000001 (NEEDED)                     Shared library: [libm.so]
 0x00000001 (NEEDED)                     Shared library: [libc.so]
 0x00000001 (NEEDED)                     Shared library: [libdl.so]
 0x0000000e (SONAME)                     Library soname:
[libsharedB.so]
 0x00000010 (SYMBOLIC)                   0x0
 0x0000000f (RPATH)                      Library rpath: [/home/corbin/
sharedA/.libs:/home/corbin/pcreout/lib]
 0x00000019 (INIT_ARRAY)                 0xe9a000
 0x0000001b (INIT_ARRAYSZ)               2032 (bytes)
 0x0000001a (FINI_ARRAY)                 0xe9a7f0
 0x0000001c (FINI_ARRAYSZ)               12 (bytes)
 0x00000004 (HASH)                       0xd4
 0x00000005 (STRTAB)                     0xaf734
 0x00000006 (SYMTAB)                     0x2ff44
 0x0000000a (STRSZ)                      1534855 (bytes)
 0x0000000b (SYMENT)                     16 (bytes)
 0x00000003 (PLTGOT)                     0xea6378
 0x00000002 (PLTRELSZ)                   4216 (bytes)
 0x00000014 (PLTREL)                     REL
 0x00000017 (JMPREL)                     0x2964e4
 0x00000011 (REL)                        0x2262bc
 0x00000012 (RELSZ)                      459304 (bytes)
 0x00000013 (RELENT)                     8 (bytes)
 0x00000016 (TEXTREL)                    0x0
 0x6ffffffa (RELCOUNT)                   9922
 0x00000000 (NULL)                       0x0

The next is libsharedC.so. This is a prebuilt shared library. It fails to load, with the SEGV described previously. Here is the readelf from it:

File: libsharedC.so

Dynamic section at offset 0xed7934 contains 29 entries:
  Tag        Type                         Name/Value
 0x00000001 (NEEDED)                     Shared library:
[libsharedB.so]
 0x00000001 (NEEDED)                     Shared library:
[libsharedA.so]
 0x00000001 (NEEDED)                     Shared library: [libz.so]
 0x00000001 (NEEDED)                     Shared library:
[libgnustl_shared.so]
 0x00000001 (NEEDED)                     Shared library: [libm.so]
 0x00000001 (NEEDED)                     Shared library: [libc.so]
 0x00000001 (NEEDED)                     Shared library: [libdl.so]
 0x0000000e (SONAME)                     Library soname:
[libsharedC.so]
 0x00000010 (SYMBOLIC)                   0x0
 0x0000000f (RPATH)                      Library rpath: [/home/corbin/
libsharedB/.libs:/home/corbin/libsharedA/.libs]
 0x00000019 (INIT_ARRAY)                 0xeb6000
 0x0000001b (INIT_ARRAYSZ)               1068 (bytes)
 0x0000001a (FINI_ARRAY)                 0xeb642c
 0x0000001c (FINI_ARRAYSZ)               12 (bytes)
 0x00000004 (HASH)                       0xd4
 0x00000005 (STRTAB)                     0xab79c
 0x00000006 (SYMTAB)                     0x2f28c
 0x0000000a (STRSZ)                      1557316 (bytes)
 0x0000000b (SYMENT)                     16 (bytes)
 0x00000003 (PLTGOT)                     0xed7a3c
 0x00000002 (PLTRELSZ)                   45320 (bytes)
 0x00000014 (PLTREL)                     REL
 0x00000017 (JMPREL)                     0x296258
 0x00000011 (REL)                        0x227ae0
 0x00000012 (RELSZ)                      452472 (bytes)
 0x00000013 (RELENT)                     8 (bytes)
 0x00000016 (TEXTREL)                    0x0
 0x6ffffffa (RELCOUNT)                   31042
 0x00000000 (NULL)                       0x0

I don't get to loading the 6th shared library, but that is the one that I create at the top which is dependent on these prebuilt shared libraries.

When I try David's suggestion:

03-27 20:13:18.483: I/utils(255): trying dlopen of </data/data/com.example.hellojni/lib/libpcre.so>
03-27 20:13:18.483: I/utils(255): handle=0xb0012c08 error: Symbol not found: 
03-27 20:13:18.483: I/utils(255): trying dlopen of </data/data/com.example.hellojni/lib/libsharedA.so>
03-27 20:13:18.503: I/utils(255): handle=0xb0012d20 error: (null)
03-27 20:13:18.515: I/utils(255): trying dlopen of </data/data/com.example.hellojni/lib/libsharedB.so>
03-27 20:13:19.053: I/utils(255): handle=0xb0012e38 error: (null)
03-27 20:13:19.053: I/utils(255): trying dlopen of </data/data/com.example.hellojni/lib/libsharedC.so>
03-27 20:13:19.753: I/DEBUG(28): *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** ***
03-27 20:13:19.763: I/DEBUG(28): Build fingerprint: 'generic/sdk/generic/:2.1-update1/ECLAIR/35983:eng/test-keys'
03-27 20:13:19.773: I/DEBUG(28): pid: 255, tid: 255  >>> com.example.hellojni <<<
03-27 20:13:19.773: I/DEBUG(28): signal 11 (SIGSEGV), fault addr 00000000
03-27 20:13:19.773: I/DEBUG(28):  r0 00000000  r1 00000000  r2 80808080  r3 00000000
03-27 20:13:19.773: I/DEBUG(28):  r4 00000000  r5 be890574  r6 be890628  r7 00000000
03-27 20:13:19.773: I/DEBUG(28):  r8 80b03a18  r9 be890768  10 4186bc28  fp be890524
03-27 20:13:19.773: I/DEBUG(28):  ip 80a81058  sp be8904e8  lr 80a63cd8  pc afe0e7c8  cpsr 40000010
03-27 20:13:19.863: I/DEBUG(28):          #00  pc 0000e7c8  /system/lib/libc.so
03-27 20:13:19.863: I/DEBUG(28):          #01  pc 00063cd4  /data/data/com.example.hellojni/lib/libgnustl_shared.so

I see a funny with libpcre, but it is libsharedB that is dependent on it and he ended up loading fine. But, I don't get any more info for when it actually crashes via a SEGV on libsharedC.

Please tell me what other info is needed to debug. I am stuck, but this is important to me, and can provide any info necessary to understand the failure better.

I also switched to using static versions of my libraries and got to the exact same place.

Another update:

If I use addr2line based on the static trace I get the following:

android-linux-addr2line.exe -C -f -e libc.so 0000e7c8
strlen
??:0

android-linux-addr2line.exe -C -f -e libgnustl_shared.so 00063cd4
std::string::operator=(char const*)
??:0

The lib I am loading is open source (so I have the source code), how do I find out where this problem is originating?

Community
  • 1
  • 1
corbin
  • 1,446
  • 2
  • 27
  • 40

4 Answers4

3

The way I debug this kind of nonsense is to create a tiny helper library which calls dlopen() and reports any error. The C++ code is quite long but is nearly all boilerplate:

#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <jni.h>
#include <dlfcn.h>
#include <android/log.h>

#define  LOG_TAG "utils"
#define  LOGI(...)  __android_log_print(ANDROID_LOG_INFO, LOG_TAG, __VA_ARGS__)
#define  LOGW(...)  __android_log_print(ANDROID_LOG_WARN, LOG_TAG, __VA_ARGS__)
#define  LOGE(...)  __android_log_print(ANDROID_LOG_ERROR, LOG_TAG, __VA_ARGS__)
#define  LOGD(...)  __android_log_print(ANDROID_LOG_INFO, LOG_TAG, __VA_ARGS__)

static void dlopen_impl(JNIEnv* jenv, jclass clazz, jstring path)
{
    int pathlen = jenv->GetStringUTFLength(path);
    char pathb[pathlen + 1];
    jenv->GetStringUTFRegion(path, 0, pathlen, pathb);

    LOGD("trying dlopen of <%s>", pathb);
    void* handle = dlopen(pathb, RTLD_NOW);
    LOGD("handle=%p error: %s", handle, dlerror());
}

static int registerNativeMethods(JNIEnv* env, const char* className,
        const JNINativeMethod* gMethods, int numMethods)
{
    jclass clazz;

    clazz = env->FindClass(className);
    if (clazz == NULL)
        return -1;

    int result = 0;
    if (env->RegisterNatives(clazz, gMethods, numMethods) < 0)
        result = -1;

    env->DeleteLocalRef(clazz);
    return result;
}

extern "C" jint JNI_OnLoad(JavaVM* vm, void *);

__attribute__((visibility("default")))
jint JNI_OnLoad(JavaVM* vm, void *)
{
    JNIEnv* jenv;
    vm->GetEnv((void**) &jenv, JNI_VERSION_1_4);

    static const JNINativeMethod m[] =
    {
        { "dlopentest", "(Ljava/lang/String;)V", (void*) &dlopen_impl },
    };

    registerNativeMethods(jenv, "com/cowlark/android/Utils",
            m, sizeof(m)/sizeof(*m));

    return JNI_VERSION_1_4;
}

Then I create a Java class, com.cowlark.android.Utils, as follows:

package com.antixlabs.agpndk;

import java.io.File;

public class Utils
{
    static
    {
        System.loadLibrary("agputils");
    }

    public native static void dlopentest(String path);
}

Now all this is done, I can insert the following code into my actual application class:

static
{
    Utils.dlopentest("/data/data/com.cowlark.myapp/lib/libdodgy.so");
}

If libdodgy.so fails to load, I actually get an actually informative error message.

This trick has saved me so much time in the past.

David Given
  • 13,277
  • 9
  • 76
  • 123
  • See my edit I made on your answer, it contains what happened doing this trick in my scenario. Basically, I got this: trying dlopen of handle=0xb0012c08 error: Symbol not found: trying dlopen of handle=0xb0012d20 error: (null) trying dlopen of handle=0xb0012e38 error: (null) trying dlopen of , then the same SEGV reported initially. No additional info about the SEGV – corbin Mar 27 '12 at 20:33
  • I do see the funny when loading libpcre, but it is libsharedB that is dependent on it and it was happy. I think since it is dieing due to a SEGV, your trick might not provide additional info?? – corbin Mar 27 '12 at 20:36
  • That's very strange --- it looks like it's crashing _inside_ the call to `dlopen()`. Which it shouldn't. I'm also surprised by the fact that the load error for `libpcre.so` doesn't tell you what symbol couldn't be found; it does for me. I see you're running Eclair, which has got a very old and manky version of the JNI code. I'd suggest running it in an Ice Cream Sandwich emulator image (or a real phone, if you have one) and seeing what happens there. – David Given Mar 27 '12 at 21:05
  • Exact same on a 2.2 device vs. 2.1 emulator. Will try ICS emulator next. – corbin Mar 27 '12 at 22:10
  • @David: I copied corbin's suggested edit into his question, please give it a look if you're inclined. – sarnold Mar 27 '12 at 22:41
3

Based on your reply to David Given where dlopen is complaining about a missing symbol, one other thing to try that has helped me is to take all the .o files in your shared library

ar x libsharedC.so

along with any dependant ones copied off of any android device and dump them all in to one directory, then try linking all the .o files from your shared lib with g++ from the standalone tool chain. It can end up being a bit fiddly and a potential wild goose chase, but it may show you any missing symbols.

The line I use to link is

arm-linux-androideabi-g++ -O3 -shared -o biglib.a -fpic  *.o -Wl,--no-whole-archive  -Wl,--no-undefined -Wl,-z,noexecstack -Wl,--fix-cortex-a8,--entry=main,-rpath-link=/tmp/tc/sysroot/usr/lib -llog -lz
Wil
  • 349
  • 3
  • 12
  • 1
    Just a thought as well, you could try copying off the libc.so and gnustl_shared and running the toolchain version of nm or readelf to find out what function is at or about 0000e7c8 and 00063cd4 as it may give you a clue as to what is going wrong. Also could you try adding your ndk makefiles to see if there anything odd like bringing in the wrong version of something? – Wil Mar 28 '12 at 15:20
  • I have confirmed it is not a linking problem, similar to as suggested. Will look more into what is at those addresses. – corbin Mar 29 '12 at 16:06
  • I have another random stab in the dark, this http://stackoverflow.com/questions/6551670/android-jni-onload-lead-to-a-crash-on-device has a ( very ) vaguely similar stack trace but I can see in your case you are running on an ARM device. You're not by any chance compiling for x86 though? – Wil Mar 29 '12 at 19:45
  • And there is this http://stackoverflow.com/questions/5776594/signal-11-sigsegv-fault-addr-00000000-comes-in-my-app which claims it may be a firmware bug on your phone. Are you running a custom rom or can you update? – Wil Mar 29 '12 at 19:50
  • /edit Strike the x86 guess, I can see from the ELF header that the lib is built for ARM. – Wil Mar 29 '12 at 20:34
  • 1
    One last thing, it will be interesting to see what nm dumps for your /system/lib/libc.so at e7c8 as I can not find any libc.so that goes up to that address. – Wil Mar 29 '12 at 20:55
  • I added the output of addr2line to my description. I can see the issue has something to do with the assignment of a string or strlen. How do I find out where the static initialize is in the library's source code that is causing this issue? – corbin Mar 30 '12 at 16:17
  • If it is a static initialize, which would be my best guess as well ( though I'd still expect a stack frame in your code, I stand to be corrected ) then at this point I would say the only way forward is do divide and conquer. Try commenting / stubbing out all the native calls in your JNI wrapper and see if the new light library loads or has the same issue. If it has the issue then examine all statics in there, otherwise add native bits one at a time or in any other search pattern you fancy and keep going until you at least find the area that is going wrong. Sorry I can't help any more than that – Wil Apr 02 '12 at 13:53
  • Thank you for your effort. Giving this to you. Got further by using addr2line on some of what was on the stack. Had to calculate real pc to figure out what addr to feed it. Will post example later. – corbin Apr 02 '12 at 19:53
  • Wil, about libc you have to grab the same libc.so that I am using, it can be different per android release, or even per device, but they should be backwards compatible per new version, but that doesn't help you if you are trying to use addr2line. So, I ran the same scenario on the 2.1 emulator, then used unyaffs.exe on the system.img found under android-sdks\platforms\android-7\images to get the libc.so out. Then I used addr2line and it gave me what I added to my question. – corbin Apr 03 '12 at 05:43
0

Most likely libsharedC is failing due to needing libz.so.

Even if you bundle libz with your package it will not get loaded unless the library is in the directory /system/lib directory. This is the only place android looks for dependencies such as this ( don't ask me why! ) and you can only put libs in there if your device is rooted.

Easiest way round this is to either statically link z with sharedC or bundle libZ with your app and explicitly load it in Java land before libsharedC.

Wil
  • 349
  • 3
  • 12
  • This occurs even if I run on the emulator and on the emulator system image libz.so is there in the correct place. So, this seems unlikely. Also, the errors you get when it cannot find a library are different. – corbin Mar 27 '12 at 17:22
0

I reasked this question in a more straghtforward way, but still didn't get a solution. But, I did figure it out through. See the answer I posted here:

Need help debugging further into a SEGV issue - Android NDK

I gave the bounty away to the person who was the most helpful. Thanks Wil for trying so hard to help! I already tried addr2line before you mentioned it, but your comment made me go back and try it again. Then I got to thinking...what about these other parts of the trace further down.

Community
  • 1
  • 1
corbin
  • 1,446
  • 2
  • 27
  • 40