[llvm-bugs] [Bug 38739] New: Assertion fails when linking relocatable ELF

via llvm-bugs llvm-bugs at lists.llvm.org
Tue Aug 28 07:29:53 PDT 2018


https://bugs.llvm.org/show_bug.cgi?id=38739

            Bug ID: 38739
           Summary: Assertion fails when linking relocatable ELF
           Product: lld
           Version: unspecified
          Hardware: PC
                OS: All
            Status: NEW
          Severity: normal
          Priority: P
         Component: ELF
          Assignee: unassignedbugs at nondot.org
          Reporter: tdhutt at gmail.com
                CC: llvm-bugs at lists.llvm.org

Ok this is a pretty annoying bug, and I haven't been able to make a nice small
repro yet but I figured you guys might be able to help anyway.

Basically, I'm linking some ELF files something like this:

    ld.lld a.o b.o c.o -o out.elf -L/bar -lbar --entry=_my_start --relocatable
--script=myscript.x

If I do that on the command line it works fine. If I do it via
`lld::elf::link()` it also works fine in release mode. However, in debug mode I
get this assertion failure:

    Assertion failed: (isa<X>(Val) && "cast_or_null<Ty>() argument of
incompatible type!"), function cast_or_null, file
/..../llvm/llvm/include/llvm/Support/Casting.h, line 299.

I debugged it, and here is the backtrace:

-------------------------------------------------------------

* thread #1, queue = 'com.apple.main-thread', stop reason = signal SIGABRT
    frame #0: 0x00007fff63649b66 libsystem_kernel.dylib`__pthread_kill + 10
libsystem_kernel.dylib`__pthread_kill:
->  0x7fff63649b66 <+10>: jae    0x7fff63649b70            ; <+20>
    0x7fff63649b68 <+12>: movq   %rax, %rdi
    0x7fff63649b6b <+15>: jmp    0x7fff63640ae9            ; cerror_nocancel
    0x7fff63649b70 <+20>: retq
Target 0: (Sim_OutOfMemory) stopped.
(lldb) bt
frame* thread #1, queue = 'com.apple.main-thread', stop reason = signal SIGABRT
  * frame #0: 0x00007fff63649b66 libsystem_kernel.dylib`__pthread_kill + 10
    frame #1: 0x00007fff63814080 libsystem_pthread.dylib`pthread_kill + 333
    frame #2: 0x00007fff635a51ae libsystem_c.dylib`abort + 127
    frame #3: 0x00007fff6356d1ac libsystem_c.dylib`__assert_rtn + 320
    frame #4: 0x0000000100ff1e7c
libfoo.dylib`llvm::cast_retty<lld::elf::OutputSection,
lld::elf::SectionBase*>::ret_type llvm::cast_or_null<lld::elf::OutputSection,
lld::elf::SectionBase>(Val=0x0000000111860468) at Casting.h:299
    frame #5: 0x0000000100fef939
libfoo.dylib`lld::elf::InputSection::getParent(this=0x0000000110035a08) const
at InputSection.cpp:308
    frame #6: 0x000000010128d1f0 libfoo.dylib`applySynthetic(Sections=size=1,
Fn=0x00007ffeefbeb820)>) at Writer.cpp:1448
    frame #7: 0x000000010127b14e libfoo.dylib`(anonymous
namespace)::Writer<llvm::object::ELFType<(this=0x00007ffeefbebb88)1, false>
>::finalizeSections() at Writer.cpp:1547
    frame #8: 0x00000001012769a1 libfoo.dylib`(anonymous
namespace)::Writer<llvm::object::ELFType<(this=0x00007ffeefbebb88)1, false>
>::run() at Writer.cpp:430
    frame #9: 0x00000001012768ba libfoo.dylib`void
lld::elf::writeResult<llvm::object::ELFType<(llvm::support::endianness)1,
false> >() at Writer.cpp:129
    frame #10: 0x0000000100ed4aae libfoo.dylib`void
lld::elf::LinkerDriver::link<llvm::object::ELFType<(llvm::support::endianness)1,
false> >(this=0x000000011001b800, Args=0x00007ffeefbed030) at Driver.cpp:1320
    frame #11: 0x0000000100ec44d6
libfoo.dylib`lld::elf::LinkerDriver::main(this=0x000000011001b800,
ArgsArr=ArrayRef<const char *> @ 0x00007ffeefbeccd0) at Driver.cpp:392
    frame #12: 0x0000000100ec3281
libfoo.dylib`lld::elf::link(Args=ArrayRef<const char *> @ 0x00007ffeefbed2b0,
CanExitEarly=false, Error=0x00007ffeefbee000) at Driver.cpp:98

(lldb) frame select 4
frame #4: 0x0000000100ff1e8c
libfoo.dylib`llvm::cast_retty<lld::elf::OutputSection,
lld::elf::SectionBase*>::ret_type llvm::cast_or_null<lld::elf::OutputSection,
lld::elf::SectionBase>(Val=0x0000000111813268) at Casting.h:299
   296  LLVM_NODISCARD inline typename cast_retty<X, Y *>::ret_type
   297  cast_or_null(Y *Val) {
   298    if (!Val) return nullptr;
-> 299    assert(isa<X>(Val) && "cast_or_null<Ty>() argument of incompatible
type!");
   300    return cast<X>(Val);
   301  }
   302
(lldb) frame select 5
frame #5: 0x0000000100fef949
libfoo.dylib`lld::elf::InputSection::getParent(this=0x00000001120aa608) const
at InputSection.cpp:308
   305  }
   306
   307  OutputSection *InputSection::getParent() const {
-> 308    return cast_or_null<OutputSection>(Parent);
   309  }
   310
   311  // Copy SHT_GROUP section contents. Used only for the -r option.
(lldb) frame select 6
frame #6: 0x000000010128d200 libfoo.dylib`applySynthetic(Sections=size=1,
Fn=0x00007ffeefbeb990)>) at Writer.cpp:1448
   1445 static void applySynthetic(const std::vector<SyntheticSection *>
&Sections,
   1446                            std::function<void(SyntheticSection *)> Fn)
{
   1447   for (SyntheticSection *SS : Sections)
-> 1448     if (SS && SS->getParent() && !SS->empty())    // SS is
EhFrameSection*, SS->Parent is SectionBase*
   1449       Fn(SS);
   1450 }
   1451
(lldb) frame select 7
frame #7: 0x000000010127b15e libfoo.dylib`(anonymous
namespace)::Writer<llvm::object::ELFType<(this=0x00007ffeefbebcf8)1, false>
>::finalizeSections() at Writer.cpp:1547
   1544   // This responsible for splitting up .eh_frame section into
   1545   // pieces. The relocation scan uses those pieces, so this has to be
   1546   // earlier.
-> 1547   applySynthetic({InX::EhFrame},
   1548                  [](SyntheticSection *SS) { SS->finalizeContents(); });
   1549
   1550   for (Symbol *S : Symtab->getSymbols())
(lldb) frame select 8
frame #8: 0x00000001012769b1 libfoo.dylib`(anonymous
namespace)::Writer<llvm::object::ELFType<(this=0x00007ffeefbebcf8)1, false>
>::run() at Writer.cpp:430
   427    // completes section contents. For example, we need to add strings
   428    // to the string table, and add entries to .got and .plt.
   429    // finalizeSections does that.
-> 430    finalizeSections();
   431    if (errorCount())
   432      return;
   433
(lldb) frame select 9
frame #9: 0x00000001012768ca libfoo.dylib`void
lld::elf::writeResult<llvm::object::ELFType<(llvm::support::endianness)1,
false> >() at Writer.cpp:129
   126           Script->needsInterpSection();
   127  }
   128
-> 129  template <class ELFT> void elf::writeResult() { Writer<ELFT>().run(); }
   130
   131  template <class ELFT> void Writer<ELFT>::removeEmptyPTLoad() {
   132    llvm::erase_if(Phdrs, [&](const PhdrEntry *P) {

------------------------------------------------------------------

According to LLDB, `SS` is an `EhFrameSection*` with the name `.eh_frame`.
`SS->Parent` is a `SectionBase*` with an empty name. Actually when I ran it
before it had a corrupted name, like the object had been deleted.

As I said this is a little hard to reproduce given that the assertion doesn't
seem to fire on the command line (using a debug build of LLD). LLVM seems to
have a lot of awkward global state, and we do some compilation in the same
process earlier so maybe that is what causes the difference.

Anyway, does anyone have any idea why this might be happening, or what I could
do to debug it further?

Possibly related: https://reviews.llvm.org/D30566

-- 
You are receiving this mail because:
You are on the CC list for the bug.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-bugs/attachments/20180828/3ab6b9c1/attachment-0001.html>


More information about the llvm-bugs mailing list