Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[zigcc] Building a C file with casts creates UB #17434

Closed
heysokam opened this issue Oct 8, 2023 · 4 comments
Closed

[zigcc] Building a C file with casts creates UB #17434

heysokam opened this issue Oct 8, 2023 · 4 comments
Labels
bug Observed behavior contradicts documented or intended behavior

Comments

@heysokam
Copy link

heysokam commented Oct 8, 2023

Zig Version

0.12.0-dev.798+5a4a5875d

Steps to Reproduce and Observed Behavior

Building this file: raycaster.c
Triggers what I think (and have been told in a C-lang discord server by others) is caused by UB.
Here is the result of objdump -d raycaster > raycaster.asm

The error does not happen with either of these:

(clang.16) clang -o raycaster raycaster.c -std=c2x -Weverything -lglfw -lGL -lepoxy
(gcc.13)   gcc   -o raycaster raycaster.c -std=c2x -Wall -Wextra -lglfw -lGL -lepoxy

But crashes at runtime with any of these:

(zigcc.dev.798) zig cc -o raycaster raycaster.c -std=c2x -Weverything -lglfw -lGL -lepoxy
(zigcc.dev.4xx) zig cc -o raycaster raycaster.c -std=c2x -Weverything -lglfw -lGL -lepoxy
(zigcc.0.11.0)  zig cc -o raycaster raycaster.c -std=c2x -Weverything -lglfw -lGL -lepoxy

The function that triggers the SIGILL is this one.

void rc_update (u32* const pix, u32 const size, u32 const clear) {
  (void)size; //discard
  (void)clear; //discard
  for(size_t col = 0; col < cfg_W; ++col) {
    for(size_t row = 0; row < cfg_H; ++row) {
      u8 const r = (u8)((f64)(255 * col) / (f64)(cfg_H));  // <--- This line
      u8 const g = (u8)((f64)(255 * row) / (f64)(cfg_W));  // <--- And this line
      pix[row * cfg_W + col] = rc_color_pack(r, g, 0, 255);
    }
  }
}

This is my complete zig cc command:

zig cc -v -std=c2x -Weverything -Werror -pedantic -pedantic-errors -Wno-declaration-after-statement -Wno-error=pre-c2x-compat -Wno-error=#warnings -Wno-error=unsafe-buffer-usage -Wno-error=vla -Wno-error=padded -Wno-c++-compat -Wno-c++0x-compat -Wno-c++0x-extensions -Wno-c++0x-narrowing -Wno-c++11-compat -Wno-c++11-compat-deprecated-writable-strings -Wno-c++11-compat-pedantic -Wno-c++11-compat-reserved-user-defined-literal -Wno-c++11-extensions -Wno-c++11-extra-semi -Wno-c++11-inline-namespace -Wno-c++11-long-long -Wno-c++11-narrowing -Wno-c++14-attribute-extensions -Wno-c++14-binary-literal -Wno-c++14-compat -Wno-c++14-compat-pedantic -Wno-c++14-extensions -Wno-c++17-attribute-extensions -Wno-c++17-compat -Wno-c++17-compat-mangling -Wno-c++17-compat-pedantic -Wno-c++17-extensions -Wno-c++1y-extensions -Wno-c++1z-compat -Wno-c++1z-compat-mangling -Wno-c++1z-extensions -Wno-c++20-attribute-extensions -Wno-c++20-compat -Wno-c++20-compat-pedantic -Wno-c++20-designator -Wno-c++20-extensions -Wno-c++2a-compat -Wno-c++2a-compat-pedantic -Wno-c++2a-extensions -Wno-c++2b-extensions -Wno-c++98-c++11-c++14-c++17-compat -Wno-c++98-c++11-c++14-c++17-compat-pedantic -Wno-c++98-c++11-c++14-compat -Wno-c++98-c++11-c++14-compat-pedantic -Wno-c++98-c++11-compat -Wno-c++98-c++11-compat-binary-literal -Wno-c++98-c++11-compat-pedantic -Wno-c++98-compat -Wno-c++98-compat-bind-to-temporary-copy -Wno-c++98-compat-extra-semi -Wno-c++98-compat-local-type-template-args -Wno-c++98-compat-pedantic -Wno-c++98-compat-unnamed-type-template-args -ggdb -lglfw -lGL -lepoxy -o raycaster raycaster.c

Here is the output of the zig cc -v [flags] command listed above.

clang version 17.0.1 (https://github.com/ziglang/zig-bootstrap 675dcf63d9805103b9803033ba073f5c8c37813f)
Target: x86_64-unknown-linux-gnu
Thread model: posix
InstalledDir: /usr/bin
Found candidate GCC installation: /usr/bin/../lib/gcc/x86_64-pc-linux-gnu/13.2.1
Found candidate GCC installation: /usr/bin/../lib64/gcc/x86_64-pc-linux-gnu/13.2.1
Selected GCC installation: /usr/bin/../lib64/gcc/x86_64-pc-linux-gnu/13.2.1
Candidate multilib: .;@m64
Candidate multilib: 32;@m32
Selected multilib: .;@m64
 (in-process)
 "/usr/lib/zig/zig" -cc1 -triple x86_64-unknown-linux-gnu -emit-obj -mrelax-all -disable-free -clear-ast-before-backend -disable-llvm-verifier -discard-value-names -main-file-name raycaster.c -mrelocation-model pic -pic-level 2 -fhalf-no-semantic-interposition -mframe-pointer=all -fmath-errno -ffp-contract=on -fno-rounding-math -mconstructor-aliases -funwind-tables=2 -target-cpu x86-64 -tune-cpu generic -debug-info-kind=constructor -dwarf-version=4 -debugger-tuning=gdb -v -fcoverage-compilation-dir=/home/sokam/gd/other/mm/goal/e04 -nostdsysteminc -nobuiltininc -resource-dir /usr/lib/lib/clang/17 -dependency-file /home/sokam/.cache/zig/tmp/7e3066df6af0641c-raycaster.o.d -MT /home/sokam/.cache/zig/tmp/7e3066df6af0641c-raycaster.o -sys-header-deps -canonical-system-headers -MV -isystem /usr/lib/zig/lib/include -isystem /usr/include -isystem /usr/local/include -isystem /usr/include/x86_64-linux-gnu -isystem /usr/include -D __GLIBC_MINOR__=19 -D _DEBUG -O0 -Weverything -Werror -Wno-declaration-after-statement -Wno-error=pre-c2x-compat -Wno-error=#warnings -Wno-error=unsafe-buffer-usage -Wno-error=vla -Wno-error=padded -Wno-c++-compat -Wno-c++0x-compat -Wno-c++0x-extensions -Wno-c++0x-narrowing -Wno-c++11-compat -Wno-c++11-compat-deprecated-writable-strings -Wno-c++11-compat-pedantic -Wno-c++11-compat-reserved-user-defined-literal -Wno-c++11-extensions -Wno-c++11-extra-semi -Wno-c++11-inline-namespace -Wno-c++11-long-long -Wno-c++11-narrowing -Wno-c++14-attribute-extensions -Wno-c++14-binary-literal -Wno-c++14-compat -Wno-c++14-compat-pedantic -Wno-c++14-extensions -Wno-c++17-attribute-extensions -Wno-c++17-compat -Wno-c++17-compat-mangling -Wno-c++17-compat-pedantic -Wno-c++17-extensions -Wno-c++1y-extensions -Wno-c++1z-compat -Wno-c++1z-compat-mangling -Wno-c++1z-extensions -Wno-c++20-attribute-extensions -Wno-c++20-compat -Wno-c++20-compat-pedantic -Wno-c++20-designator -Wno-c++20-extensions -Wno-c++2a-compat -Wno-c++2a-compat-pedantic -Wno-c++2a-extensions -Wno-c++2b-extensions -Wno-c++98-c++11-c++14-c++17-compat -Wno-c++98-c++11-c++14-c++17-compat-pedantic -Wno-c++98-c++11-c++14-compat -Wno-c++98-c++11-c++14-compat-pedantic -Wno-c++98-c++11-compat -Wno-c++98-c++11-compat-binary-literal -Wno-c++98-c++11-compat-pedantic -Wno-c++98-compat -Wno-c++98-compat-bind-to-temporary-copy -Wno-c++98-compat-extra-semi -Wno-c++98-compat-local-type-template-args -Wno-c++98-compat-pedantic -Wno-c++98-compat-unnamed-type-template-args -pedantic -pedantic-errors -std=c2x -fdebug-compilation-dir=/home/sokam/gd/other/mm/goal/e04 -ferror-limit 19 -fsanitize=alignment,array-bounds,bool,builtin,enum,float-cast-overflow,integer-divide-by-zero,nonnull-attribute,null,pointer-overflow,return,returns-nonnull-attribute,shift-base,shift-exponent,signed-integer-overflow,unreachable,vla-bound -fsanitize-trap=alignment,array-bounds,bool,builtin,enum,float-cast-overflow,integer-divide-by-zero,nonnull-attribute,null,pointer-overflow,return,returns-nonnull-attribute,shift-base,shift-exponent,signed-integer-overflow,unreachable,vla-bound -fno-sanitize-memory-param-retval -fno-sanitize-address-use-odr-indicator -stack-protector 2 -stack-protector-buffer-size 4 -fgnuc-version=4.2.1 -fno-spell-checking -target-cpu znver1 -target-feature -16bit-mode -target-feature -32bit-mode -target-feature -3dnow -target-feature -3dnowa -target-feature +64bit -target-feature +adx -target-feature +aes -target-feature +allow-light-256-bit -target-feature -amx-bf16 -target-feature -amx-complex -target-feature -amx-fp16 -target-feature -amx-int8 -target-feature -amx-tile -target-feature +avx -target-feature +avx2 -target-feature -avx512bf16 -target-feature -avx512bitalg -target-feature -avx512bw -target-feature -avx512cd -target-feature -avx512dq -target-feature -avx512er -target-feature -avx512f -target-feature -avx512fp16 -target-feature -avx512ifma -target-feature -avx512pf -target-feature -avx512vbmi -target-feature -avx512vbmi2 -target-feature -avx512vl -target-feature -avx512vnni -target-feature -avx512vp2intersect -target-feature -avx512vpopcntdq -target-feature -avxifma -target-feature -avxneconvert -target-feature -avxvnni -target-feature -avxvnniint16 -target-feature -avxvnniint8 -target-feature +bmi -target-feature +bmi2 -target-feature +branchfusion -target-feature -cldemote -target-feature +clflushopt -target-feature -clwb -target-feature +clzero -target-feature +cmov -target-feature -cmpccxadd -target-feature +crc32 -target-feature +cx16 -target-feature +cx8 -target-feature -enqcmd -target-feature -ermsb -target-feature +f16c -target-feature -false-deps-getmant -target-feature -false-deps-lzcnt-tzcnt -target-feature -false-deps-mulc -target-feature -false-deps-mullq -target-feature -false-deps-perm -target-feature -false-deps-popcnt -target-feature -false-deps-range -target-feature -fast-11bytenop -target-feature +fast-15bytenop -target-feature -fast-7bytenop -target-feature +fast-bextr -target-feature -fast-gather -target-feature -fast-hops -target-feature +fast-lzcnt -target-feature +fast-movbe -target-feature +fast-scalar-fsqrt -target-feature +fast-scalar-shift-masks -target-feature -fast-shld-rotate -target-feature -fast-variable-crosslane-shuffle -target-feature +fast-variable-perlane-shuffle -target-feature +fast-vector-fsqrt -target-feature -fast-vector-shift-masks -target-feature -faster-shift-than-shuffle -target-feature +fma -target-feature -fma4 -target-feature +fsgsbase -target-feature -fsrm -target-feature +fxsr -target-feature -gfni -target-feature -harden-sls-ijmp -target-feature -harden-sls-ret -target-feature -hreset -target-feature -idivl-to-divb -target-feature -idivq-to-divl -target-feature -invpcid -target-feature -kl -target-feature -lea-sp -target-feature -lea-uses-ag -target-feature -lvi-cfi -target-feature -lvi-load-hardening -target-feature -lwp -target-feature +lzcnt -target-feature -macrofusion -target-feature +mmx -target-feature +movbe -target-feature -movdir64b -target-feature -movdiri -target-feature +mwaitx -target-feature -no-bypass-delay -target-feature -no-bypass-delay-blend -target-feature -no-bypass-delay-mov -target-feature -no-bypass-delay-shuffle -target-feature +nopl -target-feature -pad-short-functions -target-feature +pclmul -target-feature -pconfig -target-feature -pku -target-feature +popcnt -target-feature -prefer-128-bit -target-feature -prefer-256-bit -target-feature -prefer-mask-registers -target-feature -prefer-movmsk-over-vtest -target-feature -prefetchi -target-feature -prefetchwt1 -target-feature +prfchw -target-feature -ptwrite -target-feature -raoint -target-feature -rdpid -target-feature -rdpru -target-feature +rdrnd -target-feature +rdseed -target-feature -retpoline -target-feature -retpoline-external-thunk -target-feature -retpoline-indirect-branches -target-feature -retpoline-indirect-calls -target-feature -rtm -target-feature +sahf -target-feature +sbb-dep-breaking -target-feature -serialize -target-feature -seses -target-feature -sgx -target-feature +sha -target-feature -sha512 -target-feature -shstk -target-feature -slow-3ops-lea -target-feature -slow-incdec -target-feature -slow-lea -target-feature -slow-pmaddwd -target-feature -slow-pmulld -target-feature +slow-shld -target-feature -slow-two-mem-ops -target-feature -slow-unaligned-mem-16 -target-feature -slow-unaligned-mem-32 -target-feature -sm3 -target-feature -sm4 -target-feature -soft-float -target-feature +sse -target-feature +sse2 -target-feature +sse3 -target-feature +sse4.1 -target-feature +sse4.2 -target-feature +sse4a -target-feature -sse-unaligned-mem -target-feature +ssse3 -target-feature -tagged-globals -target-feature -tbm -target-feature -tsxldtrk -target-feature -tuning-fast-imm-vector-shift -target-feature -uintr -target-feature -use-glm-div-sqrt-costs -target-feature -use-slm-arith-costs -target-feature -vaes -target-feature -vpclmulqdq -target-feature +vzeroupper -target-feature -waitpkg -target-feature -wbnoinvd -target-feature -widekl -target-feature +x87 -target-feature -xop -target-feature +xsave -target-feature +xsavec -target-feature +xsaveopt -target-feature +xsaves -faddrsig -D__GCC_HAVE_DWARF2_CFI_ASM=1 -o /home/sokam/.cache/zig/tmp/7e3066df6af0641c-raycaster.o -x c raycaster.c
clang -cc1 version 17.0.1 based upon LLVM 17.0.1 default target x86_64-linux-musl
ignoring nonexistent directory "/usr/include/x86_64-linux-gnu"
ignoring duplicate directory "/usr/include"
#include "..." search starts here:
#include <...> search starts here:
 /usr/lib/zig/lib/include
 /usr/include
 /usr/local/include
End of search list.
raycaster.c:75:1: warning: [[]] attributes are incompatible with C standards before C2x [-Wpre-c2x-compat]
   75 | [[noreturn]] static void err (cstr const msg) {
      | ^
raycaster.c:200:16: warning: variable length array used [-Wvla]
  200 |   char infoLog[InfoMsgLen];
      |                ^~~~~~~~~~
raycaster.c:145:5: warning: unsafe buffer access [-Wunsafe-buffer-usage]
  145 |     pix[id] = clear;
      |     ^~~
raycaster.c:156:7: warning: unsafe buffer access [-Wunsafe-buffer-usage]
  156 |       pix[row * cfg_W + col] = rc_color_pack(r, g, 0, 255);
      |       ^~~
4 warnings generated.
LLD Link... ld.lld --error-limit=0 -O0 -z stack-size=16777216 --gc-sections --eh-frame-hdr -znow -m elf_x86_64 -o raycaster /usr/lib/gcc/x86_64-pc-linux-gnu/13.2.1/../../../../lib/crt1.o /usr/lib/gcc/x86_64-pc-linux-gnu/13.2.1/../../../../lib/crti.o -L /usr/local/lib64 -L /usr/local/lib -L /usr/lib/x86_64-linux-gnu -L /lib64 -L /lib -L /usr/lib64 -L /usr/lib -L /lib/x86_64-linux-gnu -L /usr/lib/gcc/x86_64-pc-linux-gnu/13.2.1/../../../../lib -dynamic-linker /lib64/ld-linux-x86-64.so.2 /home/sokam/.cache/zig/o/78c57cfba98380bf5458d92aec7f5d0b/raycaster.o --as-needed /lib64/libglfw.so /lib64/libGL.so /lib64/libepoxy.so -lm -lpthread -lc -ldl -lrt -lutil /home/sokam/.cache/zig/o/849746ebedfaaeb984db570ec4a9dca5/libcompiler_rt.a /usr/lib/gcc/x86_64-pc-linux-gnu/13.2.1/../../../../lib/crtn.o

And here is the output of running the application inside gdb

❖ gdb ./raycaster

GNU gdb (GDB) 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 "x86_64-pc-linux-gnu".
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 ./raycaster...
(gdb) r
Starting program: /home/sokam/gd/other/mm/goal/e04/raycaster

This GDB supports auto-downloading debuginfo from the following URLs:
  <https://debuginfod.archlinux.org>
Enable debuginfod for this session? (y or [n]) n
Debuginfod has been disabled.
To make this setting permanent, add 'set debuginfod enabled off' to .gdbinit.
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/usr/lib/libthread_db.so.1".
MinC | RayCaster

Program received signal SIGILL, Illegal instruction.
0x0000000000202c2d in rc_update (pix=0x7ffff13c0010, size=518400, clear=4294901760) at raycaster.c:154
154	      u8 const r = (u8)((f64)(255 * col) / (f64)(cfg_H));
(gdb) bt
#0  0x0000000000202c2d in rc_update (pix=0x7ffff13c0010, size=518400, clear=4294901760) at raycaster.c:154
#1  0x0000000000203286 in main () at raycaster.c:233

Expected Behavior

The application should not crash at runtime, just like it does not crash when building with raw clang and/or gcc.

I'm guessing some of the flags set by zigcc as defaults might be causing this problem.
I've spent the entire day (+6 hours already) trying to comb through the list of flags, in hopes to find the guilty flag and disable it... but I just cannot find which one is causing the problem. I have no idea what most of them do... and there are a LOT of them...

That's all the information I could gather, but let me know if there is something else that could be useful.

@heysokam heysokam added the bug Observed behavior contradicts documented or intended behavior label Oct 8, 2023
@xdBronch
Copy link
Contributor

xdBronch commented Oct 8, 2023

zig cc passes -fsanitize=undefined by default which inserts an illegal instruction in places it finds could cause UB, you can disable it with -fno-sanitize=undefined (or by fixing the UB)

@heysokam
Copy link
Author

heysokam commented Oct 8, 2023

raycaster.c:154:20: runtime error: 256.417 is outside the range of representable values of type 'unsigned char'
SUMMARY: UndefinedBehaviorSanitizer: undefined-behavior raycaster.c:154:20 in

Oh, I just saw the UB!
But this is showing when building with raw clang.

Why does the file built with zigcc not report this by default?

@xdBronch
Copy link
Contributor

xdBronch commented Oct 8, 2023

see #5163

@heysokam
Copy link
Author

heysokam commented Oct 8, 2023

Extremely useful to know, ty! I didn't find that on my search.
I guess I should close this issue and go read that extensive list of comments about it.

Also, ty for the prompt reponse @xdBronch. That was really useful, since I already lost a lot of hours trying to find the invisible ghost of this problem today.
Thank you so much!

@heysokam heysokam closed this as completed Oct 8, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Observed behavior contradicts documented or intended behavior
Projects
None yet
Development

No branches or pull requests

2 participants