Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

crash on Android when loading prevoius levels #171

Open
Luciogi opened this issue May 26, 2024 · 2 comments
Open

crash on Android when loading prevoius levels #171

Luciogi opened this issue May 26, 2024 · 2 comments
Labels
Android Issues specific to the Android platform Bug Crash

Comments

@Luciogi
Copy link

Luciogi commented May 26, 2024

Principia version

24.02.29

OS / Hardware
  • Platform:
    • Operating system: Android 14
Summary

When I load any previous level, game crashes

Steps to reproduce
49fc114e-612b-4321-a0d5-08ff404bcf14.mp4
@Luciogi Luciogi added the Bug label May 26, 2024
@rollerozxa
Copy link
Collaborator

rollerozxa commented Jun 16, 2024

I've disabled prompting for puzzle solutions in 1c506dd on Android which fixes the crash but doesn't solve the underlying issue that some sort of mangling that happens when data is passed from the dialog prompt between C++ and Java. (This issue is exclusive to the Android version and doesn't occur with the GTK3 dialogs on desktop)

@rollerozxa rollerozxa added Android Issues specific to the Android platform Crash labels Jun 16, 2024
@rollerozxa
Copy link
Collaborator

rollerozxa commented Jun 16, 2024

Some technical details:

When the dialog opens (src/src/menu_pkg.cc:483) it sends a pointer to some data (open_play_data) within a principia_action to accompany the button label.

open_play_data *opd = new open_play_data(LEVEL_LOCAL, level_id, &pkg, false, 1);
ui::confirm("Do you want to load your last saved solution?",
    "Yes",    principia_action(ACTION_OPEN_MAIN_PUZZLE_SOLUTION, opd),
    "No",     principia_action(ACTION_CREATE_MAIN_PUZZLE_SOLUTION, opd),
    "Cancel", principia_action(ACTION_IGNORE, 0));

For Android ui::confirm is implemented in src/src/ui_android.hh at ~line 81 which passes a reference to the action data over the JNI from C++ to Java:

env->CallStaticVoidMethod(cls, mid,
        _text,
        _button1, (jint)action1.action_id, (jlong)action1.action_data,
        _button2, (jint)action2.action_id, (jlong)action2.action_data,
        _button3, (jint)action3.action_id, (jlong)action3.action_data,
        (jboolean)_confirm_data.confirm_type == CONFIRM_TYPE_BACK_SANDBOX);

This in turn calls org.libsdl.app.SDLActivity.confirm, which is a custom method added in there by Principia (gross, I know). What it effectively does is send the action of the pressed button back to C++-land which is either ACTION_OPEN_MAIN_PUZZLE_SOLUTION or ACTION_CREATE_MAIN_PUZZLE_SOLUTION. It should keep the same pointer to the action data which it casts to open_play_data and then retrieves fields from:

open_play_data *opd = static_cast<open_play_data*>(data);
uint8_t pkg_type = opd->id_type;

Then, segfault. The pointer is garbage and it fails when trying to get the package type.

Clue: The crash only occurs on 64-bit. I can reproduce the issue on my 64-bit ARM phone or on an x86_64 emulator. I cannot reproduce the issue on 32-bit ARM (namely my Nexus 7 tablet), which would make me believe it has something about pointer sizes differing that causes issues when sending it over the JNI in ui::confirm. This would also explain why it never caused issues in 2014 since the game did not have a 64-bit build back then. But I really do not know where the issue exactly lies. Maybe someone smarter than me could point to how to actually fix it.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Android Issues specific to the Android platform Bug Crash
Projects
None yet
Development

No branches or pull requests

2 participants