<div dir="ltr"><div>Here's a fix:</div><div><br></div><div>--- a/lld/COFF/Driver.cpp<br>+++ b/lld/COFF/Driver.cpp<br>@@ -72,6 +72,9 @@ bool link(ArrayRef<const char *> Args, bool CanExitEarly, raw_ostream &Diag) {<br>     exitLld(errorCount() ? 1 : 0);<br><br>   freeArena();<br>+  ObjFile::Instances.clear();<br>+  ImportFile::Instances.clear();<br>+  BitcodeFile::Instances.clear();<br>   return !errorCount();<br> }<br><br></div><div>I don't know how to make a test for this, since it depends on running LLD twice in the same process.</div><div><br></div><div>Can I get some assistance trying to get this fix upstreamed?<br></div><div><div class="gmail_extra"><br><div class="gmail_quote">On Wed, Jul 25, 2018 at 2:18 AM, Andrew Kelley <span dir="ltr"><<a href="mailto:superjoe30@gmail.com" target="_blank">superjoe30@gmail.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div dir="ltr"><div>If you call lld::coff::link twice, the second time gives this backtrace:<br></div><div><br></div><div>     msvcp140d.dll!<wbr>00007ffc35830806()    Unknown</div>>    zig.exe!std::_Debug_pointer<<wbr>lld::coff::Chunk * __ptr64 const>(lld::coff::Chunk * const * _Ptr, const wchar_t * _File, unsigned int _Line) Line 926    C++<br>     zig.exe!std::_Debug_range2<<wbr>lld::coff::Chunk * __ptr64 const * __ptr64>(lld::coff::Chunk * const * _First, lld::coff::Chunk * const * _Last, const wchar_t * _File, unsigned int _Line, std::random_access_iterator_<wbr>tag __formal) Line 958    C++<br>     zig.exe!std::_Debug_range<lld:<wbr>:coff::Chunk * __ptr64 const * __ptr64>(lld::coff::Chunk * const * _First, lld::coff::Chunk * const * _Last, const wchar_t * _File, unsigned int _Line) Line 968    C++<br>     zig.exe!std::vector<lld::coff:<wbr>:Chunk * __ptr64,std::allocator<lld::<wbr>coff::Chunk * __ptr64> >::_Insert<lld::coff::Chunk * __ptr64 const * __ptr64>(std::_Vector_const_<wbr>iterator<std::_Vector_val<std:<wbr>:_Simple_types<lld::coff::<wbr>Chunk *> > > _Where, lld::coff::Chunk * const * _First, lld::coff::Chunk * const * _Last, std::forward_iterator_tag __formal) Line 1421    C++<br>     zig.exe!std::vector<lld::coff:<wbr>:Chunk * __ptr64,std::allocator<lld::<wbr>coff::Chunk * __ptr64> >::insert<lld::coff::Chunk * __ptr64 const * __ptr64>(std::_Vector_const_<wbr>iterator<std::_Vector_val<std:<wbr>:_Simple_types<lld::coff::<wbr>Chunk *> > > _Where, lld::coff::Chunk * const * _First, lld::coff::Chunk * const * _Last) Line 1376    C++<br>     zig.exe!lld::coff::<wbr>SymbolTable::getChunks() Line 311    C++<br>     zig.exe!`anonymous namespace'::Writer::<wbr>createSections() Line 340    C++<br>     zig.exe!`anonymous namespace'::Writer::run() Line 288    C++<br>     zig.exe!lld::coff::<wbr>writeResult() Line 166    C++<br>     zig.exe!lld::coff::<wbr>LinkerDriver::link(llvm::<wbr>ArrayRef<char const *> ArgsArr) Line 1331    C++<br>     zig.exe!lld::coff::link(llvm::<wbr>ArrayRef<char const *> Args, bool CanExitEarly, llvm::raw_ostream & Diag) Line 71    C++<br>     zig.exe!ZigLLDLink(ZigLLVM_<wbr>ObjectFormatType oformat, const char * * args, unsigned __int64 arg_count, void(*)(void *, const char *, unsigned __int64) append_diagnostic, void * context) Line 837    C++<br>     zig.exe!zig_lld_link(ZigLLVM_<wbr>ObjectFormatType oformat, const char * * args, unsigned __int64 arg_count, Buf * diag) Line 435    C++<br>     zig.exe!codegen_link(CodeGen * g, const char * out_file) Line 1020    C++<br>     zig.exe!main(int argc, char * * argv) Line 909    C++<br>     [External Code]    <br><div><br></div><div>It appears that in this code, ObjFile::Instance is garbage data:</div><div><br></div><div>std::vector<Chunk *> SymbolTable::getChunks() {<br>  std::vector<Chunk *> Res;<br>  for (ObjFile *File : ObjFile::Instances) {<br>    ArrayRef<Chunk *> V = File->getChunks();<br>    Res.insert(Res.end(), V.begin(), V.end());<br>  }<br>  return Res;<br>}<br><br></div><div>When I go to the definition of ObjFile::Instances, it appears to be static data:</div><div><br></div><div>  static std::vector<ObjFile *> Instances;<br></div><div><br></div><div>It appears that LLD is not resetting this data between calls. On the other hand, lld::elf::link and lld::macho::link work no problem when called multiple times in the same process.</div><div><br></div><div>My understanding is that there is supposed to be an arena allocator, which is freed here:</div><div><br></div><div>bool link(ArrayRef<const char *> Args, bool CanExitEarly, raw_ostream &Diag) {<br>  // ...<br><br>  Driver = make<LinkerDriver>();<br>  Driver->link(Args);<br><br>  // Call exit() if we can to avoid calling destructors.<br>  if (CanExitEarly)<br>    exitLld(errorCount() ? 1 : 0);<br><br>  freeArena();  // <------ here<br>  return !errorCount();<br>}</div><div><br></div><div>Is there a simple fix for this?</div><div><br></div><div>Downstream issue reference: <a href="https://github.com/ziglang/zig/issues/1289" target="_blank">https://github.com/ziglang/<wbr>zig/issues/1289</a></div><div><br></div><div>Thanks,</div><div>Andrew<br></div></div>
</blockquote></div><br></div></div></div>