Fix v1.26 crashes: emutls corruption#132
Fix v1.26 crashes: emutls corruption#132ChristopherHX merged 11 commits intominecraft-linux:masterfrom
Conversation
Minecraft v1.26 calls GameActivity_finish() during startup as part of the Android activity lifecycle transition (switching from the splash activity to the game activity). The launcher was incorrectly treating this as a real exit request, causing the game to shut down within ~3 seconds of launch with "The graphics context was lost". Make onGameActivityClose a no-op since the window close event already handles clean shutdown via WindowCallbacks::onClose().
The v1.26 libminecraftpe.so binary has a corrupted __emutls_control
struct at base+0x13701258 where the emutls data overlaps with
rand_meth symbol data due to linker symbol collisions. This causes
SIGABRT when TLS variables are accessed during startup.
Patch the corrupted control to valid values {size=8, align=8, index=0,
templ=NULL} after the library is loaded.
The v1.26 libminecraftpe.so has two known crash sites that can be safely recovered from using a signal handler: 1. mc+0x9dc22fd: Table lookup with out-of-bounds index triggered by keyboard input (e.g. arrow keys). The function loads a string pointer/length pair from a global table indexed by edx*16 without bounds checking. Recovery: set r14=r15=0 (null string) and skip to mc+0x9dc2306, letting the function's built-in null check handle it. 2. mc+0xcbe8f40: URL decode function crashes on invalid string pointer. Recovery: unwind the function prologue and return 0 (no match). Unknown SIGSEGV crashes are logged with register state and instruction bytes for diagnosis, then re-raised with default behavior.
15d697d to
e8411f6
Compare
|
Sounds interesting, thank you (but I didn't yet come to the point for evaluating this patchset)
Now I wonder could we reimplement emutls that it automatically detects corruption, since this is a common problem we face for x86_64 builds not only once. |
This breaks closing the game for me, but actually I think by lib folder contains except libminecraftpe.so shared libs from 26.0.27 x86_64. But Thank you very much 26.0 x86_64 is playable with your patchset |
Couldn't repro this yet, will rollback by .so files to the apk version..., and try again |
|
CC @GameParrot What do you think? The game activity close patch causes more issues than it solves for me, the segv handler patch never got called on my end. Tested with the 26.0.2 x86_64 apk and the replaced prefabmultiplayer .so file. |
|
Thanks for the detailed feedback and for pushing the version-scoping commit! A few responses: Re: Re: GameActivity_finish — Sorry about that. The immediate shutdown I was hitting was specifically on 1.26.0.2 x86_64 where Re: SIGSEGV handler — This only triggers with the specific 1.26.0.2 x86_64 binary at exact offsets. If you're using .so files from a different version the offsets would be different, so the handler would never match (and would fall through to the default abort path). Makes sense you couldn't repro with mixed libs. Re: moving to mcpelauncher-core — Agreed, that's a better home for it. I can rebase it there if you'd like, or feel free to cherry-pick and restructure however works best for the project. Re: auto-detecting emutls corruption — That would be a much cleaner long-term solution. The pattern is pretty detectable: valid controls should have reasonable size/align values (typically 4 or 8) and templ should either be NULL or point within the binary. Anything with garbage values in those fields is corrupt. |
I have it fully playable with the patchset too, stable also. Does break game closing for me also though, need some form of termination either with a kill or closing the launcher and having it do the prompted force kill it offers. Today was my first build of this from source some I'm not mega sure I haven't got crossover on libs from the .deb install and flatpack install I also have Good stuff :-) |
|
This specific crash can also be mitigated by this code that has no hardcoded offsets.
struct EmutlsControl {
size_t size;
size_t align;
uintptr_t index;
void* templ;
};
static mcpelauncher_hook_t val;
val.value = linker::dlsym(libcxx, "__emutls_get_address");
static mcpelauncher_hook_t* org = &val;
hooks.emplace_back(mcpelauncher_hook_t{"__emutls_get_address", (void*)+[](EmutlsControl* ctrl) {
double scratch;
if(modf(log2(ctrl->align), &scratch) != 0.0) {
Log::error("MinecraftUtils", "Unsupported emutls alignment %zu", ctrl->align);
ctrl->size = 64;
ctrl->align = 8;
ctrl->index = 0;
ctrl->templ = nullptr;
}
return ((void*(*)(EmutlsControl* ctrl))org->value)(ctrl);
}});I will still do revert pushes here like explained in #132 (comment), plz create a new PR for the changes I could not validate yet. Maybe then target another repository directly. Thank you for trying your luck yourself, the last time some versions behind I probably did interpret the emutl struct wrongly to correct the crash. |
|
One follow up is minecraft-linux/mcpelauncher-core#22 that I keep open for further research. |
|
Sorry about the GameActivity_finish issue — I got the game running for the first time and immediately started playing with my kids rather than testing the close button properly. I've reworked the patch based on your feedback:
Tested both close paths — X button and in-game "Save and Quit" both work correctly. The commits are reorganized as 4 independent patches now:
|
|
I merged
so this PR is closed as merged. I am not yet convinced by the other 3, since they appear to not affect me... The patches 1&2 might be interesting for me to validate on macOS 26.0 arm64, where I saw a 80% reproductive game close with exit code 0 Does this sound like your observed problem? I released the merged change in 1.6.4, thank you very much for the patch 3. |
|
Was your symptom before patchset 1 and 2 a black(or white) screen? Or did the process actually ended with exit code 0? Saw one white and one black screen report in discord |
Summary
Fixes three crash/shutdown issues when running Minecraft Bedrock v1.26.0.2:
(REMOVED) Immediate shutdown after ~3 seconds: Minecraft v1.26 calls
GameActivity_finish()during startup as part of the Android activity lifecycle transition. The launcher was treating this as a real exit request. Fixed by makingonGameActivityClosea no-op since window close already handles clean shutdown.SIGABRT on startup from corrupted emutls: The v1.26
libminecraftpe.sohas a corrupted__emutls_controlstruct atbase+0x13701258where emutls data overlaps withrand_methsymbol data due to linker symbol collisions. Fixed by patching the corrupted control to valid values after library load.(REMOVED) SIGSEGV on keyboard input and world creation: Two crash sites in
libminecraftpe.sothat can be safely recovered from via signal handler:mc+0x9dc22fd: Table lookup with out-of-bounds index triggered by keyboard input (arrow keys). Sets null string values and lets the function's built-in null-check path handle recovery.mc+0xcbe8f40: URL decode with invalid string pointer. Unwinds the function prologue and returns 0 (no match).Unknown crashes are logged with register state and instruction bytes for diagnosis, then re-raised with default behavior.
Testing
Tested on Pop!_OS 22.04 (x86_64) with Minecraft Bedrock v1.26.0.2 via Flatpak. All three issues are resolved - the game launches, signs into Xbox Live, creates/loads worlds, and handles keyboard input without crashing.
Notes
This PR builds on top of #131 (1.26.0 fixes by GameParrot). The three commits are independent fixes that can be reviewed/cherry-picked separately.