Skip to content

ANativeActivity_onCreate not found (with solution) #381

Closed
@twaik

Description

@twaik

Description

I got an error "W/NativeActivity(18489): ANativeActivity_onCreate not found" in Android after building a large NativeActivity application. I tried to use LOCAL_WHOLE_STATIC_LIBRARIES, but it still didn't work. Command "nm -D -C -g libs/armeabi-v7a/libNativeActivity.so" told me ANativeActivity_onCreate had not been exported.

Solution

I think found a solution that can solve the problem in general. gcc can export functions with using version-script. NativeActivity application doesn't need any functions to be exported except ANativeActivity_onCreate, so I think using this wouldn't cause any problems. If I am right it can be committed to project tree.
native_app_glue Android.mk

LOCAL_PATH:= $(call my-dir)

include $(CLEAR_VARS)

LOCAL_MODULE:= android_native_app_glue
LOCAL_SRC_FILES:= android_native_app_glue.c
LOCAL_EXPORT_C_INCLUDES := $(LOCAL_PATH)
LOCAL_EXPORT_LDFLAGS:= -Wl,--version-script=$(LOCAL_PATH)/exports.txt
LOCAL_EXPORT_LDLIBS := -llog

include $(BUILD_STATIC_LIBRARY)

native_app_glue exports.txt

{
	global:
		ANativeActivity_onCreate;
	local: *;         # hide everything else
};

Please, correct me if I am not right.

Activity

alexcohn

alexcohn commented on May 9, 2017

@alexcohn

UPDATE: this comment does not apply to the root cause

If you follow the official sample, this won't happen: a call to app_dummy() will keep ANativeActivity_onCreate in your libNativeActivity.so

twaik

twaik commented on May 9, 2017

@twaik
Author

I've seen many posts at 4pda and stackoverflow about the problem. In all the cases ANativeActivity was not exported even if it was built. That solution not for problem when the ANativeActivity was stripped but for problem where it was build as a local function.

alexcohn

alexcohn commented on May 9, 2017

@alexcohn

If your xxx_CFLAGS include -fvisibility=hidden (which is a good practice), it would be enough to add JNIEXPORT to its definition in android_native_app_glue.c

This is defined in <jni.h>:

#define JNIEXPORT  __attribute__ ((visibility ("default")))

I sincerely don't understand why this __attribute__ was never added there.

DanAlbert

DanAlbert commented on May 9, 2017

@DanAlbert
Member

@alexcohn's solution LGTM, but I want to make sure there isn't something weird going on first.

@twaik: do you have APP_CFLAGS := -fvisibility=hidden set? I was able to repro this if I did that, but without that it was exported properly as long as I used LOCAL_WHOLE_STATIC_LIBRARIES (which the sample doesn't say to use, sigh).

I also noticed that android_native_app_glue doesn't export -landroid like it should. I'll get both of these things fixed in r15 and see if I can find some time to clean up the sample.

Thanks for reporting this (and thanks @alexcohn for doing the initial analysis!)

self-assigned this
on May 9, 2017
added this to the r15 milestone on May 9, 2017
DanAlbert

DanAlbert commented on May 9, 2017

@DanAlbert
Member

https://android-review.googlesource.com/392595 Export libandroid from android_native_app_glue.
https://android-review.googlesource.com/392596 Ensure that ANativeActivity_onCreate isn't hidden.

twaik

twaik commented on May 9, 2017

@twaik
Author
__attribute__((visibility("default")))
void ANativeActivity_onCreate(ANativeActivity* activity,
        void* savedState, size_t savedStateSize) {
    LOGV("Creating: %p\n", activity);

android_native_app_glue.c includes <jni.h>, which defines JNIEXPORT, isn't it?

JNIEXPORT void ANativeActivity_onCreate(ANativeActivity* activity,
        void* savedState, size_t savedStateSize) {
    LOGV("Creating: %p\n", activity);

And -fvisibility=hidden flag may be not useful in project which doesn't use native_app_glue, so

LOCAL_PATH:= $(call my-dir)

include $(CLEAR_VARS)

LOCAL_MODULE:= android_native_app_glue
LOCAL_SRC_FILES:= android_native_app_glue.c
LOCAL_EXPORT_CFLAGS := -fvisibility=hidden //THIS LINE
LOCAL_EXPORT_C_INCLUDES := $(LOCAL_PATH)
LOCAL_EXPORT_LDLIBS := -llog -landroid

include $(BUILD_STATIC_LIBRARY)
DanAlbert

DanAlbert commented on May 9, 2017

@DanAlbert
Member

@twaik: so is that a yes then? Did you have APP_CFLAGS := -fvisibility=hidden? Otherwise there may be another bug here (which those patches will conveniently hide, but not fix).

android_native_app_glue.c includes <jni.h>, which defines JNIEXPORT, isn't it?

Good point. I'll fix that.

And -fvisibility=hidden flag may be not useful in project which doesn't use native_app_glue, so

That's just a test. The point is to make sure we're tolerant of people putting that in APP_CFLAGS.

twaik

twaik commented on May 9, 2017

@twaik
Author

Tried to add it to project. What I did:
0. Added JNIEXPORT to void ANativeActivity_onCreate definition (in both lower cases).

  1. Tried to add LOCAL_EXPORT_CFLAGS := -fvisibility=hidden to Android.mk of native_app_glue. It didn't work.
  2. Tried to add APP_CFLAGS := -fvisibility=hidden to Application.mk and that didn't work too.

In both cases ANativeActivity_onCreate was not exported.

Maybe variant with
LOCAL_EXPORT_LDFLAGS:= -Wl,--version-script=$(LOCAL_PATH)/exports.txt
is the only guaranteed to work. And it is usable only for NativeActivity applications, so this line's place only in Android.mk of native_app_glue

DanAlbert

DanAlbert commented on May 9, 2017

@DanAlbert
Member

What I'm asking is what you did to cause this in the first place. What did your test case that caused you to file the bug look like?

twaik

twaik commented on May 9, 2017

@twaik
Author

I don't sure know. I tried to build X KDrive server with NDK, it has hundreds of files with thousands function definitions. Result library exports list consists of function names called from the library, but it doesn't contain function names defined in the library (I may be wrong, I just looked for ANativeActivity_onCreate) Maybe a project with the bug must contain a lot of function definitions. I can send the bug project via email.

alexcohn

alexcohn commented on May 10, 2017

@alexcohn

@twaik you probably got android_native_app_glue.o stripped away, if you used neither LOCAL_EXPORT_WHOLE_STATIC_LIBRARIES nor app_dummy() trick.

@DanAlbert I don't think NDK supports LOCAL_EXPORT_WHOLE_STATIC_LIBRARIES; that's why the app_dummy trick is easier.

twaik

twaik commented on May 10, 2017

@twaik
Author

My android_main starts from

void android_main( struct android_app * app ) {
    app_dummy();
    app->onAppCmd     = android_handle_cmd;
    app->onInputEvent = android_handle_input;

	chdir(app->activity->internalDataPath);

And my project has this line in Android.mk
LOCAL_WHOLE_STATIC_LIBRARIES := android_native_app_glue android-shmem libpixman
But ANativeActivity_onCreate still is not exported

DanAlbert

DanAlbert commented on May 10, 2017

@DanAlbert
Member

Could you share your Android.mk/Application.mk?

@DanAlbert I don't think NDK supports LOCAL_EXPORT_WHOLE_STATIC_LIBRARIES; that's why the app_dummy trick is easier.

Why is LOCAL_EXPORT_WHOLE_STATIC_LIBRARIES needed? I'm having trouble coming up with a test case that makes this needed (given that I've already added the __attribute__((visibility("default")))).

I was thinking maybe we didn't handle LOCAL_WHOLE_STATIC_LIBRARIES properly for static libraries, but it looks like we already do the smart thing and export those to consumers. To be fair, I would not have guessed that we had support for that :)

53 remaining items

Loading
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

No labels
No labels

Type

No type

Projects

No projects

Relationships

None yet

    Development

    No branches or pull requests

      Participants

      @DanAlbert@alexcohn@twaik@ggfan@nileshshah89

      Issue actions

        ANativeActivity_onCreate not found (with solution) · Issue #381 · android/ndk