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?
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.
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
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.
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.
User contributions licensed under CC BY-SA 3.0