1

I'm attempting to develop an android native glue application that uses LibEvents.
I obtained an android friendly build of LibEvents from here... https://github.com/ventureresearch/libevent

My android.mk file is almost identical (other than relative paths).

It successfully compiles as a static library and links into my own shared library. However when I attempt to execute I get an error from Dalvik indicating it cannot load my shared library.

E/AndroidRuntime(16123): Process: com.marty.socketclient1, PID: 16123
E/AndroidRuntime(16123): java.lang.RuntimeException: Unable to start activity ComponentInfo{com.marty.socketclient1/android.app.NativeActivity}: java.lang.IllegalArgumentException: Unable to load native library: /data/app-lib/com.marty.socketclient1-1/libSocketClient1.so

My native code functions correctly if I do not use my build of LibEvents. Also note that if I remove all the existing source files from LibEvents and add a new module with my own function and just call that in my shared library then everything behaves.
This leads me to believe it is being correctly built (or at least the compile/link flags does not themselves prohibiting loading).

ndk-depends reports no additional shared object dependencies so I thought that maybe there is some errant code being executed in LibEvents as dlopen is executing.
I tried replacing the LibEvents logging mechanism with android logging but I'm getting no further output.

Neither can I find any occurrences of

__attribute__((__constructor__))

or

_init 

in the LibEvents source code.

Note that LibEvents is just 'C' library so there can't be statically initialised objects as with C++ (or am I incorrect in this assumption?).

Are there any other means of executing functionality at load time that I'm unaware of?
Any ideas what I can check next?
Are there any further logging options I can enable that might provide further insight?

I also distilled the android.mk file (as below) to the minimum to allow me to just call:

evutil_make_socket_nonblocking()

And still suffer the issue with being unable to load the library.

LOCAL_PATH := $(call my-dir)

include $(CLEAR_VARS)

LOCAL_MODULE := libevents
LOCAL_MODULE_TAGS := optional

LOCAL_SRC_FILES :=      \
    ../evutil.c         \
    ../event.c          \
    ../log.c            \
    ../evthread.c       \
    ../evmap.c          \
    ../signal.c         \
    ../epoll.c          \
    ../poll.c           \
    ../evutil_rand.c    \
    ../select.c

LOCAL_C_INCLUDES := \
    $(LOCAL_PATH) \
    $(LOCAL_PATH)/../android \
    $(LOCAL_PATH)/../include
LOCAL_CFLAGS := -DHAVE_CONFIG_H -DANDROID -fvisibility=hidden   
#LOCAL_CFLAGS := -DHAVE_CONFIG_H -DANDROID -DNDEBUG -fvisibility=hidden

include $(BUILD_STATIC_LIBRARY)
nearproc
  • 35
  • 8

1 Answers1

1

In case anyone else suffers this issue, here's the solution.

It was a long process but I stubbed functions and isolated modules until I could reproduce the problem with just one source file. I then commented out code until I found the errant call that caused my library not to load.

It turns out to be this...

long _evutil_weakrand(void)
{
  return random();
}

And in fact if I created any function that calls random() then my shared object failed to load.

Apparently this relates to the android level. You need to use level 19, I was using level 21.

Relates to this... Android NDK: load_library: cannot locate srand

Community
  • 1
  • 1
nearproc
  • 35
  • 8