OFAndroid doesn't work on x86 devices?

Hi,

I’m using a variant of almost latest master, and I crash immediately on startup when the native library loads on my Asus phone with x86 processor. That seems to be the only difference between the other devices. Every OF app fails with the same stack trace, and they work fine on every other phone. Perhaps something is not compiling correctly for x86??

The stack:

10-26 12:31:14.302: I/DEBUG(183): *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** ***
10-26 12:31:14.302: I/DEBUG(183): Build fingerprint: 'asus/WW_a501cg/ASUS_T00J:4.4.2/KVT49L/WW_user_2.22.40.54_20150527_44:user/release-keys'
10-26 12:31:14.302: I/DEBUG(183): Revision: '0'
10-26 12:31:14.302: I/DEBUG(183): pid: 16055, tid: 16055, name: oidEmptyExample  >>> cc.openframeworks.androidEmptyExample <<<
10-26 12:31:14.302: I/DEBUG(183): signal 11 (SIGSEGV), code 1 (SEGV_MAPERR), fault addr dead0000
10-26 12:31:14.702: I/DEBUG(183):     eax 00000000  ebx 00000001  ecx 61a7d114  edx 00000000
10-26 12:31:14.702: I/DEBUG(183):     esi 00000008  edi 1a100030
10-26 12:31:14.702: I/DEBUG(183):     xcs 00000073  xds 0000007b  xes 0000007b  xfs 0000003b  xss 0000007b
10-26 12:31:14.702: I/DEBUG(183):     eip 61876595  ebp 1a111ebc  esp 1a111e94  flags 00210246
10-26 12:31:14.702: I/DEBUG(183): backtrace:
10-26 12:31:14.702: I/DEBUG(183):     #00  pc 0018c595  /system/lib/libhoudini.so.4.0.8.45720
10-26 12:31:14.702: I/DEBUG(183):     #01  pc 0000dea3  [stack:16055]
10-26 12:31:14.702: I/DEBUG(183):     #02  pc 000b333b  /system/lib/libhoudini.so.4.0.8.45720
10-26 12:31:14.702: I/DEBUG(183):     #03  pc 00000e4b  /system/lib/libhoudini.so.4.0.8.45720
10-26 12:31:14.702: I/DEBUG(183):     #04  pc 000b2263  /system/lib/libhoudini.so.4.0.8.45720
10-26 12:31:14.702: I/DEBUG(183):     #05  pc 000ff02f  [stack:16071]
10-26 12:31:14.702: I/DEBUG(183):     #06  pc 000aeea7  /system/lib/libhoudini.so.4.0.8.45720
10-26 12:31:14.702: I/DEBUG(183):     #07  pc 00450987  /data/app-lib/cc.openframeworks.androidEmptyExample-1/libOFAndroidApp_neon.so
10-26 12:31:14.702: I/DEBUG(183):     #08  pc 000ae88c  /system/lib/libhoudini.so.4.0.8.45720
10-26 12:31:14.702: I/DEBUG(183):     #09  pc ffffffff  <unknown>
10-26 12:31:14.702: I/DEBUG(183):     #10  pc 000fdb2c  /system/lib/libhoudini.so.4.0.8.45720
10-26 12:31:14.702: I/DEBUG(183): stack:
10-26 12:31:14.702: I/DEBUG(183):          1a111e54  61933bdc  /system/lib/libhoudini.so.4.0.8.45720
10-26 12:31:14.702: I/DEBUG(183):          1a111e58  00000001  
10-26 12:31:14.702: I/DEBUG(183):          1a111e5c  1a111ebc  [stack:16055]
10-26 12:31:14.702: I/DEBUG(183):          1a111e60  617a9326  /system/lib/libhoudini.so.4.0.8.45720
10-26 12:31:14.702: I/DEBUG(183):          1a111e64  619cde4c  /system/lib/libhoudini.so.4.0.8.45720
10-26 12:31:14.702: I/DEBUG(183):          1a111e68  00000000  
10-26 12:31:14.702: I/DEBUG(183):          1a111e6c  00000138  
10-26 12:31:14.702: I/DEBUG(183):          1a111e70  00000000  
10-26 12:31:14.702: I/DEBUG(183):          1a111e74  000000fc  
10-26 12:31:14.702: I/DEBUG(183):          1a111e78  fffffd5b  
10-26 12:31:14.702: I/DEBUG(183):          1a111e7c  00000900  
10-26 12:31:14.702: I/DEBUG(183):          1a111e80  00000190  
10-26 12:31:14.702: I/DEBUG(183):          1a111e84  00000008  
10-26 12:31:14.702: I/DEBUG(183):          1a111e88  00000001  
10-26 12:31:14.702: I/DEBUG(183):          1a111e8c  1a111ebc  [stack:16055]
10-26 12:31:14.702: I/DEBUG(183):          1a111e90  61876595  /system/lib/libhoudini.so.4.0.8.45720
10-26 12:31:14.702: I/DEBUG(183):     #00  1a111e94  1a111ea4  [stack:16055]
10-26 12:31:14.702: I/DEBUG(183):          ........  ........
10-26 12:31:14.702: I/DEBUG(183):          ........  ........
10-26 12:31:14.702: I/DEBUG(183):     #02  1a111ec4  619cde4c  /system/lib/libhoudini.so.4.0.8.45720
10-26 12:31:14.702: I/DEBUG(183):          ........  ........
10-26 12:31:14.702: I/DEBUG(183): memory map around fault addr dead0000:
10-26 12:31:14.702: I/DEBUG(183):     bfe53000-bfe74000 rw- 
10-26 12:31:14.702: I/DEBUG(183):     (no map for address)
10-26 12:31:14.702: I/DEBUG(183):     (no map above)

in debug by default we compile for arm7 only so compilation is faster, if you compile in release you will get an application that will work in arm7, arm7 with neon acceleration and x86.

you can also add at the end of your config.make file:

ABIS_TO_COMPILE_DEBUG = x86

to compile for x86 instead of arm7 in debug mode or:

ABIS_TO_COMPILE_DEBUG = armv7 x86

to compile for both

The stack above was taken from an APK compiled for release. But I’ll check again.

Yes, definately on release. The x86 compiled exists.

Here are the lines that come before the crash:

10-27 10:47:55.615: D/dalvikvm(27734): Trying to load lib /data/app-lib/cc.openframeworks.androidEmptyExample-1/libneondetection.so 0x43a261b0
10-27 10:47:55.625: D/houdini(27734): [27734] Loading library(version: 4.0.8.45720 RELEASE)... successfully.
10-27 10:47:55.635: D/dalvikvm(27734): Added shared lib /data/app-lib/cc.openframeworks.androidEmptyExample-1/libneondetection.so 0x43a261b0
10-27 10:47:55.635: D/dalvikvm(27734): No JNI_OnLoad found in /data/app-lib/cc.openframeworks.androidEmptyExample-1/libneondetection.so 0x43a261b0, skipping init
10-27 10:47:55.635: I/OF(27734): loading neon optimized library
10-27 10:47:55.635: D/dalvikvm(27734): Trying to load lib /data/app-lib/cc.openframeworks.androidEmptyExample-1/libOFAndroidApp_neon.so 0x43a261b0
10-27 10:47:55.775: D/houdini(27734): [27734] Unsupported feature (ID:0x20e00149).
10-27 10:47:55.775: A/libc(27734): Fatal signal 11 (SIGSEGV) at 0xdead0000 (code=1), thread 27734 (oidEmptyExample)

can you try adding at the end of config.make:

ABIS_TO_COMPILE_RELEASE = armv7 x86

it might seem that the neon detection is crashing on x86, this disables the neon optimized build

Didn’t work, it failed neon, and then it seems to try arm and crashes…

BUT, if I change to

ABIS_TO_COMPILE_RELEASE = x86

as if to force it to be x86, it runs… So there’s a problem in architecture detection? Asus’s somehow misreporting this or something? Any ideas?

i guess we can change the library detection code in the java side so if it’s x86 it won’t try to load the neon library at all

That will still fail. The neon library is protected with a try catch. But after it fails neon, it loads non-neon, but it selects arm and not x86.

As I read here, that SHOULD work:

Meaning, these chips should read arm also, but for some reason it fails, probably due to some third party that is integrated without the support or something.

Removing the neon was not sufficient. I had to remove arm completely in order for it to pick x86 and run correctly… And that’s not a solution, of course…

that’s really strange, i’ve added a check to not try neon at all if it’s not arm, can you check that? if the architecture is x86 android itself should detect the right folder from the name of the library it’s in and use that not the arm one. i’ve run android apps compiled for both architectures before on x86 devices

That’s the thing, because that asus is kind of hybrid, that runs x86 natively and arm via emulation (houdini), it seems to choose arm first, but I guess that emulation is not all that, since it crashes… The only way I was able to “force” android to choose x86 over arm for that handset is by not including arm in it at all… Know of another way to force it? I doubt that your fix will be related, since just removing neon from compilation didn’t work, just removing arm altogether…

can you give it a try anyway? it’s in master the problem is that before no matter the architecture it was trying to run the neondetection library. that library is arm and it was probably making crash the houdini emulation because it uses some very cpu specific instructions to detect the type of fpu.

now if arm is detected the java side won’t try to run the neon detection at all which will probably fix it

Ok, so it’s not working. The problem is not neon detection, it’s the fact that the OS picks up OFAndroidLib.so for arm instead of x86. Meaning: the fix delays the crash, but doesn’t prevent it.

Another hint: OF from 3 months ago doesn’t crash! Perhaps some third party that was introduced/updated is incompatible with this? Or something changed in the compilation process?

The absurd thing is that the phone returns “armv7” for “os.arch”, and not x86, so you can’t really blame the OS for picking up arm…

One of the ways to resolve this is to figure out what is feature ID:0x20e00149… and then understand where are we using that…

Another way I thought of is not counting on the OS for lib selection at all. Compile arm and x86 to different names and use x86 as fallback if arm loading as crashed (provided that this crash is catchable, or by detecting the architecture correctly somehow).

What do you think?

UPDATE: here’s a post exactly on the issue. Works on x86 devices, but doesn’t work on asus devices with the arm emulation. The solution involves “having the same set of libs names and numbers for each architecture”. Not sure what is means… I tried looking through the libs to find any discrepencies between arm and x86 folders, and found only one - glu, that doesn’t contain an x86 lib. Can it be related??

It seems to me that the device is trying to load arm version of the OF to the x86 device, instead of x86 version of the OF.

I mean; as i remember, Houdini is writen to load arm apps to the x86 devices. I see libhoudini.so lines on the stack strace. That’s why it seems to me that the device try to load arm library, not x86 library.

Yep, that’s what happening. For some reason, the device prefers the arm emulation over pure x86. I thought arm was supposed to be the fallback, but it seems that it’s not so on these Asus devices.

I wasn’t able to find a way to change that behaviour, but I did find something that does work, I’m not sure if it’s elegant enough.

I changed the lib name for x86 from OFAndroidApp to OFAndroidApp_x86 by editing the make file:

ifeq ($(ABI),x86)
	ABI_PATH = x86
	PLATFORM_PROJECT_RELEASE_TARGET = libs/$(ABI_PATH)/libOFAndroidApp_x86.so
	PLATFORM_PROJECT_DEBUG_TARGET = libs/$(ABI_PATH)/libOFAndroidApp_x86.so
endif

Then in OFAndroid, I’m trying to load OFAndroidApp_x86 before trying to load the regular OFAndroidApp. That way, x86 devices load successfully and never get to the arm lib part, and arm devices fail the first load and load successfully the second time. Essentially, I disabled the automatic selection of the OS by giving the libs different names:

static {
    	try{
    		Log.i("OF","static x86");
    		System.loadLibrary("OFAndroidApp_x86"); 
    	}catch(Throwable ex)
    	{
	    	try{
        		Log.i("OF","static init");
        		System.loadLibrary("neondetection"); 
	        	if(hasNeon()){
	        		Log.i("OF","loading neon optimized library");
	        		System.loadLibrary("OFAndroidApp_neon");
	        	}else{
	        		Log.i("OF","loading not-neon optimized library");
	        		System.loadLibrary("OFAndroidApp");
	        	}
	    	}catch(Throwable e){
	    		Log.i("OF","failed neon detection, loading not-neon library",e);
	    		System.loadLibrary("OFAndroidApp");
	    	}
    	}
    	Log.i("OF","initializing app");
    }

What do you think? Is it elegant enough? It would have been better to take the problem out in the root, but I’m not sure where the problem is exactly… I know it didn’t happen on OF from about 3 months ago. My suspicion is in some third parties, probably POCO or openSSL…

Confirmed to be working on both the Asus x86 and regular arm devices.

“OFAndroidApp_x86” looks as elegant as “OFAndroidApp_neon”. I think it should be done like that.

Nice job.

kind of hacky but i can’t really think of any other way to solve the problem, this seems really a bug on that specific device, but let’s merge it anyway, can you send a PR?

Yep, definitely, I’ll make it on first occasion. :+1:

According to my crash logs, I’m getting this error not only on my device, but on several other types of Asus made devices that are out there.

Did you read the post I put somewhere up there? Something about a guy that fixed it by correcting mismatches in library versions? Does it say anything to you? Something perhaps about POCO/openSSL versions that don’t match between architectures or something?

no, not really, i think this is just a feature of some library that the emulator is not able to emulate. if there’s an x86 library it should just be picking that up. would be great to get this in for 0.9 so if you have a moment to send a PR before the release that’d be great