Android SDL2 App black screen then exits - android

I have a working SDL2 demo running in Windows, but when I port this code to Android the finished app will display a black screen for few seconds and then quietly exit (no errors, nothing), rather than display the pretty test graphics within a game-loop.
If I add a call to SDL_ShowSimpleMessageBox at the start of my main, nothing happens (I've since learned that it's not implemented for Android yet - grrr), but if I comment-out my main code, ndk-build complains that it's missing, so it's certainly being included in the build, but doesn't appear to get called.
I've followed the steps in README-android.txt. After about 200 hours of solving problems over the past 2 months I eventually produced an apk. Have the following fixes I made maybe broken something?
The first problem is NDK-BUILD failing to find SDL_config.h, because of the instructions at step #2 in README-android.txt being wrong. Fixed restructuring the directories, or editing paths in Android.mk.
Second problem is NDK-BUILD failing to find EGL/eglplatform.h. Fixed by adding APP_PLATFORM := android-9 to Application.mk.
Third problem is NDK-BUILD not recognising C++11, so I added APP_CPPFLAGS += -std=c++11 to Application.mk.
Fourth problem is NDK-BUILD not finding #include <cstdarg> (used for va_list and va_start). Including <SDL.h> instead fixed this.
Fith problem is ant build failing at [aapt] Generating resource IDs. I fixed this in Android SDK Manager by deleting build-tools verion 21.1.1 and installing version 20 instead.
This is the first time I've posted for help on here because I'm desperate. I'm a veteran C++ coder but a complete novice when it comes to java. I'm using C++ in eclipse for the Windows SDL2, and I built the apk entirely from the command-line.
Tried on several different devices. Looking at the logcat, there's a signal 7 SIGBUS error:
V/SurfaceView( 3497): Layout: x=0 y=0 w=1280 h=720, frame=Rect(0, 0 - 1280, 720)
F/libc ( 3497): Fatal signal 7 (SIGBUS) at 0x00000000 (code=128)
I/ActivityManager( 162): Displayed org.libsdl.app/.SDLActivity: +416ms
V/SDL ( 3497): onWindowFocusChanged(): true
W/InputManagerService( 162): Starting input on non-focused client
com.android.internal.view.IInputMethodClient$StubProxy#410b72d8 (uid=10021 pid=331)

I've found the problem. Feel free to slap my wrists.
I've always coded with the assumption that I can address memory with 8-bit aligned pointers. This has worked for me for the past 25 years, until now. My code fails when it's targeting Android because whatever CPU it's using refuses to address memory with pointers that are 8-bit aligned. So as soon as I move a pointer along a byte-aligned butter and cast that pointer to an object and reference that pointer, BAM, android quietly exits the app.
Now the question is what to do with this question? It logs all the problems and solutions I've battled with over the past 2 months, so must be useful to someone?

I had a similar problem, but quite a different cause.
After starting the app it remained black and seemed to minimize itself after half a second. Switching to the app also minimized it again.
It turns out Makefile Syntax highlighting is bugged in SciTE (and also Stackoverflow it seems), so that something like this:
# LOCAL_SRC_FILES := $(SDL_PATH)/src/main/android/SDL_android_main.c \
LOCAL_SRC_FILES := $(SDL_PATH)/src/main/android/SDL_android_main.c \
$(PROJECT_PATH)/main.cpp
was in effect commented out completely but not shown as such. This resulted in I guess the main routine from SDL being used instead of mine.
This problem could be spotted by looking into the compiled file with nm -C android-project/obj/local/arm64-v8a/libmain.so and noticing that it contains almost no functions:
00000000000004c4 t atexit
00000000000004ac t __atexit_handler_wrapper
0000000000011008 A __bss_end__
0000000000011008 A _bss_end__
0000000000011008 A __bss_start
0000000000011008 A __bss_start__
U __cxa_atexit##LIBC
U __cxa_finalize##LIBC
0000000000010d70 t $d
0000000000011000 d $d
0000000000011000 d __dso_handle
0000000000010d80 a _DYNAMIC
0000000000011008 A _edata
0000000000011008 A _end
0000000000011008 A __end__
0000000000010ff8 a _GLOBAL_OFFSET_TABLE_
00000000000004a0 t __on_dlclose
00000000000004ac t $x
00000000000004a0 t $x
0000000000000480 t $x

Related

warning: libcryptopp.so: is missing DT_SONAME will use basename as a replacement

I am trying to build libcryptopp.so and include it in my JNI code, follow the guide in Android Crypto++, I experienced the following problems.
Missing symbol problems in Crypto++ 5.6.3
Originally I used Crypto++ 5.6.3, I came across this problem:
java.lang.UnsatisfiedLinkError: dlopen failed: cannot locate symbol "_Z9GlobalRNGv"
referenced by "/data/app/com.example.administrator.jnitest-2/lib/arm/libcryptopp.so"...
I check the libcryptopp.so:
$ readelf -Ws libcryptopp.so | grep _Z9GlobalRNGv
1406: 00000000 0 NOTYPE GLOBAL DEFAULT UND _Z9GlobalRNGv
15836: 00000000 0 NOTYPE GLOBAL DEFAULT UND _Z9GlobalRNGv
switching to Crypto++ 5.6.4 fix this problem, but I still do not know the cause and met another problem:
Missing DT_SONAME
12-21 09:50:20.837 21677-21677/com.example.administrator.jnitest
W/linker: /data/app/com.example.administrator.jnitest- 1/lib/arm/libcryptopp.so: is missing DT_SONAME will use basename as a
replacement: "libcryptopp.so"
Actually this is only a warning, app will not crash.
I am using the latest version of android Mashwallow MOB31K.
Somebody have also experienced similar problems using other libraries
https://github.com/bytedeco/javacpp-presets/issues/188
on Android N-preview.
Why am I getting the warning, and how do I fix it?
After some attempts, I find one imperfect solution.
It appears that android N turns requires library version now.
turn on SONAME flag on build.
Cryptopp turns off the version flag by defaults. In the GNUmakefile-cross,:
HAS_SOLIB_VERSION ?= 0
set the value to 1:
HAS_SOLIB_VERSION ?= 1
build, and then use the generated .so file. the warning will go.
the problem is that is library will not work on android 5.0. So we'd better leave alone this warning now.

ffmpeg for Android: neon build has text relocations

Hi I successfully built the appunite ffmpeg library including arm-v7a neon support, however when I try to run the libraries on my Marshmallow device I get this error:
01-08 23:42:02.350: E/AndroidRuntime(10144): java.lang.UnsatisfiedLinkError:
dlopen failed: /data/app/com.example.demo-1/lib/arm/libffmpeg-neon.so: has text relocations
When I use the non-neon builds it works without any problems.
So I googled a bit and found out, that this is probably a bug in the corresponding C/C++ code but on the other hand it should be fixed when rebuilt with with NDK v. 10e. This is what I did. But I still get these text relocations:
~/Projekte/AndroidFFmpeg$ /usr/Android/ndk/toolchains/arm-linux-androideabi-4.9/prebuilt/linux-x86_64/bin/arm-linux-androideabi-readelf -a library/src/main/jniLibs/armeabi-v7a/libffmpeg-neon.so | grep TEXTREL
0x00000016 (TEXTREL) 0x0
0x0000001e (FLAGS) SYMBOLIC TEXTREL
This questions seemed to be relevant, but didn't help:
"ffmpeg has text relocations" error in Android
libavcodec.so: has text relocations
How do I fix that?
This should be fixed already (since commit https://git.libav.org/?p=libav.git;a=commitdiff;h=f963f80399d, December 2014), so make sure you build a new enough version and it should be fine.
arm, aarch64 and x86_64 should all work fine without text relocations, but for 32 bit x86, you can't easily avoid it. (For x86, the simplest way around it is to do --disable-asm, but that does give quite a bit of performance loss.)

android kernel build (first time)

Ok so first off,
Im brand new to android dev. This is my first attempt at any form of kernel anything. I have a limited knowledge of java and python, but no C.
I have a galaxy tab 4 sm-t330nu running 4.4.2. its running a qualcomm snapdragon 400 msm8226 cpu. im simply trying to do a test build with a vanilla kernel at this point. (also my build environment is the newest kali 1.1 and im loosely following the tutorial at https://github.com/offensive-security/kali-nethunter/wiki/Porting-Nethunter)
so i have all of the required dependencies (i hope), and ive downloaded my source from samsung opensource. unzipped and went through the available defconfigs. after finding "msm8226-sec_milletwifiue_defconfig" i decided it was the most likely candidate for my tablet. (when doing a custom recovery i remember it being "philz touch milletwifiue something)
Ive done my exports (arch= subarch= cross_compile=) and all seems well. When i run a build following exactly as the tutorial says (using the defconfig in their example as a test) i receive an error stating "must define variant_defconfig". So i instead do "make variant_defconfig=msm8974_sec_defconfig" and it builds great.
Now the issue:
When i change "msm8974_sec_defconfig" to my actual msm8226 i receive an error on every build that i cannot seem to workaround. (cut down for size)
CC arch/arm/kernel/armksyms.o
CC arch/arm/kernel/module.o
AS arch/arm/kernel/sleep.o
CC arch/arm/kernel/suspend.o
CC arch/arm/kernel/io.o
arch/arm/kernel/io.c: In function '_memcpy_fromio':
arch/arm/kernel/io.c:14:3: error: implicit declaration of function 'nop' [-Werror=implicit-function-declaration]
cc1: some warnings being treated as errors
make[1]: *** [arch/arm/kernel/io.o] Error 1
make: *** [arch/arm/kernel] Error 2
My exact bash line reads
make VARIANT_DEFCONFIG=msm8226-sec_milletwifiue_defconfig
Any assistance on clearing this up would be great
edit
although im not familiar with c, it seems to me that '_memcpy_fromio' is where the error lies. and my google searches tell me that the error is that a function is used without being declared. however i dont know if memcpy is a function? or is the function within class memcpy (dont know if c has classes just closest equivalent that i know of) how do i debug this code and declare what needs to be declared (more importantly, if this is a stock kernel thats used by thousands of devices, how can it possibly have an undeclared function?
/edit
found the answer! needed
#import linux/modules.h
#import linux/kernel.h

Native Android - Can't locate undefined method when loading a shared lib even though previously loaded shared lib contains the definition

I am building an Android app that loads in 2 native shared libraries at runtime: 1 that was built with an unresolved symbol in it and the other which resolves and defines that symbol. In Java, I load the shared library that defines the symbol first, then load the library that has the symbol declared as unresolved, and at this point, the runtime fails with:
"Cannot load library: reloc_library[]: 33 cannot locate 'someMethod'
So here's the one unique difference. The shared library with the undefined symbol obviously doesn't know about the shared library with the definition for the symbol in it.
I just assumed that if I loaded the library with the definition of the method first that when I loaded the 2nd library that called the method, it would be able to find it. Am I wrong on that? It seems in my case, an explicit dependency HAS to be compiled in between the two native libs, which means (I think) making .so's with unresolved symbols is useless.
I have searched vigorously for a similar issue with no luck. I think my problem is due to an architectural limitation, and I am considering approaching it a couple of other ways, but I would like to know if it can be fixed simply.
To be sure it wasn't some complexity of the library itself, I created two very simple C files:
fcn_defined.c:
int someMethod()
{
return 1;
}
fcn_undefined.c:
extern int someMethod();
int someOtherMethod()
{
someMethod();
}
Then build two shared objects where the fcn_undefined.c code creates a .so with someMethod still undefined and fcn_defined.c builds a .so with someMethod defined:
gcc -o libfcn_undefined.so fcn_undefined.c -shared -Wl,--export-dynamic
gcc -o libfcn_defined.so fcn_defined.c -shared -Wl,--export-dynamic
Doing a nm on these produces:
libfcn_undefined.so:
0001f08 d _DYNAMIC
00001fe8 d _GLOBAL_OFFSET_TABLE_
00002004 A __bss_start
U __cxa_atexit
U __cxa_finalize
00002000 d __dso_handle
00000290 t __on_dlclose
00002004 A _edata
00002004 A _end
000002a0 t atexit
000002b4 T someOtherMethod
U someMethod
and libfcn_defined.so:
00001f0c d _DYNAMIC
00001fec d _GLOBAL_OFFSET_TABLE_
00002004 A __bss_start
U __cxa_atexit
U __cxa_finalize
00002000 d __dso_handle
0000025c t __on_dlclose
00002004 A _edata
00002004 A _end
0000026c t atexit
00000280 T someMethod
So you can see someMethod() is defined in libfcn_defined.so (and it appears in the read elf dynsym section) and is undefined in the other lib.
If anyone is interested in the readelf output, I can add that as well.
In the Java side, I have a simple button in the emulator that I click, and it creates a class with the following in it:
static
{
System.loadLibrary("fcn_defined");
System.loadLibrary("fcn_undefined");
}
Just out of curiosity, I added a "-lfcn_defined" to the fcn_undefined compile line, and compared the nm and readelf outputs. the only difference in nm was that the "T someOtherMethod" started a few bytes further out and the readelf difference was the "NEEDED" line for fcn_defined. That's pretty much about what I expected. And it doesn't crash like this.
That's pretty much the full explanation. I did find some details about how Android forces you to load your libraries in reverse dependency order in Java, because it has (rather it had, has been fixed in API 18) no reference to your app's lib path in the LD_LIBRARY_PATH envvar. Unfortunately, I am requiring a minimum API lvl 10 to be able to use my app because of the market penetration, and secondly I tried API 19 anyway, and it still fails.
If I had to guess, I believe Android just doesn't support finding a symbol if you haven't explicitly told it to look at library X for the symbol. In other words, because I didn't build the library fcn_undefined with an explicit dependency on libfcn_defined.so, Android can't resolve it. Does anyone know if this is a bug or by design? Is this normal? It seems like you wouldn't have the option to create a .so with unresolved symbols if this was the case, and even funnier is that the Android NDK toolchain I'm using to build this has this feature on by default when you use ld (it doesn't complain about unresolved), and I tried turning the feature off but didn't seem to do anything, no warnings or errors generating the library.
So you may ask why I don't just compile the fcn_undefined library with a dependency on the fcn_defined library. Well that gets into a much bigger architectural discussion. The code I'm working with (fcn_undefined.c in this example) is a python extension built with a cross compiled python toolchain for ARM, and I'm calling this library from an NDK library, so now the NDK library depends on the python module which has an unresolved method in Python, which is defined in a static lib. Linking the static lib into the NDK shared lib means that I can't load the native shared libs in the correct order in Java (due to the issue mentioned previously that they fixed in API 18). I'm trying to work with the existing system since a team of others use it, and it is used to build for many platforms. sigh I clearly have other things to figure out, but I was hoping to nail the one above down at least.
The behavior you so beautifully demonstrated is by design (or lack of, if you will). You are right in part, the crazy_linker does resolve some of such issues (but not all of them). There is an easy but ugly workaround. Build a dummy libfcn_defined.so which only has T someMethod in its nm. Use it to link libfnc_undefined.so, using LD_LIBS. NDK will show a warning, but that's OK. LAoad the real libfcn_defined.so in your Java.
By Unix/ELF design, you need a NEEDED entry in libfnc_undefined.so that lists libfnc_defines.so as a dependency for the dynamic linker to look into it for missing symbols.
I.e. you should ensure that -lfcn_defined (or /path/to/libfcn_defined.so) appears in the link command that generated libfcn_undefined.so.
If you use ndk-build to generate both libraries, just list libfcn_defined.so as a LOCAL_STATIC_LIBRARIES or LOCAL_SHARED_LIBRARIES entry for libfcn_undefined.so.
If you use another build system, adapt accordingly.

Android crashing on specific device - caused by int64 allocation

I'm having a problem that only seems to happen on my Lenovo Thinkpad Tablet running Android OS 3.1. I am running a native app using the NDK. The application runs fine in the emulator and on other devices.
Whenever I allocate an int64_t (defined as long long) I get a SIGILL crash with signal (4). As an example these lines will crash on the device.
int64_t i = 0;
long long j = 0;
I should note, the application runs fine, I can see menus rendering correctly, animating and waiting for input. When I touch, I allocate int64 variables for the timestamps, this is when the crash occurs. Regardless of where I allocate an int64 in this app, I get a crash.
The strange thing is, I loaded up the native-activity sample that comes with the NDK and tried allocating the above data types and it works fine. Both applications have the same Application.mk and very similar Android.mk files. I have also tried cleaning the project.
I am really unsure of what to look at next.
I have solved the problem. This project is a port from an iOS project which has some NEON math classes in it. We use the following flags for NEON support:
-mfpu=neon -mfloat-abi=softfp
We used the same flags in the Android project initially which worked initially. Although as soon as we got a new test device (Lenovo Thinkpad Tablet) we started getting the crash as above. Since building for armeabi-v5 worked and doesn't use NEON I knew it was related. It turns out there are better ways to compile for NEON for Android than using the above flags. I removed the above flags so that our Android.mk looks like so:
ifeq ($(TARGET_ARCH_ABI),armeabi-v7a)
LOCAL_CFLAGS += -DHAS_NEON=1
MY_SRC_FILES += myfile.cpp.neon
else
LOCAL_CFLAGS += -DHAS_NEON=0
MY_SRC_FILES += myfile.cpp
endif
This means that only the files that actually need to be built for NEON are. The processor inside the Lenovo Thinkpad Tablet (Nvidia Tegra 2) doesn't support NEON so clearly building all files with NEON support was generating the instructions in a way which the processor didn't like.
Thanks for Keith for suggesting that I try the other architectures which led me to my solution.
Sounds like your compiler is generating 64-bit instructions that are not implemented by the processor on your machine. Are you cross-compiling? If so, make sure you're targeting the correct version of the ARM (x86?) chip in your tablet.

Categories

Resources