[gnu.g++.bug] Global string constant causes core dump g++/libg++ 1.36.x on 386

rp@osc.COM (Rich Patterson) (02/10/90)

Hi,
	Here is a problem that I've found in g++/libg++. Flames --> /dev/null.

Synopsis: __CTOR_LIST__ is invalid for the following program (G++-1.36.4/
	  LIBG++-1.35.3 386 System V GAS and COFF encapsulaton) and dumps
	  core.  Initialized global string constant causes problems.

Description: If I compile the following "3" line program and run it, it dumps
	core.  I used GDB to detect where, it is happening in __do_global_init
	What I noticed is that the __CTOR__LIST__ length and vectors
	are garbage.  The length is something like 5030 and any vector with
	an odd index is an invalid entry.  The first entry *ppf[0] is valid
	and returns when called.  The second entry(*ppf[1]) is 0, and obviously
	crashes.  If I compile the modified program,ie., take the string
	constant and make it local and not a global the program runs fine.  The
	__CTOR_LIST__ in this case contains two entries both valid.

G++ configuration: Version 1.36.4, i386-sysv-gas (386 System V, GAS COFFencap)
LIBG++: Version 1.36.3
Hardware: 386 IBM/PC clone with 7 megs
Software: Unix System V release 3.0 for the 386 (Microport System V/386)
Submitter: Rich Patterson <osc!rp@pacbell.com>

	I've included the test programs plus the assembler output etc. that
exercise the problem.  If the program is compiled with g++ 1.35 on a Sun-3
or AT&T C++ 2.0, it runs fine.  If you need anymore information, etc. let
me know.  I'd like to get the bugs worked out of the 386 version.

Here is the problem test program:
#include <stream.h>

char   *tops = "This is a test.";

main()
{
        cout << tops;
}

Here is the assembler output:

        .file   "btest.c"
gcc_compiled.:
.text
        .align 4
LC0:
        .double 0d0.00000000000000000000e+00
.globl _tops
LC1:
        .ascii "This is a test.\0"
.data
        .align 4
_tops:
        .long LC1
.text
        .align 4
.globl _main
_main:
        pushl %ebp
        movl %esp,%ebp
        pushl %edi
        pushl %esi
        pushl %ebx
        call ___main
        movl %eax,%eax
        movl $_cout,%ebx
        movl _tops,%esi
        xorl %edi,%edi
        cmpl $0,_cout+4
        jne L714
        pushl %esi
        pushl _cout
        call _sputs__9streambufPCc
        movl %eax,%eax
        addl $8,%esp
        cmpl $-1,%eax
        je L714
        jmp L713
        .align 4
L714:
        movl $1,%edi
L713:
        testl %edi,%edi
        je L716
        movl $2,%eax
        orl $2,_cout+4
L717:
L716:
        movl $_cout,%eax
        jmp L715
        .align 4
L715:
        jmp L712
        .align 4
L712:
        xorl %eax,%eax
        jmp L711
        .align 4
L711:
        leal -12(%ebp),%esp
        popl %ebx
        popl %esi
        popl %edi
        leave
        ret

Here is the version of the program that doesn't dump core:

#include <stream.h>

main()
{
	char   *tops = "This is a test.";

        cout << tops;
}

Here is the assembler produced by that program:

        .file   "btest.c"
gcc_compiled.:
.text
        .align 4
LC0:
        .double 0d0.00000000000000000000e+00
LC1:
        .ascii "This is a test.\0"
        .align 4
.globl _main
_main:
        pushl %ebp
        movl %esp,%ebp
        subl $4,%esp
        pushl %edi
        pushl %esi
        pushl %ebx
        call ___main
        movl %eax,%eax
        movl $LC1,-4(%ebp)
        movl $_cout,%ebx
        movl -4(%ebp),%esi
        xorl %edi,%edi
        cmpl $0,_cout+4
        jne L714
        pushl %esi
        pushl _cout
        call _sputs__9streambufPCc
        movl %eax,%eax
        addl $8,%esp
        cmpl $-1,%eax
        je L714
        jmp L713
        .align 4
L714:
        movl $1,%edi
L713:
        testl %edi,%edi
        je L716
        movl $2,%eax
        orl $2,_cout+4
L717:
L716:
        movl $_cout,%eax
        jmp L715
        .align 4
L715:
        jmp L712
        .align 4
L712:
        xorl %eax,%eax
        jmp L711
        .align 4
L711:
        leal -16(%ebp),%esp
        popl %ebx
        popl %esi
        popl %edi
        leave
        ret

And here is the g++ -v output that was used to compile the program:

/usr2/tmp/g++/g++ -B/usr2/tmp/g++/ -I/usr2/tmp/libg++/g++-include -v -o btest
btest.c
g++ version 1.36.4 (based on GCC 1.36.93)
 /usr/local/lib/gcc-cpp -+ -v -I/usr2/tmp/libg++/g++-include -undef -D__GNUC__
 -D__GNUG__ -D__cplusplus -Dunix -Di386 -D__unix__ -D__i386__ btest.c
 /usr/tmp/cca02562.cpp
GNU CPP version 1.36
 /usr2/tmp/g++/cc1plus /usr/tmp/cca02562.cpp -quiet -dumpbase btest.c -version
 -o /usr/tmp/cca02562.s
GNU C++ version 1.36.4 (based on GCC 1.36.93) (80386, BSD syntax) compiled by
GNU C version 1.36.
default target switches: -m80387
 /usr/local/lib/gcc-as -o btest.o /usr/tmp/cca02562.s
 /usr/local/lib/gcc-ld -o btest /usr/local/lib/gcc-crt0.o btest.o -lg++
 /usr/local/lib/gcc-gnulib -lc

rp@rpx.UUCP (Rich Patterson) (02/11/90)

In article <2019@osc.COM>, rp@osc.COM (Rich Patterson) writes:
> Hi,
> 	Here is a problem that I've found in g++/libg++. Flames --> /dev/null.
> 
> Synopsis: __CTOR_LIST__ is invalid for the following program (G++-1.36.4/
> 	  LIBG++-1.35.3 386 System V GAS and COFF encapsulaton) and dumps
> 	  core.  Initialized global string constant causes problems.
> 

I found the problem.  The problem was I was using ld instead of ld++.  I had
tried ld++ earlier and, ld++ itself core dumped on my while linking.  It had
something to do with cplus-dem.c.  When I built ld++ the first time it
needed 'index' (which is incompatible on SysV) instead of strchr.  I recompiled
it using strchr and both the linker and program work just fine now.

Rich P.
rp@osc	[by day]
{pacbell,amdcad}!osc!rp
rp@rpx	[by night]
{pyramid,zycad}!rpx!rp