
Hi there, I just tried to build nhc98-1.16, with the three patches that are available applied, on my (Gentoo) Linux-x86 machine. After a ./configure --buildwith=gcc make I get the following error: [...] make[1]: Leaving directory `/var/tmp/portage/nhc98-1.16-r1/work/nhc98-1.16/src/compiler98' cd src/prelude/ix86-Linux/NHC; make clean all # Patch machine-specific parts. make[1]: Entering directory `/var/tmp/portage/nhc98-1.16-r1/work/nhc98-1.16/src/prelude/ix86-Linux/NHC' rm -f *.hi rm -f DErrNo.hc rm -f /var/tmp/portage/nhc98-1.16-r1/work/nhc98-1.16/targets/ix86-Linux/obj/prelude/DErrNo/*.o *.o rm -f rm -f /var/tmp/portage/nhc98-1.16-r1/work/nhc98-1.16/script/nhc98 -cpp -c +CTS -lib -redefine -CTS +RTS -H32M -RTS -o /var/tmp/portage/nhc98-1.16-r1/work/nhc98-1.16/targets/ix86-Linux/obj/prelude/DErrNo/DErrNo.o DErrNo.hs /var/tmp/portage/nhc98-1.16-r1/work/nhc98-1.16/script/nhc98: line 605: 10142 Segmentation fault $COMP $RUNFLAGS $COMPFLAGS $HINCDIRS -I. $UNLIT -P${NHC98INCDIR} $HSFILE $POSTGRFILE $TMPHIFILE $TMPCPPASFILE make[1]: *** [/var/tmp/portage/nhc98-1.16-r1/work/nhc98-1.16/targets/ix86-Linux/obj/prelude/DErrNo/DErrNo.o] Error 1 make[1]: Leaving directory `/var/tmp/portage/nhc98-1.16-r1/work/nhc98-1.16/src/prelude/ix86-Linux/NHC' make: *** [targets/ix86-Linux/compiler-gcc] Error 2 Note that I am building in /var/tmp/portage/nhc98-1.16-r1/work/nhc98-1.16. This seems to be the first call to the nhc98 script that does actually call the nhc98comp binary. Indeed, calling nhc98comp immediately produces a Segmentation fault. Here's an "strace ./nhc98comp": execve("./nhc98comp", ["./nhc98comp"], [/* 60 vars */]) = 0 uname({sys="Linux", node="adorp.cs.uu.nl", ...}) = 0 brk(0) = 0x8135000 open("/etc/ld.so.preload", O_RDONLY) = -1 ENOENT (No such file or directory) mmap2(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x40015000 open("/etc/ld.so.cache", O_RDONLY) = 3 fstat64(3, {st_mode=S_IFREG|0644, st_size=99363, ...}) = 0 mmap2(NULL, 99363, PROT_READ, MAP_PRIVATE, 3, 0) = 0x40016000 close(3) = 0 open("/lib/libm.so.6", O_RDONLY) = 3 read(3, "\177ELF\1\1\1\0\0\0\0\0\0\0\0\0\3\0\3\0\1\0\0\0\3404\0"..., 512) = 512 fstat64(3, {st_mode=S_IFREG|0755, st_size=153448, ...}) = 0 mmap2(NULL, 137184, PROT_READ|PROT_EXEC, MAP_PRIVATE, 3, 0) = 0x4002f000 mmap2(0x40050000, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED, 3, 0x20) = 0x40050000 close(3) = 0 open("/lib/libc.so.6", O_RDONLY) = 3 read(3, "\177ELF\1\1\1\0\0\0\0\0\0\0\0\0\3\0\3\0\1\0\0\0 ]\1\000"..., 512) = 512 fstat64(3, {st_mode=S_IFREG|0755, st_size=1304540, ...}) = 0 mmap2(NULL, 1238628, PROT_READ|PROT_EXEC, MAP_PRIVATE, 3, 0) = 0x40051000 mmap2(0x4017a000, 12288, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED, 3, 0x129) = 0x4017a000 mmap2(0x4017d000, 9828, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS, -1, 0) = 0x4017d000 close(3) = 0 munmap(0x40016000, 99363) = 0 open("/dev/urandom", O_RDONLY) = 3 read(3, "\fQ;g:2l\261\275\377\310\324#\240Z\210Gi\345\373\265\245"..., 32) = 32 close(3) = 0 brk(0) = 0x8135000 brk(0x8156000) = 0x8156000 brk(0) = 0x8156000 mmap2(NULL, 8081408, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x40180000 times({tms_utime=0, tms_stime=0, tms_cutime=0, tms_cstime=0}) = 892864824 times({tms_utime=0, tms_stime=0, tms_cutime=0, tms_cstime=0}) = 892864824 --- SIGSEGV (Segmentation fault) @ 0 (0) --- +++ killed by SIGSEGV +++ Here is which gcc and glibc I use: gcc-3.3.2 glibc-2.3.2 Any ideas? Best, Andres

Andres Loeh
I just tried to build nhc98-1.16, with the three patches that are available applied, on my (Gentoo) Linux-x86 machine.
[ segfault when calling the nhc98comp binary for the first time ]
Yes, this indicates that your compiler build is definitely broken. Thanks for the strace output - it does not immediately seem to show anything out of place, but I will study it more closely just in case.
Here is which gcc and glibc I use:
gcc-3.3.2 glibc-2.3.2
I assume you applied the gcc3.3 patch for nhc98. Here, on Slackware 9 Linux, with gcc-3.2.2 and glibc-2.3.1, I don't see these problems. However, others have reported seg faults on e.g. NetBSD. My best guess is that this is another byte-code alignment problem of the same kind that we have already seen a couple of times with different versions of the gcc toolset. Unfortunately, it would be very difficult for me to debug this remotely. Regards, Malcolm

I wrote:
My best guess is that this is another byte-code alignment problem of the same kind that we have already seen a couple of times with different versions of the gcc toolset.
A quick thought, which might help us track down the alignment problem. Please can you send me the output of the following command: gcc -S -x c src/prelude/DErrNo.hc -Iinclude -o - | grep align Regards, Malcolm

A quick thought, which might help us track down the alignment problem. Please can you send me the output of the following command:
gcc -S -x c src/prelude/DErrNo.hc -Iinclude -o - | grep align
Here is the output: .align 4 .align 4 .align 4 .align 4 .align 4 .align 4 .align 4 .align 4 .align 4 .align 4 .align 4 .align 4 .align 4 .align 4 .align 4 .align 4 .align 4 .align 4 .align 4 .align 4 .align 4 .align 4 .align 4 .align 4 .align 4 .align 4 .align 4 .align 4 .align 4 .align 4 .align 4 .align 4 .align 4 .align 4 .align 4 .align 32 .align 4 .align 32 .align 4 .align 32 .align 4 .align 32 .align 4 .align 32 .align 4 .align 32 .align 4 .align 4 .align 4 .align 4 .align 32 .align 32 .align 32 .align 4 .align 4 .align 4 .align 4 .align 4 .align 4 .align 4 .align 4 .align 4 .align 4 .align 4 .align 4 .align 4 .align 4 .align 4 .align 4 .align 4 .align 4 .align 4 .align 4 .align 4 .align 4 .align 4 .align 4 .align 4 .align 4 .align 32 .align 32 .align 32 .align 32 HTH, Andres

On Wed, Apr 14, 2004 at 12:05:40PM +0000, Andres Loeh wrote:
[...]
/var/tmp/portage/nhc98-1.16-r1/work/nhc98-1.16/script/nhc98 -cpp -c +CTS -lib -redefine -CTS +RTS -H32M -RTS -o /var/tmp/portage/nhc98-1.16-r1/work/nhc98-1.16/targets/ix86-Linux/obj/prelude/DErrNo/DErrNo.o DErrNo.hs /var/tmp/portage/nhc98-1.16-r1/work/nhc98-1.16/script/nhc98: line 605: 10142 Segmentation fault $COMP $RUNFLAGS $COMPFLAGS $HINCDIRS -I. $UNLIT -P${NHC98INCDIR} $HSFILE $POSTGRFILE $TMPHIFILE $TMPCPPASFILE make[1]: *** [/var/tmp/portage/nhc98-1.16-r1/work/nhc98-1.16/targets/ix86-Linux/obj/prelude/DErrNo/DErrNo.o] Error 1 make[1]: Leaving directory `/var/tmp/portage/nhc98-1.16-r1/work/nhc98-1.16/src/prelude/ix86-Linux/NHC' make: *** [targets/ix86-Linux/compiler-gcc] Error 2
I've just had a quick look at this. Between 3.2 and 3.3 gcc seems to have changed from generating ----- .file "DErrNo.hc" .data .align 4 .type startLabel,@object .size startLabel,0 startLabel: .globl C0_NHC_46DErrNo_46ERANGE .align 4 ----- to generating ----- .file "DErrNo.hc" .local startLabel .comm startLabel,0,4 .globl C0_NHC_46DErrNo_46ERANGE .data .align 4 ----- It looks like nhc uses offsets from startLabel but (IANA assembler expert) startLabel is now common to all such files linked together and will now probably be created at some other location (hmm, or perhaps nowhere at all if it is 0 size everywhere?) An (extremely ugly) solution is to add perl -e 'undef $/; $_ = <>; s/^\s*\.local\s+startLabel\n\s*.comm\s+startLabel,0,4\n\s*\.globl\s+([^\n]+)\n\s*\.data/\t.data\n\t.align 4\n\t.type startLabel,\@object\n\t.size startLabel,0\nstartLabel:\n.globl $1/m; print' | above the line sed -e '/.align 32/s/32/4/' >$TMPASFILE # evil mangler! in script/nhc98.inst I'm not sure if removing the last .data is necessary; the hack is marginally less ugly if not. This seems to work for me. Better (or even just prettier :-) ) solutions welcomed. Thanks Ian

On Sun, Jun 13, 2004 at 03:42:49AM +0100, Ian Lynagh wrote:
I've just had a quick look at this. Between 3.2 and 3.3 gcc seems to have changed from generating
----- .file "DErrNo.hc" .data .align 4 .type startLabel,@object .size startLabel,0 startLabel: .globl C0_NHC_46DErrNo_46ERANGE .align 4 -----
to generating
----- .file "DErrNo.hc" .local startLabel .comm startLabel,0,4 .globl C0_NHC_46DErrNo_46ERANGE .data .align 4 -----
Just had a look on mips (one of the arches where it currently matters for me) and both 3.2 and 3.3 are generating ".align 2" rather than ".align 4". As far as I know this hasn't caused a problem in the past. Have I just been lucky or is this also fine? Or is it something that should be fixed? Thanks Ian

Ian Lynagh
Just had a look on mips (one of the arches where it currently matters for me) and both 3.2 and 3.3 are generating ".align 2" rather than ".align 4". As far as I know this hasn't caused a problem in the past. Have I just been lucky or is this also fine? Or is it something that should be fixed?
I imagine that, since 'startLabel' is always the first symbol to be defined in any object file, it will naturally get a 4-byte alignment anyway thanks to the linker, regardless of whether the compiler places an ".align 2" or ".align 4" in front of it. But yes, technically it should probably be .align 4. Regards, Malcolm

On Sun, Jun 13, 2004 at 02:27:52PM +0100, Malcolm Wallace wrote:
Ian Lynagh
writes: Just had a look on mips (one of the arches where it currently matters for me) and both 3.2 and 3.3 are generating ".align 2" rather than ".align 4". As far as I know this hasn't caused a problem in the past. Have I just been lucky or is this also fine? Or is it something that should be fixed?
I imagine that, since 'startLabel' is always the first symbol to be defined in any object file, it will naturally get a 4-byte alignment anyway thanks to the linker, regardless of whether the compiler places an ".align 2" or ".align 4" in front of it.
But yes, technically it should probably be .align 4.
It's actually every .align, not just the first one, that is .align 2, so I assume they should all be changed. Is there a reason why you don't do sed "s/\.align [0-9]\+/.align 4/" rather than fixing them on a case-by-case basis? Thanks Ian

Ian Lynagh
It's actually every .align, not just the first one, that is .align 2, so I assume they should all be changed.
Is it possible that, in the MIPS assembler, the .align instruction is coded as powers of two rather than absolute numbers?
Is there a reason why you don't do sed "s/\.align [0-9]\+/.align 4/" rather than fixing them on a case-by-case basis?
I'm not certain that all alignments should be 4 byte. Doubles are 8, although I don't offhand remember whether we generate any of those in the bytecode itself. Regards, Malcolm

Ian Lynagh
I've just had a quick look at this. Between 3.2 and 3.3 gcc seems to have changed from generating
----- .file "DErrNo.hc" .data .align 4 .type startLabel,@object .size startLabel,0 startLabel: .globl C0_NHC_46DErrNo_46ERANGE .align 4 -----
to generating
----- .file "DErrNo.hc" .local startLabel .comm startLabel,0,4 .globl C0_NHC_46DErrNo_46ERANGE .data .align 4 -----
Thanks for your perl patch for this problem. I have checked it into CVS, but guarded in the configure script so that it is only enabled if gcc-3.3 is present. Regards, Malcolm

----- .file "DErrNo.hc" .local startLabel .comm startLabel,0,4 .globl C0_NHC_46DErrNo_46ERANGE .data .align 4 -----
Another thought: the gcc-3.3.3 manual mentions this flag: -fno-common In C, allocate even uninitialized global variables in the data section of the object file, rather than generating them as common blocks. This has the effect that if the same variable is declared (without extern) in two different compilations, you will get an error when you link them. The only reason this might be useful is if you wish to verify that the program will work on other systems which always work this way. Does it make any difference when compiling with nhc98? To test, add the flag to line 80 of script/nhc98.inst: CPPAS="${CC} -x c -S -fno-common" and re-run configure. Regards, Malcolm

On Mon, Jun 14, 2004 at 12:00:57PM +0100, Malcolm Wallace wrote:
Ian Lynagh
writes: Thanks for your perl patch for this problem. I have checked it into CVS, but guarded in the configure script so that it is only enabled if gcc-3.3 is present.
Here's a better one (accepts global as well as globl, uses STT_OBJECT instead of @object (@ starts a comment on arm), uses the align of the original rather than assuming 4 is right) that I believe works on at least x86, mips(el) and arm. I haven't tried it on anything else. perl -e 'undef $/; $_ = <>; s/^ \s*\.local\s+startLabel\n \s*.comm\s+startLabel,0,4\n (\s*\.globa?l\s+[^\n]+)\n \s*\.data\n (\s*\.align\s*\d+)\n /"\t.data\n" ."$2\n" ."\t.type startLabel,STT_OBJECT\n" ."\t.size startLabel,0\n" ."startLabel:\n" ."$1\n" ."$2\n"/emx; print;' | -fno-common seemed to have no effect and the meaning of .align does indeed vary depending on what platform you are using GNU as on. If you're already GNU tools only and you did want to replace all aligns with 4-byte alignment then you could use .balign 4 (or .p2align 2) though. Thanks Ian
participants (3)
-
Andres Loeh
-
Ian Lynagh
-
Malcolm Wallace