Shpoike / Quakespasm

Extra bloaty junk to modernise stuff a bit.
http://triptohell.info/moodles/qss/
GNU General Public License v2.0
185 stars 41 forks source link

SIGBUS on ARM in model-related code when starting Arcane Dimensions #3

Open aitap opened 5 years ago

aitap commented 5 years ago

Hi!

I wanted to run a little test using a headless ARM computer I have as a dedicated server. When running version 0.92.1-275-g2ac22f6c with -game ad, the game crashes with the following backtrace:

#0  0x00461046 in Mod_LoadSubmodels (l=0xb613a16c) at gl_model.c:2322
        in = 0xb613a99e
        out = 0xa6d4fa38
        i = 0
        j = 0
        count = 1
        inq1 = 0xb613a99e
        inh2 = 0xb613a99e
#1  0x00461638 in Mod_LoadBrushModel (mod=0x9e2640 <mod_known+91000>, buffer=0xb613a0f8) at gl_model.c:2456
        i = 31
        j = 6
        bsp2 = 0
        header = 0xb613a0f8
        bm = 0x20
        radius = -0.49984026
#2  0x0045c1ba in Mod_LoadModel (mod=0x9e2640 <mod_known+91000>, crash=false) at gl_model.c:417
        buf = 0xb613a0f8 "\035"
        stackbuf = "\002\000\000\000X\277\251\246\303\v\000\000\310BʦP\353\377\276\000\022\252\246\270Cʦ8\233\063\243\003\000\000\000\003\000\000\000\307\v\000\000\270Cʦp\353\377\276\330\a\252\246؀Ǧx\376\064\243\003\000\000\000\003\000\000\000\301\n\000\000P\006ʦ\220\353\377\276\231,M\000؀Ǧx\376\064\243\003\000\000\000\330\a\252\246\307\351\f\303!\364d\301\260\353\377\276\231,M\000h\240Ϧx\376\064\243\003\000\000\000\000\b\252\246\300\n\000\000\024\006ʦ\320\353\377\276\231,M\000\060\240Ϧx\376\064\243\003\000\000\000(\263\251\246\273\n\000\000\350\004ʦ\360\353\377\276\231,M\000\300\237Ϧx\376\064\243\002\000\000\000ĭ\251\246\260\n\000\000T\002ʦ\020\354\377\276\231,M"...
        mod_type = 29
#3  0x0045c23e in Mod_ForName (name=0xa666ce57 "maps/ad_brk/wood04.bsp", crash=false) at gl_model.c:445
        mod = 0x9e2640 <mod_known+91000>
#4  0x004ad1d4 in PF_sv_precache_model () at pr_cmds.c:1200
        s = 0xa666ce57 "maps/ad_brk/wood04.bsp"
        i = 176
#5  0x004c5752 in PR_ExecuteProgram (fnum=474) at pr_exec.c:603
        i = 20
        ptr = 0xa3351e38
        st = 0xa66af0d4
        f = 0xa6793bd4
        newf = 0xa678fbd8
        profile = 178
        startprofile = 178
        ed = 0xa33517d8
        exitdepth = 0
#6  0x004c2760 in ED_LoadFromFile (
    data=0xa6accdb8 "\n{\n\"_dirt\" \"-1\"\n\"_minlight\" \"25\"\n\"classname\" \"func_breakable\"\n\"cnt\" \"3\"\n\"count\" \"3\"\n\"health\" \"5\"\n\"model\" \"*62\"\n\"style\" \"2\"\n}\n{\n\"_dirt\" \"-1\"\n\"_minlight\" \"25\"\n\"classname\" \"func_breakable\"\n\"cnt\" \"3\"\n\"cou"...)
    at pr_edict.c:1056
        func = 0xa6793bd4
        ent = 0xa33517d8
        inhibit = 0
        usingspawnfunc = 0
#7  0x004cc78e in SV_SpawnServer (server=0xbefff018 "start") at sv_main.c:3103
        dummy = "\000\000\000\000\000\000\000"
        ent = 0xa32a7008
        i = 105
#8  0x004a5392 in Host_Map_f () at host_cmd.c:855
        i = 2
        name = "start\000\377\276\360\333\024\246\006\000\000\000\250\300S\246\350\333\024\246\070\360\377\276\000\000\000\000@\360\377\276@\360\377\276\350\333\024\246\000\000\000\000P\360\377\276a\233I\000\374jN\000\310\333\024\246"
        p = 0x0
#9  0x00499642 in Cmd_ExecuteString (text=0xbefff098 " map start", src=src_command) at cmd.c:825
        cmd = 0xa657c728
        a = 0x0
#10 0x00498884 in Cbuf_Execute () at cmd.c:216
        i = 11
        text = 0xa653c0a8 " map start\n; map start\n 1; map start\n start\nfg\nstuffcmdsstuffcmdser.cfg\nexec autoexec.cfg\nstuffcmdsdsoexec.cfg\nstuffcmdsoexec.cfg\nstuffcmdsexec.cfg\nstuffcmdsc.cfg\nstuffcmdsexec.cfg\nstuffcmdsdsec.cfg\ns"...
        line = " map start\000\000\060\000cfg\000e-look enabled\r\000creenshot\"\r\000ick\"\r\000;fov 30;wait;fov 50;wait;fov 70;wait;fov 90;bind F11 zoom_in; sensitivity 3\"\r\000\377\276\000\000\000\000\360\354\377\266\004Xֶ\001\000\000\000\000\000\000\000\000\000\001", '\000' <repeats 24 times>, "\001", '\000' <repeats 124 times>...
        quotes = 0
        comment = 0
#11 0x004a3b38 in Host_Init () at host.c:1003
No locals.
#12 0x004d5d50 in main (argc=13, argv=0xbefff654) at main_sdl.c:142
        t = -1224855843
        time = 3.2704419817919037e-307
        oldtime = 6.4660271879726615e-312
        newtime = 3.2705166777260294e-307

I think that the crash was not present in the original quakespasm-0.93.1.tar.gz, but I'm not sure because I had quickly removed it, having found the networked gameplay very jerky (with packet loss icon flashing all the time).

There is no crash if I start vanilla Quake and play it for a while.

Shpoike commented 5 years ago

This is a known issue. Some of AD's bsp files are misaligned due to the use of a buggy map compiler that padded the lumps incorrectly, and will cause this sort of problem for any quake engine running those maps on anything other than x86.

QSS detects the misalignment, but currently takes no action other than to warn (now hidden as a developer print, because everyone was just ignoring it anyway). As this is something that really should be fixed in Quakespasm rather than just QSS, I'm going to wait for ericw's guidance on this one (even if he simply tells me to work around it myself).

FTE also detects the misalignment and throws lots of ram at the problem to realign the bsp in memory, which is generally not what you want on eg an rpi, but should otherwise work. It is also capable of using the same network protocol as QSS.

aitap commented 5 years ago

On Sat, 01 Sep 2018 22:11:17 -0700 Shpoike notifications@github.com wrote:

This is a known issue. Some of AD's bsp files are misaligned due to the use of a buggy map compiler that padded the lumps incorrectly, and will cause this sort of problem for any quake engine running those maps on anything other than x86.

Thank you for the explanation!

FTE also detects the misalignment and throws lots of ram at the problem to realign the bsp in memory, which is generally not what you want on eg an rpi, but should otherwise work. It is also capable of using the same network protocol as QSS.

Great! I'll try FTE next time I want to run Quake on ARM.

-- Best regards, Ivan

ericwa commented 5 years ago

Yeah, I'd like to fix/workaround it in upsteam Quakespasm at some point.

FTE also detects the misalignment and throws lots of ram at the problem to realign the bsp in memory, which is generally not what you want on eg an rpi, but should otherwise work.

Possibly a more invasive but no extra ram use fix could be:

float LittleFloatUnaligned(const char* in)
{
    float temp;
    memcpy(&temp, in, 4);
    return LittleFloat(temp);
}

and then replacing LittleFloat(in->foo) with LittleFloatUnaligned(&in->foo)... it'd be more invasive though. would also need to look out for stuff like

// swap all the lumps
    mod_base = (byte *)header;

    for (i = 0; i < (int) sizeof(dheader_t) / 4; i++)
        ((int *)header)[i] = LittleLong ( ((int *)header)[i]);
Shpoike commented 5 years ago

If you just want to avoid extra memory usage, then you can memmove the file into the storage currently used by the file's header (note: needs to be done in descending file order rather than lump order). You'll get enough space for the needed padding that way, but does mean you would have to make a copy of the header on the stack however.

The alternative is to read each lump as if it were a network message. You'd need to read each lump's fields in order, but on the plus side removal of the dfoo_t structs would make handling of different bsp29/bsp2/2psb lumps a little bit cleaner.