When build with _GLIBCXX_ASSERTIONS enabled it hits assert
Gentoo Hardened by default enables _GLIBCXX_ASSERTIONS https://github.com/gentoo/gentoo/blob/master/eclass/toolchain.eclass#L683 https://github.com/gentoo/gentoo/blob/master/eclass/toolchain-funcs.eclass#L986
When building Xonotic from git (./all clean; ./all compile) it fails when running gmqcc to build some files:
make[1]: Entering directory '/home/amade/workdir/xonotic2/xonotic/data/xonotic-data.pk3dir/qcsrc'
make[1]: Entering directory `/home/amade/workdir/xonotic2/xonotic/data/xonotic-data.pk3dir/qcsrc/client'
./tools/qcc.sh client ../csprogs.dat client/progs.inc
make[1]: Entering directory `/home/amade/workdir/xonotic2/xonotic/data/xonotic-data.pk3dir/qcsrc/menu'
+ qpp client/progs.inc ../csprogs.dat -I. -DGMQCC -DXONOTIC=1 '-DWATERMARK="xonotic-v0.8.6-6-gc2c16160d"' -DNDEBUG=1 -DENABLE_EFFECTINFO=0 -DENABLE_DEBUGDRAW=0 -DENABLE_DEBUGTRACE=0
+ IN=client/progs.inc
+ OUT=../csprogs.dat
+ case ${MODE} in
+ DEFS='-DGAMEQC -DCSQC'
+ set +e
+ cc -xc -E -I. -DGMQCC -DXONOTIC=1 '-DWATERMARK="xonotic-v0.8.6-6-gc2c16160d"' -DNDEBUG=1 -DENABLE_EFFECTINFO=0 -DENABLE_DEBUGDRAW=0 -DENABLE_DEBUGTRACE=0 -DGAMEQC -DCSQC -dM -H client/progs.inc
./tools/qcc.sh menu ../menu.dat menu/progs.inc
make[1]: Entering directory `/home/amade/workdir/xonotic2/xonotic/data/xonotic-data.pk3dir/qcsrc/server'
./tools/qcc.sh server ../progs.dat server/progs.inc
+ qpp menu/progs.inc ../menu.dat -I. -DGMQCC -DXONOTIC=1 '-DWATERMARK="xonotic-v0.8.6-6-gc2c16160d"' -DNDEBUG=1 -DENABLE_EFFECTINFO=0 -DENABLE_DEBUGDRAW=0 -DENABLE_DEBUGTRACE=0
+ IN=menu/progs.inc
+ OUT=../menu.dat
+ case ${MODE} in
+ DEFS=-DMENUQC
+ set +e
+ cc -xc -E -I. -DGMQCC -DXONOTIC=1 '-DWATERMARK="xonotic-v0.8.6-6-gc2c16160d"' -DNDEBUG=1 -DENABLE_EFFECTINFO=0 -DENABLE_DEBUGDRAW=0 -DENABLE_DEBUGTRACE=0 -DMENUQC -dM -H menu/progs.inc
+ qpp server/progs.inc ../progs.dat -I. -DGMQCC -DXONOTIC=1 '-DWATERMARK="xonotic-v0.8.6-6-gc2c16160d"' -DNDEBUG=1 -DENABLE_EFFECTINFO=0 -DENABLE_DEBUGDRAW=0 -DENABLE_DEBUGTRACE=0
+ IN=server/progs.inc
+ OUT=../progs.dat
+ case ${MODE} in
+ DEFS='-DGAMEQC -DSVQC'
+ set +e
+ cc -xc -E -I. -DGMQCC -DXONOTIC=1 '-DWATERMARK="xonotic-v0.8.6-6-gc2c16160d"' -DNDEBUG=1 -DENABLE_EFFECTINFO=0 -DENABLE_DEBUGDRAW=0 -DENABLE_DEBUGTRACE=0 -DGAMEQC -DSVQC -dM -H server/progs.inc
+ cc -xc -E -I. -DGMQCC -DXONOTIC=1 '-DWATERMARK="xonotic-v0.8.6-6-gc2c16160d"' -DNDEBUG=1 -DENABLE_EFFECTINFO=0 -DENABLE_DEBUGDRAW=0 -DENABLE_DEBUGTRACE=0 -DMENUQC -MMD -MP -MT ../menu.dat -Wall -Wundef -Werror menu/progs.inc -o ../.tmp/menu.txt
+ cc -xc -E -I. -DGMQCC -DXONOTIC=1 '-DWATERMARK="xonotic-v0.8.6-6-gc2c16160d"' -DNDEBUG=1 -DENABLE_EFFECTINFO=0 -DENABLE_DEBUGDRAW=0 -DENABLE_DEBUGTRACE=0 -DGAMEQC -DCSQC -MMD -MP -MT ../csprogs.dat -Wall -Wundef -Werror client/progs.inc -o ../.tmp/client.txt
+ cc -xc -E -I. -DGMQCC -DXONOTIC=1 '-DWATERMARK="xonotic-v0.8.6-6-gc2c16160d"' -DNDEBUG=1 -DENABLE_EFFECTINFO=0 -DENABLE_DEBUGDRAW=0 -DENABLE_DEBUGTRACE=0 -DGAMEQC -DSVQC -MMD -MP -MT ../progs.dat -Wall -Wundef -Werror server/progs.inc-o ../.tmp/server.txt
+ err=0
+ set -e
+ '[' 0 -ne 0 ']'
+ sed -E 's/^#(line)? ([[:digit:]]+) "(.*)".*/\
#pragma file(\3)\
#pragma line(\2)/g' ../.tmp/menu.txt
+ qcc -std=gmqcc -Ooverlap-locals -O3 -Werror -Wall -Wno-field-redeclared -flno -futf8 -fno-bail-on-werror -frelaxed-switch -freturn-assignments -o /home/amade/workdir/xonotic2/xonotic/data/xonotic-data.pk3dir/qcsrc/../menu.dat ../../.tmp/menu.qc
+ cd tools
+ ../../../../gmqcc/gmqcc -std=gmqcc -Ooverlap-locals -O3 -Werror -Wall -Wno-field-redeclared -flno -futf8 -fno-bail-on-werror -frelaxed-switch -freturn-assignments -o /home/amade/workdir/xonotic2/xonotic/data/xonotic-data.pk3dir/qcsrc/../menu.dat ../../.tmp/menu.qc
Mode: manual
There are 1 items to compile:
item: ../../.tmp/menu.qc (qc)
/usr/lib/gcc/x86_64-pc-linux-gnu/13/include/g++-v13/bits/stl_vector.h:1125: std::vector<_Tp, _Alloc>::reference std::vector<_Tp, _Alloc>::operator[](size_type) [with _Tp = sy_elem; _Alloc = std::allocator<sy_elem>; reference = sy_elem&;size_type = long unsigned int]: Assertion '__n < this->size()' failed.
./tools/qcc.sh: line 38: 4869 Aborted ( cd tools && ${QCC} "$@" )
make[1]: *** [Makefile:144: ../menu.dat] Error 134
make[1]: *** Waiting for unfinished jobs....
+ err=0
+ set -e
+ '[' 0 -ne 0 ']'
+ sed -E 's/^#(line)? ([[:digit:]]+) "(.*)".*/\
#pragma file(\3)\
#pragma line(\2)/g' ../.tmp/client.txt
+ qcc -std=gmqcc -Ooverlap-locals -O3 -Werror -Wall -Wno-field-redeclared -flno -futf8 -fno-bail-on-werror -frelaxed-switch -freturn-assignments -o /home/amade/workdir/xonotic2/xonotic/data/xonotic-data.pk3dir/qcsrc/../csprogs.dat ../../.tmp/client.qc
+ cd tools
+ ../../../../gmqcc/gmqcc -std=gmqcc -Ooverlap-locals -O3 -Werror -Wall -Wno-field-redeclared -flno -futf8 -fno-bail-on-werror -frelaxed-switch -freturn-assignments -o /home/amade/workdir/xonotic2/xonotic/data/xonotic-data.pk3dir/qcsrc/../csprogs.dat ../../.tmp/client.qc
Mode: manual
There are 1 items to compile:
item: ../../.tmp/client.qc (qc)
/usr/lib/gcc/x86_64-pc-linux-gnu/13/include/g++-v13/bits/stl_vector.h:1125: std::vector<_Tp, _Alloc>::reference std::vector<_Tp, _Alloc>::operator[](size_type) [with _Tp = sy_elem; _Alloc = std::allocator<sy_elem>; reference = sy_elem&;size_type = long unsigned int]: Assertion '__n < this->size()' failed.
./tools/qcc.sh: line 38: 4871 Aborted ( cd tools && ${QCC} "$@" )
make[1]: *** [Makefile:134: ../csprogs.dat] Error 134
+ err=0
+ set -e
+ '[' 0 -ne 0 ']'
+ sed -E 's/^#(line)? ([[:digit:]]+) "(.*)".*/\
#pragma file(\3)\
#pragma line(\2)/g' ../.tmp/server.txt
+ qcc -std=gmqcc -Ooverlap-locals -O3 -Werror -Wall -Wno-field-redeclared -flno -futf8 -fno-bail-on-werror -frelaxed-switch -freturn-assignments -o /home/amade/workdir/xonotic2/xonotic/data/xonotic-data.pk3dir/qcsrc/../progs.dat ../../.tmp/server.qc
+ cd tools
+ ../../../../gmqcc/gmqcc -std=gmqcc -Ooverlap-locals -O3 -Werror -Wall -Wno-field-redeclared -flno -futf8 -fno-bail-on-werror -frelaxed-switch -freturn-assignments -o /home/amade/workdir/xonotic2/xonotic/data/xonotic-data.pk3dir/qcsrc/../progs.dat ../../.tmp/server.qc
Mode: manual
There are 1 items to compile:
item: ../../.tmp/server.qc (qc)
/usr/lib/gcc/x86_64-pc-linux-gnu/13/include/g++-v13/bits/stl_vector.h:1125: std::vector<_Tp, _Alloc>::reference std::vector<_Tp, _Alloc>::operator[](size_type) [with _Tp = sy_elem; _Alloc = std::allocator<sy_elem>; reference = sy_elem&;size_type = long unsigned int]: Assertion '__n < this->size()' failed.
./tools/qcc.sh: line 38: 4873 Aborted ( cd tools && ${QCC} "$@" )
make[1]: *** [Makefile:139: ../progs.dat] Error 134
make[1]: Leaving directory '/home/amade/workdir/xonotic2/xonotic/data/xonotic-data.pk3dir/qcsrc'
make: *** [Makefile:12: all] Error 2
It can be worked around by adding -U_GLIBCXX_ASSERTIONS in CXXFLAGS in Makefile.
However looking at what this assertion checks it seems that it is out of bounds access in vector. Running gmqcc (build with DEBUG=1 for symbols) under gdb:
$ gdb ../../../../gmqcc/gmqcc
Reading symbols from ../../../../gmqcc/gmqcc...
(gdb) run -std=gmqcc -Ooverlap-locals -O3 -Werror -Wall -Wno-field-redeclared -flno -futf8 -fno-bail-on-werror -frelaxed-switch -freturn-assignments -o /home/amade/workdir/xonotic2/xonotic/data/xonotic-data.pk3dir/qcsrc/../progs.dat ../../.tmp/server.qc
Starting program: /home/amade/workdir/xonotic2/xonotic/gmqcc/gmqcc -std=gmqcc -Ooverlap-locals -O3 -Werror -Wall -Wno-field-redeclared -flno -futf8 -fno-bail-on-werror -frelaxed-switch -freturn-assignments -o /home/amade/workdir/xonotic2/xonotic/data/xonotic-data.pk3dir/qcsrc/../progs.dat ../../.tmp/server.qc
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib64/libthread_db.so.1".
Mode: manual
There are 1 items to compile:
item: ../../.tmp/server.qc (qc)
/usr/lib/gcc/x86_64-pc-linux-gnu/13/include/g++-v13/bits/stl_vector.h:1125: std::vector<_Tp, _Alloc>::reference std::vector<_Tp, _Alloc>::operator[](size_type) [with _Tp = sy_elem; _Alloc = std::allocator<sy_elem>; reference = sy_elem&;size_type = long unsigned int]: Assertion '__n < this->size()' failed.
Program received signal SIGABRT, Aborted.
0x00007ffff7ac9eec in __pthread_kill_implementation () from /lib64/libc.so.6
(gdb) bt
#0 0x00007ffff7ac9eec in __pthread_kill_implementation () from /lib64/libc.so.6
#1 0x00007ffff7a7b106 in raise () from /lib64/libc.so.6
#2 0x00007ffff7a6487c in abort () from /lib64/libc.so.6
#3 0x00007ffff7dfae3f in std::__glibcxx_assert_fail (file=<optimized out>, line=<optimized out>, function=<optimized out>, condition=<optimized out>)
at /var/tmp/portage/sys-devel/gcc-13.1.1_p20230527/work/gcc-13-20230527/libstdc++-v3/src/c++11/debug.cc:61
#4 0x00005555555decb1 in std::vector<sy_elem, std::allocator<sy_elem> >::operator[] (this=0x7fffffffca70, __n=0) at /usr/lib/gcc/x86_64-pc-linux-gnu/13/include/g++-v13/bits/stl_vector.h:1125
#5 0x00005555555c4f90 in parser_sy_apply_operator (parser=0x5555556134d0, sy=0x7fffffffca70) at parser.cpp:382
#6 0x00005555555cd45f in parse_expression_leave (parser=0x5555556134d0, stopatcomma=true, truthvalue=false, with_labels=false) at parser.cpp:1963
#7 0x00005555555db1a3 in parse_variable (parser=0x5555556134d0, localblock=0x0, nofields=false, qualifier=0, cached_typedef=0x0, noref=false, is_static=false, qflags=0, vstring=0x0) at parser.cpp:5763
#8 0x00005555555dbbdc in parser_global_statement (parser=0x5555556134d0) at parser.cpp:5919
#9 0x00005555555dcfc4 in parser_compile (parser=0x5555556134d0) at parser.cpp:6127
#10 0x00005555555dd11a in parser_compile_file (parser=0x5555556134d0, filename=0x7fffffffe0f5 "../../.tmp/server.qc") at parser.cpp:6157
#11 0x00005555555bf27f in main (argc=15, argv=0x7fffffffdb28) at main.cpp:726
It seems to fail in parser_sy_apply_operator in parser.cpp on line 382. And indeed looking at https://gitlab.com/xonotic/gmqcc/-/blob/2fe0af00e78d55edecd7ca7ee1808c4ea946b05f/parser.cpp#L382 there is:
exprs[i] = sy->out[sy->out.size()+i].out;
blocks[i] = sy->out[sy->out.size()+i].block;
sy->out is a vector and it seems like it tries to access data beyond its size?
I'm not sure what the correct fix is, so I leave it at that for someone else to fix.
Should be easily reproducible by adding -D_GLIBCXX_ASSERTIONS to CXXFLAGS in Makefile.