Release Build crash on start

Create issue
Issue #23 resolved
Christiaan Janssen created an issue

I just tried this port of Löve2D with one of my games and worked like a charm. Great job! Unfortunately, only Debug builds seem to work. Release builds crash at application launch.

Tested on a Nexus 7 tablet (Android 4.3) and an HTC one mini (Android 4.2.2). In case it helps I copy here the output of logcat:

Nexus 7:

I/WindowState(  428): WIN DEATH: Window{41f81808 u0}
I/ActivityManager(  428): Process (pid 4792) has died.
W/WindowManager(  428): Force-removing child win Window{41f97348 u0 SurfaceView} from container Window{41f81808 u0}
W/ActivityManager(  428): Force removing ActivityRecord{4226fb28 u0}: app died, no saved state
W/WindowManager(  428): Failed looking up window
W/WindowManager(  428): java.lang.IllegalArgumentException: Requested window android.os.BinderProxy@42321a40 does not exist
W/WindowManager(  428):     at
W/WindowManager(  428):     at
W/WindowManager(  428):     at$DeathRecipient.binderDied(
W/WindowManager(  428):     at android.os.BinderProxy.sendDeathNotice(
W/WindowManager(  428):     at Method)
I/WindowState(  428): WIN DEATH: null

HTC one mini:

I/WindowState(  631): WIN DEATH: Window{4192cdc0 u0}
W/WindowManager(  631): Force-removing child win Window{41940728 u0 SurfaceView} from container Window{4192cdc0 u0}
D/InputManager(  631): setFocusedApplication Exception: java.lang.NullPointerException
W/ActivityManager(  631): handleTopAppChanged(): The previous AP is died unexpectedly.
D/WirelessDisplayService(  631): getMirrorDisplayStatus:falsecurState:1
W/WindowManager(  631): Failed looking up window
W/WindowManager(  631): java.lang.IllegalArgumentException: Requested window android.os.BinderProxy@419f3dc0 does not exist
W/WindowManager(  631):     at
W/WindowManager(  631):     at
W/WindowManager(  631):     at$DeathRecipient.binderDied(
W/WindowManager(  631):     at android.os.BinderProxy.sendDeathNotice(
W/WindowManager(  631):     at Method)
I/WindowState(  631): WIN DEATH: null

Comments (11)

  1. Christiaan Janssen reporter

    Yes, I tried and I get the same crash. I wanted to make sure that it was not my code causing it.

  2. Christiaan Janssen reporter

    Hi again, I'm looking at the log and it seems that the exception I'm reporting is what happens when the window already crashed. In other words, it might not be very useful to you. Comparing the "Debug" and "Release" logs, I found that the app crashes after SDL_Init finishes and before the message "Checking directory exists for... ... /save". Maybe this helps narrow down the source of the crash?

    V/SDL     ( 8555): onResume()
    V/SDL     ( 8555): surfaceCreated()
    V/SDL     ( 8555): surfaceChanged()
    V/SDL     ( 8555): pixel format RGB_565
    V/SDL     ( 8555): Window size:1280x736
    I/SDL     ( 8555): SDL_Android_Init()
    I/SDL     ( 8555): SDL_Android_Init() finished!
    W/InputDispatcher(  428): channel '42607880 (server)' ~ Consumer closed input channel or an error occurred.  events=0x9
    E/InputDispatcher(  428): channel '42607880 (server)' ~ Channel is unrecoverably broken and will be disposed!
    W/InputDispatcher(  428): Attempted to unregister already unregistered input channel '42607880 (server)'
    I/WindowState(  428): WIN DEATH: Window{42607880 u0}
    I/ActivityManager(  428): Process (pid 8555) has died.
  3. Christiaan Janssen reporter

    It's me again. I've been littering the code with Log statements in order to find out the point where it crashes. It seems to be the call to PHYSFS_init in modules/filesystem/physfs/Filesystem.cpp . That function returns a 0, and then an exception is thrown. The call to PHYSFS_getLastError() returns the string "Invalid argument". It seems that several functions inside Physfs can launch that error, I'm trying to figure out which one exactly in this case.

  4. Christiaan Janssen reporter

    What I found so far:

    The love filesystem module is basically a wrapper around Physfs. The love.boot script initializes it, which in turn calls PHYSFS_init. That method returns 0 in release mode, and the wrapper throws an exception (that is the crash I was seeing).

    One of the steps PHYSFS_init goes through is to get the base directory of the executable. It's a call to calculateBaseDir(...), also in physfs.c.

    calculateBaseDir calls __PHYSFS_platformCalcBaseDir(argv0), which is platform-dependent. In Android, the implementation is found in unix.c.

    argv0 is hardcoded to be the string "SDL_app", that happens in Java_org_libsdl_app_SDLActivity_nativeInit(...), which is found in SDL_android_main.c.

    Since __PHYSFS_platformCalcBaseDir is not able to deduce the path from that string, it tries to figure it out through the symlink "/proc/self/exe". In debug mode, this returns "/system/bin/app_process". This means, the app name is not "SDL_app", but "app_process". However, that information is enough for the app to figure out the path ("/system/bin"), and proceed.

    In Release mode, though, that symlink call returns NULL. I guess it's got something to do with the Android security model. Maybe some extra permissions in AndroidManifest could fix it, but I'm not an expert on the topic and I don't know if that is a viable solution.

    Anyway, since that was NULL, the next thing __PHYSFS_platformCalcBaseDir is look at the system path (an environment variable) and try to find the executable in the path. If we had the proper name passed in argv0, we would find it. Unfortunately, that search fails again.

    And this is the point where the "Invalid argument" error is set (since we haven't found the path of the executable by any means). Everything returns, and love and sdl are closed. The app stops.

    Possible solutions from the top of my head:

    • figure out how to enable permissions in release mode, in order to access /proc/self/exe or /proc/PID/exe (any of the two would suffice)

    • modify SDL_android_main.c and hardcode "app_process" as the argv0 string, or even better if we can get that information from the system somehow.

    • when running love.boot, discard argv0 and hardcode that string.

    • write a proper version of the platform-dependent functions of PhysFS for Android (right now it defaults to "unix").

    In my case, I can just hack my game and hardcode the proper string somewhere, but it feels like an ugly hack. You will probably have a better idea on how to solve this issue properly. I hope this information is useful.

  5. Martin Felis repo owner

    Wow! Thank you for being so adventurous!

    My suggestion would be to simply modify SDL_android_main.c. The name there is arbitrary anyways (as far as I can see). Can you check whether this fixes it? I haven't got into signing apks so cannot test it right now.

  6. Christiaan Janssen reporter

    Yes, it fixes it for me. Now everything works like a charm. I don't know to what degree the fix is "universal", but it works on my two devices.

  7. Log in to comment