quadmath crash from stack misalignment
The following program, when compiled with the 32-bit ucrt gcc, crashes in libgcc:
C:\Users\Tony\dev\perl\git>type stackquad.c
#include <quadmath.h>
#include <windows.h>
#include <stdio.h>
#include <stdbool.h>
__float128 x = 1.0;
bool y;
DWORD WINAPI ThreadProc(
LPVOID lpParameter) {
y = x < 0;
return 0;
}
int main() {
HANDLE h = CreateThread(NULL, 0, ThreadProc, NULL, 0, NULL);
if (WaitForSingleObject(h, 10000) != WAIT_OBJECT_0) {
printf("Failed wait\n");
return 1;
}
return 0;
}
C:\Users\Tony\dev\perl\git>gcc -ostackquad.exe -g stackquad.c -lquadmath
C:\Users\Tony\dev\perl\git>gdb .\stackquad.exe
GNU gdb (GDB for MinGW-W64 i686, built by Brecht Sanders) 13.2
Copyright (C) 2023 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.
Type "show copying" and "show warranty" for details.
This GDB was configured as "i686-w64-mingw32".
Type "show configuration" for configuration details.
For bug reporting instructions, please see:
<https://www.gnu.org/software/gdb/bugs/>.
Find the GDB manual and other documentation resources online at:
<http://www.gnu.org/software/gdb/documentation/>.
For help, type "help".
Type "apropos word" to search for commands related to "word"...
Reading symbols from .\stackquad.exe...
(gdb) r
Starting program: C:\Users\Tony\dev\perl\git\stackquad.exe
[New Thread 22248.0x8cf8]
[New Thread 22248.0x284c]
Thread 3 received signal SIGSEGV, Segmentation fault.
[Switching to Thread 22248.0x284c]
__letf2 (a=1, b=0) at ../../../libgcc/soft-fp/letf2.c:41
41 ../../../libgcc/soft-fp/letf2.c: No such file or directory.
(gdb) bt
#0 __letf2 (a=1, b=0) at ../../../libgcc/soft-fp/letf2.c:41
#1 0x007015fc in ThreadProc@4 (lpParameter=0x0) at stackquad.c:12
#2 0x76ce00c9 in KERNEL32!BaseThreadInitThunk () from C:\WINDOWS\SysWOW64\kernel32.dll
#3 0x779b7b1e in ntdll!RtlGetAppContainerNamedObjectPath () from C:\WINDOWS\SysWOW64\ntdll.dll
#4 0x779b7aee in ntdll!RtlGetAppContainerNamedObjectPath () from C:\WINDOWS\SysWOW64\ntdll.dll
#5 0x00000000 in ?? ()
(gdb) info register esp
esp 0xe8feb8 0xe8feb8
(gdb)
When originally debugging this I found libgcc has code like:
Dump of assembler code for function __letf2:
0x6342bab0 <+0>: push %ebp
0x6342bab1 <+1>: push %edi
0x6342bab2 <+2>: push %esi
0x6342bab3 <+3>: push %ebx
0x6342bab4 <+4>: sub $0x6c,%esp
0x6342bab7 <+7>: fnstcw 0x4e(%esp)
=> 0x6342babb <+11>: movdqa 0x80(%esp),%xmm0
0x6342bac4 <+20>: mov 0x88(%esp),%edi
the crash occurs on the movdqa instruction, which requires 16-byte alignment, but is done through a non-aligned esp.
The lhmouse mingw does not crash, it has a movdqu instruction at this point, which may be due to this patch.
Originally discussed at https://github.com/Perl/perl5/issues/21313
Thanks for finding and figuring out this issue.
If this is indeed an issue in the GCC code it would be best to report your findings there (https://gcc.gnu.org/bugzilla/).
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=40838 discusses it, as does https://gcc.gnu.org/bugzilla/show_bug.cgi?id=38496 which was closed as WONTFIX.