Why is this code unreliable?

Discussions related to using the integrated assembler
Richard Russell
Posts: 591
Joined: Tue 18 Jun 2024, 09:32

Why is this code unreliable?

Post by Richard Russell »

I don't understand why this code sometimes runs successfully but sometimes crashes (on 32-bit Windows):

Code: Select all

      DIM code%% 100
      ]^P% = code%%
      [.thread
      mov ecx,1000000000
      .pause
      loop pause
      mov eax,&12345678
      ret
      ]

      SYS "SDL_CreateThread", thread, "thread", FALSE TO thread%
      PRINT ~thread%
      SYS "SDL_WaitThread", thread%, ^result%
      PRINT ~result%
      END
There's nothing I can see that should introduce any variability between one run and another. Also, the addition of a *REFRESH command immediately before the SYS call results in it crashing 100% of the time, here. Why does such a seemingly innocuous change have such a drastic effect?

I'm at a complete loss with this one. If anybody has a clue what is going on I would be very interested.
Richard Russell
Posts: 591
Joined: Tue 18 Jun 2024, 09:32

Re: Why is this code unreliable?

Post by Richard Russell »

Richard Russell wrote: Wed 04 Mar 2026, 15:49 There's nothing I can see that should introduce any variability between one run and another.
Experimentally, adding two additional dummy parameters to the SYS call makes it more stable:

Code: Select all

      SYS "SDL_CreateThread", thread, "thread", FALSE, 0, 0 TO thread%
That doesn't make much sense, because the function signature is:

SDL_CreateThread(SDL_ThreadFunction fn, const char *name, void *data);

With this additional information I asked DeepSeek AI and it explained it as follows:

"You've essentially stumbled upon a real, documented ABI bug in SDL2's thread creation on 32-bit Windows through your debugging.

"The core of the issue lies in how SDL creates threads on Windows. It doesn't call the Windows CreateThread API directly. Instead, it calls the C runtime function _beginthreadex to ensure the C runtime is properly initialized for the new thread.

"The problem is that the SDL_CreateThread function is designed to accept a pointer to this _beginthreadex function as a parameter. On different compilers and C runtime configurations, the expected function signature (the way parameters are passed on the stack) for _beginthreadex can differ . This is a classic application binary interface (ABI) issue.

"The official SDL2 binaries for 32-bit Windows (the ones you download from libsdl.org) are built with one configuration, while many MinGW environments (and some others) compile with a different configuration, leading to the exact crash you described
."

So now you know!