For the following programm gcc produces wrong code. To pass the struct colour by value gcc reads 8 bytes although the struct has a size of 6. This causes reads after allocated memory. In the example program the memory is mmap'ed and the last element passed. The 8 byte read crosses page boundaries and causes a segmentation violation. The code in question is:
movq -8(%rbp), %rax addq $12282, %rax movq (%rax), %rdi call print_colour The error also occurs if you malloc the memory in question but it is harder to provoke a segmentation violation. The error occurs only in 64bit mode. It does not depend on the optimization level. However if you want to reproduce it with higher optimization, you have to move print_colour to a different compilation unit. It could be reproduced on different gcc versions up to 4.3.0 #include <sys/mman.h> #include <stdio.h> struct colour { unsigned short red; unsigned short green; unsigned short blue; }; void print_colour(struct colour col) { printf( "colour is %d %d %d\n", col.red, col.green, col.blue); } int main(void) { struct colour * c = mmap(NULL, sizeof(struct colour) * 2048, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, 0, 0); if (c != MAP_FAILED) { c[2047].red = 115; c[2047].green = 122; c[2047].blue = 98; print_colour(c[2047]); munmap(c, sizeof(struct colour) * 2048); } return 0; } Here is the whole command line: -bash-3.00$ LANG=C /lfs/user/bartosch/software/gcc/bin/gcc -v -save-temps -Wall -W -pedantic gls.c Using built-in specs. Target: x86_64-unknown-linux-gnu Configured with: ../gcc-4.3.0/configure --prefix=/lfs/user/bartosch/software/gcc --enable-languages=c,c++ --with-mpfr=/lfs/user/bartosch/software/gcc Thread model: posix gcc version 4.3.0 (GCC) COLLECT_GCC_OPTIONS='-v' '-save-temps' '-Wall' '-W' '-pedantic' '-mtune=generic' /lfs/user/bartosch/software/gcc/libexec/gcc/x86_64-unknown-linux-gnu/4.3.0/cc1 -E -quiet -v gls.c -mtune=generic -Wall -W -pedantic -fpch-preprocess -o gls.i ignoring nonexistent directory "/lfs/user/bartosch/software/gcc/lib/gcc/x86_64-unknown-linux-gnu/4.3.0/../../../../x86_64-unknown-linux-gnu/include" #include "..." search starts here: #include <...> search starts here: /usr/local/include /lfs/user/bartosch/software/gcc/include /lfs/user/bartosch/software/gcc/lib/gcc/x86_64-unknown-linux-gnu/4.3.0/include /lfs/user/bartosch/software/gcc/lib/gcc/x86_64-unknown-linux-gnu/4.3.0/include-fixed /usr/include End of search list. COLLECT_GCC_OPTIONS='-v' '-save-temps' '-Wall' '-W' '-pedantic' '-mtune=generic' /lfs/user/bartosch/software/gcc/libexec/gcc/x86_64-unknown-linux-gnu/4.3.0/cc1 -fpreprocessed gls.i -quiet -dumpbase gls.c -mtune=generic -auxbase gls -Wall -W -pedantic -version -o gls.s GNU C (GCC) version 4.3.0 (x86_64-unknown-linux-gnu) compiled by GNU C version 4.3.0, GMP version 4.2.1, MPFR version 2.3.0. GGC heuristics: --param ggc-min-expand=100 --param ggc-min-heapsize=131072 Compiler executable checksum: 261e5a68fb24a56eb3beaa6eb43384e4 COLLECT_GCC_OPTIONS='-v' '-save-temps' '-Wall' '-W' '-pedantic' '-mtune=generic' as -V -Qy -o gls.o gls.s GNU assembler version 2.15.92.0.2 (x86_64-redhat-linux) using BFD version 2.15.92.0.2 20040927 COMPILER_PATH=/lfs/user/bartosch/software/gcc/libexec/gcc/x86_64-unknown-linux-gnu/4.3.0/:/lfs/user/bartosch/software/gcc/libexec/gcc/x86_64-unknown-linux-gnu/4.3.0/:/lfs/user/bartosch/software/gcc/libexec/gcc/x86_64-unknown-linux-gnu/:/lfs/user/bartosch/software/gcc/lib/gcc/x86_64-unknown-linux-gnu/4.3.0/:/lfs/user/bartosch/software/gcc/lib/gcc/x86_64-unknown-linux-gnu/ LIBRARY_PATH=/lfs/user/bartosch/software/gcc/lib/gcc/x86_64-unknown-linux-gnu/4.3.0/:/lfs/user/bartosch/software/gcc/lib/gcc/x86_64-unknown-linux-gnu/4.3.0/../../../../lib64/:/lib/../lib64/:/usr/lib/../lib64/:/lfs/user/bartosch/software/gcc/lib/gcc/x86_64-unknown-linux-gnu/4.3.0/../../../:/lib/:/usr/lib/ COLLECT_GCC_OPTIONS='-v' '-save-temps' '-Wall' '-W' '-pedantic' '-mtune=generic' /lfs/user/bartosch/software/gcc/libexec/gcc/x86_64-unknown-linux-gnu/4.3.0/collect2 --eh-frame-hdr -m elf_x86_64 -dynamic-linker /lib64/ld-linux-x86-64.so.2 /usr/lib/../lib64/crt1.o /usr/lib/../lib64/crti.o /lfs/user/bartosch/software/gcc/lib/gcc/x86_64-unknown-linux-gnu/4.3.0/crtbegin.o -L/lfs/user/bartosch/software/gcc/lib/gcc/x86_64-unknown-linux-gnu/4.3.0 -L/lfs/user/bartosch/software/gcc/lib/gcc/x86_64-unknown-linux-gnu/4.3.0/../../../../lib64 -L/lib/../lib64 -L/usr/lib/../lib64 -L/lfs/user/bartosch/software/gcc/lib/gcc/x86_64-unknown-linux-gnu/4.3.0/../../.. gls.o -lgcc --as-needed -lgcc_s --no-as-needed -lc -lgcc --as-needed -lgcc_s --no-as-needed /lfs/user/bartosch/software/gcc/lib/gcc/x86_64-unknown-linux-gnu/4.3.0/crtend.o /usr/lib/../lib64/crtn.o -bash-3.00$ ./a.out Speicherzugriffsfehler -bash-3.00$ -- Summary: gcc reads 8 bytes for a struct of size 6 which leads to sigsegv Product: gcc Version: 4.3.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: c AssignedTo: unassigned at gcc dot gnu dot org ReportedBy: bartoschek at gmx dot de GCC build triplet: x86_64-unknown-linux-gnu GCC host triplet: x86_64-unknown-linux-gnu GCC target triplet: x86_64-unknown-linux-gnu http://gcc.gnu.org/bugzilla/show_bug.cgi?id=36043