rui314 / mold

Mold: A Modern Linker 🦠
MIT License
14.38k stars 470 forks source link

Mold segfaults when linking with relocations and debuginfo #567

Closed nuudlman closed 2 years ago

nuudlman commented 2 years ago

Fastest repro is libbsd, but this affected almost all packages when I had these flags set globally.

CFLAGS=-O3 -march=native -g -fPIC -pipe LDFLAGS=-fuse-ld=mold -Wl,-q

System: 5.18.3 zen, Gentoo, 5900hs/16GB Compiler GCC 12.1.1 Mold v1.3.0

Invocation:

/usr/bin/ld.mold -plugin /usr/libexec/gcc/x86_64-pc-linux-gnu/12.1.1/liblto_plugin.so -plugin-opt=/usr/libexec/gcc/x86_64-pc-linux-gnu/12.1.1/lto-wrapper -plugin-opt=-fresolution=/var/tmp/portage/dev-libs/libbsd-0.11.6/temp/ccLopY24.res -plugin-opt=-pass-through=-lgcc -plugin-opt=-pass-through=-lgcc_s -plugin-opt=-pass-through=-lc -plugin-opt=-pass-through=-lgcc -plugin-opt=-pass-through=-lgcc_s --eh-frame-hdr -m elf_x86_64 -shared -o .libs/libbsd.so.0.11.6 /usr/lib/gcc/x86_64-pc-linux-gnu/12.1.1/../../../../lib64/crti.o /usr/lib/gcc/x86_64-pc-linux-gnu/12.1.1/crtbeginS.o -L/usr/lib/gcc/x86_64-pc-linux-gnu/12.1.1 -L/usr/lib/gcc/x86_64-pc-linux-gnu/12.1.1/../../../../lib64 -L/lib/../lib64 -L/usr/lib/../lib64 -L/usr/lib/gcc/x86_64-pc-linux-gnu/12.1.1/../../../../x86_64-pc-linux-gnu/lib -L/usr/lib/gcc/x86_64-pc-linux-gnu/12.1.1/../../.. .libs/arc4random.o .libs/arc4random_uniform.o .libs/bsd_getopt.o .libs/closefrom.o .libs/dehumanize_number.o .libs/err.o .libs/expand_number.o .libs/explicit_bzero.o .libs/fgetln.o .libs/freezero.o .libs/fgetwln.o .libs/flopen.o .libs/fmtcheck.o .libs/fparseln.o .libs/fpurge.o .libs/funopen.o .libs/getbsize.o .libs/getpeereid.o .libs/heapsort.o .libs/humanize_number.o .libs/inet_net_pton.o .libs/md5.o .libs/merge.o .libs/nlist.o .libs/pidfile.o .libs/progname.o .libs/pwcache.o .libs/radixsort.o .libs/readpassphrase.o .libs/reallocarray.o .libs/reallocf.o .libs/recallocarray.o .libs/setmode.o .libs/setproctitle.o .libs/strlcat.o .libs/strlcpy.o .libs/stringlist.o .libs/strmode.o .libs/strnstr.o .libs/strtoi.o .libs/strtonum.o .libs/strtou.o .libs/timeconv.o .libs/unvis.o .libs/vis.o .libs/wcslcat.o .libs/wcslcpy.o .libs/getentropy.o -lmd --version-script=/var/tmp/portage/dev-libs/libbsd-0.11.6/work/libbsd-0.11.6/src/libbsd.map -q -v -soname libbsd.so.0 -lgcc --push-state --as-needed -lgcc_s --pop-state -lc -lgcc --push-state --as-needed -lgcc_s --pop-state /usr/lib/gcc/x86_64-pc-linux-gnu/12.1.1/crtendS.o /usr/lib/gcc/x86_64-pc-linux-gnu/12.1.1/../../../../lib64/crtn.o

dmesg log:

ld.mold[87538]: segfault at 8 ip 00005588aea35703 sp 00007f18ea4cd410 error 4 in mold[5588ae744000+4fb000]
Code: 45 85 c9 0f 8e b6 03 00 00 41 80 7a 70 00 0f 85 47 02 00 00 4d 8b 92 10 01 00 00 49 ff c3 48 83 c1 18 48 83 c0 18 4f 8b 0c ca <4d> 8b 49 08 4d 8b 49 58 44 89 48 f4 44 8b 4e 30 4c 03 49 f8 4c 89

Mold works fine with either relocs enabled, or debuginfo enabled.

Stacktrace:

#0  0x00007ffff728e4dc in __pthread_kill_implementation () from /lib64/libc.so.6
#1  0x00007ffff723e182 in raise () from /lib64/libc.so.6
#2  0x00005555559c930f in mold::elf::fork_child () at elf/subprocess.cc:44
#3  0x0000555555790142 in mold::elf::elf_main<mold::elf::X86_64> (argc=argc@entry=91, argv=argv@entry=0x7fffffffd318) at elf/main.cc:413
#4  0x00005555557bb685 in mold::elf::main (argc=argc@entry=91, argv=argv@entry=0x7fffffffd318) at elf/main.cc:747
#5  0x00005555555a796b in main (argc=91, argv=0x7fffffffd318) at main.cc:87
nuudlman commented 2 years ago

Updated to mold 1.3.1, new stacktrace

#0  0x00007ffff728e4dc in __pthread_kill_implementation () from /lib64/libc.so.6
#1  0x00007ffff723e182 in raise () from /lib64/libc.so.6
#2  0x0000555555930d3f in mold::elf::fork_child () at elf/subprocess.cc:44
#3  0x00005555557046bd in mold::elf::elf_main<mold::elf::X86_64> (argc=<optimized out>, argv=<optimized out>) at elf/main.cc:413
#4  0x00005555555af252 in mold::elf::main (argv=0x7fffffffd348, argc=91) at elf/main.cc:747
#5  main (argc=91, argv=0x7fffffffd348) at /var/tmp/portage/sys-devel/mold-1.3.1/work/mold-1.3.1/main.cc:87
rui314 commented 2 years ago

Can you run mold with --no-fork? By default, mold spawns a subprocess and subprocess does actual linking, so the stacktrace of the parent process doesn't have too much information.

nuudlman commented 2 years ago

here it is:

#0  0x00005555558112d5 in mold::elf::RelocSection<mold::elf::X86_64>::copy_buf(mold::elf::Context<mold::elf::X86_64>&)::{lambda(long)#1}::operator()(long) const (__closure=<optimized out>, 
    i=<optimized out>) at elf/output-chunks.cc:2545
#1  tbb::detail::d1::parallel_for_body_wrapper<mold::elf::RelocSection<mold::elf::X86_64>::copy_buf(mold::elf::Context<mold::elf::X86_64>&)::{lambda(long)#1}, long>::operator()(tbb::detail::d1::blocked_range<long> const&) const (r=..., this=0x7ffff7583258) at /usr/include/oneapi/tbb/parallel_for.h:208
#2  tbb::detail::d1::start_for<tbb::detail::d1::blocked_range<long>, tbb::detail::d1::parallel_for_body_wrapper<mold::elf::RelocSection<mold::elf::X86_64>::copy_buf(mold::elf::Context<mold::elf::X86_64>&)::{lambda(long)#1}, long>, tbb::detail::d1::auto_partitioner const>::run_body(tbb::detail::d1::blocked_range<long>&) (r=..., this=0x7ffff7583200)
    at /usr/include/oneapi/tbb/parallel_for.h:119
#3  tbb::detail::d1::dynamic_grainsize_mode<tbb::detail::d1::adaptive_mode<tbb::detail::d1::auto_partition_type> >::work_balance<tbb::detail::d1::start_for<tbb::detail::d1::blocked_range<long>, tbb::detail::d1::parallel_for_body_wrapper<mold::elf::RelocSection<mold::elf::X86_64>::copy_buf(mold::elf::Context<mold::elf::X86_64>&)::{lambda(long)#1}, long>, tbb::detail::d1::auto_partitioner const>, tbb::detail::d1::blocked_range<long> >(tbb::detail::d1::start_for<tbb::detail::d1::blocked_range<long>, tbb::detail::d1::parallel_for_body_wrapper<mold::elf::RelocSection<mold::elf::X86_64>::copy_buf(mold::elf::Context<mold::elf::X86_64>&)::{lambda(long)#1}, long>, tbb::detail::d1::auto_partitioner const>&, tbb::detail::d1::blocked_range<long>&, tbb::detail::d1::execution_data&) (this=<optimized out>, start=warning: RTTI symbol not found for class 'tbb::detail::d1::start_for<tbb::detail::d1::blocked_range<long>, tbb::detail::d1::parallel_for_body_wrapper<mold::elf::RelocSection<mold::elf::X86_64>::copy_buf(mold::elf::Context<mold::elf::X86_64>&)::{lambda(long)#1}, long>, tbb::detail::d1::auto_partitioner const>'
..., range=..., ed=...) at /usr/include/oneapi/tbb/partitioner.h:447
#4  0x00005555557fef83 in tbb::detail::d1::partition_type_base<tbb::detail::d1::auto_partition_type>::execute<tbb::detail::d1::start_for<tbb::detail::d1::blocked_range<long>, tbb::detail::d1::parallel_for_body_wrapper<mold::elf::RelocSection<mold::elf::X86_64>::copy_buf(mold::elf::Context<mold::elf::X86_64>&)::{lambda(long)#1}, long>, tbb::detail::d1::auto_partitioner const>, tbb::detail::d1::blocked_range<long> >(tbb::detail::d1::start_for<tbb::detail::d1::blocked_range<long>, tbb::detail::d1::parallel_for_body_wrapper<mold::elf::RelocSection<mold::elf::X86_64>::copy_buf(mold::elf::Context<mold::elf::X86_64>&)::{lambda(long)#1}, long>, tbb::detail::d1::auto_partitioner const>&, tbb::detail::d1::blocked_range<long>&, tbb::detail::d1::execution_data&) (ed=..., range=..., start=warning: RTTI symbol not found for class 'tbb::detail::d1::start_for<tbb::detail::d1::blocked_range<long>, tbb::detail::d1::parallel_for_body_wrapper<mold::elf::RelocSection<mold::elf::X86_64>::copy_buf(mold::elf::Context<mold::elf::X86_64>&)::{lambda(long)#1}, long>, tbb::detail::d1::auto_partitioner const>'
..., this=0x7ffff7583278) at /usr/include/oneapi/tbb/partitioner.h:288
#5  tbb::detail::d1::start_for<tbb::detail::d1::blocked_range<long>, tbb::detail::d1::parallel_for_body_wrapper<mold::elf::RelocSection<mold::elf::X86_64>::copy_buf(mold::elf::Context<mold::elf::X86_64>&)::{lambda(long)#1}, long>, tbb::detail::d1::auto_partitioner const>::execute(tbb::detail::d1::execution_data&) (this=0x7ffff7583200, ed=...)
    at /usr/include/oneapi/tbb/parallel_for.h:172
#6  0x00007ffff7ec65db in tbb::detail::r1::task_dispatcher::execute_and_wait(tbb::detail::d1::task*, tbb::detail::d1::wait_context&, tbb::detail::d1::task_group_context&) ()
   from /usr/lib64/libtbb.so.12
#7  0x0000555555776195 in mold::elf::RelocSection<mold::elf::X86_64>::copy_buf (this=<optimized out>, ctx=...) at /usr/include/oneapi/tbb/detail/_task.h:191
#8  0x00005555557484c1 in operator() (chunk=0x200000f2060, __closure=0x7fffffffbbf0) at /usr/lib/gcc/x86_64-pc-linux-gnu/12.1.1/include/g++-v12/bits/allocator.h:174
#9  tbb::detail::d2::parallel_for_each_operator_selector<mold::elf::elf_main<X86_64>(int, char**)::<lambda(mold::elf::Chunk<mold::elf::X86_64>*)> >::call<mold::elf::Chunk<mold::elf::X86_64>*&, tbb::detail::d2::feeder_impl<mold::elf::elf_main<X86_64>(int, char**)::<lambda(mold::elf::Chunk<mold::elf::X86_64>*)>, mold::elf::Chunk<mold::elf::X86_64>*> > (item=<optimized out>, 
    body=...) at /usr/include/oneapi/tbb/parallel_for_each.h:95
#10 tbb::detail::d2::parallel_for_body_wrapper<__gnu_cxx::__normal_iterator<mold::elf::Chunk<mold::elf::X86_64>**, std::vector<mold::elf::Chunk<mold::elf::X86_64>*, std::allocator<mold::elf::Chunk<mold::elf::X86_64>*> > >, mold::elf::elf_main<X86_64>(int, char**)::<lambda(mold::elf::Chunk<mold::elf::X86_64>*)>, mold::elf::Chunk<mold::elf::X86_64>*>::operator() (range=..., 
    this=<optimized out>) at /usr/include/oneapi/tbb/parallel_for_each.h:400
#11 tbb::detail::d1::start_for<tbb::detail::d1::blocked_range<long unsigned int>, tbb::detail::d2::parallel_for_body_wrapper<__gnu_cxx::__normal_iterator<mold::elf::Chunk<mold::elf::X86_64>**, std::vector<mold::elf::Chunk<mold::elf::X86_64>*, std::allocator<mold::elf::Chunk<mold::elf::X86_64>*> > >, mold::elf::elf_main<X86_64>(int, char**)::<lambda(mold::elf::Chunk<mold::elf::X86_64>*)>, mold::elf::Chunk<mold::elf::X86_64>*>, const tbb::detail::d1::auto_partitioner>::run_body (r=..., this=<optimized out>) at /usr/include/oneapi/tbb/parallel_for.h:119
#12 tbb::detail::d1::dynamic_grainsize_mode<tbb::detail::d1::adaptive_mode<tbb::detail::d1::auto_partition_type> >::work_balance<tbb::detail::d1::start_for<tbb::detail::d1::blocked_range<long unsigned int>, tbb::detail::d2::parallel_for_body_wrapper<__gnu_cxx::__normal_iterator<mold::elf::Chunk<mold::elf::X86_64>**, std::vector<mold::elf::Chunk<mold::elf::X86_64>*, std::allocator<mold::elf::Chunk<mold::elf::X86_64>*> > >, mold::elf::elf_main<X86_64>(int, char**)::<lambda(mold::elf::Chunk<mold::elf::X86_64>*)>, mold::elf::Chunk<mold::elf::X86_64>*>, const tbb::detail::d1::auto_partitioner>, tbb::detail::d1::blocked_range<long unsigned int> >(tbb::detail::d1::start_for<tbb::detail::d1::blocked_range<long unsigned int>, tbb::detail::d2::parallel_for_body_wrapper<__gnu_cxx::__normal_iterator<mold::elf::Chunk<mold::elf::X86_64>**, std::vector<mold::elf::Chunk<mold::elf::X86_64>*, std::allocator<mold::elf::Chunk<mold::elf::X86_64>*> > >, mold::elf::elf_main<X86_64>(int, char**)::<lambda(mold::elf::Chunk<mold::elf::X86_64>*)>, mold::elf::Chunk<mold::elf::X86_64>*>, const tbb::detail::d1::auto_partitioner> &, tbb::detail::d1::blocked_range<unsigned long> &, tbb::detail::d1::execution_data &) (this=this@entry=0x7ffff75d3978, start=warning: RTTI symbol not found for class 'tbb::detail::d1::start_for<tbb::detail::d1::blocked_range<unsigned long>, tbb::detail::d2::parallel_for_body_wrapper<__gnu_cxx::__normal_iterator<mold::elf::Chunk<mold::elf::X86_64>**, std::vector<mold::elf::Chunk<mold::elf::X86_64>*, std::allocator<mold::elf::Chunk<mold::elf::X86_64>*> > >, mold::elf::elf_main<mold::elf::X86_64>(int, char**)::{lambda(mold::elf::Chunk<mold::elf::X86_64>*)#4}, mold::elf::Chunk<mold::elf::X86_64>*>, tbb::detail::d1::auto_partitioner const>'
..., range=..., ed=...) at /usr/include/oneapi/tbb/partitioner.h:447
#13 0x00005555557490c3 in tbb::detail::d1::partition_type_base<tbb::detail::d1::auto_partition_type>::execute<tbb::detail::d1::start_for<tbb::detail::d1::blocked_range<long unsigned int>, tbb::detail::d2::parallel_for_body_wrapper<__gnu_cxx::__normal_iterator<mold::elf::Chunk<mold::elf::X86_64>**, std::vector<mold::elf::Chunk<mold::elf::X86_64>*, std::allocator<mold::elf::Chunk<mold::elf::X86_64>*> > >, mold::elf::elf_main<X86_64>(int, char**)::<lambda(mold::elf::Chunk<mold::elf::X86_64>*)>, mold::elf::Chunk<mold::elf::X86_64>*>, const tbb::detail::d1::auto_partitioner>, tbb::detail::d1::blocked_range<long unsigned int> > (ed=..., range=..., start=warning: RTTI symbol not found for class 'tbb::detail::d1::start_for<tbb::detail::d1::blocked_range<unsigned long>, tbb::detail::d2::parallel_for_body_wrapper<__gnu_cxx::__normal_iterator<mold::elf::Chunk<mold::elf::X86_64>**, std::vector<mold::elf::Chunk<mold::elf::X86_64>*, std::allocator<mold::elf::Chunk<mold::elf::X86_64>*> > >, mold::elf::elf_main<mold::elf::X86_64>(int, char**)::{lambda(mold::elf::Chunk<mold::elf::X86_64>*)#4}, mold::elf::Chunk<mold::elf::X86_64>*>, tbb::detail::d1::auto_partitioner const>'
..., this=0x7ffff75d3978) at /usr/include/oneapi/tbb/partitioner.h:288
#14 tbb::detail::d1::start_for<tbb::detail::d1::blocked_range<long unsigned int>, tbb::detail::d2::parallel_for_body_wrapper<__gnu_cxx::__normal_iterator<mold::elf::Chunk<mold::elf::X86_64>**, std::vector<mold::elf::Chunk<mold::elf::X86_64>*, std::allocator<mold::elf::Chunk<mold::elf::X86_64>*> > >, mold::elf::elf_main<X86_64>(int, char**)::<lambda(mold::elf::Chunk<mold::elf::X86_64>*)>, mold::elf::Chunk<mold::elf::X86_64>*>, const tbb::detail::d1::auto_partitioner>::execute(tbb::detail::d1::execution_data &) (this=0x7ffff75d3900, ed=...)
    at /usr/include/oneapi/tbb/parallel_for.h:172
#15 0x00007ffff7ea882b in tbb::detail::r1::arena::process(tbb::detail::r1::thread_data&) () from /usr/lib64/libtbb.so.12
#16 0x00007ffff7ebc53b in tbb::detail::r1::market::process(rml::job&) () from /usr/lib64/libtbb.so.12
#17 0x00007ffff7ec1422 in tbb::detail::r1::rml::private_worker::run() () from /usr/lib64/libtbb.so.12
#18 0x00007ffff7ec17e9 in tbb::detail::r1::rml::private_worker::thread_routine(void*) () from /usr/lib64/libtbb.so.12
#19 0x00007ffff728c6a3 in start_thread (arg=<optimized out>) at pthread_create.c:442
#20 0x00007ffff731252c in clone3 () at ../sysdeps/unix/sysv/linux/x86_64/clone3.S:81
rui314 commented 2 years ago

Does this patch fix your issue?

diff --git a/elf/output-chunks.cc b/elf/output-chunks.cc
index bc14b3ffa..7f36f0b3f 100644
--- a/elf/output-chunks.cc
+++ b/elf/output-chunks.cc
@@ -2530,27 +2530,28 @@ void RelocSection<E>::copy_buf(Context<E> &ctx) {
     for (i64 j = 0; j < rels.size(); j++) {
       const ElfRel<E> &r = rels[j];
       Symbol<E> &sym = *isec.file.symbols[r.r_sym];
       memset(buf + j, 0, sizeof(RelaTy));

-      if (sym.esym().st_type != STT_SECTION && !sym.write_to_symtab) {
-        buf[j].r_type = E::R_NONE;
-        continue;
-      }
-
-      buf[j].r_offset =
-        isec.output_section->shdr.sh_addr + isec.offset + r.r_offset;
+      buf[j].r_type = E::R_NONE;

       if (sym.esym().st_type == STT_SECTION) {
+        if (!sym.get_input_section()->output_section)
+          continue;
         buf[j].r_type = STT_SECTION;
         buf[j].r_sym = sym.get_input_section()->output_section->shndx;
         buf[j].r_addend = isec.get_addend(r) + isec.offset;
       } else {
+        if (!sym.write_to_symtab)
+          continue;
         buf[j].r_type = r.r_type;
         buf[j].r_sym = get_output_sym_idx(sym);
         buf[j].r_addend = isec.get_addend(r);
       }
+
+      buf[j].r_offset =
+        isec.output_section->shdr.sh_addr + isec.offset + r.r_offset;
     }
   });
 }

 #define INSTANTIATE(E)                                                  \
nuudlman commented 2 years ago

Unfortunately it didn't help (I applied it through /etc/portage/patches if that matters). The stacktrace seems to be the same, but here it is for good measure:

#0  0x0000555555810dd1 in mold::elf::RelocSection<mold::elf::X86_64>::copy_buf(mold::elf::Context<mold::elf::X86_64>&)::{lambda(long)#1}::operator()(long) const (__closure=<optimized out>, 
    i=<optimized out>) at elf/output-chunks.cc:2538
#1  tbb::detail::d1::parallel_for_body_wrapper<mold::elf::RelocSection<mold::elf::X86_64>::copy_buf(mold::elf::Context<mold::elf::X86_64>&)::{lambda(long)#1}, long>::operator()(tbb::detail::d1::blocked_range<long> const&) const (r=..., this=0x7ffff75bb958) at /usr/include/oneapi/tbb/parallel_for.h:208
#2  tbb::detail::d1::start_for<tbb::detail::d1::blocked_range<long>, tbb::detail::d1::parallel_for_body_wrapper<mold::elf::RelocSection<mold::elf::X86_64>::copy_buf(mold::elf::Context<mold::elf::X86_64>&)::{lambda(long)#1}, long>, tbb::detail::d1::auto_partitioner const>::run_body(tbb::detail::d1::blocked_range<long>&) (r=..., this=0x7ffff75bb900)
    at /usr/include/oneapi/tbb/parallel_for.h:119
#3  tbb::detail::d1::dynamic_grainsize_mode<tbb::detail::d1::adaptive_mode<tbb::detail::d1::auto_partition_type> >::work_balance<tbb::detail::d1::start_for<tbb::detail::d1::blocked_range<long>, tbb::detail::d1::parallel_for_body_wrapper<mold::elf::RelocSection<mold::elf::X86_64>::copy_buf(mold::elf::Context<mold::elf::X86_64>&)::{lambda(long)#1}, long>, tbb::detail::d1::auto_partitioner const>, tbb::detail::d1::blocked_range<long> >(tbb::detail::d1::start_for<tbb::detail::d1::blocked_range<long>, tbb::detail::d1::parallel_for_body_wrapper<mold::elf::RelocSection<mold::elf::X86_64>::copy_buf(mold::elf::Context<mold::elf::X86_64>&)::{lambda(long)#1}, long>, tbb::detail::d1::auto_partitioner const>&, tbb::detail::d1::blocked_range<long>&, tbb::detail::d1::execution_data&) (this=<optimized out>, start=warning: RTTI symbol not found for class 'tbb::detail::d1::start_for<tbb::detail::d1::blocked_range<long>, tbb::detail::d1::parallel_for_body_wrapper<mold::elf::RelocSection<mold::elf::X86_64>::copy_buf(mold::elf::Context<mold::elf::X86_64>&)::{lambda(long)#1}, long>, tbb::detail::d1::auto_partitioner const>'
..., range=..., ed=...) at /usr/include/oneapi/tbb/partitioner.h:447
#4  0x00005555557fee33 in tbb::detail::d1::partition_type_base<tbb::detail::d1::auto_partition_type>::execute<tbb::detail::d1::start_for<tbb::detail::d1::blocked_range<long>, tbb::detail::d1::parallel_for_body_wrapper<mold::elf::RelocSection<mold::elf::X86_64>::copy_buf(mold::elf::Context<mold::elf::X86_64>&)::{lambda(long)#1}, long>, tbb::detail::d1::auto_partitioner const>, tbb::detail::d1::blocked_range<long> >(tbb::detail::d1::start_for<tbb::detail::d1::blocked_range<long>, tbb::detail::d1::parallel_for_body_wrapper<mold::elf::RelocSection<mold::elf::X86_64>::copy_buf(mold::elf::Context<mold::elf::X86_64>&)::{lambda(long)#1}, long>, tbb::detail::d1::auto_partitioner const>&, tbb::detail::d1::blocked_range<long>&, tbb::detail::d1::execution_data&) (ed=..., range=..., start=warning: RTTI symbol not found for class 'tbb::detail::d1::start_for<tbb::detail::d1::blocked_range<long>, tbb::detail::d1::parallel_for_body_wrapper<mold::elf::RelocSection<mold::elf::X86_64>::copy_buf(mold::elf::Context<mold::elf::X86_64>&)::{lambda(long)#1}, long>, tbb::detail::d1::auto_partitioner const>'
..., this=0x7ffff75bb978) at /usr/include/oneapi/tbb/partitioner.h:288
#5  tbb::detail::d1::start_for<tbb::detail::d1::blocked_range<long>, tbb::detail::d1::parallel_for_body_wrapper<mold::elf::RelocSection<mold::elf::X86_64>::copy_buf(mold::elf::Context<mold::elf::X86_64>&)::{lambda(long)#1}, long>, tbb::detail::d1::auto_partitioner const>::execute(tbb::detail::d1::execution_data&) (this=0x7ffff75bb900, ed=...)
    at /usr/include/oneapi/tbb/parallel_for.h:172
#6  0x00007ffff7ec65db in tbb::detail::r1::task_dispatcher::execute_and_wait(tbb::detail::d1::task*, tbb::detail::d1::wait_context&, tbb::detail::d1::task_group_context&) ()
   from /usr/lib64/libtbb.so.12
#7  0x00005555557761c5 in mold::elf::RelocSection<mold::elf::X86_64>::copy_buf (this=<optimized out>, ctx=...) at /usr/include/oneapi/tbb/detail/_task.h:191
#8  0x0000555555748501 in operator() (chunk=0x200000f21a0, __closure=0x7fffffffbbb0) at /usr/lib/gcc/x86_64-pc-linux-gnu/12.1.1/include/g++-v12/bits/allocator.h:174
#9  tbb::detail::d2::parallel_for_each_operator_selector<mold::elf::elf_main<X86_64>(int, char**)::<lambda(mold::elf::Chunk<mold::elf::X86_64>*)> >::call<mold::elf::Chunk<mold::elf::X86_64>*&, tbb::detail::d2::feeder_impl<mold::elf::elf_main<X86_64>(int, char**)::<lambda(mold::elf::Chunk<mold::elf::X86_64>*)>, mold::elf::Chunk<mold::elf::X86_64>*> > (item=<optimized out>, 
    body=...) at /usr/include/oneapi/tbb/parallel_for_each.h:95
#10 tbb::detail::d2::parallel_for_body_wrapper<__gnu_cxx::__normal_iterator<mold::elf::Chunk<mold::elf::X86_64>**, std::vector<mold::elf::Chunk<mold::elf::X86_64>*, std::allocator<mold::elf::Chunk<mold::elf::X86_64>*> > >, mold::elf::elf_main<X86_64>(int, char**)::<lambda(mold::elf::Chunk<mold::elf::X86_64>*)>, mold::elf::Chunk<mold::elf::X86_64>*>::operator() (range=..., 
    this=<optimized out>) at /usr/include/oneapi/tbb/parallel_for_each.h:400
#11 tbb::detail::d1::start_for<tbb::detail::d1::blocked_range<long unsigned int>, tbb::detail::d2::parallel_for_body_wrapper<__gnu_cxx::__normal_iterator<mold::elf::Chunk<mold::elf::X86_64>**, std::vector<mold::elf::Chunk<mold::elf::X86_64>*, std::allocator<mold::elf::Chunk<mold::elf::X86_64>*> > >, mold::elf::elf_main<X86_64>(int, char**)::<lambda(mold::elf::Chunk<mold::elf::X86_64>*)>, mold::elf::Chunk<mold::elf::X86_64>*>, const tbb::detail::d1::auto_partitioner>::run_body (r=..., this=<optimized out>) at /usr/include/oneapi/tbb/parallel_for.h:119
#12 tbb::detail::d1::dynamic_grainsize_mode<tbb::detail::d1::adaptive_mode<tbb::detail::d1::auto_partition_type> >::work_balance<tbb::detail::d1::start_for<tbb::detail::d1::blocked_range<long unsigned int>, tbb::detail::d2::parallel_for_body_wrapper<__gnu_cxx::__normal_iterator<mold::elf::Chunk<mold::elf::X86_64>**, std::vector<mold::elf::Chunk<mold::elf::X86_64>*, std::allocator<mold::elf::Chunk<mold::elf::X86_64>*> > >, mold::elf::elf_main<X86_64>(int, char**)::<lambda(mold::elf::Chunk<mold::elf::X86_64>*)>, mold::elf::Chunk<mold::elf::X86_64>*>, const tbb::detail::d1::auto_partitioner>, tbb::detail::d1::blocked_range<long unsigned int> >(tbb::detail::d1::start_for<tbb::detail::d1::blocked_range<long unsigned int>, tbb::detail::d2::parallel_for_body_wrapper<__gnu_cxx::__normal_iterator<mold::elf::Chunk<mold::elf::X86_64>**, std::vector<mold::elf::Chunk<mold::elf::X86_64>*, std::allocator<mold::elf::Chunk<mold::elf::X86_64>*> > >, mold::elf::elf_main<X86_64>(int, char**)::<lambda(mold::elf::Chunk<mold::elf::X86_64>*)>, mold::elf::Chunk<mold::elf::X86_64>*>, const tbb::detail::d1::auto_partitioner> &, tbb::detail::d1::blocked_range<unsigned long> &, tbb::detail::d1::execution_data &) (this=this@entry=0x7ffff7553d78, start=warning: RTTI symbol not found for class 'tbb::detail::d1::start_for<tbb::detail::d1::blocked_range<unsigned long>, tbb::detail::d2::parallel_for_body_wrapper<__gnu_cxx::__normal_iterator<mold::elf::Chunk<mold::elf::X86_64>**, std::vector<mold::elf::Chunk<mold::elf::X86_64>*, std::allocator<mold::elf::Chunk<mold::elf::X86_64>*> > >, mold::elf::elf_main<mold::elf::X86_64>(int, char**)::{lambda(mold::elf::Chunk<mold::elf::X86_64>*)#4}, mold::elf::Chunk<mold::elf::X86_64>*>, tbb::detail::d1::auto_partitioner const>'
..., range=..., ed=...) at /usr/include/oneapi/tbb/partitioner.h:447
#13 0x0000555555749103 in tbb::detail::d1::partition_type_base<tbb::detail::d1::auto_partition_type>::execute<tbb::detail::d1::start_for<tbb::detail::d1::blocked_range<long unsigned int>, tbb::detail::d2::parallel_for_body_wrapper<__gnu_cxx::__normal_iterator<mold::elf::Chunk<mold::elf::X86_64>**, std::vector<mold::elf::Chunk<mold::elf::X86_64>*, std::allocator<mold::elf::Chunk<mold::elf::X86_64>*> > >, mold::elf::elf_main<X86_64>(int, char**)::<lambda(mold::elf::Chunk<mold::elf::X86_64>*)>, mold::elf::Chunk<mold::elf::X86_64>*>, const tbb::detail::d1::auto_partitioner>, tbb::detail::d1::blocked_range<long unsigned int> > (ed=..., range=..., start=warning: RTTI symbol not found for class 'tbb::detail::d1::start_for<tbb::detail::d1::blocked_range<unsigned long>, tbb::detail::d2::parallel_for_body_wrapper<__gnu_cxx::__normal_iterator<mold::elf::Chunk<mold::elf::X86_64>**, std::vector<mold::elf::Chunk<mold::elf::X86_64>*, std::allocator<mold::elf::Chunk<mold::elf::X86_64>*> > >, mold::elf::elf_main<mold::elf::X86_64>(int, char**)::{lambda(mold::elf::Chunk<mold::elf::X86_64>*)#4}, mold::elf::Chunk<mold::elf::X86_64>*>, tbb::detail::d1::auto_partitioner const>'
..., this=0x7ffff7553d78) at /usr/include/oneapi/tbb/partitioner.h:288
#14 tbb::detail::d1::start_for<tbb::detail::d1::blocked_range<long unsigned int>, tbb::detail::d2::parallel_for_body_wrapper<__gnu_cxx::__normal_iterator<mold::elf::Chunk<mold::elf::X86_64>**, std::vector<mold::elf::Chunk<mold::elf::X86_64>*, std::allocator<mold::elf::Chunk<mold::elf::X86_64>*> > >, mold::elf::elf_main<X86_64>(int, char**)::<lambda(mold::elf::Chunk<mold::elf::X86_64>*)>, mold::elf::Chunk<mold::elf::X86_64>*>, const tbb::detail::d1::auto_partitioner>::execute(tbb::detail::d1::execution_data &) (this=0x7ffff7553d00, ed=...)
    at /usr/include/oneapi/tbb/parallel_for.h:172
#15 0x00007ffff7ea882b in tbb::detail::r1::arena::process(tbb::detail::r1::thread_data&) () from /usr/lib64/libtbb.so.12
#16 0x00007ffff7ebc53b in tbb::detail::r1::market::process(rml::job&) () from /usr/lib64/libtbb.so.12
#17 0x00007ffff7ec1422 in tbb::detail::r1::rml::private_worker::run() () from /usr/lib64/libtbb.so.12
#18 0x00007ffff7ec17e9 in tbb::detail::r1::rml::private_worker::thread_routine(void*) () from /usr/lib64/libtbb.so.12
#19 0x00007ffff728c6a3 in start_thread (arg=<optimized out>) at pthread_create.c:442
#20 0x00007ffff7311650 in clone () at ../sysdeps/unix/sysv/linux/x86_64/clone.S:100
lkr0n commented 2 years ago

Hello,

I spent some time looking into this and I think the culprit here is a .gnu.warning. section.

When compiling with debuginfo a relocation for this section is generated by the compiler but mold ignores all .gnu.warning. sections, so in mold::elf::RelocSection<mold::elf::X86_64>::copy_buf there is no corresponding InputSection to the relocation of the .gnu.warning. section. This causes a segfault because copy_buf then uses an invalid pointer to the non-existingInputSection.

This is a minimal example which demonstrates the segfault. Compile with gcc -g -Wl,-q -fuse-ld=mold example.c -o example. Segfaults for mold 1.5.0 and gcc 12.1. Code for example.c:

void foo(void){};

static const char foo_warning[] __attribute__((section(".gnu.warning.foo"))) =
        "foo is deprecated, please use the shiny new foobar function";

int main(void) {
    foo();
    return 0;
}

I fixed this by not ignoring .gnu.warning. sections if the emit_relocs option is passed. I have implemented this in PR #744.

Have a good day! Louis

rui314 commented 2 years ago

Should be fixed now.