Skip site navigation (1)Skip section navigation (2)
Date:      Mon, 27 Jan 2025 09:52:34 -0800
From:      Steve Kargl <sgk@troutmask.apl.washington.edu>
To:        Dimitry Andric <dim@freebsd.org>
Cc:        Konstantin Belousov <kostikbel@gmail.com>, freebsd-hackers@freebsd.org
Subject:   Re: gcc14 static linking ends with segfault
Message-ID:  <Z5fH4vJ3aqEMVZ_O@troutmask.apl.washington.edu>
In-Reply-To: <C09215C1-ABF0-4248-A69A-F0137BBC7E2B@FreeBSD.org>
References:  <Z5aYNdVQdGdVImBG@troutmask.apl.washington.edu> <Z5cRe8tivqpgme1I@kib.kiev.ua> <Z5cnYyWxcT5pk1Wf@troutmask.apl.washington.edu> <C09215C1-ABF0-4248-A69A-F0137BBC7E2B@FreeBSD.org>

next in thread | previous in thread | raw e-mail | index | archive | help
On Mon, Jan 27, 2025 at 04:34:22PM +0100, Dimitry Andric wrote:
> On 27 Jan 2025, at 07:27, Steve Kargl <sgk@troutmask.apl.washington.edu> wrote:
> > 
> > On Mon, Jan 27, 2025 at 06:54:19AM +0200, Konstantin Belousov wrote:
> >> On Sun, Jan 26, 2025 at 12:16:53PM -0800, Steve Kargl wrote:
> >>> In replacing an ancient system with new I re-installed all ports
> >>> including lang/gcc14 of FreeBSD-current.  -current is 2 day old
> >>> sources.
> >>> 
> >>> Consider,
> >>> 
> >>> #include <stdio.h>
> >>> #include <stdlib.h>
> >>> #include "mpfr.h"
> >>> 
> >>> int
> >>> main(void)
> >>> {
> >>>   mpfr_t pi;
> >>>   mpfr_inits2(512, pi, NULL);
> >>>   mpfr_const_pi(pi, MPFR_RNDN);
> >>>   mpfr_printf("pi = %25.20Rf\n", pi);
> >>> // A conscientious programmer cleans up after themself,
> >>> // but on exit the system should take care of memory.
> >>> //   mpfr_clears(pi, NULL);
> >>>   return (0);
> >>> }

(remove some unimportant info)

> >>> So, did someone break the startup files?
> >> Why do you think that startup (crt) files are broken?
> >> Note that they are involved in the trace above, but the lowest frame is
> >> from gmp destructor, i.e. the problem formally happens in the gmp code.
> >> 
> >> Perhaps try to rebuild gmp with debug info to get more information.
> > 
> > You likely correct that its a gmp problem unmasked by the
> > new hardware that I have.  Rebuilding gmp with debugging
> > did not help :(
> > 
> > (gdb) run
> > ...
> > Program received signal SIGSEGV, Segmentation fault.
> > Address not mapped to object.
> > __gmpn_sqr_basecase () at tmp-sqr_basecase.s:222
> > warning: 222    tmp-sqr_basecase.s: No such file or directory
> > (gdb) bt
> > #0  __gmpn_sqr_basecase () at tmp-sqr_basecase.s:222
> > #1  0x00000000004004df in __do_global_dtors_aux ()
> >    at /usr/src/lib/csu/common/crtbegin.c:83
> > #2  0x00000000004c8875 in _fini ()
> > #3  0x000000000046518f in __cxa_finalize (dso=dso@entry=0x0)
> >    at /usr/src/lib/libc/stdlib/atexit.c:234
> > #4  0x0000000000465280 in exit (status=0) at /usr/src/lib/libc/stdlib/exit.c:89
> > #5  0x0000000000454ae9 in __libc_start1 (argc=1, argv=0x7fffffffe738, 
> >    env=0x7fffffffe748, cleanup=<optimized out>, mainX=0x400515 <main>)
> >    at /usr/src/lib/libc/csu/libc_start1.c:172
> > #6  0x00000000004004b0 in _start () at /usr/src/lib/csu/amd64/crt1_s.S:83
> > 
> > It seems gmp's build infrastructure removes tmp files. 
> 
> The sqr_basecase.s thing is a red herring. In fact, the whole mpfr/gmp
> thing is a red herring. :) The actual problem is in the way gcc emits
> the .dtors section:
> 
>   $ readelf --hex-dump=.dtors static-test-clang
> 
>   Hex dump of section '.dtors':
>     0x004f3d30 ffffffff ffffffff 00000000 00000000 ................
> 
>   $ readelf --hex-dump=.dtors static-test-gcc 
> 
>   Hex dump of section '.dtors':
>     0x004efca8 ffffffff ffffffff                   ........
> 

(Debugging info removed to keep this short)

> 
> During gcc's configure phase, I see:
> 
>   checking for .preinit_array/.init_array/.fini_array support... yes
> 
> so initfini_array support is then enabled.

I tried building gcc14 with --enable-initfini-array configure option.
Maybe I should try --disable-initfini-array.

> In libgcc's crtstuff.c, which is used to generate crtbegin.o and
> crtend.o, the definitions of .ctors and .dtors are all conditional on
> #ifndef USE_INITFINI_ARRAY. This is why gcc's crtbegin.o and crtend.o 
> only have .init and .fini sections, but no .ctors or .dtors.

Thanks for the thorough explanation!

You've given me someplace to poke around in crtstuff.c.
I do see in gcc/config/freebsd-spec.h

/* Provide a STARTFILE_SPEC appropriate for FreeBSD.  Here we add
   the magical crtbegin.o file (see crtstuff.c) which provides part
        of the support for getting C++ file-scope static object constructed
        before entering `main'.  */

#define FBSD_STARTFILE_SPEC \
  "%{!shared: \
     %{pg:gcrt1.o%s} %{!pg:%{p:gcrt1.o%s} \
                       %{!p:%{profile:gcrt1.o%s} \
                         %{!profile: \
                            %{pie: Scrt1.o%s;:crt1.o%s}}}}} \
   crti.o%s %{static:crtbeginT.o%s;shared|pie:crtbeginS.o%s;:crtbegin.o%s}"

/* Provide a ENDFILE_SPEC appropriate for FreeBSD.  Here we tack on
   the magical crtend.o file (see crtstuff.c) which provides part of
        the support for getting C++ file-scope static object constructed
        before entering `main', followed by a normal "finalizer" file,
        `crtn.o'.  */

#define FBSD_ENDFILE_SPEC \
  "%{shared|pie:crtendS.o%s;:crtend.o%s} crtn.o%s"

So, the paths must be dealt with by crtstuff.c.

-- 
Steve



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?Z5fH4vJ3aqEMVZ_O>